6
6
7
7
const utils = require ( '../utils' )
8
8
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
+
9
34
function create ( context ) {
10
- // ----------------------------------------------------------------------
11
- // Public
12
- // ----------------------------------------------------------------------
35
+ const sourceCode = context . getSourceCode ( )
13
36
14
37
return utils . executeOnVueComponent ( context , ( obj ) => {
15
38
obj . properties
@@ -21,10 +44,24 @@ function create (context) {
21
44
8000
p . value . type !== 'ArrowFunctionExpression' &&
22
45
p . value . type !== 'Identifier'
23
46
)
24
- . forEach ( cp => {
47
+ . forEach ( p => {
25
48
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
+ }
28
65
} )
29
66
} )
30
67
} )
@@ -40,7 +77,7 @@ module.exports = {
40
77
description : "enforce component's data property to be a function" ,
41
78
category : 'essential'
42
79
} ,
43
- fixable : null , // or " code" or "whitespace"
80
+ fixable : ' code' ,
44
81
schema : [ ]
45
82
} ,
46
83
0 commit comments