Skip to content

Commit

Permalink
fix if statement and support context module
Browse files Browse the repository at this point in the history
  • Loading branch information
baseballyama committed Jun 3, 2023
1 parent a86eac8 commit 6b8edb4
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 7 deletions.
43 changes: 39 additions & 4 deletions src/rules/valid-context-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default createRule("valid-context-access", {
description:
"context functions must be called during component initialization.",
category: "Possible Errors",
// TODO Switch to recommended in the major version.
recommended: false,
},
schema: [],
Expand All @@ -19,7 +18,28 @@ export default createRule("valid-context-access", {
type: "problem",
},
create(context) {
const scopeManager = context.getSourceCode().scopeManager
// // This rule doesn't check other than Svelte files.
if (!context.parserServices.isSvelte) {
return {}
}

// Extract <script> blocks that is not module=context.
const sourceCode = context.getSourceCode()
const scriptNotModuleElements = sourceCode.ast.body.filter((b) => {
if (b.type !== "SvelteScriptElement") return false
const isModule = b.startTag.attributes.some((a) => {
return (
a.type === "SvelteAttribute" &&
a.key.name === "context" &&
a.value.some(
(v) => v.type === "SvelteLiteral" && v.value === "module",
)
)
})
return !isModule
})

const scopeManager = sourceCode.scopeManager
const toplevelScope =
scopeManager.globalScope?.childScopes.find(
(scope) => scope.type === "module",
Expand Down Expand Up @@ -53,17 +73,32 @@ export default createRule("valid-context-access", {
return []
}

/** Return true if the node is there inside of <script> block that is not module=context. */
function isInsideOfSvelteScriptElement(node: TSESTree.Node) {
for (const script of scriptNotModuleElements) {
if (
node.range[0] >= script.range[0] &&
node.range[1] <= script.range[1]
) {
return true
}
}
return false
}

/** Let's lint! */
function doLint(
visitedCallExpressions: TSESTree.CallExpression[],
contextCallExpression: TSESTree.CallExpression,
currentNode: TSESTree.CallExpression,
) {
let { parent } = currentNode
if (parent?.type !== "ExpressionStatement") {
// Report if context function is called outside of <script> block.
if (!isInsideOfSvelteScriptElement(currentNode)) {
report(contextCallExpression)
return
}

let { parent } = currentNode
while (parent) {
parent = parent.parent
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
const something = () => {
setContext("answer", 42)
}
something()
</script>

<button on:click={() => something()}>Click Me</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- message: Do not call setContext except during component initialization.
line: 3
column: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<script context="module">
import { setContext } from "svelte"
setContext("answer", 42)
</script>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import { setContext, onMount } from "svelte"
import { setContext } from "svelte"
const something = () => {
setContext("answer", 42)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import { setContext, onMount } from "svelte"
if (setContext("answer", 42)) {
console.log("setContext")
}
</script>
17 changes: 17 additions & 0 deletions tests/fixtures/rules/valid-context-access/valid/case09-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { setContext } from "svelte"

const something = () => {
setContext("answer", 42)
}

const something2 = async () => {
await Promise.resolve()
setContext("answer", 42)
}

const aaa = (fn) => {
fn()
}

aaa(() => something())
something2()

0 comments on commit 6b8edb4

Please sign in to comment.