Skip to content

Commit

Permalink
Refactoring (#1154)
Browse files Browse the repository at this point in the history
* Refactoring

* update
  • Loading branch information
ota-meshi committed May 21, 2020
1 parent d0e8e47 commit e80c2f0
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 223 deletions.
5 changes: 1 addition & 4 deletions lib/rules/no-async-in-computed-properties.js
Expand Up @@ -115,10 +115,7 @@ module.exports = {
})
}
return utils.defineVueVisitor(context, {
ObjectExpression (node, { node: vueNode }) {
if (node !== vueNode) {
return
}
onVueObjectEnter (node) {
computedPropertiesMap.set(node, utils.getComputedProperties(node))
},
':function': onFunctionEnter,
Expand Down
19 changes: 6 additions & 13 deletions lib/rules/no-lifecycle-after-await.js
Expand Up @@ -50,22 +50,15 @@ module.exports = {
},
utils.defineVueVisitor(context,
{
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
if (node.parent !== vueNode) {
return
}
if (utils.getStaticPropertyName(node) !== 'setup') {
return
}

setupFunctions.set(node.value, {
setupProperty: node,
afterAwait: false
})
},
':function' (node) {
scopeStack = { upper: scopeStack, functionNode: node }
},
onSetupFunctionEnter (node) {
setupFunctions.set(node, {
setupProperty: node.parent,
afterAwait: false
})
},
'AwaitExpression' () {
const setupFunctionData = setupFunctions.get(scopeStack.functionNode)
if (!setupFunctionData) {
Expand Down
76 changes: 6 additions & 70 deletions lib/rules/no-mutating-props.js
Expand Up @@ -124,64 +124,12 @@ module.exports = {
* @param {string} name
*/
function verifyMutating (props, name) {
const invalid = findMutating(props)
const invalid = utils.findMutating(props)
if (invalid) {
report(invalid.node, name)
}
}

/**
* @param {MemberExpression|Identifier} props
* @returns { { kind: 'assignment' | 'update' | 'call' , node: Node, pathNodes: MemberExpression[] } }
*/
function findMutating (props) {
/** @type {MemberExpression[]} */
const pathNodes = []
let node = props
let target = node.parent
while (true) {
if (target.type === 'AssignmentExpression') {
if (target.left === node) {
// this.xxx <=|+=|-=>
return {
kind: 'assignment',
node: target,
pathNodes
}
}
} else if (target.type === 'UpdateExpression') {
// this.xxx <++|-->
return {
kind: 'update',
node: target,
pathNodes
}
} else if (target.type === 'CallExpression') {
if (node !== props && target.callee === node) {
const callName = utils.getStaticPropertyName(node)
if (callName && /^push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill$/u.exec(callName)) {
// this.xxx.push()
pathNodes.pop()
return {
kind: 'call',
node: target,
pathNodes
}
}
}
} else if (target.type === 'MemberExpression') {
if (target.object === node) {
pathNodes.push(target)
node = target
target = target.parent
continue // loop
}
}

return null
}
}

/**
* @param {Pattern} param
* @param {string[]} path
Expand Down Expand Up @@ -220,32 +168,20 @@ module.exports = {
return Object.assign({},
utils.defineVueVisitor(context,
{
ObjectExpression (node, { node: vueNode }) {
if (node !== vueNode) {
return
}
onVueObjectEnter (node) {
propsMap.set(node, new Set(utils.getComponentProps(node).map(p => p.propName)))
},
'ObjectExpression:exit' (node, { node: vueNode, type }) {
if (node !== vueNode) {
return
}
onVueObjectExit (node, { type }) {
if (!vueObjectData || vueObjectData.type !== 'export') {
vueObjectData = {
type,
object: node
}
}
},
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
if (node.parent !== vueNode) {
return
}
if (utils.getStaticPropertyName(node) !== 'setup') {
return
}
onSetupFunctionEnter (node) {
/** @type {Pattern} */
const propsParam = node.value.params[0]
const propsParam = node.params[0]
if (!propsParam) {
// no arguments
return
Expand All @@ -268,7 +204,7 @@ module.exports = {
/** @type {Identifier} */
const id = reference.identifier

const invalid = findMutating(id)
const invalid = utils.findMutating(id)
if (!invalid) {
continue
}
Expand Down
18 changes: 6 additions & 12 deletions lib/rules/no-setup-props-destructure.js
Expand Up @@ -52,14 +52,11 @@ module.exports = {
let scopeStack = null

return utils.defineVueVisitor(context, {
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
if (node.parent !== vueNode) {
return
}
if (utils.getStaticPropertyName(node) !== 'setup') {
return
}
const propsParam = node.value.params[0]
':function' (node) {
scopeStack = { upper: scopeStack, functionNode: node }
},
onSetupFunctionEnter (node) {
const propsParam = node.params[0]
if (!propsParam) {
// no arguments
return
Expand All @@ -85,10 +82,7 @@ module.exports = {

propsReferenceIds.add(reference.identifier)
}
setupScopePropsReferenceIds.set(node.value, propsReferenceIds)
},
':function' (node) {
scopeStack = { upper: scopeStack, functionNode: node }
setupScopePropsReferenceIds.set(node, propsReferenceIds)
},
'VariableDeclarator' (node) {
const propsReferenceIds = setupScopePropsReferenceIds.get(scopeStack.functionNode)
Expand Down
73 changes: 35 additions & 38 deletions lib/rules/no-side-effects-in-computed-properties.js
Expand Up @@ -6,6 +6,12 @@

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

/**
* @typedef {import('vue-eslint-parser').AST.ESLintObjectExpression} ObjectExpression
* @typedef {import('vue-eslint-parser').AST.ESLintMemberExpression} MemberExpression
* @typedef {import('../utils').ComponentComputedProperty} ComponentComputedProperty
*/

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
Expand All @@ -23,6 +29,7 @@ module.exports = {
},

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

Expand All @@ -34,53 +41,43 @@ module.exports = {
scopeStack = scopeStack.upper
}

function verify (node, targetBody, computedProperties) {
computedProperties.forEach(cp => {
if (
cp.value &&
node.loc.start.line >= cp.value.loc.start.line &&
node.loc.end.line <= cp.value.loc.end.line &&
targetBody === cp.value
) {
context.report({
node: node,
message: 'Unexpected side effect in "{{key}}" computed property.',
data: { key: cp.key }
})
}
})
}

return utils.defineVueVisitor(context, {
ObjectExpression (node, { node: vueNode }) {
if (node !== vueNode) {
return
}
onVueObjectEnter (node) {
computedPropertiesMap.set(node, utils.getComputedProperties(node))
},
':function': onFunctionEnter,
':function:exit': onFunctionExit,

// this.xxx <=|+=|-=>
'AssignmentExpression' (node, { node: vueNode }) {
if (node.left.type !== 'MemberExpression') return
if (utils.parseMemberExpression(node.left)[0] === 'this') {
verify(node, scopeStack.body, computedPropertiesMap.get(vueNode))
'MemberExpression > :matches(Identifier, ThisExpression)' (node, { node: vueNode }) {
const targetBody = scopeStack.body
const computedProperty = computedPropertiesMap.get(vueNode).find(cp => {
return (
cp.value &&
node.loc.start.line >= cp.value.loc.start.line &&
node.loc.end.line <= cp.value.loc.end.line &&
targetBody === cp.value
)
})
if (!computedProperty) {
return
}
},
// this.xxx <++|-->
'UpdateExpression > MemberExpression' (node, { node: vueNode }) {
if (utils.parseMemberExpression(node)[0] === 'this') {
verify(node, scopeStack.body, computedPropertiesMap.get(vueNode))

if (!utils.isThis(node, context)) {
return
}
/** @type {MemberExpression} */
const mem = node.parent
if (mem.object !== node) {
return
}
},
// this.xxx.func()
'CallExpression' (node, { node: vueNode }) {
const code = utils.parseMemberOrCallExpression(node)
const MUTATION_REGEX = /(this.)((?!(concat|slice|map|filter)\().)[^\)]*((push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill)\()/g

if (MUTATION_REGEX.test(code)) {
verify(node, scopeStack.body, computedPropertiesMap.get(vueNode))
const invalid = utils.findMutating(mem)
if (invalid) {
context.report({
node: invalid.node,
message: 'Unexpected side effect in "{{key}}" computed property.',
data: { key: computedProperty.key }
})
}
}
}
Expand Down
20 changes: 5 additions & 15 deletions lib/rules/no-unused-properties.js
Expand Up @@ -412,12 +412,8 @@ module.exports = {
const scriptVisitor = Object.assign(
{},
utils.defineVueVisitor(context, {
ObjectExpression (node, vueData) {
if (node !== vueData.node) {
return
}

const container = getVueComponentPropertiesContainer(vueData.node)
onVueObjectEnter (node) {
const container = getVueComponentPropertiesContainer(node)
const watcherNames = new Set()
for (const watcher of utils.iterateProperties(node, new Set([GROUP_WATCHER]))) {
watcherNames.add(watcher.name)
Expand All @@ -429,20 +425,14 @@ module.exports = {
container.properties.push(prop)
}
},
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, vueData) {
if (node.parent !== vueData.node) {
return
}
if (utils.getStaticPropertyName(node) !== 'setup') {
return
}
onSetupFunctionEnter (node, vueData) {
const container = getVueComponentPropertiesContainer(vueData.node)
const propsParam = node.value.params[0]
const propsParam = node.params[0]
if (!propsParam) {
// no arguments
return
}
const paramsUsedProps = getParamsUsedProps(node.value)
const paramsUsedProps = getParamsUsedProps(node)
const paramUsedProps = paramsUsedProps.getParam(0)

for (const { usedNames, unknown } of iterateUsedProps(paramUsedProps)) {
Expand Down
19 changes: 6 additions & 13 deletions lib/rules/no-watch-after-await.js
Expand Up @@ -76,22 +76,15 @@ module.exports = {
},
utils.defineVueVisitor(context,
{
'Property[value.type=/^(Arrow)?FunctionExpression$/]' (node, { node: vueNode }) {
if (node.parent !== vueNode) {
return
}
if (utils.getStaticPropertyName(node) !== 'setup') {
return
}

setupFunctions.set(node.value, {
setupProperty: node,
afterAwait: false
})
},
':function' (node) {
scopeStack = { upper: scopeStack, functionNode: node }
},
onSetupFunctionEnter (node) {
setupFunctions.set(node, {
setupProperty: node.parent,
afterAwait: false
})
},
'AwaitExpression' () {
const setupFunctionData = setupFunctions.get(scopeStack.functionNode)
if (!setupFunctionData) {
Expand Down

0 comments on commit e80c2f0

Please sign in to comment.