@@ -1365,8 +1365,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
1365
1365
let privateNameTempFlags : TempFlags ; // TempFlags for the current name generation scope.
1366
1366
let tempFlagsStack : TempFlags [ ] ; // Stack of enclosing name generation scopes.
1367
1367
let tempFlags : TempFlags ; // TempFlags for the current name generation scope.
1368
- let reservedNamesStack : Set < string > [ ] ; // Stack of TempFlags reserved in enclosing name generation scopes.
1369
- let reservedNames : Set < string > ; // TempFlags to reserve in nested name generation scopes.
1368
+ let reservedNamesStack : ( Set < string > | undefined ) [ ] ; // Stack of reserved names in enclosing name generation scopes.
1369
+ let reservedNames : Set < string > | undefined ; // Names reserved in nested name generation scopes.
1370
+ let reservedPrivateNamesStack : ( Set < string > | undefined ) [ ] ; // Stack of reserved member names in enclosing name generation scopes.
1371
+ let reservedPrivateNames : Set < string > | undefined ; // Member names reserved in nested name generation scopes.
1370
1372
let preserveSourceNewlines = printerOptions . preserveSourceNewlines ; // Can be overridden inside nodes with the `IgnoreSourceNewlines` emit flag.
1371
1373
let nextListElementPos : number | undefined ; // See comment in `getLeadingLineTerminatorCount`.
1372
1374
@@ -1658,6 +1660,9 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
1658
1660
tempFlagsStack = [ ] ;
1659
1661
tempFlags = TempFlags . Auto ;
1660
1662
reservedNamesStack = [ ] ;
1663
+ reservedNames = undefined ;
1664
+ reservedPrivateNamesStack = [ ] ;
1665
+ reservedPrivateNames = undefined ;
1661
1666
currentSourceFile = undefined ;
1662
1667
currentLineMap = undefined ;
1663
1668
detachedCommentsInfo = undefined ;
@@ -2501,9 +2506,13 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
2501
2506
}
2502
2507
2503
2508
function emitComputedPropertyName ( node : ComputedPropertyName ) {
2509
+ const savedPrivateNameTempFlags = privateNameTempFlags ;
2510
+ const savedReservedMemberNames = reservedPrivateNames ;
2511
+ popPrivateNameGenerationScope ( ) ;
2504
2512
writePunctuation ( "[" ) ;
2505
2513
emitExpression ( node . expression , parenthesizer . parenthesizeExpressionOfComputedPropertyName ) ;
2506
2514
writePunctuation ( "]" ) ;
2515
+ pushPrivateNameGenerationScope ( savedPrivateNameTempFlags , savedReservedMemberNames ) ;
2507
2516
}
2508
2517
2509
2518
//
@@ -2723,10 +2732,16 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
2723
2732
}
2724
2733
2725
2734
function emitTypeLiteral ( node : TypeLiteralNode ) {
2735
+ // Type literals don't have private names, but we need to push a new scope so that
2736
+ // we can step out of it when emitting a computed property.
2737
+ pushPrivateNameGenerationScope ( TempFlags . Auto , /*newReservedMemberNames*/ undefined ) ;
2738
+
2726
2739
writePunctuation ( "{" ) ;
2727
2740
const flags = getEmitFlags ( node ) & EmitFlags . SingleLine ? ListFormat . SingleLineTypeLiteralMembers : ListFormat . MultiLineTypeLiteralMembers ;
2728
2741
emitList ( node , node . members , flags | ListFormat . NoSpaceIfEmpty ) ;
2729
2742
writePunctuation ( "}" ) ;
2743
+
2744
+ popPrivateNameGenerationScope ( ) ;
2730
2745
}
2731
2746
2732
2747
function emitArrayType ( node : ArrayTypeNode ) {
@@ -2943,6 +2958,9 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
2943
2958
}
2944
2959
2945
2960
function emitObjectLiteralExpression ( node : ObjectLiteralExpression ) {
2961
+ // Object literals don't have private names, but we need to push a new scope so that
2962
+ // we can step out of it when emitting a computed property.
2963
+ pushPrivateNameGenerationScope ( TempFlags . Auto , /*newReservedMemberNames*/ undefined ) ;
2946
2964
forEach ( node . properties , generateMemberNames ) ;
2947
2965
2948
2966
const indentedFlag = getEmitFlags ( node ) & EmitFlags . Indented ;
@@ -2957,6 +2975,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
2957
2975
if ( indentedFlag ) {
2958
2976
decreaseIndent ( ) ;
2959
2977
}
2978
+
2979
+ popPrivateNameGenerationScope ( ) ;
2960
2980
}
2961
2981
2962
2982
function emitPropertyAccessExpression ( node : PropertyAccessExpression ) {
@@ -3763,6 +3783,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
3763
3783
}
3764
3784
3765
3785
function emitClassDeclarationOrExpression ( node : ClassDeclaration | ClassExpression ) {
3786
+ pushPrivateNameGenerationScope ( TempFlags . Auto , /*newReservedMemberNames*/ undefined ) ;
3787
+
3766
3788
forEach ( node . members , generateMemberNames ) ;
3767
3789
3768
3790
emitDecoratorsAndModifiers ( node , node . modifiers ) ;
@@ -3788,9 +3810,15 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
3788
3810
if ( indentedFlag ) {
3789
3811
decreaseIndent ( ) ;
3790
3812
}
3813
+
3814
+ popPrivateNameGenerationScope ( ) ;
3791
3815
}
3792
3816
3793
3817
function emitInterfaceDeclaration ( node : InterfaceDeclaration ) {
3818
+ // Interfaces don't have private names, but we need to push a new scope so that
3819
+ // we can step out of it when emitting a computed property.
3820
+ pushPrivateNameGenerationScope ( TempFlags . Auto , /*newReservedMemberNames*/ undefined ) ;
3821
+
3794
3822
emitModifiers ( node , node . modifiers ) ;
3795
3823
writeKeyword ( "interface" ) ;
3796
3824
writeSpace ( ) ;
@@ -3801,6 +3829,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
3801
3829
writePunctuation ( "{" ) ;
3802
3830
emitList ( node , node . members , ListFormat . InterfaceMembers ) ;
3803
3831
writePunctuation ( "}" ) ;
3832
+
3833
+ popPrivateNameGenerationScope ( ) ;
3804
3834
}
3805
3835
3806
3836
function emitTypeAliasDeclaration ( node : TypeAliasDeclaration ) {
@@ -5486,8 +5516,6 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5486
5516
}
5487
5517
tempFlagsStack . push ( tempFlags ) ;
5488
5518
tempFlags = TempFlags . Auto ;
5489
- privateNameTempFlagsStack . push ( privateNameTempFlags ) ;
5490
- privateNameTempFlags = TempFlags . Auto ;
5491
5519
formattedNameTempFlagsStack . push ( formattedNameTempFlags ) ;
5492
5520
formattedNameTempFlags = undefined ;
5493
5521
reservedNamesStack . push ( reservedNames ) ;
@@ -5501,9 +5529,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5501
5529
return ;
5502
5530
}
5503
5531
tempFlags = tempFlagsStack . pop ( ) ! ;
5504
- privateNameTempFlags = privateNameTempFlagsStack . pop ( ) ! ;
5505
5532
formattedNameTempFlags = formattedNameTempFlagsStack . pop ( ) ;
5506
- reservedNames = reservedNamesStack . pop ( ) ! ;
5533
+ reservedNames = reservedNamesStack . pop ( ) ;
5507
5534
}
5508
5535
5509
5536
function reserveNameInNestedScopes ( name : string ) {
@@ -5513,6 +5540,31 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5513
5540
reservedNames . add ( name ) ;
5514
5541
}
5515
5542
5543
+ /**
5544
+ * Push a new member name generation scope.
5545
+ */
5546
+ function pushPrivateNameGenerationScope ( newPrivateNameTempFlags : TempFlags , newReservedMemberNames : Set < string > | undefined ) {
5547
+ privateNameTempFlagsStack . push ( privateNameTempFlags ) ;
5548
+ privateNameTempFlags = newPrivateNameTempFlags ;
5549
+ reservedPrivateNamesStack . push ( reservedNames ) ;
5550
+ reservedPrivateNames = newReservedMemberNames ;
5551
+ }
5552
+
5553
+ /**
5554
+ * Pop the current member name generation scope.
5555
+ */
5556
+ function popPrivateNameGenerationScope ( ) {
5557
+ privateNameTempFlags = privateNameTempFlagsStack . pop ( ) ! ;
5558
+ reservedPrivateNames = reservedPrivateNamesStack . pop ( ) ;
5559
+ }
5560
+
5561
+ function reservePrivateNameInNestedScopes ( name : string ) {
5562
+ if ( ! reservedPrivateNames || reservedPrivateNames === lastOrUndefined ( reservedPrivateNamesStack ) ) {
5563
+ reservedPrivateNames = new Set ( ) ;
5564
+ }
5565
+ reservedPrivateNames . add ( name ) ;
5566
+ }
5567
+
5516
5568
function generateNames ( node : Node | undefined ) {
5517
5569
if ( ! node ) return ;
5518
5570
switch ( node . kind ) {
@@ -5650,16 +5702,23 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5650
5702
* Returns a value indicating whether a name is unique globally, within the current file,
5651
5703
* or within the NameGenerator.
5652
5704
*/
5653
- function isUniqueName ( name : string ) : boolean {
5654
- return isFileLevelUniqueName ( name )
5655
- && ! generatedNames . has ( name )
5656
- && ! ( reservedNames && reservedNames . has ( name ) ) ;
5705
+ function isUniqueName ( name : string , privateName : boolean ) : boolean {
5706
+ return isFileLevelUniqueName ( name , privateName )
5707
+ && ! isReservedName ( name , privateName )
5708
+ && ! generatedNames . has ( name ) ;
5709
+ }
5710
+
5711
+ function isReservedName ( name : string , privateName : boolean ) : boolean {
5712
+ return privateName ? ! ! reservedPrivateNames ?. has ( name ) : ! ! reservedNames ?. has ( name ) ;
5657
5713
}
5658
5714
5659
5715
/**
5660
5716
* Returns a value indicating whether a name is unique globally or within the current file.
5717
+ *
5718
+ * @param _isPrivate (unused) this parameter exists to avoid an unnecessary adaptor frame in v8
5719
+ * when `isfileLevelUniqueName` is passed as a callback to `makeUniqueName`.
5661
5720
*/
5662
- function isFileLevelUniqueName ( name : string ) {
5721
+ function isFileLevelUniqueName ( name : string , _isPrivate : boolean ) {
5663
5722
return currentSourceFile ? ts . isFileLevelUniqueName ( currentSourceFile , name , hasGlobalName ) : true ;
5664
5723
}
5665
5724
@@ -5722,9 +5781,12 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5722
5781
if ( flags && ! ( tempFlags & flags ) ) {
5723
5782
const name = flags === TempFlags . _i ? "_i" : "_n" ;
5724
5783
const fullName = formatGeneratedName ( privateName , prefix , name , suffix ) ;
5725
- if ( isUniqueName ( fullName ) ) {
5784
+ if ( isUniqueName ( fullName , privateName ) ) {
5726
5785
tempFlags |= flags ;
5727
- if ( reservedInNestedScopes ) {
5786
+ if ( privateName ) {
5787
+ reservePrivateNameInNestedScopes ( fullName ) ;
5788
+ }
5789
+ else if ( reservedInNestedScopes ) {
5728
5790
reserveNameInNestedScopes ( fullName ) ;
5729
5791
}
5730
5792
setTempFlags ( key , tempFlags ) ;
@@ -5741,8 +5803,11 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5741
5803
? "_" + String . fromCharCode ( CharacterCodes . a + count )
5742
5804
: "_" + ( count - 26 ) ;
5743
5805
const fullName = formatGeneratedName ( privateName , prefix , name , suffix ) ;
5744
- if ( isUniqueName ( fullName ) ) {
5745
- if ( reservedInNestedScopes ) {
5806
+ if ( isUniqueName ( fullName , privateName ) ) {
5807
+ if ( privateName ) {
5808
+ reservePrivateNameInNestedScopes ( fullName ) ;
5809
+ }
5810
+ else if ( reservedInNestedScopes ) {
5746
5811
reserveNameInNestedScopes ( fullName ) ;
5747
5812
}
5748
5813
setTempFlags ( key , tempFlags ) ;
@@ -5759,7 +5824,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5759
5824
* makeUniqueName are guaranteed to never conflict.
5760
5825
* If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1'
5761
5826
*/
5762
- function makeUniqueName ( baseName : string , checkFn : ( name : string ) => boolean = isUniqueName , optimistic : boolean , scoped : boolean , privateName : boolean , prefix : string , suffix : string ) : string {
5827
+ function makeUniqueName ( baseName : string , checkFn : ( name : string , privateName : boolean ) => boolean = isUniqueName , optimistic : boolean , scoped : boolean , privateName : boolean , prefix : string , suffix : string ) : string {
5763
5828
if ( baseName . length > 0 && baseName . charCodeAt ( 0 ) === CharacterCodes . hash ) {
5764
5829
baseName = baseName . slice ( 1 ) ;
5765
5830
}
@@ -5768,8 +5833,11 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5768
5833
}
5769
5834
if ( optimistic ) {
5770
5835
const fullName = formatGeneratedName ( privateName , prefix , baseName , suffix ) ;
5771
- if ( checkFn ( fullName ) ) {
5772
- if ( scoped ) {
5836
+ if ( checkFn ( fullName , privateName ) ) {
5837
+ if ( privateName ) {
5838
+ reservePrivateNameInNestedScopes ( fullName ) ;
5839
+ }
5840
+ else if ( scoped ) {
5773
5841
reserveNameInNestedScopes ( fullName ) ;
5774
5842
}
5775
5843
else {
@@ -5785,8 +5853,11 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
5785
5853
let i = 1 ;
5786
5854
while ( true ) {
5787
5855
const fullName = formatGeneratedName ( privateName , prefix , baseName + i , suffix ) ;
5788
- if ( checkFn ( fullName ) ) {
5789
- if ( scoped ) {
5856
+ if ( checkFn ( fullName , privateName ) ) {
5857
+ if ( privateName ) {
5858
+ reservePrivateNameInNestedScopes ( fullName ) ;
5859
+ }
5860
+ else if ( scoped ) {
5790
5861
reserveNameInNestedScopes ( fullName ) ;
5791
5862
}
5792
5863
else {
0 commit comments