From 4be5d9d0820980016ea45c5ee8d17a6846ea1e43 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Fri, 25 Feb 2022 13:20:02 +0000 Subject: [PATCH] Detect conflicting multi-rule classes (#498) --- .../diagnostics/getCssConflictDiagnostics.ts | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts index c061ec4..4459d24 100644 --- a/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts +++ b/packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts @@ -25,42 +25,40 @@ export async function getCssConflictDiagnostics( classNames.forEach((className, index) => { if (state.jit) { let { rules } = jit.generateRules(state, [className.className]) - if (rules.length !== 1) { + if (rules.length === 0) { return } - let rule = rules[0] - let context: string[] - let properties = [] - rule.walkDecls(({ prop }) => { - properties.push(prop) + + let info: Array<{ context: string[]; properties: string[] }> = rules.map((rule) => { + let properties: string[] = [] + rule.walkDecls(({ prop }) => { + properties.push(prop) + }) + let context = jit.getRuleContext(state, rule, className.className) + return { context, properties } }) let otherClassNames = classNames.filter((_className, i) => i !== index) let conflictingClassNames = otherClassNames.filter((otherClassName) => { - let { rules } = jit.generateRules(state, [otherClassName.className]) - if (rules.length !== 1) { + let { rules: otherRules } = jit.generateRules(state, [otherClassName.className]) + if (otherRules.length !== rules.length) { return false } - let otherRule = rules[0] - - let otherProperties = [] - otherRule.walkDecls(({ prop }) => { - otherProperties.push(prop) - }) - - if (!equal(properties, otherProperties)) { - return false - } - - if (!context) { - context = jit.getRuleContext(state, rule, className.className) - } - let otherContext = jit.getRuleContext(state, otherRule, otherClassName.className) - - if (!equal(context, otherContext)) { - return false + for (let i = 0; i < otherRules.length; i++) { + let rule = otherRules[i] + let properties: string[] = [] + rule.walkDecls(({ prop }) => { + properties.push(prop) + }) + if (!equal(info[i].properties, properties)) { + return false + } + let context = jit.getRuleContext(state, rule, otherClassName.className) + if (!equal(info[i].context, context)) { + return false + } } return true @@ -77,9 +75,7 @@ export async function getCssConflictDiagnostics( severity === 'error' ? 1 /* DiagnosticSeverity.Error */ : 2 /* DiagnosticSeverity.Warning */, - message: `'${className.className}' applies the same CSS ${ - properties.length === 1 ? 'property' : 'properties' - } as ${joinWithAnd( + message: `'${className.className}' applies the same CSS properties as ${joinWithAnd( conflictingClassNames.map( (conflictingClassName) => `'${conflictingClassName.className}'` )