@@ -250,7 +250,7 @@ namespace ts {
250
250
Debug . attachFlowNodeDebugInfo ( unreachableFlow ) ;
251
251
Debug . attachFlowNodeDebugInfo ( reportedUnreachableFlow ) ;
252
252
253
- if ( ! file . locals ) {
253
+ if ( ! getBindExtraFields ( file ) ? .locals ) {
254
254
tracing ?. push ( tracing . Phase . Bind , "bindSourceFile" , { path : file . path } , /*separateBeginAndEnd*/ true ) ;
255
255
bind ( file ) ;
256
256
tracing ?. pop ( ) ;
@@ -553,7 +553,7 @@ namespace ts {
553
553
return declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ;
554
554
}
555
555
else {
556
- return declareSymbol ( container . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
556
+ return declareSymbol ( getBindExtraFields ( container ) ! . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
557
557
}
558
558
}
559
559
else {
@@ -574,17 +574,18 @@ namespace ts {
574
574
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
575
575
if ( isJSDocTypeAlias ( node ) ) Debug . assert ( isInJSFile ( node ) ) ; // We shouldn't add symbols for JSDoc nodes if not in a JS file.
576
576
if ( ! isAmbientModule ( node ) && ( hasExportModifier || container . flags & NodeFlags . ExportContext ) ) {
577
- if ( ! container . locals || ( hasSyntacticModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) ) {
577
+ const containerBindNode = getBindExtraFields ( container ) ;
578
+ if ( ! containerBindNode ?. locals || ( hasSyntacticModifier ( node , ModifierFlags . Default ) && ! getDeclarationName ( node ) ) ) {
578
579
return declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ; // No local symbol for an unnamed default!
579
580
}
580
581
const exportKind = symbolFlags & SymbolFlags . Value ? SymbolFlags . ExportValue : 0 ;
581
- const local = declareSymbol ( container . locals , /*parent*/ undefined , node , exportKind , symbolExcludes ) ;
582
+ const local = declareSymbol ( containerBindNode . locals , /*parent*/ undefined , node , exportKind , symbolExcludes ) ;
582
583
local . exportSymbol = declareSymbol ( container . symbol . exports ! , container . symbol , node , symbolFlags , symbolExcludes ) ;
583
- node . localSymbol = local ;
584
+ getOrCreateBindExtraFields ( node ) . localSymbol = local ;
584
585
return local ;
585
586
}
586
587
else {
587
- return declareSymbol ( container . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
588
+ return declareSymbol ( getBindExtraFields ( container ) ! . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
588
589
}
589
590
}
590
591
}
@@ -641,13 +642,13 @@ namespace ts {
641
642
}
642
643
container = blockScopeContainer = node ;
643
644
if ( containerFlags & ContainerFlags . HasLocals ) {
644
- container . locals = createSymbolTable ( ) ;
645
+ getOrCreateBindExtraFields ( container ) . locals = createSymbolTable ( ) ;
645
646
}
646
647
addToContainerChain ( container ) ;
647
648
}
648
649
else if ( containerFlags & ContainerFlags . IsBlockScopedContainer ) {
649
650
blockScopeContainer = node ;
650
- blockScopeContainer . locals = undefined ;
651
+ getOrCreateBindExtraFields ( blockScopeContainer ) . locals = undefined ;
651
652
}
652
653
if ( containerFlags & ContainerFlags . IsControlFlowContainer ) {
653
654
const saveCurrentFlow = currentFlow ;
@@ -685,7 +686,7 @@ namespace ts {
685
686
if ( ! ( currentFlow . flags & FlowFlags . Unreachable ) && containerFlags & ContainerFlags . IsFunctionLike && nodeIsPresent ( ( node as FunctionLikeDeclaration | ClassStaticBlockDeclaration ) . body ) ) {
686
687
node . flags |= NodeFlags . HasImplicitReturn ;
687
688
if ( hasExplicitReturn ) node . flags |= NodeFlags . HasExplicitReturn ;
688
- ( node as FunctionLikeDeclaration | ClassStaticBlockDeclaration ) . endFlowNode = currentFlow ;
689
+ setEndFlowNode ( node as FunctionLikeDeclarationBase | ClassStaticBlockDeclaration , currentFlow ) ;
689
690
}
690
691
if ( node . kind === SyntaxKind . SourceFile ) {
691
692
node . flags |= emitFlags ;
@@ -696,7 +697,7 @@ namespace ts {
696
697
addAntecedent ( currentReturnTarget , currentFlow ) ;
697
698
currentFlow = finishFlowLabel ( currentReturnTarget ) ;
698
699
if ( node . kind === SyntaxKind . Constructor || node . kind === SyntaxKind . ClassStaticBlockDeclaration || ( isInJSFile ( node ) && ( node . kind === SyntaxKind . FunctionDeclaration || node . kind === SyntaxKind . FunctionExpression ) ) ) {
699
- ( node as FunctionLikeDeclaration | ClassStaticBlockDeclaration ) . returnFlowNode = currentFlow ;
700
+ setReturnFlowNode ( node as FunctionLikeDeclaration | ClassStaticBlockDeclaration , currentFlow ) ;
700
701
}
701
702
}
702
703
if ( ! isImmediatelyInvoked ) {
@@ -752,7 +753,7 @@ namespace ts {
752
753
return ;
753
754
}
754
755
if ( node . kind >= SyntaxKind . FirstStatement && node . kind <= SyntaxKind . LastStatement && ! options . allowUnreachableCode ) {
755
- node . flowNode = currentFlow ;
756
+ setFlowNode ( node , currentFlow ) ;
756
757
}
757
758
switch ( node . kind ) {
758
759
case SyntaxKind . WhileStatement :
@@ -1352,7 +1353,7 @@ namespace ts {
1352
1353
bind ( clause ) ;
1353
1354
fallthroughFlow = currentFlow ;
1354
1355
if ( ! ( currentFlow . flags & FlowFlags . Unreachable ) && i !== clauses . length - 1 && options . noFallthroughCasesInSwitch ) {
1355
- clause . fallthroughFlowNode = currentFlow ;
1356
+ setFallthroughFlowNode ( clause , currentFlow ) ;
1356
1357
}
1357
1358
}
1358
1359
}
@@ -1905,7 +1906,7 @@ namespace ts {
1905
1906
1906
1907
function addToContainerChain ( next : Node ) {
1907
1908
if ( lastContainer ) {
1908
- lastContainer . nextContainer = next ;
1909
+ getOrCreateBindExtraFields ( lastContainer ) . nextContainer = next ;
1909
1910
}
1910
1911
1911
1912
lastContainer = next ;
@@ -1968,7 +1969,7 @@ namespace ts {
1968
1969
// their container in the tree). To accomplish this, we simply add their declared
1969
1970
// symbol to the 'locals' of the container. These symbols can then be found as
1970
1971
// the type checker walks up the containers, checking them for matching names.
1971
- return declareSymbol ( container . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
1972
+ return declareSymbol ( getBindExtraFields ( container ) ! . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
1972
1973
}
1973
1974
}
1974
1975
@@ -1981,7 +1982,7 @@ namespace ts {
1981
1982
function declareSourceFileMember ( node : Declaration , symbolFlags : SymbolFlags , symbolExcludes : SymbolFlags ) {
1982
1983
return isExternalModule ( file )
1983
1984
? declareModuleMember ( node , symbolFlags , symbolExcludes )
1984
- : declareSymbol ( file . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
1985
+ : declareSymbol ( getBindExtraFields ( container ) ! . locals ! , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
1985
1986
}
1986
1987
1987
1988
function hasExportDeclarations ( node : ModuleDeclaration | SourceFile ) : boolean {
@@ -2095,11 +2096,12 @@ namespace ts {
2095
2096
}
2096
2097
// falls through
2097
2098
default :
2098
- if ( ! blockScopeContainer . locals ) {
2099
- blockScopeContainer . locals = createSymbolTable ( ) ;
2099
+ const bindNode = getOrCreateBindExtraFields ( blockScopeContainer ) ;
2100
+ if ( ! bindNode . locals ) {
2101
+ bindNode . locals = createSymbolTable ( ) ;
2100
2102
addToContainerChain ( blockScopeContainer ) ;
2101
2103
}
2102
- declareSymbol ( blockScopeContainer . locals , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
2104
+ declareSymbol ( bindNode . locals , /*parent*/ undefined , node , symbolFlags , symbolExcludes ) ;
2103
2105
}
2104
2106
}
2105
2107
@@ -2450,12 +2452,12 @@ namespace ts {
2450
2452
function bindJSDoc ( node : Node ) {
2451
2453
if ( hasJSDocNodes ( node ) ) {
2452
2454
if ( isInJSFile ( node ) ) {
2453
- for ( const j of node . jsDoc ! ) {
2455
+ for ( const j of getJSDocExtraFields ( node ) ! . jsDoc ! ) {
2454
2456
bind ( j ) ;
2455
2457
}
2456
2458
}
2457
2459
else {
2458
- for ( const j of node . jsDoc ! ) {
2460
+ for ( const j of getJSDocExtraFields ( node ) ! . jsDoc ! ) {
2459
2461
setParent ( j , node ) ;
2460
2462
setParentRecursive ( j , /*incremental*/ false ) ;
2461
2463
}
@@ -2505,25 +2507,25 @@ namespace ts {
2505
2507
// falls through
2506
2508
case SyntaxKind . ThisKeyword :
2507
2509
if ( currentFlow && ( isExpression ( node ) || parent . kind === SyntaxKind . ShorthandPropertyAssignment ) ) {
2508
- node . flowNode = currentFlow ;
2510
+ setFlowNode ( node , currentFlow ) ;
2509
2511
}
2510
2512
return checkContextualIdentifier ( node as Identifier ) ;
2511
2513
case SyntaxKind . QualifiedName :
2512
2514
if ( currentFlow && isPartOfTypeQuery ( node ) ) {
2513
- node . flowNode = currentFlow ;
2515
+ setFlowNode ( node , currentFlow ) ;
2514
2516
}
2515
2517
break ;
2516
2518
case SyntaxKind . MetaProperty :
2517
2519
case SyntaxKind . SuperKeyword :
2518
- node . flowNode = currentFlow ;
2520
+ setFlowNode ( node , currentFlow ) ;
2519
2521
break ;
2520
2522
case SyntaxKind . PrivateIdentifier :
2521
2523
return checkPrivateIdentifier ( node as PrivateIdentifier ) ;
2522
2524
case SyntaxKind . PropertyAccessExpression :
2523
2525
case SyntaxKind . ElementAccessExpression :
2524
2526
const expr = node as PropertyAccessExpression | ElementAccessExpression ;
2525
2527
if ( currentFlow && isNarrowableReference ( expr ) ) {
2526
- expr . flowNode = currentFlow ;
2528
+ setFlowNode ( expr , currentFlow ) ;
2527
2529
}
2528
2530
if ( isSpecialPropertyDeclaration ( expr ) ) {
2529
2531
bindSpecialPropertyDeclaration ( expr ) ;
@@ -2532,7 +2534,7 @@ namespace ts {
2532
2534
file . commonJsModuleIndicator &&
2533
2535
isModuleExportsAccessExpression ( expr ) &&
2534
2536
! lookupSymbolForName ( blockScopeContainer , "module" as __String ) ) {
2535
- declareSymbol ( file . locals ! , /*parent*/ undefined , expr . expression ,
2537
+ declareSymbol ( getBindExtraFields ( file ) ! . locals ! , /*parent*/ undefined , expr . expression ,
2536
2538
SymbolFlags . FunctionScopedVariable | SymbolFlags . ModuleExports , SymbolFlags . FunctionScopedVariableExcludes ) ;
2537
2539
}
2538
2540
break ;
@@ -2598,7 +2600,7 @@ namespace ts {
2598
2600
case SyntaxKind . VariableDeclaration :
2599
2601
return bindVariableDeclarationOrBindingElement ( node as VariableDeclaration ) ;
2600
2602
case SyntaxKind . BindingElement :
2601
- node . flowNode = currentFlow ;
2603
+ setFlowNode ( node , currentFlow ) ;
2602
2604
return bindVariableDeclarationOrBindingElement ( node as BindingElement ) ;
2603
2605
case SyntaxKind . PropertyDeclaration :
2604
2606
case SyntaxKind . PropertySignature :
@@ -3360,7 +3362,7 @@ namespace ts {
3360
3362
}
3361
3363
}
3362
3364
if ( currentFlow ) {
3363
- node . flowNode = currentFlow ;
3365
+ setFlowNode ( node , currentFlow ) ;
3364
3366
}
3365
3367
checkStrictModeFunctionName ( node ) ;
3366
3368
const bindingName = node . name ? node . name . escapedText : InternalSymbolName . Function ;
@@ -3373,7 +3375,7 @@ namespace ts {
3373
3375
}
3374
3376
3375
3377
if ( currentFlow && isObjectLiteralOrClassExpressionMethodOrAccessor ( node ) ) {
3376
- node . flowNode = currentFlow ;
3378
+ setFlowNode ( node , currentFlow ) ;
3377
3379
}
3378
3380
3379
3381
return hasDynamicName ( node )
@@ -3390,10 +3392,8 @@ namespace ts {
3390
3392
if ( isJSDocTemplateTag ( node . parent ) ) {
3391
3393
const container = getEffectiveContainerForJSDocTemplateTag ( node . parent ) ;
3392
3394
if ( container ) {
3393
- if ( ! container . locals ) {
3394
- container . locals = createSymbolTable ( ) ;
3395
- }
3396
- declareSymbol ( container . locals , /*parent*/ undefined , node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
3395
+ const locals = getOrCreateBindExtraFields ( container ) . locals ??= createSymbolTable ( ) ;
3396
+ declareSymbol ( locals , /*parent*/ undefined , node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
3397
3397
}
3398
3398
else {
3399
3399
declareSymbolAndAddToSymbolTable ( node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
@@ -3402,10 +3402,8 @@ namespace ts {
3402
3402
else if ( node . parent . kind === SyntaxKind . InferType ) {
3403
3403
const container = getInferTypeContainer ( node . parent ) ;
3404
3404
if ( container ) {
3405
- if ( ! container . locals ) {
3406
- container . locals = createSymbolTable ( ) ;
3407
- }
3408
- declareSymbol ( container . locals , /*parent*/ undefined , node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
3405
+ const locals = getOrCreateBindExtraFields ( container ) . locals ??= createSymbolTable ( ) ;
3406
+ declareSymbol ( locals , /*parent*/ undefined , node , SymbolFlags . TypeParameter , SymbolFlags . TypeParameterExcludes ) ;
3409
3407
}
3410
3408
else {
3411
3409
bindAnonymousDeclaration ( node , SymbolFlags . TypeParameter , getDeclarationName ( node ) ! ) ; // TODO: GH#18217
@@ -3524,7 +3522,7 @@ namespace ts {
3524
3522
}
3525
3523
3526
3524
function lookupSymbolForName ( container : Node , name : __String ) : Symbol | undefined {
3527
- const local = container . locals && container . locals . get ( name ) ;
3525
+ const local = getBindExtraFields ( container ) ? .locals ? .get ( name ) ;
3528
3526
if ( local ) {
3529
3527
return local . exportSymbol || local ;
3530
3528
}
0 commit comments