Skip to content

Commit b412783

Browse files
authored
Fixed false positives inside the ternary operator in no-async-in-computed-properties (#962)
* Fixed false positives inside the ternary operator in `no-async-in-computed-properties` * Add testcase
1 parent e8f130c commit b412783

File tree

2 files changed

+62
-33
lines changed

2 files changed

+62
-33
lines changed

Diff for: lib/rules/no-async-in-computed-properties.js

+19-33
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ module.exports = {
7373

7474
create (context) {
7575
const forbiddenNodes = []
76-
const allowedScopes = []
76+
let scopeStack = { upper: null, body: null }
7777

7878
const expressionTypes = {
7979
promise: 'asynchronous action',
@@ -87,65 +87,54 @@ module.exports = {
8787
if (node.async) {
8888
forbiddenNodes.push({
8989
node: node,
90-
type: 'async'
90+
type: 'async',
91+
targetBody: node.body
9192
})
92-
} else if (node.parent.type === 'ReturnStatement') {
93-
allowedScopes.push(node)
9493
}
94+
95+
scopeStack = { upper: scopeStack, body: node.body }
9596
}
9697

98+
function onFunctionExit () {
99+
scopeStack = scopeStack.upper
100+
}
97101
return Object.assign({},
98102
{
99-
FunctionDeclaration: onFunctionEnter,
100-
101-
FunctionExpression: onFunctionEnter,
102-
103-
ArrowFunctionExpression: onFunctionEnter,
103+
':function': onFunctionEnter,
104+
':function:exit': onFunctionExit,
104105

105106
NewExpression (node) {
106107
if (node.callee.name === 'Promise') {
107108
forbiddenNodes.push({
108109
node: node,
109-
type: 'new'
110+
type: 'new',
111+
targetBody: scopeStack.body
110112
})
111-
} else if (node.parent.type === 'ReturnStatement') {
112-
allowedScopes.push(node)
113113
}
114114
},
115115

116116
CallExpression (node) {
117117
if (isPromise(node)) {
118118
forbiddenNodes.push({
119119
node: node,
120-
type: 'promise'
120+
type: 'promise',
121+
targetBody: scopeStack.body
121122
})
122123
} else if (isTimedFunction(node)) {
123124
forbiddenNodes.push({
124125
node: node,
125-
type: 'timed'
126+
type: 'timed',
127+
targetBody: scopeStack.body
126128
})
127-
} else if (node.parent.type === 'ReturnStatement') {
128-
allowedScopes.push(node)
129129
}
130130
},
131131

132132
AwaitExpression (node) {
133133
forbiddenNodes.push({
134134
node: node,
135-
type: 'await'
135+
type: 'await',
136+
targetBody: scopeStack.body
136137
})
137-
},
138-
139-
'ReturnStatement' (node) {
140-
if (
141-
node.argument &&
142-
(
143-
node.argument.type === 'ObjectExpression' ||
144-
node.argument.type === 'ArrayExpression'
145-
)
146-
) {
147-
allowedScopes.push(node.argument)
148-
}
149138
}
150139
},
151140
utils.executeOnVue(context, (obj) => {
@@ -157,10 +146,7 @@ module.exports = {
157146
cp.value &&
158147
el.node.loc.start.line >= cp.value.loc.start.line &&
159148
el.node.loc.end.line <= cp.value.loc.end.line &&
160-
!allowedScopes.some(scope =>
161-
scope.range[0] < el.node.range[0] &&
162-
scope.range[1] > el.node.range[1]
163-
)
149+
el.targetBody === cp.value
164150
) {
165151
context.report({
166152
node: el.node,

Diff for: tests/lib/rules/no-async-in-computed-properties.js

+43
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,49 @@ ruleTester.run('no-async-in-computed-properties', rule, {
181181
}
182182
`,
183183
parserOptions
184+
},
185+
{
186+
filename: 'test.vue',
187+
code: `
188+
export default {
189+
computed: {
190+
foo() {
191+
return this.bar
192+
? {
193+
baz:() => Promise.resolve(1)
194+
}
195+
: {}
196+
}
197+
}
198+
}
199+
`,
200+
parserOptions
201+
},
202+
{
203+
filename: 'test.vue',
204+
code: `
205+
export default {
206+
computed: {
207+
foo() {
208+
return this.bar ? () => Promise.resolve(1) : null
209+
}
210+
}
211+
}
212+
`,
213+
parserOptions
214+
},
215+
{
216+
filename: 'test.vue',
217+
code: `
218+
export default {
219+
computed: {
220+
foo() {
221+
return this.bar ? async () => 1 : null
222+
}
223+
}
224+
}
225+
`,
226+
parserOptions
184227
}
185228
],
186229

0 commit comments

Comments
 (0)