Skip to content

Commit

Permalink
Fix: Incorrect collision warning highlighting, resolved #353
Browse files Browse the repository at this point in the history
  • Loading branch information
0Miles committed Jun 23, 2024
1 parent 64c75c6 commit e301eac
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ export default function filterCollisionClasses(classNames: string[], css: Master
const collisionClassesRecord: Record<string, string[]> = {}
for (let i = 0; i < classNames.length; i++) {
const className = classNames[i]
const rule = validRules.find((eachValidRule) => eachValidRule.className === className)
const rule = validRules.find((eachValidRule) => eachValidRule.name === className)
const collisionClasses = []
if (rule) {
for (let j = 0; j < classNames.length; j++) {
const compareClassName = classNames[j]
const compareRule = validRules.find((eachValidRule) => eachValidRule.className === compareClassName)
const compareRule = validRules.find((eachValidRule) => eachValidRule.name === compareClassName)
if (i !== j && compareRule
&& areRulesDuplicated(rule, compareRule)
&& areRuleStatesEqual(rule, compareRule)
&& areRulesDuplicated(rule as any, compareRule as any)
&& areRuleStatesEqual(rule as any, compareRule as any)
) {
collisionClasses.push(compareClassName)
}
Expand Down
5 changes: 4 additions & 1 deletion packages/eslint-plugin/src/rules/class-collision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export default createRule({
const sourceCode = context.sourceCode
const sourceCodeLines = sourceCode.lines
const nodeStartLine = node.loc.start.line
const nodeStartColumn = node.loc.start.column
const nodeEndLine = node.loc.end.line
const nodeEndColumn = node.loc.end.column
// todo css
const collisionClassesRecord = filterCollisionClasses(classNames, css)
for (const className in collisionClassesRecord) {
Expand All @@ -42,8 +44,9 @@ export default createRule({
const regexSafe = collisionClassName.replace(/(\\|\.|\(|\)|\[|\]|\{|\}|\+|\*|\?|\^|\$|\||\/)/g, '\\$1')
fixClassNames = fixClassNames.replace(new RegExp(`\\s+${regexSafe}|${regexSafe}\\s+`), '')
}

context.report({
loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeStartColumn, nodeEndLine, nodeEndColumn),
messageId: 'collisionClass',
data: {
message: `"${className}" applies the same CSS declarations as ${collisionClassNamesMsg}.`,
Expand Down
4 changes: 3 additions & 1 deletion packages/eslint-plugin/src/rules/class-order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,12 @@ export default createRule({

const sourceCodeLines = sourceCode.lines
const nodeStartLine = node.loc.start.line
const nodeStartColumn = node.loc.start.column
const nodeEndLine = node.loc.end.line
const nodeEndColumn = node.loc.end.column

context.report({
loc: findLoc(originalClassNamesValue, sourceCodeLines, nodeStartLine, nodeEndLine),
loc: findLoc(originalClassNamesValue, sourceCodeLines, nodeStartLine, nodeStartColumn, nodeEndLine, nodeEndColumn),
messageId: 'invalidClassOrder',
fix: function (fixer) {
return fixer.replaceTextRange([start, end], validatedClassNamesValue)
Expand Down
7 changes: 5 additions & 2 deletions packages/eslint-plugin/src/rules/class-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,25 @@ export default createRule({
const sourceCode = context.sourceCode
const sourceCodeLines = sourceCode.lines
const nodeStartLine = node.loc.start.line
const nodeStartColumn = node.loc.start.column
const nodeEndLine = node.loc.end.line
const nodeEndColumn = node.loc.end.column

for (const className of classNames) {
const { matched, errors } = validate(className, css)
if (errors.length > 0) {
for (const error of errors) {
if (matched) {
context.report({
loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeStartColumn, nodeEndLine, nodeEndColumn),
messageId: 'invalidClass',
data: {
message: error.message + '.',
}
})
} else if (options.disallowUnknownClass) {
context.report({
loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeEndLine),
loc: findLoc(className, sourceCodeLines, nodeStartLine, nodeStartColumn, nodeEndLine, nodeEndColumn),
messageId: 'disallowUnknownClass',
data: {
message: `"${className}" is not a valid or known class.`
Expand Down
6 changes: 5 additions & 1 deletion packages/eslint-plugin/src/utils/find-loc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { indexOfAll } from './index-of-all'

export default function findLoc(text, lines, startLine, endLine) {
export default function findLoc(text, lines, startLine, startColumn, endLine, endColumn) {
const targetLines = text.match(/.+(?:\r\n|\n)?/g)

let checkingTargetLine = 0
Expand All @@ -15,6 +15,10 @@ export default function findLoc(text, lines, startLine, endLine) {
if (indexes.length > 0) {
for (const index of indexes) {

if (i === startLine && index < startColumn || i === endLine && index > endColumn) {
continue
}

if ((index !== 0 && sourceCodeLine[index - 1].match(/\w/)) ||
(index + content.length < sourceCodeLine.length && sourceCodeLine[index + content.length].match(/\w/))) {
continue
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/utils/parse-node-recursive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function parseNodeRecursive(rootNode, childNode, cb, skipConditional = fa
}

parseNodeRecursive(
rootNode,
prop,
isUsedByClassNamesPlugin ? prop.key : prop.value,
cb,
skipConditional,
Expand Down
3 changes: 2 additions & 1 deletion packages/eslint-plugin/tests/class-matching/styles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ new RuleTester({
}
}).run('class matching styles', rule, {
valid: [
{ code: 'export default { styles: { btn: "block" } }' }
{ code: 'export default { styles: { btn: "block" } }' },
{ code: 'export default { styles: { btn: { xs: "font: 12 h: 6x px: 2x r: 2x", rounded: { xs: "font: 12 h: 6x px: 2x r: 2x" } } } }' }
],
invalid: [
{ code: 'export default { styles: { btn: "bg:error" } }', errors: [{ messageId: 'invalidClass' }] },
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/tests/find-loc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('findLoc', () => {
it('Causes incorrect class selection when there is only one character #345', () => {
const text = 'f'
const lines = ['font:12 font:24@sm m:32 block font:32@md mb:48 f', 'bg:indigo font:']
const result = findLoc(text, lines, 1, 2)
const result = findLoc(text, lines, 1, 0, 2, 0)
expect(result).toEqual({ start: { line: 1, column: 47 }, end: { line: 1, column: 48 } })
})
})

0 comments on commit e301eac

Please sign in to comment.