Skip to content

Commit 21c10af

Browse files
committed
Moved constant value emit to ts transform.
1 parent bfb8933 commit 21c10af

File tree

5 files changed

+76
-60
lines changed

5 files changed

+76
-60
lines changed

src/compiler/emitter.ts

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,10 +1143,6 @@ const _super = (function (geti, seti) {
11431143
}
11441144

11451145
function emitPropertyAccessExpression(node: PropertyAccessExpression) {
1146-
if (tryEmitConstantValue(node)) {
1147-
return;
1148-
}
1149-
11501146
let indentBeforeDot = false;
11511147
let indentAfterDot = false;
11521148
if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) {
@@ -1156,11 +1152,13 @@ const _super = (function (geti, seti) {
11561152
indentBeforeDot = needsIndentation(node, node.expression, dotToken);
11571153
indentAfterDot = needsIndentation(node, dotToken, node.name);
11581154
}
1159-
const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression);
11601155

11611156
emitExpression(node.expression);
11621157
increaseIndentIf(indentBeforeDot);
1158+
1159+
const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression);
11631160
write(shouldEmitDotDot ? ".." : ".");
1161+
11641162
increaseIndentIf(indentAfterDot);
11651163
emit(node.name);
11661164
decreaseIndentIf(indentBeforeDot, indentAfterDot);
@@ -1176,17 +1174,15 @@ const _super = (function (geti, seti) {
11761174
}
11771175
else {
11781176
// check if constant enum value is integer
1179-
const constantValue = tryGetConstEnumValue(expression);
1177+
const constantValue = getConstantValue(expression);
11801178
// isFinite handles cases when constantValue is undefined
1181-
return isFinite(constantValue) && Math.floor(constantValue) === constantValue;
1179+
return isFinite(constantValue)
1180+
&& Math.floor(constantValue) === constantValue
1181+
&& compilerOptions.removeComments;
11821182
}
11831183
}
11841184

11851185
function emitElementAccessExpression(node: ElementAccessExpression) {
1186-
if (tryEmitConstantValue(node)) {
1187-
return;
1188-
}
1189-
11901186
emitExpression(node.expression);
11911187
write("[");
11921188
emitExpression(node.argumentExpression);
@@ -2260,24 +2256,6 @@ const _super = (function (geti, seti) {
22602256
}
22612257
}
22622258

2263-
// TODO(rbuckton): Move this into a transformer
2264-
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
2265-
const constantValue = tryGetConstEnumValue(node);
2266-
if (constantValue !== undefined) {
2267-
write(String(constantValue));
2268-
if (!compilerOptions.removeComments) {
2269-
const propertyName = isPropertyAccessExpression(node)
2270-
? declarationNameToString(node.name)
2271-
: getTextOfNode(node.argumentExpression);
2272-
write(` /* ${propertyName} */`);
2273-
}
2274-
2275-
return true;
2276-
}
2277-
2278-
return false;
2279-
}
2280-
22812259
function emitEmbeddedStatement(node: Statement) {
22822260
if (isBlock(node)) {
22832261
write(" ");
@@ -2628,16 +2606,6 @@ const _super = (function (geti, seti) {
26282606
return getLiteralText(node, currentSourceFile, languageVersion);
26292607
}
26302608

2631-
function tryGetConstEnumValue(node: Node): number {
2632-
if (compilerOptions.isolatedModules) {
2633-
return undefined;
2634-
}
2635-
2636-
return isPropertyAccessExpression(node) || isElementAccessExpression(node)
2637-
? resolver.getConstantValue(<PropertyAccessExpression | ElementAccessExpression>node)
2638-
: undefined;
2639-
}
2640-
26412609
function isSingleLineEmptyBlock(block: Block) {
26422610
return !block.multiLine
26432611
&& block.statements.length === 0

src/compiler/factory.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,6 +2798,20 @@ namespace ts {
27982798
return tokenSourceMapRanges && tokenSourceMapRanges[token];
27992799
}
28002800

2801+
export function getConstantValue(node: Node) {
2802+
const emitNode = node.emitNode;
2803+
if (emitNode && emitNode.flags & EmitFlags.ConstantValue) {
2804+
return emitNode.constantValue;
2805+
}
2806+
}
2807+
2808+
export function setConstantValue(node: Node, value: number) {
2809+
const emitNode = getOrCreateEmitNode(node);
2810+
emitNode.constantValue = value;
2811+
emitNode.flags |= EmitFlags.ConstantValue;
2812+
return node;
2813+
}
2814+
28012815
export function setTextRange<T extends TextRange>(node: T, location: TextRange): T {
28022816
if (location) {
28032817
node.pos = location.pos;

src/compiler/transformers/ts.ts

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ namespace ts {
4242
context.onEmitNode = onEmitNode;
4343
context.onSubstituteNode = onSubstituteNode;
4444

45+
// Enable substitution for property/element access to emit const enum values.
46+
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
47+
context.enableSubstitution(SyntaxKind.ElementAccessExpression);
48+
4549
// These variables contain state that changes as we descend into the tree.
4650
let currentSourceFile: SourceFile;
4751
let currentNamespace: ModuleDeclaration;
@@ -3294,17 +3298,15 @@ namespace ts {
32943298
switch (node.kind) {
32953299
case SyntaxKind.Identifier:
32963300
return substituteExpressionIdentifier(<Identifier>node);
3297-
}
3298-
3299-
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) {
3300-
switch (node.kind) {
3301-
case SyntaxKind.CallExpression:
3301+
case SyntaxKind.PropertyAccessExpression:
3302+
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
3303+
case SyntaxKind.ElementAccessExpression:
3304+
return substituteElementAccessExpression(<ElementAccessExpression>node);
3305+
case SyntaxKind.CallExpression:
3306+
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper) {
33023307
return substituteCallExpression(<CallExpression>node);
3303-
case SyntaxKind.PropertyAccessExpression:
3304-
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
3305-
case SyntaxKind.ElementAccessExpression:
3306-
return substituteElementAccessExpression(<ElementAccessExpression>node);
3307-
}
3308+
}
3309+
break;
33083310
}
33093311

33103312
return node;
@@ -3381,7 +3383,7 @@ namespace ts {
33813383
}
33823384

33833385
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
3384-
if (node.expression.kind === SyntaxKind.SuperKeyword) {
3386+
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
33853387
const flags = getSuperContainerAsyncMethodFlags();
33863388
if (flags) {
33873389
return createSuperAccessInAsyncMethod(
@@ -3392,11 +3394,11 @@ namespace ts {
33923394
}
33933395
}
33943396

3395-
return node;
3397+
return substituteConstantValue(node);
33963398
}
33973399

33983400
function substituteElementAccessExpression(node: ElementAccessExpression) {
3399-
if (node.expression.kind === SyntaxKind.SuperKeyword) {
3401+
if (enabledSubstitutions & TypeScriptSubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
34003402
const flags = getSuperContainerAsyncMethodFlags();
34013403
if (flags) {
34023404
return createSuperAccessInAsyncMethod(
@@ -3407,9 +3409,39 @@ namespace ts {
34073409
}
34083410
}
34093411

3412+
return substituteConstantValue(node);
3413+
}
3414+
3415+
function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression {
3416+
const constantValue = tryGetConstEnumValue(node);
3417+
if (constantValue !== undefined) {
3418+
const substitute = createLiteral(constantValue);
3419+
setSourceMapRange(substitute, node);
3420+
setCommentRange(substitute, node);
3421+
if (!compilerOptions.removeComments) {
3422+
const propertyName = isPropertyAccessExpression(node)
3423+
? declarationNameToString(node.name)
3424+
: getTextOfNode(node.argumentExpression);
3425+
substitute.trailingComment = ` ${propertyName} `;
3426+
}
3427+
3428+
setConstantValue(node, constantValue);
3429+
return substitute;
3430+
}
3431+
34103432
return node;
34113433
}
34123434

3435+
function tryGetConstEnumValue(node: Node): number {
3436+
if (compilerOptions.isolatedModules) {
3437+
return undefined;
3438+
}
3439+
3440+
return isPropertyAccessExpression(node) || isElementAccessExpression(node)
3441+
? resolver.getConstantValue(<PropertyAccessExpression | ElementAccessExpression>node)
3442+
: undefined;
3443+
}
3444+
34133445
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
34143446
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
34153447
return createPropertyAccess(

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3156,6 +3156,7 @@ namespace ts {
31563156
sourceMapRange?: TextRange;
31573157
tokenSourceMapRanges?: Map<TextRange>;
31583158
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
3159+
constantValue?: number;
31593160
}
31603161

31613162
/* @internal */
@@ -3187,6 +3188,7 @@ namespace ts {
31873188
AsyncFunctionBody = 1 << 21,
31883189
ReuseTempVariableScope = 1 << 22, // Reuse the existing temp variable scope during emit.
31893190
CustomPrologue = 1 << 23, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed).
3191+
ConstantValue = 1 << 24, // The node was replaced with a constant value during substitution.
31903192
}
31913193

31923194
/* @internal */

tests/baselines/reference/constEnumToStringWithComments.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ let c1 = Foo["C"].toString();
2323

2424

2525
//// [constEnumToStringWithComments.js]
26-
var x0 = 100 /* X */..toString();
27-
var x1 = 100 /* "X" */..toString();
26+
var x0 = 100 /* X */.toString();
27+
var x1 = 100 /* "X" */.toString();
2828
var y0 = 0.5 /* Y */.toString();
2929
var y1 = 0.5 /* "Y" */.toString();
30-
var z0 = 2 /* Z */..toString();
31-
var z1 = 2 /* "Z" */..toString();
32-
var a0 = -1 /* A */..toString();
33-
var a1 = -1 /* "A" */..toString();
30+
var z0 = 2 /* Z */.toString();
31+
var z1 = 2 /* "Z" */.toString();
32+
var a0 = -1 /* A */.toString();
33+
var a1 = -1 /* "A" */.toString();
3434
var b0 = -1.5 /* B */.toString();
3535
var b1 = -1.5 /* "B" */.toString();
36-
var c0 = -1 /* C */..toString();
37-
var c1 = -1 /* "C" */..toString();
36+
var c0 = -1 /* C */.toString();
37+
var c1 = -1 /* "C" */.toString();

0 commit comments

Comments
 (0)