Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9dc78d0

Browse files
Fix false positives for <script setup> in vue/no-lifecycle-after-await, vue/no-watch-after-await, vue/no-restricted-call-after-await rules. (#1569)
1 parent cac3beb commit 9dc78d0

File tree

6 files changed

+70
-159
lines changed

6 files changed

+70
-159
lines changed

‎lib/rules/no-lifecycle-after-await.js‎

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,19 @@ module.exports = {
4848
/**
4949
* @typedef {object} ScopeStack
5050
* @property {ScopeStack | null} upper
51-
* @property {FunctionDeclaration | FunctionExpression | ArrowFunctionExpression | Program} scopeNode
51+
* @property {FunctionDeclaration | FunctionExpression | ArrowFunctionExpression} scopeNode
5252
*/
5353
/** @type {Set<ESNode>} */
5454
const lifecycleHookCallNodes = new Set()
55-
/** @type {Map<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression | Program, SetupScopeData>} */
55+
/** @type {Map<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression, SetupScopeData>} */
5656
const setupScopes = new Map()
5757

5858
/** @type {ScopeStack | null} */
5959
let scopeStack = null
6060

6161
return utils.compositingVisitors(
6262
{
63-
/**
64-
* @param {Program} node
65-
*/
66-
Program(node) {
67-
scopeStack = {
68-
upper: scopeStack,
69-
scopeNode: node
70-
}
71-
63+
Program() {
7264
const tracker = new ReferenceTracker(context.getScope())
7365
const traceMap = {
7466
/** @type {TraceMap} */
@@ -85,6 +77,14 @@ module.exports = {
8577
for (const { node } of tracker.iterateEsmReferences(traceMap)) {
8678
lifecycleHookCallNodes.add(node)
8779
}
80+
}
81+
},
82+
utils.defineVueVisitor(context, {
83+
onSetupFunctionEnter(node) {
84+
setupScopes.set(node, {
85+
afterAwait: false,
86+
range: node.range
87+
})
8888
},
8989
/**
9090
* @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
@@ -133,31 +133,6 @@ module.exports = {
133133
messageId: 'forbidden'
134134
})
135135
}
136-
}
137-
},
138-
(() => {
139-
const scriptSetup = utils.getScriptSetupElement(context)
140-
if (!scriptSetup) {
141-
return {}
142-
}
143-
return {
144-
/**
145-
* @param {Program} node
146-
*/
147-
Program(node) {
148-
setupScopes.set(node, {
149-
afterAwait: false,
150-
range: scriptSetup.range
151-
})
152-
}
153-
}
154-
})(),
155-
utils.defineVueVisitor(context, {
156-
onSetupFunctionEnter(node) {
157-
setupScopes.set(node, {
158-
afterAwait: false,
159-
range: node.range
160-
})
161136
},
162137
onSetupFunctionExit(node) {
163138
setupScopes.delete(node)

‎lib/rules/no-restricted-call-after-await.js‎

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ module.exports = {
6262

6363
/** @type {Map<ESNode, string>} */
6464
const restrictedCallNodes = new Map()
65-
/** @type {Map<FunctionExpression | ArrowFunctionExpression | FunctionDeclaration | Program, SetupScopeData>} */
65+
/** @type {Map<FunctionExpression | ArrowFunctionExpression | FunctionDeclaration, SetupScopeData>} */
6666
const setupScopes = new Map()
6767

6868
/**x
6969
* @typedef {object} ScopeStack
7070
* @property {ScopeStack | null} upper
71-
* @property {FunctionExpression | ArrowFunctionExpression | FunctionDeclaration | Program} scopeNode
71+
* @property {FunctionExpression | ArrowFunctionExpression | FunctionDeclaration} scopeNode
7272
*/
7373
/** @type {ScopeStack | null} */
7474
let scopeStack = null
@@ -142,11 +142,6 @@ module.exports = {
142142
{
143143
/** @param {Program} node */
144144
Program(node) {
145-
scopeStack = {
146-
upper: scopeStack,
147-
scopeNode: node
148-
}
149-
150145
const tracker = new ReferenceTracker(context.getScope())
151146

152147
for (const option of context.options) {
@@ -181,6 +176,14 @@ module.exports = {
181176
}
182177
}
183178
}
179+
}
180+
},
181+
utils.defineVueVisitor(context, {
182+
onSetupFunctionEnter(node) {
183+
setupScopes.set(node, {
184+
afterAwait: false,
185+
range: node.range
186+
})
184187
},
185188
/** @param {FunctionExpression | ArrowFunctionExpression | FunctionDeclaration} node */
186189
':function'(node) {
@@ -225,31 +228,6 @@ module.exports = {
225228
data: { message }
226229
})
227230
}
228-
}
229-
},
230-
(() => {
231-
const scriptSetup = utils.getScriptSetupElement(context)
232-
if (!scriptSetup) {
233-
return {}
234-
}
235-
return {
236-
/**
237-
* @param {Program} node
238-
*/
239-
Program(node) {
240-
setupScopes.set(node, {
241-
afterAwait: false,
242-
range: scriptSetup.range
243-
})
244-
}
245-
}
246-
})(),
247-
utils.defineVueVisitor(context, {
248-
onSetupFunctionEnter(node) {
249-
setupScopes.set(node, {
250-
afterAwait: false,
251-
range: node.range
252-
})
253231
},
254232
onSetupFunctionExit(node) {
255233
setupScopes.delete(node)

‎lib/rules/no-watch-after-await.js‎

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -62,26 +62,20 @@ module.exports = {
6262
* @property {boolean} afterAwait
6363
* @property {[number,number]} range
6464
*/
65-
/** @type {Map<FunctionExpression | ArrowFunctionExpression | FunctionDeclaration | Program, SetupScopeData>} */
65+
/** @type {Map<FunctionExpression | ArrowFunctionExpression | FunctionDeclaration, SetupScopeData>} */
6666
const setupScopes = new Map()
6767

6868
/**
6969
* @typedef {object} ScopeStack
7070
* @property {ScopeStack | null} upper
71-
* @property {FunctionExpression | ArrowFunctionExpression | FunctionDeclaration | Program} scopeNode
71+
* @property {FunctionExpression | ArrowFunctionExpression | FunctionDeclaration} scopeNode
7272
*/
7373
/** @type {ScopeStack | null} */
7474
let scopeStack = null
7575

7676
return utils.compositingVisitors(
7777
{
78-
/** @param {Program} node */
79-
Program(node) {
80-
scopeStack = {
81-
upper: scopeStack,
82-
scopeNode: node
83-
}
84-
78+
Program() {
8579
const tracker = new ReferenceTracker(context.getScope())
8680
const traceMap = {
8781
vue: {
@@ -98,6 +92,14 @@ module.exports = {
9892
for (const { node } of tracker.iterateEsmReferences(traceMap)) {
9993
watchCallNodes.add(node)
10094
}
95+
}
96+
},
97+
utils.defineVueVisitor(context, {
98+
onSetupFunctionEnter(node) {
99+
setupScopes.set(node, {
100+
afterAwait: false,
101+
range: node.range
102+
})
101103
},
102104
/** @param {FunctionExpression | ArrowFunctionExpression | FunctionDeclaration} node */
103105
':function'(node) {
@@ -140,31 +142,6 @@ module.exports = {
140142
messageId: 'forbidden'
141143
})
142144
}
143-
}
144-
},
145-
(() => {
146-
const scriptSetup = utils.getScriptSetupElement(context)
147-
if (!scriptSetup) {
148-
return {}
149-
}
150-
return {
151-
/**
152-
* @param {Program} node
153-
*/
154-
Program(node) {
155-
setupScopes.set(node, {
156-
afterAwait: false,
157-
range: scriptSetup.range
158-
})
159-
}
160-
}
161-
})(),
162-
utils.defineVueVisitor(context, {
163-
onSetupFunctionEnter(node) {
164-
setupScopes.set(node, {
165-
afterAwait: false,
166-
range: node.range
167-
})
168145
},
169146
onSetupFunctionExit(node) {
170147
setupScopes.delete(node)

‎tests/lib/rules/no-lifecycle-after-await.js‎

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ tester.run('no-lifecycle-after-await', rule, {
139139
<script>
140140
import {onMounted} from 'vue'
141141
await doSomething()
142+
onMounted(() => { /* ... */ }) // not error
143+
</script>
144+
`,
145+
parserOptions: { ecmaVersion: 2022 }
146+
},
147+
{
148+
filename: 'test.vue',
149+
code: `
150+
<script setup>
151+
import {onMounted} from 'vue'
152+
await doSomething()
153+
142154
onMounted(() => { /* ... */ }) // not error
143155
</script>
144156
`,
@@ -261,24 +273,6 @@ tester.run('no-lifecycle-after-await', rule, {
261273
messageId: 'forbidden'
262274
}
263275
]
264-
},
265-
{
266-
filename: 'test.vue',
267-
code: `
268-
<script setup>
269-
import {onMounted} from 'vue'
270-
await doSomething()
271-
272-
onMounted(() => { /* ... */ }) // error
273-
</script>
274-
`,
275-
parserOptions: { ecmaVersion: 2022 },
276-
errors: [
277-
{
278-
messageId: 'forbidden',
279-
line: 6
280-
}
281-
]
282276
}
283277
]
284278
})

‎tests/lib/rules/no-restricted-call-after-await.js‎

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ tester.run('no-restricted-call-after-await', rule, {
137137
`,
138138
options: [{ module: 'vue-i18n', path: 'useI18n' }],
139139
parserOptions: { ecmaVersion: 2022 }
140+
},
141+
{
142+
filename: 'test.vue',
143+
code: `
144+
<script setup>
145+
import {useI18n} from 'vue-i18n'
146+
await doSomething()
147+
useI18n()
148+
</script>
149+
`,
150+
parserOptions: { ecmaVersion: 2022 },
151+
options: [{ module: 'vue-i18n', path: 'useI18n' }]
140152
}
141153
],
142154
invalid: [
@@ -389,25 +401,6 @@ tester.run('no-restricted-call-after-await', rule, {
389401
line: 7
390402
}
391403
]
392-
},
393-
{
394-
filename: 'test.vue',
395-
code: `
396-
<script setup>
397-
import {useI18n} from 'vue-i18n'
398-
await doSomething()
399-
useI18n()
400-
</script>
401-
`,
402-
parserOptions: { ecmaVersion: 2022 },
403-
options: [{ module: 'vue-i18n', path: 'useI18n' }],
404-
errors: [
405-
{
406-
message:
407-
'The `import("vue-i18n").useI18n` after `await` expression are forbidden.',
408-
line: 5
409-
}
410-
]
411404
}
412405
]
413406
})

‎tests/lib/rules/no-watch-after-await.js‎

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,20 @@ tester.run('no-watch-after-await', rule, {
155155
</script>
156156
`,
157157
parserOptions: { ecmaVersion: 2022 }
158+
},
159+
{
160+
filename: 'test.vue',
161+
code: `
162+
<script setup>
163+
import {watch} from 'vue'
164+
watch(foo, () => { /* ... */ })
165+
166+
await doSomething()
167+
168+
watch(foo, () => { /* ... */ })
169+
</script>
170+
`,
171+
parserOptions: { ecmaVersion: 2022 }
158172
}
159173
],
160174
invalid: [
@@ -236,26 +250,6 @@ tester.run('no-watch-after-await', rule, {
236250
line: 12
237251
}
238252
]
239-
},
240-
{
241-
filename: 'test.vue',
242-
code: `
243-
<script setup>
244-
import {watch} from 'vue'
245-
watch(foo, () => { /* ... */ })
246-
247-
await doSomething()
248-
249-
watch(foo, () => { /* ... */ })
250-
</script>
251-
`,
252-
parserOptions: { ecmaVersion: 2022 },
253-
errors: [
254-
{
255-
message: 'The `watch` after `await` expression are forbidden.',
256-
line: 8
257-
}
258-
]
259253
}
260254
]
261255
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /