diff --git a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts index 3730492a688a967d2b088d953e3ab4ae10323f6f..3dbfb202e7e1ce6fe775716a4a5a0590e80be1d7 100644 --- a/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts +++ b/packages/tailwindcss-language-service/src/codeActions/provideInvalidApplyCodeActions.ts @@ -17,7 +17,6 @@ import { cssObjToAst } from '../util/cssObjToAst' import { dset } from 'dset' import selectorParser from 'postcss-selector-parser' import { flatten } from '../util/array' -import { getTextWithoutComments } from '../util/doc' export async function provideInvalidApplyCodeActions( state: State, @@ -25,7 +24,7 @@ params: CodeActionParams, diagnostic: InvalidApplyDiagnostic ): Promise { let document = state.editor.documents.get(params.textDocument.uri) - let documentText = getTextWithoutComments(document, 'css') + let documentText = document.getText() let cssRange: Range let cssText = documentText const { postcss } = state.modules @@ -48,7 +47,7 @@ cssRange = languageBoundaries .filter((b) => b.type === 'css') .find(({ range }) => isWithinRange(diagnostic.range.start, range))?.range if (!cssRange) return [] - cssText = getTextWithoutComments(document, 'css', cssRange) + cssText = document.getText(cssRange) } try { diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts index 716ce2c8a05086bd55fc13265b0e9284f2591666..9eac0b2a078ea62dde38019b51388f1517b305ca 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts @@ -10,7 +10,6 @@ import { closest } from '../util/closest' import { absoluteRange } from '../util/absoluteRange' import { combinations } from '../util/combinations' import dlv from 'dlv' -import { getTextWithoutComments } from '../util/doc' function pathToString(path: string | string[]): string { if (typeof path === 'string') return path @@ -178,7 +177,7 @@ ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range)) } ranges.forEach((range) => { - let text = getTextWithoutComments(document, 'css', range) + let text = document.getText(range) let matches = findAll( /(?\s|^)(?config|theme)\((?['"])(?[^)]+)\k[^)]*\)/g, text diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts index c9a9a75bcf01394dd22defa8c691b1f33c157360..587f1b1f32c44a877b49b7419e4e881df254b282 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidScreenDiagnostics.ts @@ -7,7 +7,6 @@ import { findAll, indexToPosition } from '../util/find' import { closest } from '../util/closest' import { absoluteRange } from '../util/absoluteRange' import dlv from 'dlv' -import { getTextWithoutComments } from '../util/doc' export function getInvalidScreenDiagnostics( state: State, @@ -29,7 +28,7 @@ ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range)) } ranges.forEach((range) => { - let text = getTextWithoutComments(document, 'css', range) + let text = document.getText(range) let matches = findAll(/(?:\s|^)@screen\s+(?[^\s{]+)/g, text) matches.forEach((match) => { diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts index 59f6de7391930cffba61ae94570a334abcc703d9..d6a9c50cc3df9299888696b14ad34fb37bce6892 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidTailwindDirectiveDiagnostics.ts @@ -7,7 +7,6 @@ import { findAll, indexToPosition } from '../util/find' import * as semver from '../util/semver' import { closest } from '../util/closest' import { absoluteRange } from '../util/absoluteRange' -import { getTextWithoutComments } from '../util/doc' export function getInvalidTailwindDirectiveDiagnostics( state: State, @@ -43,7 +42,7 @@ let hasVariantsDirective = state.jit && semver.gte(state.version, '2.1.99') ranges.forEach((range) => { - let text = getTextWithoutComments(document, 'css', range) + let text = document.getText(range) let matches = findAll(regex, text) let valid = [ diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts index 1b6c997abe4119d48fd73b428837f673c1fd08e1..1ede7ecd77d3aafd196d6ba7d16144b89c534093 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts @@ -7,7 +7,6 @@ import { findAll, indexToPosition } from '../util/find' import { closest } from '../util/closest' import { absoluteRange } from '../util/absoluteRange' import * as semver from '../util/semver' -import { getTextWithoutComments } from '../util/doc' export function getInvalidVariantDiagnostics( state: State, @@ -39,7 +38,7 @@ possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v)) } ranges.forEach((range) => { - let text = getTextWithoutComments(document, 'css', range) + let text = document.getText(range) let matches = findAll(/(?:\s|^)@variants\s+(?[^{]+)/g, text) matches.forEach((match) => { diff --git a/packages/tailwindcss-language-service/src/hoverProvider.ts b/packages/tailwindcss-language-service/src/hoverProvider.ts index 5ea1fcb6686d97eb0b8dd71b06f91f5960662a98..836d6879d2516258738685110f7382596ed9c89c 100644 --- a/packages/tailwindcss-language-service/src/hoverProvider.ts +++ b/packages/tailwindcss-language-service/src/hoverProvider.ts @@ -8,7 +8,6 @@ import { validateApply } from './util/validateApply' import { getClassNameParts } from './util/getClassNameAtPosition' import * as jit from './util/jit' import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics' -import { getTextWithoutComments } from './util/doc' export async function doHover( state: State, @@ -24,7 +23,10 @@ function provideCssHelperHover(state: State, document: TextDocument, position: Position): Hover { if (!isCssContext(state, document, position)) return null - const line = getTextWithoutComments(document, 'css').split('\n')[position.line] + const line = document.getText({ + start: { line: position.line, character: 0 }, + end: { line: position.line + 1, character: 0 }, + }) const match = line.match(/(?theme|config)\((?['"])(?[^)]+)\k[^)]*\)/) diff --git a/packages/tailwindcss-language-service/src/util/doc.ts b/packages/tailwindcss-language-service/src/util/doc.ts deleted file mode 100644 index 810f79dd537907593beff2046a23834e2d54e042..0000000000000000000000000000000000000000 --- a/packages/tailwindcss-language-service/src/util/doc.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { TextDocument, Range } from 'vscode-languageserver' - -export function getTextWithoutComments( - doc: TextDocument, - type: 'html' | 'js' | 'jsx' | 'css', - range?: Range -): string -export function getTextWithoutComments(text: string, type: 'html' | 'js' | 'jsx' | 'css'): string -export function getTextWithoutComments( - docOrText: TextDocument | string, - type: 'html' | 'js' | 'jsx' | 'css', - range?: Range -): string { - let text = typeof docOrText === 'string' ? docOrText : docOrText.getText(range) - - if (type === 'js' || type === 'jsx') { - return text.replace(/\/\*.*?\*\//gs, replace).replace(/\/\/.*?$/gms, replace) - } - - if (type === 'css') { - return text.replace(/\/\*.*?\*\//gs, replace) - } - - return text.replace(//gs, replace) -} - -function replace(match: string): string { - return match.replace(/./gs, (char) => (char === '\n' ? '\n' : ' ')) -} diff --git a/packages/tailwindcss-language-service/src/util/find.ts b/packages/tailwindcss-language-service/src/util/find.ts index 5b70d7af2877a05df4af49cf33792d934ab51910..d30ac49a9663ed92c3f4b33f43702a5fcbbb42f5 100644 --- a/packages/tailwindcss-language-service/src/util/find.ts +++ b/packages/tailwindcss-language-service/src/util/find.ts @@ -12,7 +12,6 @@ import { resolveRange } from './resolveRange' import dlv from 'dlv' import { rangesEqual } from './rangesEqual' import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib' -import { getTextWithoutComments } from './doc' export function findAll(re: RegExp, str: string): RegExpMatchArray[] { let match: RegExpMatchArray @@ -75,7 +74,7 @@ export async function findClassNamesInRange( state: State, doc: TextDocument, range?: Range, - mode?: 'html' | 'css' | 'jsx', + mode?: 'html' | 'css', includeCustom: boolean = true ): Promise { const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom) @@ -91,7 +90,7 @@ return flatten(classLists.map(getClassNamesInClassList)) } export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] { - const text = getTextWithoutComments(doc, 'css', range) + const text = doc.getText(range) const matches = findAll( /(@apply\s+)(?[^;}]+?)(?\s*!important)?\s*[;}]/g, text @@ -185,10 +184,9 @@ export async function findClassListsInHtmlRange( state: State, doc: TextDocument, - type: 'html' | 'js' | 'jsx', range?: Range ): Promise { - const text = getTextWithoutComments(doc, type, range) + const text = doc.getText(range) const matches = matchClassAttributes( text, @@ -293,14 +291,14 @@ export async function findClassListsInRange( state: State, doc: TextDocument, range?: Range, - mode?: 'html' | 'css' | 'jsx', + mode?: 'html' | 'css', includeCustom: boolean = true ): Promise { let classLists: DocumentClassList[] if (mode === 'css') { classLists = findClassListsInCssRange(doc, range) } else { - classLists = await findClassListsInHtmlRange(state, doc, mode, range) + classLists = await findClassListsInHtmlRange(state, doc, range) } return dedupeClassLists([ ...classLists, @@ -324,9 +322,7 @@ flatten([ ...(await Promise.all( boundaries .filter((b) => b.type === 'html' || b.type === 'jsx') - .map(({ type, range }) => - findClassListsInHtmlRange(state, doc, type === 'html' ? 'html' : 'jsx', range) - ) + .map(({ range }) => findClassListsInHtmlRange(state, doc, range)) )), ...boundaries .filter((b) => b.type === 'css') @@ -358,7 +354,7 @@ export function findHelperFunctionsInRange( doc: TextDocument, range?: Range ): DocumentHelperFunction[] { - const text = getTextWithoutComments(doc, 'css', range) + const text = doc.getText(range) const matches = findAll( /(?^|\s)(?theme|config)\((?:(?')([^']+)'|(?")([^"]+)")[^)]*\)/gm, text @@ -412,10 +408,8 @@ } if (isCssContext(state, doc, position)) { classNames = await findClassNamesInRange(state, doc, searchRange, 'css') - } else if (isHtmlContext(state, doc, position)) { + } else if (isHtmlContext(state, doc, position) || isJsxContext(state, doc, position)) { classNames = await findClassNamesInRange(state, doc, searchRange, 'html') - } else if (isJsxContext(state, doc, position)) { - classNames = await findClassNamesInRange(state, doc, searchRange, 'jsx') } if (classNames.length === 0) { diff --git a/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts b/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts index 3e972e94e22911343b5ae53ee78e093b8bc11134..1f91fa16b68c0047068425b4dd624ecfab6d5c34 100644 --- a/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts +++ b/packages/tailwindcss-language-service/src/util/getLanguageBoundaries.ts @@ -5,7 +5,6 @@ import { indexToPosition } from './find' import { isJsDoc } from './js' import moo from 'moo' import Cache from 'tmp-cache' -import { getTextWithoutComments } from './doc' export type LanguageBoundary = { type: 'html' | 'js' | 'css' | string; range: Range } @@ -114,22 +113,16 @@ if (cachedBoundaries !== undefined) { return cachedBoundaries } - let isJs = isJsDoc(state, doc) - let defaultType = isVueDoc(doc) ? 'none' - : isHtmlDoc(state, doc) || isSvelteDoc(doc) + : isHtmlDoc(state, doc) || isJsDoc(state, doc) || isSvelteDoc(doc) ? 'html' - : isJs - ? 'jsx' : null if (defaultType === null) { cache.set(cacheKey, null) return null } - - text = getTextWithoutComments(text, isJs ? 'js' : 'html') let lexer = defaultType === 'none' ? vueLexer : defaultLexer lexer.reset(text)