Skip to content

Commit 09f0249

Browse files
committed
wip: suggest reactive statement in <script>
Also add a description
1 parent 94271e8 commit 09f0249

File tree

5 files changed

+82
-33
lines changed

5 files changed

+82
-33
lines changed

src/rules/prefer-destructured-store-props.ts

+46-27
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import type { TSESTree } from "@typescript-eslint/types"
2+
import type { AST } from "svelte-eslint-parser"
23
import { createRule } from "../utils"
34

45
export default createRule("prefer-destructured-store-props", {
56
meta: {
67
docs: {
7-
description: "",
8+
description:
9+
"Destructure values from object stores for better change tracking & fewer redraws",
810
category: "Best Practices",
911
recommended: false,
1012
},
@@ -17,43 +19,60 @@ export default createRule("prefer-destructured-store-props", {
1719
type: "suggestion",
1820
},
1921
create(context) {
22+
let script: AST.SvelteScriptElement
23+
const reports: TSESTree.MemberExpression[] = []
24+
2025
return {
26+
[`SvelteScriptElement`](node: AST.SvelteScriptElement) {
27+
script = node
28+
},
29+
2130
// {$foo.bar + baz}
2231
// should be
2332
// $: ({ bar } = $foo);
2433
// {bar + baz}
2534
[`MemberExpression[object.name=/^\\$/][property.type="Identifier"]`](
2635
node: TSESTree.MemberExpression,
2736
) {
28-
const store = (node.object as TSESTree.Identifier).name
29-
const prop = (node.property as TSESTree.Identifier).name
37+
reports.push(node)
38+
},
3039

31-
return context.report({
32-
node,
33-
messageId: "useDestructuring",
34-
data: {
35-
store,
36-
prop,
37-
},
38-
suggest: [
39-
{
40-
messageId: "fixUseDestructuring",
41-
data: {
42-
store,
43-
prop,
44-
},
40+
[`Program:exit`]() {
41+
reports.forEach((node) => {
42+
const store = (node.object as TSESTree.Identifier).name
43+
const prop = (node.property as TSESTree.Identifier).name
4544

46-
fix(fixer) {
47-
return [
48-
fixer.insertTextBefore(
49-
node,
50-
`$: ({ ${prop} } = ${store});\n`,
51-
),
52-
fixer.replaceText(node, prop),
53-
]
54-
},
45+
context.report({
46+
node,
47+
messageId: "useDestructuring",
48+
data: {
49+
store,
50+
prop,
5551
},
56-
],
52+
suggest: [
53+
{
54+
messageId: "fixUseDestructuring",
55+
data: {
56+
store,
57+
prop,
58+
},
59+
60+
fix(fixer) {
61+
if (!script || !script.endTag) {
62+
return []
63+
}
64+
65+
return [
66+
fixer.insertTextAfterRange(
67+
[script.endTag.range[0], script.endTag.range[0]],
68+
`$: ({ ${prop} } = ${store});\n`,
69+
),
70+
fixer.replaceText(node, prop),
71+
]
72+
},
73+
},
74+
],
75+
})
5776
})
5877
},
5978
}

tests/fixtures/rules/prefer-destructured-store-props/invalid/test01-errors.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
[
22
{
33
"message": "Destructure bar from store $foo for better change tracking & fewer redraws",
4-
"line": 2,
4+
"line": 6,
55
"column": 2,
66
"suggestions": [
77
{
88
"desc": "Using destructuring like $: ({ bar } = $foo); will run faster",
99
"messageId": "fixUseDestructuring",
10-
"output": "<!-- prettier-ignore -->\n{$: ({ bar } = $foo);\nbar}\n{$foo[bar]}\n\n<!-- eslint-disable-next-line dot-notation -- tests -->\n{$foo.bar}\n"
10+
"output": "<!-- prettier-ignore -->\n<script>\n\n$: ({ bar } = $foo);\n</script>\n\n{bar}\n{$foo[bar]}\n\n<!-- eslint-disable-next-line dot-notation -- tests -->\n{$foo.bar}\n"
1111
}
1212
]
1313
},
1414
{
1515
"message": "Destructure bar from store $foo for better change tracking & fewer redraws",
16-
"line": 3,
16+
"line": 7,
1717
"column": 2,
1818
"suggestions": [
1919
{
2020
"desc": "Using destructuring like $: ({ bar } = $foo); will run faster",
2121
"messageId": "fixUseDestructuring",
22-
"output": "<!-- prettier-ignore -->\n{$foo.bar}\n{$: ({ bar } = $foo);\nbar}\n\n<!-- eslint-disable-next-line dot-notation -- tests -->\n{$foo.bar}\n"
22+
"output": "<!-- prettier-ignore -->\n<script>\n\n$: ({ bar } = $foo);\n</script>\n\n{$foo.bar}\n{bar}\n\n<!-- eslint-disable-next-line dot-notation -- tests -->\n{$foo.bar}\n"
2323
}
2424
]
2525
},
2626
{
2727
"message": "Destructure bar from store $foo for better change tracking & fewer redraws",
28-
"line": 6,
28+
"line": 10,
2929
"column": 2,
3030
"suggestions": [
3131
{
3232
"desc": "Using destructuring like $: ({ bar } = $foo); will run faster",
3333
"messageId": "fixUseDestructuring",
34-
"output": "<!-- prettier-ignore -->\n{$foo.bar}\n{$foo[bar]}\n\n<!-- eslint-disable-next-line dot-notation -- tests -->\n{$: ({ bar } = $foo);\nbar}\n"
34+
"output": "<!-- prettier-ignore -->\n<script>\n\n$: ({ bar } = $foo);\n</script>\n\n{$foo.bar}\n{$foo[bar]}\n\n<!-- eslint-disable-next-line dot-notation -- tests -->\n{bar}\n"
3535
}
3636
]
3737
}

tests/fixtures/rules/prefer-destructured-store-props/invalid/test01-input.svelte

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
<!-- prettier-ignore -->
2+
<script>
3+
4+
</script>
5+
26
{$foo.bar}
37
{$foo[bar]}
48

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"message": "Destructure bar from store $foo for better change tracking & fewer redraws",
4+
"line": 2,
5+
"column": 2,
6+
"suggestions": null
7+
},
8+
{
9+
"message": "Destructure bar from store $foo for better change tracking & fewer redraws",
10+
"line": 3,
11+
"column": 2,
12+
"suggestions": null
13+
},
14+
{
15+
"message": "Destructure bar from store $foo for better change tracking & fewer redraws",
16+
"line": 6,
17+
"column": 2,
18+
"suggestions": null
19+
}
20+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<!-- prettier-ignore -->
2+
{$foo.bar}
3+
{$foo[bar]}
4+
5+
<!-- eslint-disable-next-line dot-notation -- tests -->
6+
{$foo.bar}

0 commit comments

Comments
 (0)