1111
1212const Components = require ( '../util/Components' ) ;
1313const docsUrl = require ( '../util/docsUrl' ) ;
14+ const ast = require ( '../util/ast' ) ;
1415
1516// Descend through all wrapping TypeCastExpressions and return the expression
1617// that was cast.
@@ -41,7 +42,7 @@ function getName(node) {
4142}
4243
4344function isThisExpression ( node ) {
44- return uncast ( node ) . type === 'ThisExpression' ;
45+ return ast . unwrapTSAsExpression ( uncast ( node ) ) . type === 'ThisExpression' ;
4546}
4647
4748function getInitialClassInfo ( ) {
@@ -62,10 +63,12 @@ function getInitialClassInfo() {
6263}
6364
6465function isSetStateCall ( node ) {
66+ const unwrappedCalleeNode = ast . unwrapTSAsExpression ( node . callee ) ;
67+
6568 return (
66- node . callee . type === 'MemberExpression' &&
67- isThisExpression ( node . callee . object ) &&
68- getName ( node . callee . property ) === 'setState'
69+ unwrappedCalleeNode . type === 'MemberExpression' &&
70+ isThisExpression ( unwrappedCalleeNode . object ) &&
71+ getName ( unwrappedCalleeNode . property ) === 'setState'
6972 ) ;
7073}
7174
@@ -178,16 +181,18 @@ module.exports = {
178181 // Used to record used state fields and new aliases for both
179182 // AssignmentExpressions and VariableDeclarators.
180183 function handleAssignment ( left , right ) {
184+ const unwrappedRight = ast . unwrapTSAsExpression ( right ) ;
185+
181186 switch ( left . type ) {
182187 case 'Identifier' :
183- if ( isStateReference ( right ) && classInfo . aliases ) {
188+ if ( isStateReference ( unwrappedRight ) && classInfo . aliases ) {
184189 classInfo . aliases . add ( left . name ) ;
185190 }
186191 break ;
187192 case 'ObjectPattern' :
188- if ( isStateReference ( right ) ) {
193+ if ( isStateReference ( unwrappedRight ) ) {
189194 handleStateDestructuring ( left ) ;
190- } else if ( isThisExpression ( right ) && classInfo . aliases ) {
195+ } else if ( isThisExpression ( unwrappedRight ) && classInfo . aliases ) {
191196 for ( const prop of left . properties ) {
192197 if ( prop . type === 'Property' && getName ( prop . key ) === 'state' ) {
193198 const name = getName ( prop . value ) ;
@@ -254,24 +259,30 @@ module.exports = {
254259 if ( ! classInfo ) {
255260 return ;
256261 }
262+
263+ const unwrappedNode = ast . unwrapTSAsExpression ( node ) ;
264+ const unwrappedArgumentNode = ast . unwrapTSAsExpression ( unwrappedNode . arguments [ 0 ] ) ;
265+
257266 // If we're looking at a `this.setState({})` invocation, record all the
258267 // properties as state fields.
259268 if (
260- isSetStateCall ( node ) &&
261- node . arguments . length > 0 &&
262- node . arguments [ 0 ] . type === 'ObjectExpression'
269+ isSetStateCall ( unwrappedNode ) &&
270+ unwrappedNode . arguments . length > 0 &&
271+ unwrappedArgumentNode . type === 'ObjectExpression'
263272 ) {
264- addStateFields ( node . arguments [ 0 ] ) ;
273+ addStateFields ( unwrappedArgumentNode ) ;
265274 } else if (
266- isSetStateCall ( node ) &&
267- node . arguments . length > 0 &&
268- node . arguments [ 0 ] . type === 'ArrowFunctionExpression'
275+ isSetStateCall ( unwrappedNode ) &&
276+ unwrappedNode . arguments . length > 0 &&
277+ unwrappedArgumentNode . type === 'ArrowFunctionExpression'
269278 ) {
270- if ( node . arguments [ 0 ] . body . type === 'ObjectExpression' ) {
271- addStateFields ( node . arguments [ 0 ] . body ) ;
279+ const unwrappedBodyNode = ast . unwrapTSAsExpression ( unwrappedArgumentNode . body ) ;
280+
281+ if ( unwrappedBodyNode . type === 'ObjectExpression' ) {
282+ addStateFields ( unwrappedBodyNode ) ;
272283 }
273- if ( node . arguments [ 0 ] . params . length > 0 && classInfo . aliases ) {
274- const firstParam = node . arguments [ 0 ] . params [ 0 ] ;
284+ if ( unwrappedArgumentNode . params . length > 0 && classInfo . aliases ) {
285+ const firstParam = unwrappedArgumentNode . params [ 0 ] ;
275286 if ( firstParam . type === 'ObjectPattern' ) {
276287 handleStateDestructuring ( firstParam ) ;
277288 } else {
@@ -287,19 +298,21 @@ module.exports = {
287298 }
288299 // If we see state being assigned as a class property using an object
289300 // expression, record all the fields of that object as state fields.
301+ const unwrappedValueNode = ast . unwrapTSAsExpression ( node . value ) ;
302+
290303 if (
291304 getName ( node . key ) === 'state' &&
292305 ! node . static &&
293- node . value &&
294- node . value . type === 'ObjectExpression'
306+ unwrappedValueNode &&
307+ unwrappedValueNode . type === 'ObjectExpression'
295308 ) {
296- addStateFields ( node . value ) ;
309+ addStateFields ( unwrappedValueNode ) ;
297310 }
298311
299312 if (
300313 ! node . static &&
301- node . value &&
302- node . value . type === 'ArrowFunctionExpression'
314+ unwrappedValueNode &&
315+ unwrappedValueNode . type === 'ArrowFunctionExpression'
303316 ) {
304317 // Create a new set for this.state aliases local to this method.
305318 classInfo . aliases = new Set ( ) ;
@@ -364,12 +377,16 @@ module.exports = {
364377 if ( ! classInfo ) {
365378 return ;
366379 }
380+
381+ const unwrappedLeft = ast . unwrapTSAsExpression ( node . left ) ;
382+ const unwrappedRight = ast . unwrapTSAsExpression ( node . right ) ;
383+
367384 // Check for assignments like `this.state = {}`
368385 if (
369- node . left . type === 'MemberExpression' &&
370- isThisExpression ( node . left . object ) &&
371- getName ( node . left . property ) === 'state' &&
372- node . right . type === 'ObjectExpression'
386+ unwrappedLeft . type === 'MemberExpression' &&
387+ isThisExpression ( unwrappedLeft . object ) &&
388+ getName ( unwrappedLeft . property ) === 'state' &&
389+ unwrappedRight . type === 'ObjectExpression'
373390 ) {
374391 // Find the nearest function expression containing this assignment.
375392 let fn = node ;
@@ -383,11 +400,11 @@ module.exports = {
383400 fn . parent . type === 'MethodDefinition' &&
384401 fn . parent . kind === 'constructor'
385402 ) {
386- addStateFields ( node . right ) ;
403+ addStateFields ( unwrappedRight ) ;
387404 }
388405 } else {
389406 // Check for assignments like `alias = this.state` and record the alias.
390- handleAssignment ( node . left , node . right ) ;
407+ handleAssignment ( unwrappedLeft , unwrappedRight ) ;
391408 }
392409 } ,
393410
@@ -402,7 +419,7 @@ module.exports = {
402419 if ( ! classInfo ) {
403420 return ;
404421 }
405- if ( isStateReference ( node . object ) ) {
422+ if ( isStateReference ( ast . unwrapTSAsExpression ( node . object ) ) ) {
406423 // If we see this.state[foo] access, give up.
407424 if ( node . computed && node . property . type !== 'Literal' ) {
408425 classInfo = null ;
0 commit comments