1
1
import { createRule } from "../utils"
2
2
import { extractContextReferences } from "./reference-helpers/svelte-context"
3
3
import { extractSvelteLifeCycleReferences } from "./reference-helpers/svelte-lifecycle"
4
+ import type { AST } from "svelte-eslint-parser"
4
5
import type { TSESTree } from "@typescript-eslint/types"
5
6
6
7
export default createRule ( "valid-context-access" , {
@@ -30,19 +31,20 @@ export default createRule("valid-context-access", {
30
31
) . map ( ( r ) => r . node )
31
32
32
33
// Extract <script> blocks that is not module=context.
33
- const scriptNotModuleElements = sourceCode . ast . body . filter ( ( b ) => {
34
- if ( b . type !== "SvelteScriptElement" ) return false
35
- const isModule = b . startTag . attributes . some ( ( a ) => {
36
- return (
37
- a . type === "SvelteAttribute" &&
38
- a . key . name === "context" &&
39
- a . value . some (
40
- ( v ) => v . type === "SvelteLiteral" && v . value === "module" ,
34
+ const scriptNotModuleElements : AST . SvelteScriptElement [ ] =
35
+ sourceCode . ast . body . filter ( ( b ) => {
36
+ if ( b . type !== "SvelteScriptElement" ) return false
37
+ const isModule = b . startTag . attributes . some ( ( a ) => {
38
+ return (
39
+ a . type === "SvelteAttribute" &&
40
+ a . key . name === "context" &&
41
+ a . value . some (
42
+ ( v ) => v . type === "SvelteLiteral" && v . value === "module" ,
43
+ )
41
44
)
42
- )
43
- } )
44
- return ! isModule
45
- } )
45
+ } )
46
+ return ! isModule
47
+ } ) as AST . SvelteScriptElement [ ]
46
48
47
49
const scopeManager = sourceCode . scopeManager
48
50
const toplevelScope =
@@ -78,20 +80,44 @@ export default createRule("valid-context-access", {
78
80
return [ ]
79
81
}
80
82
83
+ /** Return true if tnodeA is inside of nodeB. */
84
+ function isInsideOfNodeB (
85
+ nodeA : TSESTree . Node | AST . SvelteScriptElement ,
86
+ nodeB : TSESTree . Node ,
87
+ ) {
88
+ return (
89
+ nodeA . range [ 0 ] <= nodeB . range [ 0 ] && nodeB . range [ 1 ] <= nodeA . range [ 1 ]
90
+ )
91
+ }
92
+
81
93
/** Return true if the node is there inside of <script> block that is not module=context. */
82
94
function isInsideOfSvelteScriptElement ( node : TSESTree . Node ) {
83
95
for ( const script of scriptNotModuleElements ) {
84
- if (
85
- node . range [ 0 ] >= script . range [ 0 ] &&
86
- node . range [ 1 ] <= script . range [ 1 ]
87
- ) {
96
+ if ( isInsideOfNodeB ( script , node ) ) {
88
97
return true
89
98
}
90
99
}
91
100
return false
92
101
}
93
102
94
- const awaitExpressions : TSESTree . AwaitExpression [ ] = [ ]
103
+ const awaitExpressions : {
104
+ belongingFunction :
105
+ | TSESTree . FunctionDeclaration
106
+ | TSESTree . VariableDeclaration
107
+ node : TSESTree . Node
108
+ } [ ] = [ ]
109
+
110
+ /** Return true if the given node is later than the await expression. */
111
+ function isAfterAwait ( node : TSESTree . CallExpression ) {
112
+ for ( const awaitExpression of awaitExpressions ) {
113
+ const { belongingFunction, node : awaitNode } = awaitExpression
114
+ if ( isInsideOfNodeB ( node , belongingFunction ) ) {
115
+ continue
116
+ }
117
+ return awaitNode . range [ 0 ] <= node . range [ 0 ]
118
+ }
119
+ return false
120
+ }
95
121
96
122
/** Let's lint! */
97
123
function doLint (
@@ -105,6 +131,11 @@ export default createRule("valid-context-access", {
105
131
return
106
132
}
107
133
134
+ if ( isAfterAwait ( currentNode ) ) {
135
+ report ( contextCallExpression )
136
+ return
137
+ }
138
+
108
139
let { parent } = currentNode
109
140
while ( parent ) {
110
141
parent = parent . parent
@@ -151,7 +182,15 @@ export default createRule("valid-context-access", {
151
182
}
152
183
} ,
153
184
AwaitExpression ( node ) {
154
- awaitExpressions . push ( node )
185
+ let parent : TSESTree . Node | undefined = node . parent
186
+ while ( parent ) {
187
+ if ( parent . type === "FunctionDeclaration" ) {
188
+ awaitExpressions . push ( { belongingFunction : parent , node } )
189
+ } else if ( parent . type === "VariableDeclaration" ) {
190
+ awaitExpressions . push ( { belongingFunction : parent , node } )
191
+ }
192
+ parent = parent . parent
193
+ }
155
194
} ,
156
195
}
157
196
} ,
0 commit comments