diff --git a/lib/rules/no-unused-properties.js b/lib/rules/no-unused-properties.js index fd9b0df2c..b64c42d36 100644 --- a/lib/rules/no-unused-properties.js +++ b/lib/rules/no-unused-properties.js @@ -268,6 +268,7 @@ module.exports = { } return container } + /** * @param {string[]} segments * @param {Expression} propertyValue @@ -350,6 +351,7 @@ module.exports = { ) { continue } + if (propertyReferences.hasProperty(property.name)) { // used if ( @@ -453,8 +455,84 @@ module.exports = { } }), utils.defineVueVisitor(context, { - onVueObjectEnter(node) { - const container = getVueComponentPropertiesContainer(node) + /** + * e.g. `mapMutations({ add: 'increment' })` + * @param {Property} 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) + + container.properties.push({ + type: 'array', + name: utils.getStringLiteralValue(node), + groupName: 'computed', + node + }) + }, + + onVueObjectEnter(node, vueNode) { + const container = getVueComponentPropertiesContainer(vueNode.node) for (const watcherOrExpose of utils.iterateProperties( node, @@ -495,8 +573,10 @@ module.exports = { ) } } + container.properties.push(...utils.iterateProperties(node, groups)) }, + /** @param { (FunctionExpression | ArrowFunctionExpression) & { parent: Property }} node */ 'ObjectExpression > Property > :function[params.length>0]'( node, diff --git a/tests/lib/rules/no-unused-properties.js b/tests/lib/rules/no-unused-properties.js index 0139559b1..da4b5e926 100644 --- a/tests/lib/rules/no-unused-properties.js +++ b/tests/lib/rules/no-unused-properties.js @@ -53,6 +53,273 @@ const unreferencedOptions = { tester.run('no-unused-properties', rule, { valid: [ + { + filename: 'test.vue', + code: ` + + + `, + options: allOptions + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, + { + filename: 'test.vue', + code: ` + + + ` + }, // a property used in a script expression { filename: 'test.vue', @@ -1730,6 +1997,410 @@ tester.run('no-unused-properties', rule, { } ], invalid: [ + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 6 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 4 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 6 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 6 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 4 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'add2' of method found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count2' of computed property found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count2' of computed property found, but never used.", + line: 6 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count2' of computed property found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count2' of computed property found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count' of computed property found, but never used.", + line: 4 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count2' of computed property found, but never used.", + line: 5 + } + ] + }, + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count3' of computed property found, but never used.", + line: 7 + } + ] + }, + + // vuex unused state + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count' of computed property found, but never used.", + line: 5 + } + ] + }, + + // vuex unused state + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'count2' of computed property found, but never used.", + line: 6 + } + ] + }, + + // vuex unused state + { + filename: 'test.vue', + code: ` + + + `, + errors: [ + { + message: "'additional' of computed property found, but never used.", + line: 5 + } + ] + }, + // unused property { filename: 'test.vue',