@@ -121,7 +121,6 @@ const _super = (function (geti, seti) {
121
121
const writer = createTextWriter ( newLine ) ;
122
122
const {
123
123
write,
124
- writeTextOfNode,
125
124
writeLine,
126
125
increaseIndent,
127
126
decreaseIndent
@@ -154,11 +153,12 @@ const _super = (function (geti, seti) {
154
153
let identifierSubstitution : ( node : Identifier ) => Identifier ;
155
154
let onBeforeEmitNode : ( node : Node ) => void ;
156
155
let onAfterEmitNode : ( node : Node ) => void ;
157
- let isUniqueName : ( name : string ) => boolean ;
158
- let temporaryVariables : string [ ] = [ ] ;
156
+ let nodeToGeneratedName : string [ ] ;
157
+ let generatedNameSet : Map < string > ;
159
158
let tempFlags : TempFlags ;
160
159
let currentSourceFile : SourceFile ;
161
160
let currentText : string ;
161
+ let currentFileIdentifiers : Map < string > ;
162
162
let extendsEmitted : boolean ;
163
163
let decorateEmitted : boolean ;
164
164
let paramEmitted : boolean ;
@@ -169,6 +169,8 @@ const _super = (function (geti, seti) {
169
169
170
170
function doPrint ( jsFilePath : string , sourceMapFilePath : string , sourceFiles : SourceFile [ ] , isBundledEmit : boolean ) {
171
171
sourceMap . initialize ( jsFilePath , sourceMapFilePath , sourceFiles , isBundledEmit ) ;
172
+ nodeToGeneratedName = [ ] ;
173
+ generatedNameSet = { } ;
172
174
isOwnFileEmit = ! isBundledEmit ;
173
175
174
176
// Emit helpers from all the files
@@ -213,8 +215,6 @@ const _super = (function (geti, seti) {
213
215
identifierSubstitution = undefined ;
214
216
onBeforeEmitNode = undefined ;
215
217
onAfterEmitNode = undefined ;
216
- isUniqueName = undefined ;
217
- temporaryVariables = undefined ;
218
218
tempFlags = TempFlags . Auto ;
219
219
currentSourceFile = undefined ;
220
220
currentText = undefined ;
@@ -236,13 +236,13 @@ const _super = (function (geti, seti) {
236
236
identifierSubstitution = context . identifierSubstitution ;
237
237
onBeforeEmitNode = context . onBeforeEmitNode ;
238
238
onAfterEmitNode = context . onAfterEmitNode ;
239
- isUniqueName = context . isUniqueName ;
240
239
return printSourceFile ;
241
240
}
242
241
243
242
function printSourceFile ( node : SourceFile ) {
244
243
currentSourceFile = node ;
245
244
currentText = node . text ;
245
+ currentFileIdentifiers = node . identifiers ;
246
246
sourceMap . setSourceFile ( node ) ;
247
247
comments . setSourceFile ( node ) ;
248
248
emitWorker ( node ) ;
@@ -659,22 +659,11 @@ const _super = (function (geti, seti) {
659
659
//
660
660
661
661
function emitIdentifier ( node : Identifier ) {
662
- if ( node . text === undefined ) {
663
- // Emit a temporary variable name for this node.
664
- const nodeId = getOriginalNodeId ( node ) ;
665
- const text = temporaryVariables [ nodeId ] || ( temporaryVariables [ nodeId ] = makeTempVariableName ( tempKindToFlags ( node . tempKind ) ) ) ;
666
- write ( text ) ;
667
10000
code>
- }
668
- else if ( nodeIsSynthesized ( node ) || ! node . parent ) {
669
- if ( getNodeEmitFlags ( node ) & NodeEmitFlags . UMDDefine ) {
670
- writeLines ( umdHelper ) ;
671
- }
672
- else {
673
- write ( node . text ) ;
674
- }
662
+ if ( getNodeEmitFlags ( node ) && NodeEmitFlags . UMDDefine ) {
663
+ writeLines ( umdHelper ) ;
675
664
}
676
665
else {
677
- writeTextOfNode ( currentText , node ) ;
666
+ write ( getTextOfNode ( node , /*includeTrivia*/ false ) ) ;
678
667
}
679
668
}
680
669
@@ -1720,7 +1709,6 @@ const _super = (function (geti, seti) {
1720
1709
emitExpression ( node . expression ) ;
1721
1710
write ( ":" ) ;
1722
1711
1723
- debugger ;
1724
1712
emitCaseOrDefaultClauseStatements ( node , node . statements ) ;
1725
1713
}
1726
1714
@@ -1763,14 +1751,14 @@ const _super = (function (geti, seti) {
1763
1751
function emitPropertyAssignment ( node : PropertyAssignment ) {
1764
1752
emit ( node . name ) ;
1765
1753
write ( ": " ) ;
1766
- // // This is to ensure that we emit comment in the following case:
1767
- // // For example:
1768
- // // obj = {
1769
- // // id: /*comment1*/ ()=>void
1770
- // / / }
1771
- // // "comment1" is not considered to be leading comment for node.initializer
1772
- // // but rather a trailing comment on the previous node.
1773
- // emitTrailingCommentsOfPosition( node.initializer.pos );
1754
+ // This is to ensure that we emit comment in the following case:
1755
+ // For example:
1756
+ // obj = {
1757
+ // id: /*comment1*/ ()=>void
1758
+ // }
1759
+ // "comment1" is not considered to be leading comment for node.initializer
1760
+ // but rather a trailing comment on the previous node.
1761
+ emitLeadingComments ( node . initializer , getTrailingComments ( collapseTextRange ( node . initializer , TextRangeCollapse . CollapseToStart ) ) ) ;
1774
1762
emitExpression ( node . initializer ) ;
1775
1763
}
1776
1764
@@ -1951,11 +1939,8 @@ const _super = (function (geti, seti) {
1951
1939
}
1952
1940
1953
1941
function emitModifiers ( node : Node , modifiers : ModifiersArray ) {
1954
- const startingPos = writer . getTextPos ( ) ;
1955
- emitList ( node , modifiers , ListFormat . SingleLine ) ;
1956
-
1957
- const endingPos = writer . getTextPos ( ) ;
1958
- if ( startingPos !== endingPos ) {
1942
+ if ( modifiers && modifiers . length ) {
1943
+ emitList ( node , modifiers , ListFormat . SingleLine ) ;
1959
1944
write ( " " ) ;
1960
1945
}
1961
1946
}
@@ -2345,7 +2330,15 @@ const _super = (function (geti, seti) {
2345
2330
}
2346
2331
2347
2332
function getTextOfNode ( node : Node , includeTrivia ?: boolean ) {
2348
- if ( nodeIsSynthesized ( node ) && ( isLiteralExpression ( node ) || isIdentifier ( node ) ) ) {
2333
+ if ( isIdentifier ( node ) ) {
2334
+ if ( node . autoGenerateKind ) {
2335
+ return getGeneratedIdentifier ( node ) ;
2336
+ }
2337
+ else if ( nodeIsSynthesized ( node ) || ! node . parent ) {
2338
+ return node . text ;
2339
+ }
2340
+ }
2341
+ else if ( isLiteralExpression ( node ) && ( nodeIsSynthesized ( node ) || ! node . parent ) ) {
2349
2342
return node . text ;
2350
2343
}
2351
2344
@@ -2368,10 +2361,22 @@ const _super = (function (geti, seti) {
2368
2361
&& rangeEndIsOnSameLineAsRangeStart ( block , block ) ;
2369
2362
}
2370
2363
2371
- function tempKindToFlags ( kind : TempVariableKind ) {
2
97AE
372
- return kind === TempVariableKind . Loop
2373
- ? TempFlags . _i
2374
- : TempFlags . Auto ;
2364
+ function isUniqueName ( name : string ) : boolean {
2365
+ return ! resolver . hasGlobalName ( name ) &&
2366
+ ! hasProperty ( currentFileIdentifiers , name ) &&
2367
+ ! hasProperty ( generatedNameSet , name ) ;
2368
+ }
2369
+
2370
+ function isUniqueLocalName ( name : string , container : Node ) : boolean {
2371
+ for ( let node = container ; isNodeDescendentOf ( node , container ) ; node = node . nextContainer ) {
2372
+ if ( node . locals && hasProperty ( node . locals , name ) ) {
2373
+ // We conservatively include alias symbols to cover cases where they're emitted as locals
2374
+ if ( node . locals [ name ] . flags & ( SymbolFlags . Value | SymbolFlags . ExportValue | SymbolFlags . Alias ) ) {
2375
+ return false ;
2376
+ }
2377
+ }
2378
+ }
2379
+ return true ;
2375
2380
}
2376
2381
2377
2382
/**
@@ -2401,6 +2406,85 @@ const _super = (function (geti, seti) {
2401
2406
}
2402
2407
}
2403
2408
}
2409
+
2410
+ // Generate a name that is unique within the current file and doesn't conflict with any names
2411
+ // in global scope. The name is formed by adding an '_n' suffix to the specified base name,
2412
+ // where n is a positive integer. Note that names generated by makeTempVariableName and
2413
+ // makeUniqueName are guaranteed to never conflict.
2414
+ function makeUniqueName ( baseName : string ) : string {
2415
+ // Find the first unique 'name_n', where n is a positive number
2416
+ if ( baseName . charCodeAt ( baseName . length - 1 ) !== CharacterCodes . _ ) {
2417
+ baseName += "_" ;
2418
+ }
2419
+ let i = 1 ;
2420
+ while ( true ) {
2421
+ const generatedName = baseName + i ;
2422
+ if ( isUniqueName ( generatedName ) ) {
2423
+ return generatedNameSet [ generatedName ] = generatedName ;
2424
+ }
2425
+ i ++ ;
2426
+ }
2427
+ }
2428
+
2429
+ function generateNameForModuleOrEnum ( node : ModuleDeclaration | EnumDeclaration ) {
2430
+ const name = node . name . text ;
2431
+ // Use module/enum name itself if it is unique, otherwise make a unique variation
2432
+ return isUniqueLocalName ( name , node ) ? name : makeUniqueName ( name ) ;
2433
+ }
2434
+
2435
+ function generateNameForImportOrExportDeclaration ( node : ImportDeclaration | ExportDeclaration ) {
2436
+ const expr = getExternalModuleName ( node ) ;
2437
+ const baseName = expr . kind === SyntaxKind . StringLiteral ?
2438
+ escapeIdentifier ( makeIdentifierFromModuleName ( ( < LiteralExpression > expr ) . text ) ) : "module" ;
2439
+ return makeUniqueName ( baseName ) ;
2440
+ }
2441
+
2442
+ function generateNameForExportDefault ( ) {
2443
+ return makeUniqueName ( "default" ) ;
2444
+ }
2445
+
2446
+ function generateNameForClassExpression ( ) {
2447
+ return makeUniqueName ( "class" ) ;
2448
+ }
2449
+
2450
+ function generateNameForNode ( node : Node ) {
2451
+ switch ( node . kind ) {
2452
+ case SyntaxKind . Identifier :
2453
+ return makeUniqueName ( ( < Identifier > node ) . text ) ;
2454
+ case SyntaxKind . ModuleDeclaration :
2455
+ case SyntaxKind . EnumDeclaration :
2456
+ return generateNameForModuleOrEnum ( < ModuleDeclaration | EnumDeclaration > node ) ;
2457
+ case SyntaxKind . ImportDeclaration :
2458
+ case SyntaxKind . ExportDeclaration :
2459
+ return generateNameForImportOrExportDeclaration ( < ImportDeclaration | ExportDeclaration > node ) ;
2460
+ case SyntaxKind . FunctionDeclaration :
2461
+ case SyntaxKind . ClassDeclaration :
2462
+ case SyntaxKind . ExportAssignment :
2463
+ return generateNameForExportDefault ( ) ;
2464
+ case SyntaxKind . ClassExpression :
2465
+ return generateNameForClassExpression ( ) ;
2466
+ default :
2467
+ return makeTempVariableName ( TempFlags . Auto ) ;
2468
+ }
2469
+ }
2470
+
2471
+ function generateIdentifier ( node : Identifier ) {
2472
+ switch ( node . autoGenerateKind ) {
2473
+ case GeneratedIdentifierKind . Auto :
2474
+ return makeTempVariableName ( TempFlags . Auto ) ;
2475
+ case GeneratedIdentifierKind . Loop :
2476
+ return makeTempVariableName ( TempFlags . _i ) ;
2477
+ case GeneratedIdentifierKind . Unique :
2478
+ return makeUniqueName ( node . text ) ;
2479
+ case GeneratedIdentifierKind . Node :
2480
+ return generateNameForNode ( getOriginalNode ( node ) ) ;
2481
+ }
2482
+ }
2483
+
2484
+ function getGeneratedIdentifier ( node : Identifier ) {
2485
+ const id = getOriginalNodeId ( node ) ;
2486
+ return nodeToGeneratedName [ id ] || ( nodeToGeneratedName [ id ] = unescapeIdentifier ( generateIdentifier ( node ) ) ) ;
2487
+ }
2404
2488
}
2405
2489
}
2406
2490
0 commit comments