Skip to content

Commit f061f82

Browse files
authored
Fix false positives for member call and autofix error in vue/v-on-function-call rule. (#1146)
1 parent 5750d7a commit f061f82

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

lib/rules/v-on-function-call.js

+26-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@
99

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

12+
// ------------------------------------------------------------------------------
13+
// Helpers
14+
// ------------------------------------------------------------------------------
15+
16+
/**
17+
* Check whether the given token is a left parenthesis.
18+
* @param {Token} token The token to check.
19+
* @returns {boolean} `true` if the token is a left parenthesis.
20+
*/
21+
function isLeftParen (token) {
22+
return token != null && token.type === 'Punctuator' && token.value === '('
23+
}
24+
1225
// ------------------------------------------------------------------------------
1326
// Rule Definition
1427
// ------------------------------------------------------------------------------
@@ -40,17 +53,24 @@ module.exports = {
4053
})
4154
},
4255

43-
"VAttribute[directive=true][key.name.name='on'][key.argument!=null] VOnExpression > ExpressionStatement > *" (node) {
44-
if (!always && node.type === 'CallExpression' && node.arguments.length === 0) {
56+
"VAttribute[directive=true][key.name.name='on'][key.argument!=null] VOnExpression > ExpressionStatement > CallExpression" (node) {
57+
if (!always && node.arguments.length === 0 && node.callee.type === 'Identifier') {
4558
context.report({
4659
node,
4760
loc: node.loc,
4861
message: "Method calls without arguments inside of 'v-on' directives must not have parentheses.",
4962
fix: fixer => {
50-
const nodeString = context.getSourceCode().getText().substring(node.range[0], node.range[1])
51-
// This ensures that parens are also removed if they contain whitespace
52-
const parensLength = nodeString.match(/\(\s*\)\s*$/)[0].length
53-
return fixer.removeRange([node.end - parensLength, node.end])
63+
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
64+
const rightToken = tokenStore.getLastToken(node)
65+
const leftToken = tokenStore.getTokenAfter(node.callee, isLeftParen)
66+
const tokens = tokenStore.getTokensBetween(leftToken, rightToken, { includeComments: true })
67+
68+
if (tokens.length) {
69+
// The comment is included and cannot be fixed.
70+
return null
71+
}
72+
73+
return fixer.removeRange([leftToken.range[0], rightToken.range[1]])
5474
}
5575
})
5676
}

tests/lib/rules/v-on-function-call.js

+34
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,33 @@ tester.run('v-on-function-call', rule, {
4444
filename: 'test.vue',
4545
code: '<template><div @click="foo"></div></template>',
4646
options: ['never']
47+
},
48+
{
49+
filename: 'test.vue',
50+
code: '<template><div @click="foo.bar()"></div></template>'
51+
},
52+
{
53+
filename: 'test.vue',
54+
code: '<template><div @click="foo.bar()"></div></template>',
55+
options: ['always']
56+
},
57+
{
58+
filename: 'test.vue',
59+
code: '<template><div @[foo()]="bar"></div></template>'
60+
},
61+
{
62+
filename: 'test.vue',
63+
code: '<template><div @[foo]="bar()"></div></template>',
64+
options: ['always']
65+
},
66+
{
67+
filename: 'test.vue',
68+
code: '<template><div @click="()=>foo.bar()"></div></template>'
69+
},
70+
{
71+
filename: 'test.vue',
72+
code: '<template><div @click="()=>foo.bar()"></div></template>',
73+
options: ['always']
4774
}
4875
],
4976
invalid: [
@@ -67,6 +94,13 @@ tester.run('v-on-function-call', rule, {
6794
output: `<template><div @click="foo"></div></template>`,
6895
errors: ["Method calls without arguments inside of 'v-on' directives must not have parentheses."],
6996
options: ['never']
97+
},
98+
{
99+
filename: 'test.vue',
100+
code: '<template><div @click="foo(/**/)"></div></template>',
101+
output: null,
102+
errors: ["Method calls without arguments inside of 'v-on' directives must not have parentheses."],
103+
options: ['never']
70104
}
71105
]
72106
})

0 commit comments

Comments
 (0)