8000 PR Feedback and defer makeUniqueName/getGeneratedNameForNode to printer. · prmdeveloper/TypeScript@cd2cf7d · GitHub
[go: up one dir, main page]

Skip to content
< 10000 script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/sessions-d044b7c46be3.js" defer="defer">

Commit cd2cf7d

Browse files
committed
PR Feedback and defer makeUniqueName/getGeneratedNameForNode to printer.
1 parent 75b2181 commit cd2cf7d

File tree

5 files changed

+161
-182
lines changed

5 files changed

+161
-182
lines changed

src/compiler/factory.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,24 +185,38 @@ namespace ts {
185185

186186
// Identifiers
187187

188-
export function createIdentifier(text: string): Identifier {
189-
const node = <Identifier>createNode(SyntaxKind.Identifier);
188+
export function createIdentifier(text: string, location?: TextRange): Identifier {
189+
const node = <Identifier>createNode(SyntaxKind.Identifier, location);
190190
node.text = text;
191191
return node;
192192
}
193193

194-
export function createTempVariable(): Identifier {
195-
const name = <Identifier>createNode(SyntaxKind.Identifier);
196-
name.text = undefined;
197-
name.tempKind = TempVariableKind.Auto;
194+
export function createTempVariable(location?: TextRange): Identifier {
195+
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
196+
name.autoGenerateKind = GeneratedIdentifierKind.Auto;
198197
getNodeId(name);
199198
return name;
200199
}
201200

202-
export function createLoopVariable(): Identifier {
203-
const name = <Identifier>createNode(SyntaxKind.Identifier);
204-
name.text = undefined;
205-
name.tempKind = TempVariableKind.Loop;
201+
export function createLoopVariable(location?: TextRange): Identifier {
202+
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
203+
name.autoGenerateKind = GeneratedIdentifierKind.Loop;
204+
getNodeId(name);
205+
return name;
206+
}
207+
208+
export function createUniqueName(text: string, location?: TextRange): Identifier {
209+
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
210+
name.text = text;
211+
name.autoGenerateKind = GeneratedIdentifierKind.Unique;
212+
getNodeId(name);
213+
return name;
214+
}
215+
216+
export function createGeneratedNameForNode(node: Node, location?: TextRange): Identifier {
217+
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
218+
name.autoGenerateKind = GeneratedIdentifierKind.Node;
219+
name.original = node;
206220
getNodeId(name);
207221
return name;
208222
}

src/compiler/printer.ts

Lines changed: 123 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ const _super = (function (geti, seti) {
121121
const writer = createTextWriter(newLine);
122122
const {
123123
write,
124-
writeTextOfNode,
125124
writeLine,
126125
increaseIndent,
127126
decreaseIndent
@@ -154,11 +153,12 @@ const _super = (function (geti, seti) {
154153
let identifierSubstitution: (node: Identifier) => Identifier;
155154
let onBeforeEmitNode: (node: Node) => void;
156155
let onAfterEmitNode: (node: Node) => void;
157-
let isUniqueName: (name: string) => boolean;
158-
let temporaryVariables: string[] = [];
156+
let nodeToGeneratedName: string[];
157+
let generatedNameSet: Map<string>;
159158
let tempFlags: TempFlags;
160159
let currentSourceFile: SourceFile;
161160
let currentText: string;
161+
let currentFileIdentifiers: Map<string>;
162162
let extendsEmitted: boolean;
163163
let decorateEmitted: boolean;
164164
let paramEmitted: boolean;
@@ -169,6 +169,8 @@ const _super = (function (geti, seti) {
169169

170170
function doPrint(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
171171
sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
172+
nodeToGeneratedName = [];
173+
generatedNameSet = {};
172174
isOwnFileEmit = !isBundledEmit;
173175

174176
// Emit helpers from all the files
@@ -213,8 +215,6 @@ const _super = (function (geti, seti) {
213215
identifierSubstitution = undefined;
214216
onBeforeEmitNode = undefined;
215217
onAfterEmitNode = undefined;
216-
isUniqueName = undefined;
217-
temporaryVariables = undefined;
218218
tempFlags = TempFlags.Auto;
219219
currentSourceFile = undefined;
220220
currentText = undefined;
@@ -236,13 +236,13 @@ const _super = (function (geti, seti) {
236236
identifierSubstitution = context.identifierSubstitution;
237237
onBeforeEmitNode = context.onBeforeEmitNode;
238238
onAfterEmitNode = context.onAfterEmitNode;
239-
isUniqueName = context.isUniqueName;
240239
return printSourceFile;
241240
}
242241

243242
function printSourceFile(node: SourceFile) {
244243
currentSourceFile = node;
245244
currentText = node.text;
245+
currentFileIdentifiers = node.identifiers;
246246
sourceMap.setSourceFile(node);
247247
comments.setSourceFile(node);
248248
emitWorker(node);
@@ -659,22 +659,11 @@ const _super = (function (geti, seti) {
659659
//
660660

661661
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-
}
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);
675664
}
676665
else {
677-
writeTextOfNode(currentText, node);
666+
write(getTextOfNode(node, /*includeTrivia*/ false));
678667
}
679668
}
680669

@@ -1720,7 +1709,6 @@ const _super = (function (geti, seti) {
17201709
emitExpression(node.expression);
17211710
write(":");
17221711

1723-
debugger;
17241712
emitCaseOrDefaultClauseStatements(node, node.statements);
17251713
}
17261714

@@ -1763,14 +1751,14 @@ const _super = (function (geti, seti) {
17631751
function emitPropertyAssignment(node: PropertyAssignment) {
17641752
emit(node.name);
17651753
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)));
17741762
emitExpression(node.initializer);
17751763
}
17761764

@@ -1951,11 +1939,8 @@ const _super = (function (geti, seti) {
19511939
}
19521940

19531941
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);
19591944
write(" ");
19601945
}
19611946
}
@@ -2345,7 +2330,15 @@ const _super = (function (geti, seti) {
23452330
}
23462331

23472332
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)) {
23492342
return node.text;
23502343
}
23512344

@@ -2368,10 +2361,22 @@ const _super = (function (geti, seti) {
23682361
&& rangeEndIsOnSameLineAsRangeStart(block, block);
23692362
}
23702363

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;
23752380
}
23762381

23772382
/**
@@ -2401,6 +2406,85 @@ const _super = (function (geti, seti) {
24012406
}
24022407
}
24032408
}
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+
}
24042488
}
24052489
}
24062490

0 commit comments

Comments
 (0)
0