Skip to content

Commit 85cf761

Browse files
committed
Merge pull request #2374 from Microsoft/renamingCleanup
use 'allowGeneratedIdentifiers' to explicitly tell when identifier can b...
2 parents ad98fad + 7f8ef38 commit 85cf761

6 files changed

+175
-49
lines changed

src/compiler/checker.ts

+4-19
Original file line numberDiff line numberDiff line change
@@ -11085,26 +11085,11 @@ module ts {
1108511085
function getBlockScopedVariableId(n: Identifier): number {
1108611086
Debug.assert(!nodeIsSynthesized(n));
1108711087

11088-
// ignore name parts of property access expressions
11089-
if (n.parent.kind === SyntaxKind.PropertyAccessExpression &&
11090-
(<PropertyAccessExpression>n.parent).name === n) {
11091-
return undefined;
11092-
}
11093-
11094-
// ignore property names in object binding patterns
11095-
if (n.parent.kind === SyntaxKind.BindingElement &&
11096-
(<BindingElement>n.parent).propertyName === n) {
11097-
return undefined;
11098-
}
11099-
11100-
// for names in variable declarations and binding elements try to short circuit and fetch symbol from the node
11101-
let declarationSymbol: Symbol =
11102-
(n.parent.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>n.parent).name === n) ||
11103-
n.parent.kind === SyntaxKind.BindingElement
11104-
? getSymbolOfNode(n.parent)
11105-
: undefined;
11088+
let isVariableDeclarationOrBindingElement =
11089+
n.parent.kind === SyntaxKind.BindingElement || (n.parent.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>n.parent).name === n);
1110611090

11107-
let symbol = declarationSymbol ||
11091+
let symbol =
11092+
(isVariableDeclarationOrBindingElement ? getSymbolOfNode(n.parent) : undefined) ||
1110811093
getNodeLinks(n).resolvedSymbol ||
1110911094
resolveName(n, n.text, SymbolFlags.Value | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined);
1111011095

src/compiler/emitter.ts

+46-26
Original file line numberDiff line numberDiff line change
@@ -2074,19 +2074,19 @@ module ts {
20742074
sourceMapDir = getDirectoryPath(normalizePath(jsFilePath));
20752075
}
20762076

2077-
function emitNodeWithSourceMap(node: Node) {
2077+
function emitNodeWithSourceMap(node: Node, allowGeneratedIdentifiers?: boolean) {
20782078
if (node) {
20792079
if (nodeIsSynthesized(node)) {
2080-
return emitNodeWithoutSourceMap(node);
2080+
return emitNodeWithoutSourceMap(node, /*allowGeneratedIdentifiers*/ false);
20812081
}
20822082
if (node.kind != SyntaxKind.SourceFile) {
20832083
recordEmitNodeStartSpan(node);
2084-
emitNodeWithoutSourceMap(node);
2084+
emitNodeWithoutSourceMap(node, allowGeneratedIdentifiers);
20852085
recordEmitNodeEndSpan(node);
20862086
}
20872087
else {
20882088
recordNewSourceFileStart(<SourceFile>node);
2089-
emitNodeWithoutSourceMap(node);
2089+
emitNodeWithoutSourceMap(node, /*allowGeneratedIdentifiers*/ false);
20902090
}
20912091
}
20922092
}
@@ -2623,17 +2623,24 @@ module ts {
26232623
}
26242624
}
26252625

