diff --git a/lib/rules/no-side-effects-in-computed-properties.js b/lib/rules/no-side-effects-in-computed-properties.js index 3abe009bf..9bda00681 100644 --- a/lib/rules/no-side-effects-in-computed-properties.js +++ b/lib/rules/no-side-effects-in-computed-properties.js @@ -24,20 +24,38 @@ module.exports = { create (context) { const forbiddenNodes = [] + let scopeStack = { upper: null, body: null } + + function onFunctionEnter (node) { + scopeStack = { upper: scopeStack, body: node.body } + } + + function onFunctionExit () { + scopeStack = scopeStack.upper + } return Object.assign({}, { + ':function': onFunctionEnter, + ':function:exit': onFunctionExit, + // this.xxx <=|+=|-=> 'AssignmentExpression' (node) { if (node.left.type !== 'MemberExpression') return if (utils.parseMemberExpression(node.left)[0] === 'this') { - forbiddenNodes.push(node) + forbiddenNodes.push({ + node, + targetBody: scopeStack.body + }) } }, // this.xxx <++|--> 'UpdateExpression > MemberExpression' (node) { if (utils.parseMemberExpression(node)[0] === 'this') { - forbiddenNodes.push(node) + forbiddenNodes.push({ + node, + targetBody: scopeStack.body + }) } }, // this.xxx.func() @@ -46,7 +64,10 @@ module.exports = { const MUTATION_REGEX = /(this.)((?!(concat|slice|map|filter)\().)[^\)]*((push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill)\()/g if (MUTATION_REGEX.test(code)) { - forbiddenNodes.push(node) + forbiddenNodes.push({ + node, + targetBody: scopeStack.body + }) } } }, @@ -54,11 +75,12 @@ module.exports = { const computedProperties = utils.getComputedProperties(obj) computedProperties.forEach(cp => { - forbiddenNodes.forEach(node => { + forbiddenNodes.forEach(({ node, targetBody }) => { if ( cp.value && node.loc.start.line >= cp.value.loc.start.line && - node.loc.end.line <= cp.value.loc.end.line + node.loc.end.line <= cp.value.loc.end.line && + targetBody === cp.value ) { context.report({ node: node, diff --git a/lib/utils/index.js b/lib/utils/index.js index 184ebbe3f..b24420a3a 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -822,7 +822,7 @@ module.exports = { isFunc = true } else { if (n.computed) { - parsedCallee.push('[]') + parsedCallee.push('[]' + (isFunc ? '()' : '')) } else if (n.property.type === 'Identifier') { parsedCallee.push(n.property.name + (isFunc ? '()' : '')) } diff --git a/tests/lib/rules/no-side-effects-in-computed-properties.js b/tests/lib/rules/no-side-effects-in-computed-properties.js index 3dc0f3fc8..df186b3a9 100644 --- a/tests/lib/rules/no-side-effects-in-computed-properties.js +++ b/tests/lib/rules/no-side-effects-in-computed-properties.js @@ -143,6 +143,36 @@ ruleTester.run('no-side-effects-in-computed-properties', rule, { } })`, parserOptions + }, + { + code: `Vue.component('test', { + computed: { + test () { + return { + action1() { + this.something++ + }, + action2() { + this.something = 1 + }, + action3() { + this.something.reverse() + } + } + }, + } + })`, + parserOptions + }, + { + code: `Vue.component('test', { + computed: { + test () { + return this.something['a']().reverse() + }, + } + })`, + parserOptions } ], invalid: [