Skip to content

Commit

Permalink
Fixed false positives for getter/setter in vue/no-dupe-keys rule (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed Jun 5, 2020
1 parent 1700708 commit 47960f6
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 56 deletions.
82 changes: 60 additions & 22 deletions lib/utils/index.js
Expand Up @@ -18,6 +18,8 @@
* @typedef {import('vue-eslint-parser').AST.ESLintFunctionExpression} FunctionExpression
* @typedef {import('vue-eslint-parser').AST.ESLintBlockStatement} BlockStatement
* @typedef {import('vue-eslint-parser').AST.ESLintNode} ESLintNode
*
* @typedef {import('vue-eslint-parser').AST.ESLintArrowFunctionExpression | { type: 'ArrowFunctionExpression', body: BlockStatement | Expression } } ArrowFunctionExpression
*/

/**
Expand All @@ -37,6 +39,11 @@
/**
* @typedef { {key: string, value: BlockStatement} } ComponentComputedProperty
*/
/**
* @typedef { { name: string, groupName: string, node: Literal | TemplateLiteral } } ComponentArrayPropertyData
* @typedef { { name: string, groupName: string, node: Identifier | Literal | TemplateLiteral } } ComponentObjectPropertyData
* @typedef { ComponentArrayPropertyData | ComponentObjectPropertyData } ComponentPropertyData
*/

// ------------------------------------------------------------------------------
// Helpers
Expand Down Expand Up @@ -799,14 +806,17 @@ module.exports = {
},
/**
* Return generator with all properties
* @param {ASTNode} node Node to check
* @param {Set} groups Name of parent group
* @param {ObjectExpression} node Node to check
* @param {Set<string>} groups Name of parent group
* @returns {IterableIterator<ComponentPropertyData>}
*/
* iterateProperties (node, groups) {
const nodes = node.properties.filter(p => p.type === 'Property' && groups.has(getStaticPropertyName(p.key)))
for (const item of nodes) {
const name = getStaticPropertyName(item.key)
if (!name) continue
for (const item of node.properties) {
if (item.type !== 'Property') {
continue
}
const name = getStaticPropertyName(item)
if (!name || !groups.has(name)) continue

if (item.value.type === 'ArrayExpression') {
yield * this.iterateArrayExpression(item.value, name)
Expand All @@ -822,40 +832,66 @@ module.exports = {

/**
* Return generator with all elements inside ArrayExpression
* @param {ASTNode} node Node to check
* @param {ArrayExpression} node Node to check
* @param {string} groupName Name of parent group
* @returns {IterableIterator<ComponentArrayPropertyData>}
*/
* iterateArrayExpression (node, groupName) {
assert(node.type === 'ArrayExpression')
for (const item of node.elements) {
const name = getStaticPropertyName(item)
if (name) {
const obj = { name, groupName, node: item }
yield obj
if (item.type === 'Literal' || item.type === 'TemplateLiteral') {
const name = getStaticPropertyName(item)
if (name) {
yield { name, groupName, node: item }
}
}
}
},

/**
* Return generator with all elements inside ObjectExpression
* @param {ASTNode} node Node to check
* @param {ObjectExpression} node Node to check
* @param {string} groupName Name of parent group
* @returns {IterableIterator<ComponentObjectPropertyData>}
*/
* iterateObjectExpression (node, groupName) {
assert(node.type === 'ObjectExpression')
let usedGetter
for (const item of node.properties) {
const name = getStaticPropertyName(item)
if (name) {
const obj = { name, groupName, node: item.key }
yield obj
if (item.type === 'Property') {
const key = item.key
if (key.type === 'Identifier' || key.type === 'Literal' || key.type === 'TemplateLiteral') {
const name = getStaticPropertyName(item)
if (name) {
if (item.kind === 'set') {
// find getter pair
if (!usedGetter) { usedGetter = new Set() }
if (node.properties.some(item2 => {
if (item2.type === 'Property' && item2.kind === 'get' && !usedGetter.has(item2)) {
const getterName = getStaticPropertyName(item2)
if (getterName === name) {
usedGetter.add(item2)
return true
}
}
return false
})) {
// has getter pair
continue
}
}
yield { name, groupName, node: key }
}
}
}
}
},

/**
* Return generator with all elements inside FunctionExpression
* @param {ASTNode} node Node to check
* @param {FunctionExpression} node Node to check
* @param {string} groupName Name of parent group
* @returns {IterableIterator<ComponentObjectPropertyData>}
*/
* iterateFunctionExpression (node, groupName) {
assert(node.type === 'FunctionExpression')
Expand All @@ -870,19 +906,21 @@ module.exports = {

/**
* Return generator with all elements inside ArrowFunctionExpression
* @param {ASTNode} node Node to check
* @param {ArrowFunctionExpression} node Node to check
* @param {string} groupName Name of parent group
* @returns {IterableIterator<ComponentObjectPropertyData>}
*/
* iterateArrowFunctionExpression (node, groupName) {
assert(node.type === 'ArrowFunctionExpression')
if (node.body.type === 'BlockStatement') {
for (const item of node.body.body) {
const body = node.body
if (body.type === 'BlockStatement') {
for (const item of body.body) {
if (item.type === 'ReturnStatement' && item.argument && item.argument.type === 'ObjectExpression') {
yield * this.iterateObjectExpression(item.argument, groupName)
}
}
} else if (node.body.type === 'ObjectExpression') {
yield * this.iterateObjectExpression(node.body, groupName)
} else if (body.type === 'ObjectExpression') {
yield * this.iterateObjectExpression(body, groupName)
}
},

Expand Down

0 comments on commit 47960f6

Please sign in to comment.