2626-
function getBlockScopedVariableId(node: Identifier): number {
2627-
// return undefined for synthesized nodes
2628-
return !nodeIsSynthesized(node) && resolver.getBlockScopedVariableId(node);
2626+
function getGeneratedNameForIdentifier(node: Identifier): string {
2627+
if (nodeIsSynthesized(node) || !generatedBlockScopeNames) {
2628+
return undefined;
2629+
}
2630+
2631+
var variableId = resolver.getBlockScopedVariableId(node)
2632+
if (variableId === undefined) {
2633+
return undefined;
2634+
}
2635+
2636+
return generatedBlockScopeNames[variableId];
26292637
}
26302638

2631-
function emitIdentifier(node: Identifier) {
2632-
let variableId = getBlockScopedVariableId(node);
2633-
if (variableId !== undefined && generatedBlockScopeNames) {
2634-
let text = generatedBlockScopeNames[variableId];
2635-
if (text) {
2636-
write(text);
2639+
function emitIdentifier(node: Identifier, allowGeneratedIdentifiers: boolean) {
2640+
if (allowGeneratedIdentifiers) {
2641+
let generatedName = getGeneratedNameForIdentifier(node);
2642+
if (generatedName) {
2643+
write(generatedName);
26372644
return;
26382645
}
26392646
}
@@ -2686,7 +2693,7 @@ module ts {
26862693

26872694
function emitBindingElement(node: BindingElement) {
26882695
if (node.propertyName) {
2689-
emit(node.propertyName);
2696+
emit(node.propertyName, /*allowGeneratedIdentifiers*/ false);
26902697
write(": ");
26912698
}
26922699
if (node.dotDotDotToken) {
@@ -3030,21 +3037,21 @@ module ts {
30303037
}
30313038

30323039
function emitMethod(node: MethodDeclaration) {
3033-
emit(node.name);
3040+
emit(node.name, /*allowGeneratedIdentifiers*/ false);
30343041
if (languageVersion < ScriptTarget.ES6) {
30353042
write(": function ");
30363043
}
30373044
emitSignatureAndBody(node);
30383045
}
30393046

30403047
function emitPropertyAssignment(node: PropertyDeclaration) {
3041-
emit(node.name);
3048+
emit(node.name, /*allowGeneratedIdentifiers*/ false);
30423049
write(": ");
30433050
emit(node.initializer);
30443051
}
30453052

30463053
function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) {
3047-
emit(node.name);
3054+
emit(node.name, /*allowGeneratedIdentifiers*/ false);
30483055
// If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example:
30493056
// module m {
30503057
// export let y;
@@ -3053,7 +3060,20 @@ module ts {
30533060
// export let obj = { y };
30543061
// }
30553062
// The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version
3056-
if (languageVersion < ScriptTarget.ES6 || resolver.getExpressionNameSubstitution(node.name)) {
3063+
if (languageVersion < ScriptTarget.ES6) {
3064+
// Emit identifier as an identifier
3065+
write(": ");
3066+
var generatedName = getGeneratedNameForIdentifier(node.name);
3067+
if (generatedName) {
3068+
write(generatedName);
3069+
}
3070+
else {
3071+
// Even though this is stored as identifier treat it as an expression
3072+
// Short-hand, { x }, is equivalent of normal form { x: x }
3073+
emitExpressionIdentifier(node.name);
3074+
}
3075+
}
3076+
else if (resolver.getExpressionNameSubstitution(node.name)) {
30573077
// Emit identifier as an identifier
30583078
write(": ");
30593079
// Even though this is stored as identifier treat it as an expression
@@ -3106,7 +3126,7 @@ module ts {
31063126
let indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
31073127
write(".");
31083128
let indentedAfterDot = indentIfOnDifferentLines(node, node.dotToken, node.name);
3109-
emit(node.name);
3129+
emit(node.name, /*allowGeneratedIdentifiers*/ false);
31103130
decreaseIndentIf(indentedBeforeDot, indentedAfterDot);
31113131
}
31123132

@@ -4294,7 +4314,7 @@ module ts {
42944314

42954315
function emitAccessor(node: AccessorDeclaration) {
42964316
write(node.kind === SyntaxKind.GetAccessor ? "get " : "set ");
4297-
emit(node.name);
4317+
emit(node.name, /*allowGeneratedIdentifiers*/ false);
42984318
emitSignatureAndBody(node);
42994319
}
43004320

@@ -5340,7 +5360,7 @@ module ts {
53405360
emitLeadingComments(node.endOfFileToken);
53415361
}
53425362

5343-
function emitNodeWithoutSourceMapWithComments(node: Node): void {
5363+
function emitNodeWithoutSourceMapWithComments(node: Node, allowGeneratedIdentifiers?: boolean): void {
53445364
if (!node) {
53455365
return;
53465366
}
@@ -5354,14 +5374,14 @@ module ts {
53545374
emitLeadingComments(node);
53555375
}
53565376

5357-
emitJavaScriptWorker(node);
5377+
emitJavaScriptWorker(node, allowGeneratedIdentifiers);
53585378

53595379
if (emitComments) {
53605380
emitTrailingComments(node);
53615381
}
53625382
}
53635383

5364-
function emitNodeWithoutSourceMapWithoutComments(node: Node): void {
5384+
function emitNodeWithoutSourceMapWithoutComments(node: Node, allowGeneratedIdentifiers?: boolean): void {
53655385
if (!node) {
53665386
return;
53675387
}
@@ -5370,7 +5390,7 @@ module ts {
53705390
return emitPinnedOrTripleSlashComments(node);
53715391
}
53725392

5373-
emitJavaScriptWorker(node);
5393+
emitJavaScriptWorker(node, allowGeneratedIdentifiers);
53745394
}
53755395

53765396
function shouldEmitLeadingAndTrailingComments(node: Node) {
@@ -5400,11 +5420,11 @@ module ts {
54005420
return true;
54015421
}
54025422

5403-
function emitJavaScriptWorker(node: Node) {
5423+
function emitJavaScriptWorker(node: Node, allowGeneratedIdentifiers: boolean = true) {
54045424
// Check if the node can be emitted regardless of the ScriptTarget
54055425
switch (node.kind) {
54065426
case SyntaxKind.Identifier:
5407-
return emitIdentifier(<Identifier>node);
5427+
return emitIdentifier(<Identifier>node, allowGeneratedIdentifiers);
54085428
case SyntaxKind.Parameter:
54095429
return emitParameter(<ParameterDeclaration>node);
54105430
case SyntaxKind.MethodDeclaration:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//// [initializePropertiesWithRenamedLet.ts]
2+
3+
var x0;
4+
if (true) {
5+
let x0;
6+
var obj1 = { x0: x0 };
7+
var obj2 = { x0 };
8+
}
9+
10+
var x, y, z;
11+
if (true) {
12+
let { x: x } = { x: 0 };
13+
let { y } = { y: 0 };
14+
let z;
15+
({ z: z } = { z: 0 });
16+
({ z } = { z: 0 });
17+
}
18+
19+
//// [initializePropertiesWithRenamedLet.js]
20+
var x0;
21+
if (true) {
22+
var _x0;
23+
var obj1 = {
24+
x0: _x0
25+
};
26+
var obj2 = {
27+
x0: _x0
28+
};
29+
}
30+
var x, y, z;
31+
if (true) {
32+
var _x = ({
33+
x: 0
34+
}).x;
35+
var _y = ({
36+
y: 0
37+
}).y;
38+
var _z;
39+
(_a = {
40+
z: 0
41+
}, _z = _a.z, _a);
42+
(_b = {
43+
z: 0
44+
}, _z = _b.z, _b);
45+
}
46+
var _a, _b;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== tests/cases/compiler/initializePropertiesWithRenamedLet.ts ===
2+
3+
var x0;
4+
>x0 : any
5+
6+
if (true) {
7+
let x0;
8+
>x0 : any
9+
10+
var obj1 = { x0: x0 };
11+
>obj1 : { x0: any; }
12+
>{ x0: x0 } : { x0: any; }
13+
>x0 : any
14+
>x0 : any
15+
16+
var obj2 = { x0 };
17+
>obj2 : { x0: any; }
18+
>{ x0 } : { x0: any; }
19+
>x0 : any
20+
}
21+
22+
var x, y, z;
23+
>x : any
24+
>y : any
25+
>z : any
26+
27+
if (true) {
28+
let { x: x } = { x: 0 };
29+
>x : unknown
30+
>x : number
31+
>{ x: 0 } : { x: number; }
32+
>x : number
33+
34+
let { y } = { y: 0 };
35+
>y : number
36+
>{ y: 0 } : { y: number; }
37+
>y : number
38+
39+
let z;
40+
>z : any
41+
42+
({ z: z } = { z: 0 });
43+
>({ z: z } = { z: 0 }) : { z: number; }
44+
>{ z: z } = { z: 0 } : { z: number; }
45+
>{ z: z } : { z: any; }
46+
>z : any
47+
>z : any
48+
>{ z: 0 } : { z: number; }
49+
>z : number
50+
51+
({ z } = { z: 0 });
52+
>({ z } = { z: 0 }) : { z: number; }
53+
>{ z } = { z: 0 } : { z: number; }
54+
>{ z } : { z: any; }
55+
>z : any
56+
>{ z: 0 } : { z: number; }
57+
>z : number
58+
}

tests/baselines/reference/shadowingViaLocalValueOrBindingElement.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ if (true) {
1616
if (true) {
1717
var x = 0; // Error
1818
var _a = ({
19-
_x: 0
19+
x: 0
2020
}).x, x = _a === void 0 ? 0 : _a; // Error
2121
var _b = ({
22-
_x: 0
22+
x: 0
2323
}).x, x = _b === void 0 ? 0 : _b; // Error
2424
var x = ({
25-
_x: 0
25+
x: 0
2626
}).x; // Error
2727
var x = ({
28-
_x: 0
28+
x: 0
2929
}).x; // Error
3030
}
3131
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @target: es5
2+
3+
var x0;
4+
if (true) {
5+
let x0;
6+
var obj1 = { x0: x0 };
7+
var obj2 = { x0 };
8+
}
9+
10+
var x, y, z;
11+
if (true) {
12+
let { x: x } = { x: 0 };
13+
let { y } = { y: 0 };
14+
let z;
15+
({ z: z } = { z: 0 });
16+
({ z } = { z: 0 });
17+
}

0 commit comments

Comments
 (0)