8000 [Update] Make `vue/no-shared-component-data` fixable (#278) · Demivan/eslint-plugin-vue@887045a · GitHub
[go: up one dir, main page]

Skip to content

Commit 887045a

Browse files
mysticateamichalsnik
authored andcommitted
[Update] Make vue/no-shared-component-data fixable (vuejs#278)
* Update: make vue/no-shared-component-data fixable * refactoring
1 parent 3137c1f commit 887045a

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

lib/rules/no-shared-component-data.js

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,33 @@
66

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

9+
function isOpenParen (token) {
10+
return token.type === 'Punctuator' && token.value === '('
11+
}
12+
13+
function isCloseParen (token) {
14+
return token.type === 'Punctuator' && token.value === ')'
15+
}
16+
17+
function getFirstAndLastTokens (node, sourceCode) {
18+
let first = sourceCode.getFirstToken(node)
19+
let last = sourceCode.getLastToken(node)
20+
21+
// If the value enclosed by parentheses, update the 'first' and 'last' by the parentheses.
22+
while (true) {
23+
const prev = sourceCode.getTokenBefore(first)
24+
const next = sourceCode.getTokenAfter(last)
25+
if (isOpenParen(prev) && isCloseParen(next)) {
26+
first = prev
27+
last = next
28+
} else {
29+
return { first, last }
30+
}
31+
}
32+
}
33+
934
function create (context) {
10-
// ----------------------------------------------------------------------
11-
// Public
12-
// ----------------------------------------------------------------------
35+
const sourceCode = context.getSourceCode()
1336

1437
return utils.executeOnVueComponent(context, (obj) => {
1538
obj.properties
@@ -21,10 +44,24 @@ function create (context) {
2144 8000
p.value.type !== 'ArrowFunctionExpression' &&
2245
p.value.type !== 'Identifier'
2346
)
24-
.forEach(cp => {
47+
.forEach(p => {
2548
context.report({
26-
node: cp.value,
27-
message: '`data` property in component must be a function'
49+
node: p,
50+
message: '`data` property in component must be a function',
51+
fix (fixer) {
52+
const tokens = getFirstAndLastTokens(p.value, sourceCode)
53+
54+
// If we can upgrade requirements to `eslint@>4.1.0`, this code can be replaced by:
55+
// return [
56+
// fixer.insertTextBefore(tokens.first, 'function() {\nreturn '),
57+
// fixer.insertTextAfter(tokens.last, ';\n}')
58+
// ]
59+
// See: https://eslint.org/blog/2017/06/eslint-v4.1.0-released#applying-multiple-autofixes-simultaneously
60+
const range = [tokens.first.range[0], tokens.last.range[1]]
61+
const valueText = sourceCode.text.slice(range[0], range[1])
62+
const replacement = `function() {\nreturn ${valueText};\n}`
63+
return fixer.replaceTextRange(range, replacement)
64+
}
2865
})
2966
})
3067
})
@@ -40,7 +77,7 @@ module.exports = {
4077
description: "enforce component's data property to be a function",
4178
category: 'essential'
4279
},
43-
fixable: null, // or "code" or "whitespace"
80+
fixable: 'code',
4481
schema: []
4582
},
4683

tests/lib/rules/no-shared-component-data.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ ruleTester.run('no-shared-component-data', rule, {
130130
}
131131
})
132132
`,
133+
output: `
134+
Vue.component('some-comp', {
135+
data: function() {
136+
return {
137+
foo: 'bar'
138+
};
139+
}
140+
})
141+
`,
133142
parserOptions,
134143
errors: [{
135144
message: '`data` property in component must be a function',
@@ -145,6 +154,39 @@ ruleTester.run('no-shared-component-data', rule, {
145154
}
146155
}
147156
`,
157+
output: `
158+
export default {
159+
data: function() {
160+
return {
161+
foo: 'bar'
162+
};
163+
}
164+
}
165+
`,
166+
parserOptions,
167+
errors: [{
168+
message: '`data` property in component must be a function',
169+
line: 3
170+
}]
171+
},
172+
{
173+
filename: 'test.vue',
174+
code: `
175+
export default {
176+
data: /*a*/ (/*b*/{
177+
foo: 'bar'
178+
})
179+
}
180+
`,
181+
output: `
182+
export default {
183+
data: /*a*/ function() {
184+
return (/*b*/{
185+
foo: 'bar'
186+
});
187+
}
188+
}
189+
`,
148190
parserOptions,
149191
errors: [{
150192
message: '`data` property in component must be a function',

0 commit comments

Comments
 (0)
0