diff --git a/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts index e73aab6..4459d24 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts @@ -20,9 +20,7 @@ export async function getCssConflictDiagnostics( const classLists = await findClassListsInDocument(state, document) classLists.forEach((classList) => { - const classNames = Array.isArray(classList) - ? classList.flatMap(getClassNamesInClassList) - : getClassNamesInClassList(classList) + const classNames = getClassNamesInClassList(classList) classNames.forEach((className, index) => { if (state.jit) { diff --git a/packages/tailwindcss-language-service/src/diagnostics/getRecommendedVariantOrderDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getRecommendedVariantOrderDiagnostics.ts index 51e8e82..2361957 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getRecommendedVariantOrderDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getRecommendedVariantOrderDiagnostics.ts @@ -22,7 +22,7 @@ export async function getRecommendedVariantOrderDiagnostics( let diagnostics: RecommendedVariantOrderDiagnostic[] = [] const classLists = await findClassListsInDocument(state, document) - classLists.flat().forEach((classList) => { + classLists.forEach((classList) => { const classNames = getClassNamesInClassList(classList) classNames.forEach((className) => { let { rules } = jit.generateRules(state, [className.className]) diff --git a/packages/tailwindcss-language-service/src/documentColorProvider.ts b/packages/tailwindcss-language-service/src/documentColorProvider.ts index f40b93a..081d1c0 100644 --- a/packages/tailwindcss-language-service/src/documentColorProvider.ts +++ b/packages/tailwindcss-language-service/src/documentColorProvider.ts @@ -20,7 +20,7 @@ export async function getDocumentColors( if (settings.tailwindCSS.colorDecorators === false) return colors let classLists = await findClassListsInDocument(state, document) - classLists.flat().forEach((classList) => { + classLists.forEach((classList) => { let classNames = getClassNamesInClassList(classList) classNames.forEach((className) => { let color = getColor(state, className.className) diff --git a/packages/tailwindcss-language-service/src/util/find.ts b/packages/tailwindcss-language-service/src/util/find.ts index d0ad266..d9a23c4 100644 --- a/packages/tailwindcss-language-service/src/util/find.ts +++ b/packages/tailwindcss-language-service/src/util/find.ts @@ -77,15 +77,7 @@ export async function findClassNamesInRange( includeCustom: boolean = true ): Promise { const classLists = await findClassListsInRange(state, doc, range, mode, includeCustom) - return flatten( - classLists.flatMap((classList) => { - if (Array.isArray(classList)) { - return classList.map(getClassNamesInClassList) - } else { - return [getClassNamesInClassList(classList)] - } - }) - ) + return flatten(classLists.map(getClassNamesInClassList)) } export async function findClassNamesInDocument( @@ -93,15 +85,7 @@ export async function findClassNamesInDocument( doc: TextDocument ): Promise { const classLists = await findClassListsInDocument(state, doc) - return flatten( - classLists.flatMap((classList) => { - if (Array.isArray(classList)) { - return classList.map(getClassNamesInClassList) - } else { - return [getClassNamesInClassList(classList)] - } - }) - ) + return flatten(classLists.map(getClassNamesInClassList)) } export function findClassListsInCssRange(doc: TextDocument, range?: Range): DocumentClassList[] { @@ -198,7 +182,7 @@ export async function findClassListsInHtmlRange( state: State, doc: TextDocument, range?: Range -): Promise> { +): Promise { const text = doc.getText(range) const matches = matchClassAttributes( @@ -206,7 +190,7 @@ export async function findClassListsInHtmlRange( (await state.editor.getConfiguration(doc.uri)).tailwindCSS.classAttributes ) - const result: Array = [] + const result: DocumentClassList[] = [] matches.forEach((match) => { const subtext = text.substr(match.index + match[0].length - 1) @@ -217,11 +201,9 @@ export async function findClassListsInHtmlRange( : getClassAttributeLexer() lexer.reset(subtext) - let classLists: Array<{ value: string; offset: number } | { value: string; offset: number }[]> = - [] - let rootClassList: { value: string; offset: number }[] = [] + let classLists: { value: string; offset: number }[] = [] + let token: moo.Token let currentClassList: { value: string; offset: number } - let depth = 0 try { for (let token of lexer) { @@ -236,53 +218,56 @@ export async function findClassListsInHtmlRange( } } else { if (currentClassList) { - if (depth === 0) { - rootClassList.push({ - value: currentClassList.value, - offset: currentClassList.offset, - }) - } else { - classLists.push({ - value: currentClassList.value, - offset: currentClassList.offset, - }) - } + classLists.push({ + value: currentClassList.value, + offset: currentClassList.offset, + }) } currentClassList = undefined } - if (token.type === 'lbrace') { - depth += 1 - } else if (token.type === 'rbrace') { - depth -= 1 - } } } catch (_) {} if (currentClassList) { - if (depth === 0) { - rootClassList.push({ - value: currentClassList.value, - offset: currentClassList.offset, - }) - } else { - classLists.push({ - value: currentClassList.value, - offset: currentClassList.offset, - }) - } + classLists.push({ + value: currentClassList.value, + offset: currentClassList.offset, + }) } - classLists.push(rootClassList) - result.push( ...classLists - .map((classList) => { - if (Array.isArray(classList)) { - return classList - .map((classList) => resolveClassList(classList, text, match, range)) - .filter((x) => x !== null) - } else { - return resolveClassList(classList, text, match, range) + .map(({ value, offset }) => { + if (value.trim() === '') { + return null + } + + const before = value.match(/^\s*/) + const beforeOffset = before === null ? 0 : before[0].length + const after = value.match(/\s*$/) + const afterOffset = after === null ? 0 : -after[0].length + + const start = indexToPosition( + text, + match.index + match[0].length - 1 + offset + beforeOffset + ) + const end = indexToPosition( + text, + match.index + match[0].length - 1 + offset + value.length + afterOffset + ) + + return { + classList: value.substr(beforeOffset, value.length + afterOffset), + range: { + start: { + line: (range?.start.line || 0) + start.line, + character: (end.line === 0 ? range?.start.character || 0 : 0) + start.character, + }, + end: { + line: (range?.start.line || 0) + end.line, + character: (end.line === 0 ? range?.start.character || 0 : 0) + end.character, + }, + }, } }) .filter((x) => x !== null) @@ -292,51 +277,14 @@ export async function findClassListsInHtmlRange( return result } -function resolveClassList( - classList: { value: string; offset: number }, - text: string, - match: RegExpMatchArray, - range?: Range -): DocumentClassList { - let { value, offset } = classList - if (value.trim() === '') { - return null - } - - const before = value.match(/^\s*/) - const beforeOffset = before === null ? 0 : before[0].length - const after = value.match(/\s*$/) - const afterOffset = after === null ? 0 : -after[0].length - - const start = indexToPosition(text, match.index + match[0].length - 1 + offset + beforeOffset) - const end = indexToPosition( - text, - match.index + match[0].length - 1 + offset + value.length + afterOffset - ) - - return { - classList: value.substr(beforeOffset, value.length + afterOffset), - range: { - start: { - line: (range?.start.line || 0) + start.line, - character: (end.line === 0 ? range?.start.character || 0 : 0) + start.character, - }, - end: { - line: (range?.start.line || 0) + end.line, - character: (end.line === 0 ? range?.start.character || 0 : 0) + end.character, - }, - }, - } -} - export async function findClassListsInRange( state: State, doc: TextDocument, range?: Range, mode?: 'html' | 'css', includeCustom: boolean = true -): Promise> { - let classLists: Array +): Promise { + let classLists: DocumentClassList[] if (mode === 'css') { classLists = findClassListsInCssRange(doc, range) } else { @@ -348,7 +296,7 @@ export async function findClassListsInRange( export async function findClassListsInDocument( state: State, doc: TextDocument -): Promise> { +): Promise { if (isCssDoc(state, doc)) { return findClassListsInCssRange(doc) }