Skip to content

Commit 9056556

Browse files
authored
Fix false positives for component in prefer-class-directive rule (#178)
* Fix false positives for component in `prefer-class-directive` rule * refactor
1 parent 24fd1f8 commit 9056556

File tree

8 files changed

+76
-23
lines changed

8 files changed

+76
-23
lines changed

src/rules/prefer-class-directive.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import type { AST } from "svelte-eslint-parser"
22
import type * as ESTree from "estree"
33
import { createRule } from "../utils"
4-
import { getStringIfConstant, needParentheses } from "../utils/ast-utils"
4+
import {
5+
getStringIfConstant,
6+
isHTMLElementLike,
7+
needParentheses,
8+
} from "../utils/ast-utils"
59
import type { Rule } from "eslint"
610

711
export default createRule("prefer-class-directive", {
@@ -348,12 +352,15 @@ export default createRule("prefer-class-directive", {
348352
}
349353

350354
return {
351-
"SvelteElement > SvelteStartTag > SvelteAttribute"(
355+
"SvelteStartTag > SvelteAttribute"(
352356
node: AST.SvelteAttribute & {
353-
parent: AST.SvelteStartTag & { parent: AST.SvelteElement }
357+
parent: AST.SvelteStartTag
354358
},
355359
) {
356-
if (node.key.name !== "class") {
360+
if (
361+
!isHTMLElementLike(node.parent.parent) ||
362+
node.key.name !== "class"
363+
) {
357364
return
358365
}
359366

src/rules/prefer-style-directive.ts

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
} from "../utils/css-utils"
99
import { parseStyleAttributeValue } from "../utils/css-utils"
1010
import type { RuleFixer } from "../types"
11+
import { isHTMLElementLike } from "../utils/ast-utils"
1112

1213
/** Checks wether the given node is string literal or not */
1314
function isStringLiteral(
@@ -222,7 +223,10 @@ export default createRule("prefer-style-directive", {
222223
parent: AST.SvelteStartTag
223224
},
224225
) {
225-
if (!isHTMLElement(node.parent.parent) || node.key.name !== "style") {
226+
if (
227+
!isHTMLElementLike(node.parent.parent) ||
228+
node.key.name !== "style"
229+
) {
226230
return
227231
}
228232
const root = parseStyleAttributeValue(node, context)
@@ -231,23 +235,5 @@ export default createRule("prefer-style-directive", {
231235
}
232236
},
233237
}
234-
235-
/** Checks whether the given node is the html element node. */
236-
function isHTMLElement(
237-
node:
238-
| AST.SvelteElement
239-
| AST.SvelteScriptElement
240-
| AST.SvelteStyleElement,
241-
) {
242-
if (node.type === "SvelteElement") {
243-
if (node.kind === "html") {
244-
return true
245-
}
246-
if (node.kind === "special") {
247-
return node.name.name === "svelte:element"
248-
}
249-
}
250-
return false
251-
}
252238
},
253239
})

src/utils/ast-utils.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ export function needParentheses(
9898
return false
9999
}
100100

101+
/** Checks whether the given node is the html element node or <svelte:element> node. */
102+
export function isHTMLElementLike(
103+
node:
104+
| SvAST.SvelteElement
105+
| SvAST.SvelteScriptElement
106+
| SvAST.SvelteStyleElement,
107+
): node is
108+
| SvAST.SvelteHTMLElement
109+
| (SvAST.SvelteSpecialElement & {
110+
name: SvAST.SvelteName & { name: "svelte:element" }
111+
}) {
112+
if (node.type !== "SvelteElement") {
113+
return false
114+
}
115+
116+
switch (node.kind) {
117+
case "html":
118+
return true
119+
case "special":
120+
return node.name.name === "svelte:element"
121+
default:
122+
return false
123+
}
124+
}
125+
101126
/**
102127
* Find the attribute from the given element node
103128
*/
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"message": "Unexpected class using the ternary operator.",
4+
"line": 6,
5+
"column": 41
6+
}
7+
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
let expression = "div"
3+
let current = "foo"
4+
</script>
5+
6+
<svelte:element this={expression} class={current === "foo" ? "selected" : ""} />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
let expression = "div"
3+
let current = "foo"
4+
</script>
5+
6+
<svelte:element this={expression} class:selected={current === "foo"} />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
import Component from "./Component.svelte"
3+
let current = "foo"
4+
</script>
5+
6+
<Component class={current === "foo" ? "selected" : ""} />
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
let foo = Math.random()
3+
let current = "foo"
4+
</script>
5+
6+
<div>
7+
{#if foo > 0.5}
8+
<svelte:self class={current === "foo" ? "selected" : ""} />
9+
{/if}
10+
</div>

0 commit comments

Comments
 (0)