3
3
*/
4
4
'use strict' ;
5
5
6
+ const variableUtil = require ( '../util/variable' ) ;
7
+
6
8
// ------------------------------------------------------------------------------
7
9
// Constants
8
10
// ------------------------------------------------------------------------------
@@ -67,14 +69,33 @@ module.exports = {
67
69
) ;
68
70
}
69
71
72
+ /**
73
+ * Find a variable by name in the current scope.
74
+ * @param {string } name Name of the variable to look for.
75
+ * @returns {ASTNode|null } Return null if the variable could not be found, ASTNode otherwise.
76
+ */
77
+ function findVariableByName ( name ) {
78
+ const variable = variableUtil . variablesInScope ( context ) . find ( item => item . name === name ) ;
79
+
80
+ if ( ! variable || ! variable . defs [ 0 ] || ! variable . defs [ 0 ] . node ) {
81
+ return null ;
82
+ }
83
+
84
+ if ( variable . defs [ 0 ] . node . type === 'TypeAlias' ) {
85
+ return variable . defs [ 0 ] . node . right ;
86
+ }
87
+
88
+ return variable . defs [ 0 ] . node . init ;
89
+ }
90
+
70
91
71
92
/**
72
93
* Checks if propTypes declarations are forbidden
73
94
* @param {Array } declarations The array of AST nodes being checked.
74
95
* @returns {void }
75
96
*/
76
- function checkForbidden ( declarations ) {
77
- ( declarations || [ ] ) . forEach ( declaration => {
97
+ function checkProperties ( declarations ) {
98
+ declarations . forEach ( declaration => {
78
99
if ( declaration . type !== 'Property' ) {
79
100
return ;
80
101
}
@@ -108,49 +129,42 @@ module.exports = {
108
129
} ) ;
109
130
}
110
131
132
+ function checkNode ( node ) {
133
+ switch ( node && node . type ) {
134
+ case 'ObjectExpression' :
135
+ checkProperties ( node . properties ) ;
136
+ break ;
137
+ case 'Identifier' :
138
+ const propTypesObject = findVariableByName ( node . name ) ;
139
+ if ( propTypesObject && propTypesObject . properties ) {
140
+ checkProperties ( propTypesObject . properties ) ;
141
+ }
142
+ break ;
143
+ case 'CallExpression' :
144
+ const innerNode = node . arguments && node . arguments [ 0 ] ;
145
+ if ( propWrapperFunctions . has ( node . callee . name ) && innerNode ) {
146
+ checkNode ( innerNode ) ;
147
+ }
148
+ break ;
149
+ default :
150
+ break ;
151
+ }
152
+ }
153
+
111
154
return {
112
155
ClassProperty : function ( node ) {
113
156
if ( ! isPropTypesDeclaration ( node ) ) {
114
157
return ;
115
158
}
116
- switch ( node . value && node . value . type ) {
117
- case 'ObjectExpression' :
118
- checkForbidden ( node . value . properties ) ;
119
- break ;
120
- case 'CallExpression' :
121
- if (
122
- propWrapperFunctions . has ( node . value . callee . name ) &&
123
- node . value . arguments && node . value . arguments [ 0 ]
124
- ) {
125
- checkForbidden ( node . value . arguments [ 0 ] . properties ) ;
126
- }
127
- break ;
128
- default :
129
- break ;
130
- }
159
+ checkNode ( node . value ) ;
131
160
} ,
132
161
133
162
MemberExpression : function ( node ) {
134
163
if ( ! isPropTypesDeclaration ( node . property ) ) {
135
164
return ;
136
165
}
137
166
138
- const right = node . parent . right ;
139
- switch ( right && right . type ) {
140
- case 'ObjectExpression' :
141
- checkForbidden ( right . properties ) ;
142
- break ;
143
- case 'CallExpression' :
144
- if (
145
- propWrapperFunctions . has ( right . callee . name ) &&
146
- right . arguments && right . arguments [ 0 ]
147
- ) {
148
- checkForbidden ( right . arguments [ 0 ] . properties ) ;
149
- }
150
- break ;
151
- default :
152
- break ;
153
- }
167
+ checkNode ( node . parent . right ) ;
154
168
} ,
155
169
156
170
ObjectExpression : function ( node ) {
@@ -163,7 +177,7 @@ module.exports = {
163
177
return ;
164
178
}
165
179
if ( property . value . type === 'ObjectExpression' ) {
166
- checkForbidden ( property . value . properties ) ;
180
+ checkProperties ( property . value . properties ) ;
167
181
}
168
182
} ) ;
169
183
}
0 commit comments