Skip to content

Commit 6b8edb4

Browse files
committed
fix if statement and support context module
1 parent a86eac8 commit 6b8edb4

File tree

7 files changed

+71
-7
lines changed

7 files changed

+71
-7
lines changed

Diff for: src/rules/valid-context-access.ts

+39-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export default createRule("valid-context-access", {
88
description:
99
"context functions must be called during component initialization.",
1010
category: "Possible Errors",
11-
// TODO Switch to recommended in the major version.
1211
recommended: false,
1312
},
1413
schema: [],
@@ -19,7 +18,28 @@ export default createRule("valid-context-access", {
1918
type: "problem",
2019
},
2120
create(context) {
22-
const scopeManager = context.getSourceCode().scopeManager
21+
// // This rule doesn't check other than Svelte files.
22+
if (!context.parserServices.isSvelte) {
23+
return {}
24+
}
25+
26+
// Extract <script> blocks that is not module=context.
27+
const sourceCode = context.getSourceCode()
28+
const scriptNotModuleElements = sourceCode.ast.body.filter((b) => {
29+
if (b.type !== "SvelteScriptElement") return false
30+
const isModule = b.startTag.attributes.some((a) => {
31+
return (
32+
a.type === "SvelteAttribute" &&
33+
a.key.name === "context" &&
34+
a.value.some(
35+
(v) => v.type === "SvelteLiteral" && v.value === "module",
36+
)
37+
)
38+
})
39+
return !isModule
40+
})
41+
42+
const scopeManager = sourceCode.scopeManager
2343
const toplevelScope =
2444
scopeManager.globalScope?.childScopes.find(
2545
(scope) => scope.type === "module",
@@ -53,17 +73,32 @@ export default createRule("valid-context-access", {
5373
return []
5474
}
5575

76+
/** Return true if the node is there inside of <script> block that is not module=context. */
77+
function isInsideOfSvelteScriptElement(node: TSESTree.Node) {
78+
for (const script of scriptNotModuleElements) {
79+
if (
80+
node.range[0] >= script.range[0] &&
81+
node.range[1] <= script.range[1]
82+
) {
83+
return true
84+
}
85+
}
86+
return false
87+
}
88+
5689
/** Let's lint! */
5790
function doLint(
5891
visitedCallExpressions: TSESTree.CallExpression[],
5992
contextCallExpression: TSESTree.CallExpression,
6093
currentNode: TSESTree.CallExpression,
6194
) {
62-
let { parent } = currentNode
63-
if (parent?.type !== "ExpressionStatement") {
95+
// Report if context function is called outside of <script> block.
96+
if (!isInsideOfSvelteScriptElement(currentNode)) {
6497
report(contextCallExpression)
6598
return
6699
}
100+
101+
let { parent } = currentNode
67102
while (parent) {
68103
parent = parent.parent
69104
if (

Diff for: tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
const something = () => {
44
setContext("answer", 42)
55
}
6-
7-
something()
86
</script>
97

108
<button on:click={() => something()}>Click Me</button>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- message: Do not call setContext except during component initialization.
2+
line: 3
3+
column: 3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script context="module">
2+
import { setContext } from "svelte"
3+
setContext("answer", 42)
4+
</script>

Diff for: tests/fixtures/rules/valid-context-access/valid/case03-input.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script>
2-
import { setContext, onMount } from "svelte"
2+
import { setContext } from "svelte"
33
const something = () => {
44
setContext("answer", 42)
55
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
import { setContext, onMount } from "svelte"
3+
4+
if (setContext("answer", 42)) {
5+
console.log("setContext")
6+
}
7+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { setContext } from "svelte"
2+
3+
const something = () => {
4+
setContext("answer", 42)
5+
}
6+
7+
const something2 = async () => {
8+
await Promise.resolve()
9+
setContext("answer", 42)
10+
}
11+
12+
const aaa = (fn) => {
13+
fn()
14+
}
15+
16+
aaa(() => something())
17+
something2()

0 commit comments

Comments
 (0)