@@ -10,6 +10,40 @@ const isAssignmentLHS = require('../util/ast').isAssignmentLHS;
10
10
11
11
const DEFAULT_OPTION = 'always' ;
12
12
13
+ function createSFCParams ( ) {
14
+ const queue = [ ] ;
15
+
16
+ return {
17
+ push ( params ) {
18
+ queue . unshift ( params ) ;
19
+ } ,
20
+ pop ( ) {
21
+ queue . shift ( ) ;
22
+ } ,
23
+ propsName ( ) {
24
+ const found = queue . find ( ( params ) => {
25
+ const props = params [ 0 ] ;
26
+ return props && ! props . destructuring && props . name ;
27
+ } ) ;
28
+ return found && found [ 0 ] && found [ 0 ] . name ;
29
+ } ,
30
+ contextName ( ) {
31
+ const found = queue . find ( ( params ) => {
32
+ const context = params [ 1 ] ;
33
+ return context && ! context . destructuring && context . name ;
34
+ } ) ;
35
+ return found && found [ 1 ] && found . name ;
36
+ }
37
+ } ;
38
+ }
39
+
40
+ function evalParams ( params ) {
41
+ return params . map ( ( param ) => ( {
42
+ destructuring : param . type === 'ObjectPattern' ,
43
+ name : param . type === 'Identifier' && param . name
44
+ } ) ) ;
45
+ }
46
+
13
47
module . exports = {
14
48
meta : {
15
49
docs : {
@@ -46,31 +80,50 @@ module.exports = {
46
80
create : Components . detect ( ( context , components , utils ) => {
47
81
const configuration = context . options [ 0 ] || DEFAULT_OPTION ;
48
82
const ignoreClassFields = ( context . options [ 1 ] && ( context . options [ 1 ] . ignoreClassFields === true ) ) || false ;
83
+ const sfcParams = createSFCParams ( ) ;
49
84
50
85
/**
51
86
* @param {ASTNode } node We expect either an ArrowFunctionExpression,
52
87
* FunctionDeclaration, or FunctionExpression
53
88
*/
54
89
function handleStatelessComponent ( node ) {
55
- const destructuringProps = node . params && node . params [ 0 ] && node . params [ 0 ] . type === 'ObjectPattern' ;
56
- const destructuringContext = node . params && node . params [ 1 ] && node . params [ 1 ] . type === 'ObjectPattern' ;
90
+ const params = evalParams ( node . params ) ;
91
+
92
+ const SFCComponent = components . get ( context . getScope ( node ) . block ) ;
93
+ if ( ! SFCComponent ) {
94
+ return ;
95
+ }
96
+ sfcParams . push ( params ) ;
57
97
58
- if ( destructuringProps && components . get ( node ) && configuration === 'never' ) {
98
+ if ( params [ 0 ] && params [ 0 ] . destructuring && components . get ( node ) && configuration === 'never' ) {
59
99
context . report ( {
60
100
node,
61
101
messageId : 'noDestructPropsInSFCArg'
62
102
} ) ;
63
- } else if ( destructuringContext && components . get ( node ) && configuration === 'never' ) {
103
+ } else if ( params [ 1 ] && params [ 1 ] . destructuring && components . get ( node ) && configuration === 'never' ) {
64
104
context . report ( {
65
105
node,
66
106
messageId : 'noDestructContextInSFCArg'
67
107
} ) ;
68
108
}
69
109
}
70
110
111
+ function handleStatelessComponentExit ( node ) {
112
+ const SFCComponent = components . get ( context . getScope ( node ) . block ) ;
113
+ if ( SFCComponent ) {
114
+ sfcParams . pop ( ) ;
115
+ }
116
+ }
117
+
71
118
function handleSFCUsage ( node ) {
119
+ const propsName = sfcParams . propsName ( ) ;
120
+ const contextName = sfcParams . contextName ( ) ;
72
121
// props.aProp || context.aProp
73
- const isPropUsed = ( node . object . name === 'props' || node . object . name === 'context' ) && ! isAssignmentLHS ( node ) ;
122
+ const isPropUsed = (
123
+ ( propsName && node . object . name === propsName )
124
+ || ( contextName && node . object . name === contextName )
125
+ )
126
+ && ! isAssignmentLHS ( node ) ;
74
127
if ( isPropUsed && configuration === 'always' ) {
75
128
context . report ( {
76
129
node,
@@ -123,6 +176,12 @@ module.exports = {
123
176
124
177
FunctionExpression : handleStatelessComponent ,
125
178
179
+ 'FunctionDeclaration:exit' : handleStatelessComponentExit ,
180
+
181
+ 'ArrowFunctionExpression:exit' : handleStatelessComponentExit ,
182
+
183
+ 'FunctionExpression:exit' : handleStatelessComponentExit ,
184
+
126
185
MemberExpression ( node ) {
127
186
const SFCComponent = components . get ( context . getScope ( node ) . block ) ;
128
187
const classComponent = utils . getParentComponent ( node ) ;
0 commit comments