diff --git a/lib/rules/no-async-in-computed-properties.js b/lib/rules/no-async-in-computed-properties.js
index b12fa3407..b405c0475 100644
--- a/lib/rules/no-async-in-computed-properties.js
+++ b/lib/rules/no-async-in-computed-properties.js
@@ -8,6 +8,7 @@ const utils = require('../utils')
/**
* @typedef {import('../utils').VueObjectData} VueObjectData
+ * @typedef {import('../utils').VueVisitor} VueVisitor
* @typedef {import('../utils').ComponentComputedProperty} ComponentComputedProperty
*/
@@ -97,11 +98,16 @@ module.exports = {
/**
* @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
- * @param {VueObjectData} data
+ * @param {VueObjectData|undefined} [info]
*/
- function onFunctionEnter(node, { node: vueNode }) {
+ function onFunctionEnter(node, info) {
if (node.async) {
- verify(node, node.body, 'async', computedPropertiesMap.get(vueNode))
+ verify(
+ node,
+ node.body,
+ 'async',
+ info ? computedPropertiesMap.get(info.node) : null
+ )
}
scopeStack = {
@@ -118,10 +124,10 @@ module.exports = {
* @param {ESNode} node
* @param {BlockStatement | Expression} targetBody
* @param {keyof expressionTypes} type
- * @param {ComponentComputedProperty[]} computedProperties
+ * @param {ComponentComputedProperty[]|undefined|null} computedProperties
*/
- function verify(node, targetBody, type, computedProperties = []) {
- for (const cp of computedProperties) {
+ function verify(node, targetBody, type, computedProperties) {
+ for (const cp of computedProperties || []) {
if (
cp.value &&
node.loc.start.line >= cp.value.loc.start.line &&
@@ -158,7 +164,74 @@ module.exports = {
}
}
}
- return Object.assign(
+ const nodeVisitor = {
+ ':function': onFunctionEnter,
+ ':function:exit': onFunctionExit,
+
+ /**
+ * @param {NewExpression} node
+ * @param {VueObjectData|undefined} [info]
+ */
+ NewExpression(node, info) {
+ if (!scopeStack) {
+ return
+ }
+ if (
+ node.callee.type === 'Identifier' &&
+ node.callee.name === 'Promise'
+ ) {
+ verify(
+ node,
+ scopeStack.body,
+ 'new',
+ info ? computedPropertiesMap.get(info.node) : null
+ )
+ }
+ },
+
+ /**
+ * @param {CallExpression} node
+ * @param {VueObjectData|undefined} [info]
+ */
+ CallExpression(node, info) {
+ if (!scopeStack) {
+ return
+ }
+ if (isPromise(node)) {
+ verify(
+ node,
+ scopeStack.body,
+ 'promise',
+ info ? computedPropertiesMap.get(info.node) : null
+ )
+ } else if (isTimedFunction(node)) {
+ verify(
+ node,
+ scopeStack.body,
+ 'timed',
+ info ? computedPropertiesMap.get(info.node) : null
+ )
+ }
+ },
+
+ /**
+ * @param {AwaitExpression} node
+ * @param {VueObjectData|undefined} [info]
+ */
+ AwaitExpression(node, info) {
+ if (!scopeStack) {
+ return
+ }
+ verify(
+ node,
+ scopeStack.body,
+ 'await',
+ info ? computedPropertiesMap.get(info.node) : null
+ )
+ }
+ }
+
+ return utils.compositingVisitors(
{
Program() {
const tracker = new ReferenceTracker(context.getScope())
@@ -181,63 +254,14 @@ module.exports = {
}
}
},
- utils.defineVueVisitor(context, {
- onVueObjectEnter(node) {
- computedPropertiesMap.set(node, utils.getComputedProperties(node))
- },
- ':function': onFunctionEnter,
- ':function:exit': onFunctionExit,
-
- NewExpression(node, { node: vueNode }) {
- if (!scopeStack) {
- return
- }
- if (
- node.callee.type === 'Identifier' &&
- node.callee.name === 'Promise'
- ) {
- verify(
- node,
- scopeStack.body,
- 'new',
- computedPropertiesMap.get(vueNode)
- )
- }
- },
-
- CallExpression(node, { node: vueNode }) {
- if (!scopeStack) {
- return
- }
- if (isPromise(node)) {
- verify(
- node,
- scopeStack.body,
- 'promise',
- computedPropertiesMap.get(vueNode)
- )
- } else if (isTimedFunction(node)) {
- verify(
- node,
- scopeStack.body,
- 'timed',
- computedPropertiesMap.get(vueNode)
- )
- }
- },
-
- AwaitExpression(node, { node: vueNode }) {
- if (!scopeStack) {
- return
- }
- verify(
- node,
- scopeStack.body,
- 'await',
- computedPropertiesMap.get(vueNode)
- )
- }
- })
+ utils.isScriptSetup(context)
+ ? utils.defineScriptSetupVisitor(context, nodeVisitor)
+ : utils.defineVueVisitor(context, {
+ onVueObjectEnter(node) {
+ computedPropertiesMap.set(node, utils.getComputedProperties(node))
+ },
+ ...nodeVisitor
+ })
)
}
}
diff --git a/tests/lib/rules/no-async-in-computed-properties.js b/tests/lib/rules/no-async-in-computed-properties.js
index 2a15712cf..c54b833af 100644
--- a/tests/lib/rules/no-async-in-computed-properties.js
+++ b/tests/lib/rules/no-async-in-computed-properties.js
@@ -15,6 +15,7 @@ const parserOptions = {
ecmaVersion: 2020,
sourceType: 'module'
}
+const parser = require.resolve('vue-eslint-parser')
// ------------------------------------------------------------------------------
// Tests
@@ -920,6 +921,207 @@ ruleTester.run('no-async-in-computed-properties', rule, {
line: 5
}
]
+ },
+
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ parser,
+ parserOptions,
+ errors: [
+ {
+ message:
+ 'Unexpected async function declaration in computed function.',
+ line: 4
+ },
+ {
+ message: 'Unexpected await operator in computed function.',
+ line: 5
+ },
+ {
+ message:
+ 'Unexpected async function declaration in computed function.',
+ line: 7
+ },
+ {
+ message: 'Unexpected await operator in computed function.',
+ line: 7
+ },
+ {
+ message:
+ 'Unexpected async function declaration in computed function.',
+ line: 8
+ },
+ {
+ message: 'Unexpected await operator in computed function.',
+ line: 9
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ parser,
+ parserOptions,
+ errors: [
+ {
+ message:
+ 'Unexpected async function declaration in computed function.',
+ line: 4
+ },
+ {
+ message: 'Unexpected Promise object in computed function.',
+ line: 5
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ parser,
+ parserOptions,
+ errors: [
+ {
+ message: 'Unexpected asynchronous action in computed function.',
+ line: 5
+ },
+ {
+ message: 'Unexpected asynchronous action in computed function.',
+ line: 8
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ parser,
+ parserOptions,
+ errors: [
+ {
+ message: 'Unexpected asynchronous action in computed function.',
+ line: 6
+ },
+ {
+ message: 'Unexpected asynchronous action in computed function.',
+ line: 11
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ parser,
+ parserOptions,
+ errors: [
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 5
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 6
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 7
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 8
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 9
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 10
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 11
+ },
+ {
+ message: 'Unexpected timed function in computed function.',
+ line: 12
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ parser,
+ parserOptions,
+ errors: [
+ {
+ message:
+ 'Unexpected async function declaration in computed function.',
+ line: 4
+ }
+ ]
}
]
})