Skip to content

Commit

Permalink
Allow to use a const in the initializer of a const enum
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Hanson committed Oct 2, 2017
1 parent 7aee3a1 commit 42761b8
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21859,8 +21859,10 @@ namespace ts {
return +(<NumericLiteral>expr).text;
case SyntaxKind.ParenthesizedExpression:
return evaluate((<ParenthesizedExpression>expr).expression);
case SyntaxKind.Identifier:
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), (<Identifier>expr).escapedText);
case SyntaxKind.Identifier: {
const id = expr as Identifier;
return nodeIsMissing(expr) ? 0 : evaluateEnumMember(id, getSymbolOfNode(member.parent), id.escapedText);
}
case SyntaxKind.ElementAccessExpression:
case SyntaxKind.PropertyAccessExpression:
const ex = <PropertyAccessExpression | ElementAccessExpression>expr;
Expand All @@ -21876,15 +21878,15 @@ namespace ts {
Debug.assert(isLiteralExpression(argument));
name = escapeLeadingUnderscores((argument as LiteralExpression).text);
}
return evaluateEnumMember(expr, type.symbol, name);
return evaluateEnumMember(ex, type.symbol, name);
}
}
break;
}
return undefined;
}

function evaluateEnumMember(expr: Expression, enumSymbol: Symbol, name: __String) {
function evaluateEnumMember(expr: Identifier | ElementAccessExpression | PropertyAccessExpression, enumSymbol: Symbol, name: __String): string | number {
const memberSymbol = enumSymbol.exports.get(name);
if (memberSymbol) {
const declaration = memberSymbol.valueDeclaration;
Expand All @@ -21896,6 +21898,12 @@ namespace ts {
return 0;
}
}
else {
const type = checkExpression(expr);
if (type.flags & TypeFlags.StringOrNumberLiteral) {
return (type as LiteralType).value;
}
}
return undefined;
}
}
Expand Down
19 changes: 19 additions & 0 deletions tests/baselines/reference/enumInitializers_const.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [enumInitializers_const.ts]
const stride = 5;
const enum E {
x = stride * 2,
}
E.x;

const s = "abc";
const enum S {
abc = s,
}
S.abc;


//// [enumInitializers_const.js]
var stride = 5;
10 /* x */;
var s = "abc";
"abc" /* abc */;
31 changes: 31 additions & 0 deletions tests/baselines/reference/enumInitializers_const.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/enumInitializers_const.ts ===
const stride = 5;
>stride : Symbol(stride, Decl(enumInitializers_const.ts, 0, 5))

const enum E {
>E : Symbol(E, Decl(enumInitializers_const.ts, 0, 17))

x = stride * 2,
>x : Symbol(E.x, Decl(enumInitializers_const.ts, 1, 14))
>stride : Symbol(stride, Decl(enumInitializers_const.ts, 0, 5))
}
E.x;
>E.x : Symbol(E.x, Decl(enumInitializers_const.ts, 1, 14))
>E : Symbol(E, Decl(enumInitializers_const.ts, 0, 17))
>x : Symbol(E.x, Decl(enumInitializers_const.ts, 1, 14))

const s = "abc";
>s : Symbol(s, Decl(enumInitializers_const.ts, 6, 5))

const enum S {
>S : Symbol(S, Decl(enumInitializers_const.ts, 6, 16))

abc = s,
>abc : Symbol(S.abc, Decl(enumInitializers_const.ts, 7, 14))
>s : Symbol(s, Decl(enumInitializers_const.ts, 6, 5))
}
S.abc;
>S.abc : Symbol(S.abc, Decl(enumInitializers_const.ts, 7, 14))
>S : Symbol(S, Decl(enumInitializers_const.ts, 6, 16))
>abc : Symbol(S.abc, Decl(enumInitializers_const.ts, 7, 14))

35 changes: 35 additions & 0 deletions tests/baselines/reference/enumInitializers_const.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
=== tests/cases/compiler/enumInitializers_const.ts ===
const stride = 5;
>stride : 5
>5 : 5

const enum E {
>E : E

x = stride * 2,
>x : E
>stride * 2 : number
>stride : 5
>2 : 2
}
E.x;
>E.x : E
>E : typeof E
>x : E

const s = "abc";
>s : "abc"
>"abc" : "abc"

const enum S {
>S : S

abc = s,
>abc : S
>s : "abc"
}
S.abc;
>S.abc : S
>S : typeof S
>abc : S

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
tests/cases/compiler/enumInitializers_const_circular.ts(3,9): error TS2474: In 'const' enum declarations member initializer must be constant expression.


==== tests/cases/compiler/enumInitializers_const_circular.ts (1 errors) ====
const x = E.y;
const enum E {
y = x,
~
!!! error TS2474: In 'const' enum declarations member initializer must be constant expression.
}

9 changes: 9 additions & 0 deletions tests/baselines/reference/enumInitializers_const_circular.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//// [enumInitializers_const_circular.ts]
const x = E.y;
const enum E {
y = x,
}


//// [enumInitializers_const_circular.js]
var x = E.y;
15 changes: 15 additions & 0 deletions tests/baselines/reference/enumInitializers_const_circular.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
=== tests/cases/compiler/enumInitializers_const_circular.ts ===
const x = E.y;
>x : Symbol(x, Decl(enumInitializers_const_circular.ts, 0, 5))
>E.y : Symbol(E.y, Decl(enumInitializers_const_circular.ts, 1, 14))
>E : Symbol(E, Decl(enumInitializers_const_circular.ts, 0, 14))
>y : Symbol(E.y, Decl(enumInitializers_const_circular.ts, 1, 14))

const enum E {
>E : Symbol(E, Decl(enumInitializers_const_circular.ts, 0, 14))

y = x,
>y : Symbol(E.y, Decl(enumInitializers_const_circular.ts, 1, 14))
>x : Symbol(x, Decl(enumInitializers_const_circular.ts, 0, 5))
}

15 changes: 15 additions & 0 deletions tests/baselines/reference/enumInitializers_const_circular.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
=== tests/cases/compiler/enumInitializers_const_circular.ts ===
const x = E.y;
>x : E
>E.y : E
>E : typeof E
>y : E

const enum E {
>E : E

y = x,
>y : E
>x : E
}

11 changes: 11 additions & 0 deletions tests/cases/compiler/enumInitializers_const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const stride = 5;
const enum E {
x = stride * 2,
}
E.x;

const s = "abc";
const enum S {
abc = s,
}
S.abc;
4 changes: 4 additions & 0 deletions tests/cases/compiler/enumInitializers_const_circular.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const x = E.y;
const enum E {
y = x,
}

0 comments on commit 42761b8

Please sign in to comment.