diff --git a/lib/rules/enforce-style-attribute.js b/lib/rules/enforce-style-attribute.js
index b4b39a73f..9710a1315 100644
--- a/lib/rules/enforce-style-attribute.js
+++ b/lib/rules/enforce-style-attribute.js
@@ -34,6 +34,7 @@ function isPlain(componentBlock) {
return !isScoped(componentBlock) && !isModule(componentBlock)
}
+/** @param {RuleContext} context */
function getUserDefinedAllowedAttrs(context) {
if (context.options[0] && context.options[0].allow) {
return context.options[0].allow
diff --git a/lib/rules/no-mutating-props.js b/lib/rules/no-mutating-props.js
index c00a92242..d5d28303a 100644
--- a/lib/rules/no-mutating-props.js
+++ b/lib/rules/no-mutating-props.js
@@ -212,7 +212,8 @@ module.exports = {
case 'ArrayPattern': {
for (let index = 0; index < param.elements.length; index++) {
const element = param.elements[index]
- yield* iteratePatternProperties(element, [...path, `${index}`])
+ if (element)
+ yield* iteratePatternProperties(element, [...path, `${index}`])
}
break
}
diff --git a/lib/rules/no-template-shadow.js b/lib/rules/no-template-shadow.js
index 8be04b9cc..e00da50e5 100644
--- a/lib/rules/no-template-shadow.js
+++ b/lib/rules/no-template-shadow.js
@@ -20,6 +20,10 @@ const GROUP_NAMES = [
'setup'
]
+/**
+ * @param {RuleContext} context
+ * @param {string} variableName
+ */
function isAllowedVarName(context, variableName) {
if (context.options[0] && context.options[0].allow) {
return context.options[0].allow.includes(variableName)
diff --git a/lib/rules/no-unused-properties.js b/lib/rules/no-unused-properties.js
index 46099267f..d09aca5c2 100644
--- a/lib/rules/no-unused-properties.js
+++ b/lib/rules/no-unused-properties.js
@@ -487,79 +487,62 @@ module.exports = {
}),
utils.defineVueVisitor(context, {
/**
- * e.g. `mapMutations({ add: 'increment' })`
- * @param {Property} node
+ * @param {CallExpression} node
* @param {VueObjectData} vueData
*/
- 'CallExpression[callee.name=/^(mapMutations|mapActions)$/][arguments] ObjectExpression Property'(
- node,
- vueData
- ) {
- const container = getVueComponentPropertiesContainer(vueData.node)
-
- container.properties.push({
- type: 'array',
- name: utils.getStaticPropertyName(node),
- groupName: 'methods',
- node
- })
- },
-
- /**
- * e.g. `mapMutations(['add'])`
- * @param {Literal} node
- * @param {VueObjectData} vueData
- */
- 'CallExpression[callee.name=/^(mapMutations|mapActions)$/][arguments] ArrayExpression Literal'(
- node,
- vueData
- ) {
- const container = getVueComponentPropertiesContainer(vueData.node)
-
- container.properties.push({
- type: 'array',
- name: utils.getStringLiteralValue(node),
- groupName: 'methods',
- node
- })
- },
-
- /**
- * e.g. `mapState({ count: state => state.todosCount })`
- * @param {Property} node
- * @param {VueObjectData} vueData
- */
- 'CallExpression[callee.name=/^(mapState|mapGetters)$/][arguments] ObjectExpression Property'(
- node,
- vueData
- ) {
- const container = getVueComponentPropertiesContainer(vueData.node)
-
- container.properties.push({
- type: 'array',
- name: utils.getStaticPropertyName(node),
- groupName: 'computed',
- node
- })
- },
-
- /**
- * e.g. `mapState(['count'])`
- * @param {Literal} node
- * @param {VueObjectData} vueData
- */
- 'CallExpression[callee.name=/^(mapState|mapGetters)$/][arguments] ArrayExpression Literal'(
- node,
- vueData
- ) {
- const container = getVueComponentPropertiesContainer(vueData.node)
+ CallExpression(node, vueData) {
+ if (node.callee.type !== 'Identifier') return
+ /** @type {'methods'|'computed'|null} */
+ let groupName = null
+ if (/^mapMutations|mapActions$/u.test(node.callee.name)) {
+ groupName = 'methods'
+ } else if (/^mapState|mapGetters$/u.test(node.callee.name)) {
+ groupName = 'computed'
+ }
- container.properties.push({
- type: 'array',
- name: utils.getStringLiteralValue(node),
- groupName: 'computed',
- node
- })
+ if (!groupName || node.arguments.length === 0) return
+ const arg = node.arguments[0]
+ if (arg.type === 'ObjectExpression') {
+ // e.g.
+ // `mapMutations({ add: 'increment' })`
+ // `mapState({ count: state => state.todosCount })`
+ const container = getVueComponentPropertiesContainer(vueData.node)
+ for (const prop of arg.properties) {
+ const name =
+ prop.type === 'SpreadElement'
+ ? null
+ : utils.getStaticPropertyName(prop)
+ if (name) {
+ container.properties.push({
+ type: 'array',
+ name,
+ groupName,
+ node: prop
+ })
+ }
+ }
+ } else if (arg.type === 'ArrayExpression') {
+ // e.g. `mapMutations(['add'])`
+ const container = getVueComponentPropertiesContainer(vueData.node)
+ for (const element of arg.elements) {
+ if (
+ !element ||
+ (element.type !== 'Literal' &&
+ element.type !== 'TemplateLiteral')
+ ) {
+ continue
+ }
+ const name = utils.getStringLiteralValue(element)
+ if (name) {
+ container.properties.push({
+ type: 'array',
+ name,
+ groupName,
+ node: element
+ })
+ }
+ }
+ }
},
onVueObjectEnter(node, vueNode) {
diff --git a/tests/lib/rules/no-unused-properties.js b/tests/lib/rules/no-unused-properties.js
index e47f346aa..93a5279f0 100644
--- a/tests/lib/rules/no-unused-properties.js
+++ b/tests/lib/rules/no-unused-properties.js
@@ -2501,6 +2501,53 @@ tester.run('no-unused-properties', rule, {
}
]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+
+ {{ count }}
+
+ `,
+ errors: [
+ {
+ message: "'a' of computed property found, but never used.",
+ line: 6
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+ {{ count }}
+
+ `,
+ errors: [
+ {
+ message: "'a' of computed property found, but never used.",
+ line: 6
+ }
+ ]
+ },
// vuex unused state
{