66
77const 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+
934function 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 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
0 commit comments