diff --git a/lib/rules/no-async-in-computed-properties.js b/lib/rules/no-async-in-computed-properties.js index b61c8ca47..7b024eb50 100644 --- a/lib/rules/no-async-in-computed-properties.js +++ b/lib/rules/no-async-in-computed-properties.js @@ -73,7 +73,7 @@ module.exports = { create (context) { const forbiddenNodes = [] - const allowedScopes = [] + let scopeStack = { upper: null, body: null } const expressionTypes = { promise: 'asynchronous action', @@ -87,29 +87,29 @@ module.exports = { if (node.async) { forbiddenNodes.push({ node: node, - type: 'async' + type: 'async', + targetBody: node.body }) - } else if (node.parent.type === 'ReturnStatement') { - allowedScopes.push(node) } + + scopeStack = { upper: scopeStack, body: node.body } } + function onFunctionExit () { + scopeStack = scopeStack.upper + } return Object.assign({}, { - FunctionDeclaration: onFunctionEnter, - - FunctionExpression: onFunctionEnter, - - ArrowFunctionExpression: onFunctionEnter, + ':function': onFunctionEnter, + ':function:exit': onFunctionExit, NewExpression (node) { if (node.callee.name === 'Promise') { forbiddenNodes.push({ node: node, - type: 'new' + type: 'new', + targetBody: scopeStack.body }) - } else if (node.parent.type === 'ReturnStatement') { - allowedScopes.push(node) } }, @@ -117,35 +117,24 @@ module.exports = { if (isPromise(node)) { forbiddenNodes.push({ node: node, - type: 'promise' + type: 'promise', + targetBody: scopeStack.body }) } else if (isTimedFunction(node)) { forbiddenNodes.push({ node: node, - type: 'timed' + type: 'timed', + targetBody: scopeStack.body }) - } else if (node.parent.type === 'ReturnStatement') { - allowedScopes.push(node) } }, AwaitExpression (node) { forbiddenNodes.push({ node: node, - type: 'await' + type: 'await', + targetBody: scopeStack.body }) - }, - - 'ReturnStatement' (node) { - if ( - node.argument && - ( - node.argument.type === 'ObjectExpression' || - node.argument.type === 'ArrayExpression' - ) - ) { - allowedScopes.push(node.argument) - } } }, utils.executeOnVue(context, (obj) => { @@ -157,10 +146,7 @@ module.exports = { cp.value && el.node.loc.start.line >= cp.value.loc.start.line && el.node.loc.end.line <= cp.value.loc.end.line && - !allowedScopes.some(scope => - scope.range[0] < el.node.range[0] && - scope.range[1] > el.node.range[1] - ) + el.targetBody === cp.value ) { context.report({ node: el.node, diff --git a/tests/lib/rules/no-async-in-computed-properties.js b/tests/lib/rules/no-async-in-computed-properties.js index cf886c7e2..171271188 100644 --- a/tests/lib/rules/no-async-in-computed-properties.js +++ b/tests/lib/rules/no-async-in-computed-properties.js @@ -181,6 +181,49 @@ ruleTester.run('no-async-in-computed-properties', rule, { } `, parserOptions + }, + { + filename: 'test.vue', + code: ` + export default { + computed: { + foo() { + return this.bar + ? { + baz:() => Promise.resolve(1) + } + : {} + } + } + } + `, + parserOptions + }, + { + filename: 'test.vue', + code: ` + export default { + computed: { + foo() { + return this.bar ? () => Promise.resolve(1) : null + } + } + } + `, + parserOptions + }, + { + filename: 'test.vue', + code: ` + export default { + computed: { + foo() { + return this.bar ? async () => 1 : null + } + } + } + `, + parserOptions } ],