@@ -22,14 +22,20 @@ const strictReservedOrKeyword = Object.assign(
22
22
} ) ;
23
23
24
24
function hasBinding ( path , bindingName ) {
25
- // Babel bug with replacement scoping creating circular scope
26
- // work around by calling the id check directly
27
- if ( path . scope === path . scope . parentScope ) {
28
- return path . scope . hasOwnBinding ( bindingName ) ;
29
- }
30
25
return path . scope . hasBinding ( bindingName ) ;
31
26
}
32
27
28
+ function isLive ( path ) {
29
+ const seen = new Set ( ) ;
30
+ let curPath = path ;
31
+ while ( curPath ) {
32
+ if ( seen . has ( curPath ) ) return false ;
33
+ seen . add ( curPath ) ;
34
+ curPath = curPath . parentPath ;
35
+ }
36
+ return true ;
37
+ }
38
+
33
39
const topLevelReserved = Object . assign (
34
40
Object . create ( null ) , {
35
41
"global" :1 , "self" :1 , "globalThis" :1
@@ -134,6 +140,14 @@ module.exports = function ({ types: t }) {
134
140
return t . isStringLiteral ( node ) || t . isTemplateLiteral ( node ) && node . quasis [ 0 ] . value . cooked . length || t . isBinaryExpression ( node ) || t . isIdentifier ( node ) && node . name === '__dirname' ;
135
141
}
136
142
143
+ // typeof setImmediate [!=]==
144
+ function isLogicalOrConditionalBinaryExpression ( path ) {
145
+ return t . isBinaryExpression ( path . node ) && (
146
+ t . isConditionalExpression ( path . parentPath . node ) && path . parentPath . node . test === path . node ||
147
+ t . isLogicalExpression ( path . parentPath . node ) && path . parentPath . node . left === path . node
148
+ ) ;
149
+ }
150
+
137
151
function addDependency ( path , state , depModuleArg , optional = false ) {
138
152
if ( path . parentPath && path . parentPath . data === 'dead' )
139
153
return null ;
@@ -307,11 +321,13 @@ module.exports = function ({ types: t }) {
307
321
let consequent = path . parentPath . get ( 'consequent' ) ;
308
322
let alternate = path . parentPath . get ( 'alternate' ) ;
309
323
310
- path . stop ( ) ;
324
+ path . skip ( ) ;
311
325
312
326
if ( truthy ) {
313
- if ( alternate . node )
327
+ if ( alternate . node ) {
328
+ alternate . skip ( ) ;
314
329
alternate . remove ( ) ;
330
+ }
315
331
if ( t . isBlockStatement ( consequent . node ) ) {
316
332
if ( consequent . node . body . length === 1 && t . isExpressionStatement ( consequent . node . body [ 0 ] ) ) {
317
333
path . parentPath . replaceWith ( consequent . node . body [ 0 ] ) ;
@@ -322,8 +338,10 @@ module.exports = function ({ types: t }) {
322
338
}
323
339
}
324
340
else {
325
- if ( consequent . node )
341
+ if ( consequent . node ) {
342
+ consequent . skip ( ) ;
326
343
consequent . remove ( ) ;
344
+ }
327
345
if ( t . isBlockStatement ( alternate . node ) ) {
328
346
if ( alternate . node . body . length === 1 && t . isExpressionStatement ( alternate . node . body [ 0 ] ) ) {
329
347
path . parentPath . replaceWith ( alternate . node . body [ 0 ] ) ;
@@ -343,7 +361,7 @@ module.exports = function ({ types: t }) {
343
361
let consequent = path . parentPath . get ( 'consequent' ) ;
344
362
let alternate = path . parentPath . get ( 'alternate' ) ;
345
363
346
- path . stop ( ) ;
364
+ path . skip ( ) ;
347
365
348
366
if ( parentNode . test . value ) {
349
367
alternate . data = 'dead' ;
@@ -1118,6 +1136,7 @@ module.exports = function ({ types: t }) {
1118
1136
}
1119
1137
else if ( path . node . init === null ) {
1120
1138
const name = path . node . id . name ;
1139
+ path . skip ( ) ;
1121
1140
path . remove ( ) ;
1122
1141
path . parentPath . scope . registerBinding ( name , newBinding . get ( 'id' ) ) ;
1123
1142
}
@@ -1208,7 +1227,7 @@ module.exports = function ({ types: t }) {
1208
1227
* detect usage of module
1209
1228
*/
1210
1229
ReferencedIdentifier ( path , state ) {
1211
- if ( state . inserting )
1230
+ if ( state . inserting || ! isLive ( path ) )
1212
1231
return ;
1213
1232
let identifierName = path . node . name ;
1214
1233
@@ -1385,12 +1404,10 @@ module.exports = function ({ types: t }) {
1385
1404
state . usesExports = true ;
1386
1405
}
1387
1406
else if ( identifierName === 'setImmediate' && ! hasBinding ( path , 'setImmediate' ) ) {
1388
- // typeof setImmediate [!=]==
1389
- if ( t . isUnaryExpression ( path . parentPath . node , { operator : 'typeof' } ) &&
1390
- ( t . isBinaryExpression ( path . parentPath . parentPath . node ) || t . isBinaryExpression ( path . parentPath . parentPath . node ) ) &&
1391
- ( t . isConditionalExpression ( path . parentPath . parentPath . parentPath . node ) && path . parentPath . parentPath . parentPath . node . test === path . parentPath . parentPath . node ||
1392
- t . isLogicalExpression ( path . parentPath . parentPath . parentPath . node ) && path . parentPath . parentPath . parentPath . node . left === path . parentPath . parentPath . node ) ) {
1393
- path . stop ( ) ;
1407
+ if ( t . isUnaryExpression ( path . parentPath . node , { operator : 'typeof' } ) && isLogicalOrConditionalBinaryExpression ( path . parentPath . parentPath ) ) {
1408
+ return ;
1409
+ }
1410
+ if ( t . isConditionalExpression ( path . parentPath ) && isLogicalOrConditionalBinaryExpression ( path . parentPath . get ( 'test' ) ) && t . isUnaryExpression ( path . parentPath . node . test . right , { operator : 'typeof' } ) && t . isIdentifier ( path . parentPath . node . test . right . argument , { name : 'setImmediate' } ) ) {
1394
1411
return ;
1395
1412
}
1396
1413
if ( hasBinding ( path , 'process' ) ) {
@@ -1499,6 +1516,7 @@ module.exports = function ({ types: t }) {
1499
1516
}
1500
1517
}
1501
1518
if ( path . node . operator === 'delete' && t . isIdentifier ( path . node . argument ) ) {
1519
+ path . skip ( ) ;
1502
1520
path . remove ( ) ;
1503
1521
}
1504
1522
}
0 commit comments