@@ -28,13 +28,11 @@ namespace ts {
28
28
const languageVersion = getEmitScriptTarget ( compilerOptions ) ;
29
29
30
30
// Save the previous transformation hooks.
31
- const previousOnBeforeEmitNode = context . onBeforeEmitNode ;
32
- const previousOnAfterEmitNode = context . onAfterEmitNode ;
31
+ const previousOnEmitNode = context . onEmitNode ;
33
32
const previousExpressionSubstitution = context . expressionSubstitution ;
34
33
35
34
// Set new transformation hooks.
36
- context . onBeforeEmitNode = onBeforeEmitNode ;
37
- context . onAfterEmitNode = onAfterEmitNode ;
35
+ context . onEmitNode = onEmitNode ;
38
36
context . expressionSubstitution = substituteExpression ;
39
37
40
38
// These variables contain state that changes as we descend into the tree.
@@ -64,19 +62,16 @@ namespace ts {
64
62
let currentDecoratedClassAliases : Map < Identifier > ;
65
63
66
64
/**
67
- * Keeps track of how deeply nested we are within any containing namespaces
68
- * when performing just-in-time substitution while printing an expression identifier.
69
- * If the nest level is greater than zero, then we are performing a substitution
70
- * inside of a namespace and we should perform the more costly checks to determine
71
- * whether the identifier points to an exported declaration.
65
+ * Keeps track of whether we are within any containing namespaces when performing
66
+ * just-in-time substitution while printing an expression identifier.
72
67
*/
73
- let namespaceNestLevel : number ;
68
+ let isEnclosedInNamespace : boolean ;
74
69
75
70
/**
76
- * This array keeps track of containers where `super` is valid, for use with
71
+ * This keeps track of containers where `super` is valid, for use with
77
72
* just-in-time substitution for `super` expressions inside of async methods.
78
73
*/
79
- let superContainerStack : SuperContainer [ ] ;
74
+ let currentSuperContainer : SuperContainer ;
80
75
81
76
return transformSourceFile ;
82
77
@@ -2378,21 +2373,24 @@ namespace ts {
2378
2373
// x_1.y = ...;
2379
2374
// })(x || (x = {}));
2380
2375
statements . push (
2381
- setOriginalNode (
2382
- createStatement (
2383
- createCall (
2384
- createParen (
2385
- createFunctionExpression (
2386
- /*asteriskToken*/ undefined ,
2387
- /*name*/ undefined ,
2388
- [ createParameter ( currentNamespaceLocalName ) ] ,
2389
- transformModuleBody ( node )
2390
- )
2391
- ) ,
2392
- [ moduleParam ]
2393
- )
2376
+ setNodeEmitFlags (
2377
+ setOriginalNode (
2378
+ createStatement (
2379
+ createCall (
2380
+ createParen (
2381
+ createFunctionExpression (
2382
+ /*asteriskToken*/ undefined ,
2383
+ /*name*/ undefined ,
2384
+ [ createParameter ( currentNamespaceLocalName ) ] ,
2385
+ transformModuleBody ( node )
2386
+ )
2387
+ ) ,
2388
+ [ moduleParam ]
2389
+ )
2390
+ ) ,
2391
+ node
2394
2392
) ,
2395
- node
2393
+ NodeEmitFlags . AdviseOnEmitNode
2396
2394
)
2397
2395
) ;
2398
2396
@@ -2594,62 +2592,51 @@ namespace ts {
2594
2592
: getClassPrototype ( node ) ;
2595
2593
}
2596
2594
2597
- function onBeforeEmitNode ( node : Node ) : void {
2598
- previousOnBeforeEmitNode ( node ) ;
2595
+ function isClassWithDecorators ( node : Node ) : node is ClassDeclaration {
2596
+ return node . kind === SyntaxKind . ClassDeclaration && node . decorators !== undefined ;
2597
+ }
2599
2598
2599
+ function isSuperContainer ( node : Node ) : node is SuperContainer {
2600
2600
const kind = node . kind ;
2601
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . DecoratedClasses
2602
- && kind === SyntaxKind . ClassDeclaration
2603
- && node . decorators ) {
2604
- currentDecoratedClassAliases [ getOriginalNodeId ( node ) ] = decoratedClassAliases [ getOriginalNodeId ( node ) ] ;
2605
- }
2601
+ return kind === SyntaxKind . ClassDeclaration
2602
+ || kind === SyntaxKind . Constructor
2603
+ || kind === SyntaxKind . MethodDeclaration
2604
+ || kind === SyntaxKind . GetAccessor
2605
+ || kind === SyntaxKind . SetAccessor ;
2606
+ }
2606
2607
2607
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports
2608
- && ( kind === SyntaxKind . ClassDeclaration
2609
- || kind === SyntaxKind . Constructor
2610
- || kind === SyntaxKind . MethodDeclaration
2611
- || kind === SyntaxKind . GetAccessor
2612
- || kind === SyntaxKind . SetAccessor ) ) {
2608
+ function isTransformedModuleDeclaration ( node : Node ) : boolean {
2609
+ return getOriginalNode ( node ) . kind === SyntaxKind . ModuleDeclaration ;
2610
+ }
2613
2611
2614
- if ( ! superContainerStack ) {
2615
- superContainerStack = [ ] ;
2616
- }
2612
+ function onEmitNode ( node : Node , emit : ( node : Node ) => void ) : void {
2613
+ const savedIsEnclosedInNamespace = isEnclosedInNamespace ;
2614
+ const savedCurrentSuperContainer = currentSuperContainer ;
2617
2615
2618
- superContainerStack . push ( < SuperContainer > node ) ;
2616
+ // If we need support substitutions for aliases for decorated classes,
2617
+ // we should enable it here.
2618
+ if ( enabledSubstitutions & TypeScriptSubstitutionFlags . DecoratedClasses && isClassWithDecorators ( node ) ) {
2619
+ currentDecoratedClassAliases [ getOriginalNodeId ( node ) ] = decoratedClassAliases [ getOriginalNodeId ( node ) ] ;
2619
2620
}
2620
2621
2621
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports
2622
- && kind === SyntaxKind . ModuleDeclaration ) {
2623
- namespaceNestLevel ++ ;
2622
+ // If we need to support substitutions for `super` in an async method,
2623
+ // we should track it here.
2624
+ if ( enabledSubstitutions & TypeScriptSubstitutionFlags . AsyncMethodsWithSuper && isSuperContainer ( node ) ) {
2625
+ currentSuperContainer = node ;
2624
2626
}
2625
- }
2626
2627
2627
- function onAfterEmitNode ( node : Node ) : void {
2628
- previousOnAfterEmitNode ( node ) ;
2629
-
2630
- const kind = node . kind ;
2631
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . DecoratedClasses
2632
- && kind === SyntaxKind . ClassDeclaration
2633
- && node . decorators ) {
2634
- currentDecoratedClassAliases [ getOriginalNodeId ( node ) ] = undefined ;
2628
+ if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports && isTransformedModuleDeclaration ( node ) ) {
2629
+ isEnclosedInNamespace = true ;
2635
2630
}
2636
2631
2637
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports
2638
- && ( kind === SyntaxKind . ClassDeclaration
2639
- || kind === SyntaxKind . Constructor
2640
- || kind === SyntaxKind . MethodDeclaration
2641
- || kind === SyntaxKind . GetAccessor
2642
- || kind === SyntaxKind . SetAccessor ) ) {
2632
+ previousOnEmitNode ( node , emit ) ;
2643
2633
2644
- if ( superContainerStack ) {
2645
- superContainerStack . pop ( ) ;
2646
- }
2634
+ if ( enabledSubstitutions & TypeScriptSubstitutionFlags . DecoratedClasses && isClassWithDecorators ( node ) ) {
2635
+ currentDecoratedClassAliases [ getOriginalNodeId ( node ) ] = undefined ;
2647
2636
}
2648
2637
2649
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports
2650
- && kind === SyntaxKind . ModuleDeclaration ) {
2651
- namespaceNestLevel -- ;
2652
- }
2638
+ isEnclosedInNamespace = savedIsEnclosedInNamespace ;
2639
+ currentSuperContainer = savedCurrentSuperContainer ;
2653
2640
}
2654
2641
2655
2642
function substituteExpression ( node : Expression ) : Expression {
@@ -2660,7 +2647,7 @@ namespace ts {
2660
2647
return substituteExpressionIdentifier ( < Identifier > node ) ;
2661
2648
}
2662
2649
2663
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports ) {
2650
+ if ( enabledSubstitutions & TypeScriptSubstitutionFlags . AsyncMethodsWithSuper ) {
2664
2651
switch ( node . kind ) {
2665
2652
case SyntaxKind . CallExpression :
2666
2653
return substituteCallExpression ( < CallExpression > node ) ;
@@ -2691,8 +2678,7 @@ namespace ts {
2691
2678
}
2692
2679
}
2693
2680
2694
- if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports
2695
- && namespaceNestLevel > 0 ) {
2681
+ if ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports && isEnclosedInNamespace ) {
2696
2682
// If we are nested within a namespace declaration, we may need to qualifiy
2697
2683
// an identifier that is exported from a merged namespace.
2698
2684
const original = getOriginalNode ( node ) ;
@@ -2758,8 +2744,8 @@ namespace ts {
2758
2744
}
2759
2745
2760
2746
function enableExpressionSubstitutionForAsyncMethodsWithSuper ( ) {
2761
- if ( ( enabledSubstitutions & TypeScriptSubstitutionFlags . NamespaceExports ) === 0 ) {
2762
- enabledSubstitutions |= TypeScriptSubstitutionFlags . NamespaceExports ;
2747
+ if ( ( enabledSubstitutions & TypeScriptSubstitutionFlags . AsyncMethodsWithSuper ) === 0 ) {
2748
+ enabledSubstitutions |= TypeScriptSubstitutionFlags . AsyncMethodsWithSuper ;
2763
2749
2764
2750
// We need to enable substitutions for call, property access, and element access
2765
2751
// if we need to rewrite super calls.
@@ -2800,9 +2786,6 @@ namespace ts {
2800
2786
2801
2787
// We need to be notified when entering and exiting namespaces.
2802
2788
context . enableEmitNotification ( SyntaxKind . ModuleDeclaration ) ;
2803
-
2804
- // Keep track of namespace nesting depth
2805
- namespaceNestLevel = 0 ;
2806
2789
}
2807
2790
}
2808
2791
@@ -2827,9 +2810,8 @@ namespace ts {
2827
2810
}
2828
2811
2829
2812
function getSuperContainerAsyncMethodFlags ( ) {
2830
- const container = lastOrUndefined ( superContainerStack ) ;
2831
- return container !== undefined
2832
- && resolver . getNodeCheckFlags ( getOriginalNode ( container ) ) & ( NodeCheckFlags . AsyncMethodWithSuper | NodeCheckFlags . AsyncMethodWithSuperBinding ) ;
2813
+ return currentSuperContainer !== undefined
2814
+ && resolver . getNodeCheckFlags ( getOriginalNode ( currentSuperContainer ) ) & ( NodeCheckFlags . AsyncMethodWithSuper | NodeCheckFlags . AsyncMethodWithSuperBinding ) ;
2833
2815
}
2834
2816
}
2835
2817
}
0 commit comments