@@ -140,8 +140,11 @@ namespace ts {
140
140
return visitEachChild ( node , visitor , context ) ;
141
141
142
142
case SyntaxKind . GetAccessor :
143
+ return doWithContext ( ContextFlags . NonTopLevel | ContextFlags . HasLexicalThis , visitGetAccessorDeclaration , node as GetAccessorDeclaration ) ;
143
144
case SyntaxKind . SetAccessor :
145
+ return doWithContext ( ContextFlags . NonTopLevel | ContextFlags . HasLexicalThis , visitSetAccessorDeclaration , node as SetAccessorDeclaration ) ;
144
146
case SyntaxKind . Constructor :
147
+ return doWithContext ( ContextFlags . NonTopLevel | ContextFlags . HasLexicalThis , visitConstructorDeclaration , node as ConstructorDeclaration ) ;
145
148
case SyntaxKind . ClassDeclaration :
146
149
case SyntaxKind . ClassExpression :
147
150
return doWithContext ( ContextFlags . NonTopLevel | ContextFlags . HasLexicalThis , visitDefault , node ) ;
@@ -278,6 +281,15 @@ namespace ts {
278
281
) ;
279
282
}
280
283
284
+ function visitConstructorDeclaration ( node : ConstructorDeclaration ) {
285
+ return factory . updateConstructorDeclaration (
286
+ node ,
287
+ visitNodes ( node . modifiers , visitor , isModifierLike ) ,
288
+ visitParameterList ( node . parameters , visitor , context ) ,
289
+ transformMethodBody ( node )
290
+ ) ;
291
+ }
292
+
281
293
/**
282
294
* Visits a MethodDeclaration node.
283
295
*
@@ -298,7 +310,28 @@ namespace ts {
298
310
/*type*/ undefined ,
299
311
getFunctionFlags ( node ) & FunctionFlags . Async
300
312
? transformAsyncFunctionBody ( node )
301
- : visitFunctionBody ( node . body , visitor , context )
313
+ : transformMethodBody ( node )
314
+ ) ;
315
+ }
316
+
317
+ function visitGetAccessorDeclaration ( node : GetAccessorDeclaration ) {
318
+ return factory . updateGetAccessorDeclaration (
319
+ node ,
320
+ visitNodes ( node . modifiers , visitor , isModifierLike ) ,
321
+ node . name ,
322
+ visitParameterList ( node . parameters , visitor , context ) ,
323
+ /*type*/ undefined ,
324
+ transformMethodBody ( node )
325
+ ) ;
326
+ }
327
+
328
+ function visitSetAccessorDeclaration ( node : SetAccessorDeclaration ) {
329
+ return factory . updateSetAccessorDeclaration (
330
+ node ,
331
+ visitNodes ( node . modifiers , visitor , isModifierLike ) ,
332
+ node . name ,
333
+ visitParameterList ( node . parameters , visitor , context ) ,
334
+ transformMethodBody ( node )
302
335
) ;
303
336
}
304
337
@@ -446,6 +479,50 @@ namespace ts {
446
479
return false ;
447
480
}
448
481
482
+ function transformMethodBody ( node : MethodDeclaration | AccessorDeclaration | ConstructorDeclaration ) : FunctionBody | undefined {
483
+ Debug . assertIsDefined ( node . body ) ;
484
+
485
+ const savedCapturedSuperProperties = capturedSuperProperties ;
486
+ const savedHasSuperElementAccess = hasSuperElementAccess ;
487
+ capturedSuperProperties = new Set ( ) ;
488
+ hasSuperElementAccess = false ;
489
+
490
+ let updated = visitFunctionBody ( node . body , visitor , context ) ;
491
+
492
+ // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
493
+ // This step isn't needed if we eventually transform this to ES5.
494
+ const originalMethod = getOriginalNode ( node , isFunctionLikeDeclaration ) ;
495
+ const emitSuperHelpers = languageVersion >= ScriptTarget . ES2015 &&
496
+ resolver . getNodeCheckFlags ( node ) & ( NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags . MethodWithSuperPropertyAccessInAsync ) &&
497
+ ( getFunctionFlags ( originalMethod ) & FunctionFlags . AsyncGenerator ) !== FunctionFlags . AsyncGenerator ;
498
+
499
+ if ( emitSuperHelpers ) {
500
+ enableSubstitutionForAsyncMethodsWithSuper ( ) ;
501
+ if ( capturedSuperProperties . size ) {
502
+ const variableStatement = createSuperAccessVariableStatement ( factory , resolver , node , capturedSuperProperties ) ;
503
+ substitutedSuperAccessors [ getNodeId ( variableStatement ) ] = true ;
504
+
505
+ const statements = updated . statements . slice ( ) ;
506
+ insertStatementsAfterStandardPrologue ( statements , [ variableStatement ] ) ;
507
+ updated = factory . updateBlock ( updated , statements ) ;
508
+ }
509
+
510
+ if ( hasSuperElementAccess ) {
511
+ // Emit helpers for super element access expressions (`super[x]`).
512
+ if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync ) {
513
+ addEmitHelper ( updated , advancedAsyncSuperHelper ) ;
514
+ }
515
+ else if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . MethodWithSuperPropertyAccessInAsync ) {
516
+ addEmitHelper ( updated , asyncSuperHelper ) ;
517
+ }
518
+ }
519
+ }
520
+
521
+ capturedSuperProperties = savedCapturedSuperProperties ;
522
+ hasSuperElementAccess = savedHasSuperElementAccess ;
523
+ return updated ;
524
+ }
525
+
449
526
function transformAsyncFunctionBody ( node : MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression ) : FunctionBody ;
450
527
function transformAsyncFunctionBody ( node : ArrowFunction ) : ConciseBody ;
451
528
function transformAsyncFunctionBody ( node : FunctionLikeDeclaration ) : ConciseBody {
@@ -495,7 +572,7 @@ namespace ts {
495
572
496
573
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
497
574
// This step isn't needed if we eventually transform this to ES5.
498
- const emitSuperHelpers = languageVersion >= ScriptTarget . ES2015 && resolver . getNodeCheckFlags ( node ) & ( NodeCheckFlags . AsyncMethodWithSuperBinding | NodeCheckFlags . AsyncMethodWithSuper ) ;
575
+ const emitSuperHelpers = languageVersion >= ScriptTarget . ES2015 && resolver . getNodeCheckFlags ( node ) & ( NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags . MethodWithSuperPropertyAccessInAsync ) ;
499
576
500
577
if ( emitSuperHelpers ) {
501
578
enableSubstitutionForAsyncMethodsWithSuper ( ) ;
@@ -511,10 +588,10 @@ namespace ts {
511
588
512
589
if ( emitSuperHelpers && hasSuperElementAccess ) {
513
590
// Emit helpers for super element access expressions (`super[x]`).
514
- if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . AsyncMethodWithSuperBinding ) {
591
+ if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync ) {
515
592
addEmitHelper ( block , advancedAsyncSuperHelper ) ;
516
593
}
517
- else if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . AsyncMethodWithSuper ) {
594
+ else if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . MethodWithSuperPropertyAccessInAsync ) {
518
595
addEmitHelper ( block , asyncSuperHelper ) ;
519
596
}
520
597
}
@@ -601,7 +678,7 @@ namespace ts {
601
678
// If we need to support substitutions for `super` in an async method,
602
679
// we should track it here.
603
680
if ( enabledSubstitutions & ES2017SubstitutionFlags . AsyncMethodsWithSuper && isSuperContainer ( node ) ) {
604
- const superContainerFlags = resolver . getNodeCheckFlags ( node ) & ( NodeCheckFlags . AsyncMethodWithSuper | NodeCheckFlags . AsyncMethodWithSuperBinding ) ;
681
+ const superContainerFlags = resolver . getNodeCheckFlags ( node ) & ( NodeCheckFlags . MethodWithSuperPropertyAccessInAsync | NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync ) ;
605
682
if ( superContainerFlags !== enclosingSuperContainerFlags ) {
606
683
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags ;
607
684
enclosingSuperContainerFlags = superContainerFlags ;
@@ -698,7 +775,7 @@ namespace ts {
698
775
}
699
776
700
777
function createSuperElementAccessInAsyncMethod ( argumentExpression : Expression , location : TextRange ) : LeftHandSideExpression {
701
- if ( enclosingSuperContainerFlags & NodeCheckFlags . AsyncMethodWithSuperBinding ) {
778
+ if ( enclosingSuperContainerFlags & NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync ) {
702
779
return setTextRange (
703
780
factory . createPropertyAccessExpression (
704
781
factory . createCallExpression (
@@ -728,7 +805,7 @@ namespace ts {
728
805
export function createSuperAccessVariableStatement ( factory : NodeFactory , resolver : EmitResolver , node : FunctionLikeDeclaration , names : Set < __String > ) {
729
806
// Create a variable declaration with a getter/setter (if binding) definition for each name:
730
807
// const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
731
- const hasBinding = ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . AsyncMethodWithSuperBinding ) !== 0 ;
808
+ const hasBinding = ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . MethodWithSuperPropertyAssignmentInAsync ) !== 0 ;
732
809
const accessors : PropertyAssignment [ ] = [ ] ;
733
810
names . forEach ( ( _ , key ) => {
734
811
const name = unescapeLeadingUnderscores ( key ) ;
0 commit comments