Skip to content

Commit e80c2f0

Browse files
authored
Refactoring (#1154)
* Refactoring * update
1 parent d0e8e47 commit e80c2f0

12 files changed

+173
-223
lines changed

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

+1-4
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,7 @@ module.exports = {
115115
})
116116
}
117117
return utils.defineVueVisitor(context, {
118-
ObjectExpression (node, { node: vueNode }) {
119-
if (node !== vueNode) {
120-
return
121-
}
118+
onVueObjectEnter (node) {
122119
computedPropertiesMap.set(node, utils.getComputedProperties(node))
123120
},
124121
':function': onFunctionEnter,

Diff for: lib/rules/no-lifecycle-after-await.js

+6-13
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,15 @@ module.exports = {
5050
},
5151
utils.defineVueVisitor(context,
5252
{
53-
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
54-
if (node.parent !== vueNode) {
55-
return
56-
}
57-
if (utils.getStaticPropertyName(node) !== 'setup') {
58-
return
59-
}
60-
61-
setupFunctions.set(node.value, {
62-
setupProperty: node,
63-
afterAwait: false
64-
})
65-
},
6653
':function' (node) {
6754
scopeStack = { upper: scopeStack, functionNode: node }
6855
},
56+
onSetupFunctionEnter (node) {
57+
setupFunctions.set(node, {
58+
setupProperty: node.parent,
59+
afterAwait: false
60+
})
61+
},
6962
'AwaitExpression' () {
7063
const setupFunctionData = setupFunctions.get(scopeStack.functionNode)
7164
if (!setupFunctionData) {

Diff for: lib/rules/no-mutating-props.js

+6-70
Original file line numberDiff line numberDiff line change
@@ -124,64 +124,12 @@ module.exports = {
124124
* @param {string} name
125125
*/
126126
function verifyMutating (props, name) {
127-
const invalid = findMutating(props)
127+
const invalid = utils.findMutating(props)
128128
if (invalid) {
129129
report(invalid.node, name)
130130
}
131131
}
132132

133-
/**
134-
* @param {MemberExpression|Identifier} props
135-
* @returns { { kind: 'assignment' | 'update' | 'call' , node: Node, pathNodes: MemberExpression[] } }
136-
*/
137-
function findMutating (props) {
138-
/** @type {MemberExpression[]} */
139-
const pathNodes = []
140-
let node = props
141-
let target = node.parent
142-
while (true) {
143-
if (target.type === 'AssignmentExpression') {
144-
if (target.left === node) {
145-
// this.xxx <=|+=|-=>
146-
return {
147-
kind: 'assignment',
148-
node: target,
149-
pathNodes
150-
}
151-
}
152-
} else if (target.type === 'UpdateExpression') {
153-
// this.xxx <++|-->
154-
return {
155-
kind: 'update',
156-
node: target,
157-
pathNodes
158-
}
159-
} else if (target.type === 'CallExpression') {
160-
if (node !== props && target.callee === node) {
161-
const callName = utils.getStaticPropertyName(node)
162-
if (callName && /^push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill$/u.exec(callName)) {
163-
// this.xxx.push()
164-
pathNodes.pop()
165-
return {
166-
kind: 'call',
167-
node: target,
168-
pathNodes
169-
}
170-
}
171-
}
172-
} else if (target.type === 'MemberExpression') {
173-
if (target.object === node) {
174-
pathNodes.push(target)
175-
node = target
176-
target = target.parent
177-
continue // loop
178-
}
179-
}
180-
181-
return null
182-
}
183-
}
184-
185133
/**
186134
* @param {Pattern} param
187135
* @param {string[]} path
@@ -220,32 +168,20 @@ module.exports = {
220168
return Object.assign({},
221169
utils.defineVueVisitor(context,
222170
{
223-
ObjectExpression (node, { node: vueNode }) {
224-
if (node !== vueNode) {
225-
return
226-
}
171+
onVueObjectEnter (node) {
227172
propsMap.set(node, new Set(utils.getComponentProps(node).map(p => p.propName)))
228173
},
229-
'ObjectExpression:exit' (node, { node: vueNode, type }) {
230-
if (node !== vueNode) {
231-
return
232-
}
174+
onVueObjectExit (node, { type }) {
233175
if (!vueObjectData || vueObjectData.type !== 'export') {
234176
vueObjectData = {
235177
type,
236178
object: node
237179
}
238180
}
239181
},
240-
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
241-
if (node.parent !== vueNode) {
242-
return
243-
}
244-
if (utils.getStaticPropertyName(node) !== 'setup') {
245-
return
246-
}
182+
onSetupFunctionEnter (node) {
247183
/** @type {Pattern} */
248-
const propsParam = node.value.params[0]
184+
const propsParam = node.params[0]
249185
if (!propsParam) {
250186
// no arguments
251187
return
@@ -268,7 +204,7 @@ module.exports = {
268204
/** @type {Identifier} */
269205
const id = reference.identifier
270206

271-
const invalid = findMutating(id)
207+
const invalid = utils.findMutating(id)
272208
if (!invalid) {
273209
continue
274210
}

Diff for: lib/rules/no-setup-props-destructure.js

+6-12
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,11 @@ module.exports = {
5252
let scopeStack = null
5353

5454
return utils.defineVueVisitor(context, {
55-
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
56-
if (node.parent !== vueNode) {
57-
return
58-
}
59-
if (utils.getStaticPropertyName(node) !== 'setup') {
60-
return
61-
}
62-
const propsParam = node.value.params[0]
55+
':function' (node) {
56+
scopeStack = { upper: scopeStack, functionNode: node }
57+
},
58+
onSetupFunctionEnter (node) {
59+
const propsParam = node.params[0]
6360
if (!propsParam) {
6461
// no arguments
6562
return
@@ -85,10 +82,7 @@ module.exports = {
8582

8683
propsReferenceIds.add(reference.identifier)
8784
}
88-
setupScopePropsReferenceIds.set(node.value, propsReferenceIds)
89-
},
90-
':function' (node) {
91-
scopeStack = { upper: scopeStack, functionNode: node }
85+
setupScopePropsReferenceIds.set(node, propsReferenceIds)
9286
},
9387
'VariableDeclarator' (node) {
9488
const propsReferenceIds = setupScopePropsReferenceIds.get(scopeStack.functionNode)

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

+35-38
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
const utils = require('../utils')
88

9+
/**
10+
* @typedef {import('vue-eslint-parser').AST.ESLintObjectExpression} ObjectExpression
11+
* @typedef {import('vue-eslint-parser').AST.ESLintMemberExpression} MemberExpression
12+
* @typedef {import('../utils').ComponentComputedProperty} ComponentComputedProperty
13+
*/
14+
915
// ------------------------------------------------------------------------------
1016
// Rule Definition
1117
// ------------------------------------------------------------------------------
@@ -23,6 +29,7 @@ module.exports = {
2329
},
2430

2531
create (context) {
32+
/** @type {Map<ObjectExpression, ComponentComputedProperty[]>} */
2633
const computedPropertiesMap = new Map()
2734
let scopeStack = { upper: null, body: null }
2835

@@ -34,53 +41,43 @@ module.exports = {
3441
scopeStack = scopeStack.upper
3542
}
3643

37-
function verify (node, targetBody, computedProperties) {
38-
computedProperties.forEach(cp => {
39-
if (
40-
cp.value &&
41-
node.loc.start.line >= cp.value.loc.start.line &&
42-
node.loc.end.line <= cp.value.loc.end.line &&
43-
targetBody === cp.value
44-
) {
45-
context.report({
46-
node: node,
47-
message: 'Unexpected side effect in "{{key}}" computed property.',
48-
data: { key: cp.key }
49-
})
50-
}
51-
})
52-
}
53-
5444
return utils.defineVueVisitor(context, {
55-
ObjectExpression (node, { node: vueNode }) {
56-
if (node !== vueNode) {
57-
return
58-
}
45+
onVueObjectEnter (node) {
5946
computedPropertiesMap.set(node, utils.getComputedProperties(node))
6047
},
6148
':function': onFunctionEnter,
6249
':function:exit': onFunctionExit,
6350

64-
// this.xxx <=|+=|-=>
65-
'AssignmentExpression' (node, { node: vueNode }) {
66-
if (node.left.type !== 'MemberExpression') return
67-
if (utils.parseMemberExpression(node.left)[0] === 'this') {
68-
verify(node, scopeStack.body, computedPropertiesMap.get(vueNode))
51+
'MemberExpression > :matches(Identifier, ThisExpression)' (node, { node: vueNode }) {
52+
const targetBody = scopeStack.body
53+
const computedProperty = computedPropertiesMap.get(vueNode).find(cp => {
54+
return (
55+
cp.value &&
56+
node.loc.start.line >= cp.value.loc.start.line &&
57+
node.loc.end.line <= cp.value.loc.end.line &&
58+
targetBody === cp.value
59+
)
60+
})
61+
if (!computedProperty) {
62+
return
6963
}
70-
},
71-
// this.xxx <++|-->
72-
'UpdateExpression > MemberExpression' (node, { node: vueNode }) {
73-
if (utils.parseMemberExpression(node)[0] === 'this') {
74-
verify(node, scopeStack.body, computedPropertiesMap.get(vueNode))
64+
65+
if (!utils.isThis(node, context)) {
66+
return
67+
}
68+
/** @type {MemberExpression} */
69+
const mem = node.parent
70+
if (mem.object !== node) {
71+
return
7572
}
76-
},
77-
// this.xxx.func()
78-
'CallExpression' (node, { node: vueNode }) {
79-
const code = utils.parseMemberOrCallExpression(node)
80-
const MUTATION_REGEX = /(this.)((?!(concat|slice|map|filter)\().)[^\)]*((push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill)\()/g
8173

82-
if (MUTATION_REGEX.test(code)) {
83-
verify(node, scopeStack.body, computedPropertiesMap.get(vueNode))
74+
const invalid = utils.findMutating(mem)
75+
if (invalid) {
76+
context.report({
77+
node: invalid.node,
78+
message: 'Unexpected side effect in "{{key}}" computed property.',
79+
data: { key: computedProperty.key }
80+
})
8481
}
8582
}
8683
}

Diff for: lib/rules/no-unused-properties.js

+5-15
Original file line numberDiff line numberDiff line change
@@ -412,12 +412,8 @@ module.exports = {
412412
const scriptVisitor = Object.assign(
413413
{},
414414
utils.defineVueVisitor(context, {
415-
ObjectExpression (node, vueData) {
416-
if (node !== vueData.node) {
417-
return
418-
}
419-
420-
const container = getVueComponentPropertiesContainer(vueData.node)
415+
onVueObjectEnter (node) {
416+
const container = getVueComponentPropertiesContainer(node)
421417
const watcherNames = new Set()
422418
for (const watcher of utils.iterateProperties(node, new Set([GROUP_WATCHER]))) {
423419
watcherNames.add(watcher.name)
@@ -429,20 +425,14 @@ module.exports = {
429425
container.properties.push(prop)
430426
}
431427
},
432-
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, vueData) {
433-
if (node.parent !== vueData.node) {
434-
return
435-
}
436-
if (utils.getStaticPropertyName(node) !== 'setup') {
437-
return
438-
}
428+
onSetupFunctionEnter (node, vueData) {
439429
const container = getVueComponentPropertiesContainer(vueData.node)
440-
const propsParam = node.value.params[0]
430+
const propsParam = node.params[0]
441431
if (!propsParam) {
442432
// no arguments
443433
return
444434
}
445-
const paramsUsedProps = getParamsUsedProps(node.value)
435+
const paramsUsedProps = getParamsUsedProps(node)
446436
const paramUsedProps = paramsUsedProps.getParam(0)
447437

448438
for (const { usedNames, unknown } of iterateUsedProps(paramUsedProps)) {

Diff for: lib/rules/no-watch-after-await.js

+6-13
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,15 @@ module.exports = {
7676
},
7777
utils.defineVueVisitor(context,
7878
{
79-
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
80-
if (node.parent !== vueNode) {
81-
return
82-
}
83-
if (utils.getStaticPropertyName(node) !== 'setup') {
84-
return
85-
}
86-
87-
setupFunctions.set(node.value, {
88-
setupProperty: node,
89-
afterAwait: false
90-
})
91-
},
9279
':function' (node) {
9380
scopeStack = { upper: scopeStack, functionNode: node }
9481
},
82+
onSetupFunctionEnter (node) {
83+
setupFunctions.set(node, {
84+
setupProperty: node.parent,
85+
afterAwait: false
86+
})
87+
},
9588
'AwaitExpression' () {
9689
const setupFunctionData = setupFunctions.get(scopeStack.functionNode)
9790
if (!setupFunctionData) {

0 commit comments

Comments
 (0)