Skip to content

Enum cleanup #2199

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Mar 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 31 additions & 19 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9747,7 +9747,7 @@ module ts {
}
let initializer = member.initializer;
if (initializer) {
autoValue = getConstantValueForEnumMemberInitializer(initializer, enumIsConst);
autoValue = getConstantValueForEnumMemberInitializer(initializer);
if (autoValue === undefined) {
if (enumIsConst) {
error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
Expand Down Expand Up @@ -9782,7 +9782,7 @@ module ts {
nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed;
}

function getConstantValueForEnumMemberInitializer(initializer: Expression, enumIsConst: boolean): number {
function getConstantValueForEnumMemberInitializer(initializer: Expression): number {
return evalConstant(initializer);

function evalConstant(e: Node): number {
Expand All @@ -9795,14 +9795,10 @@ module ts {
switch ((<PrefixUnaryExpression>e).operator) {
case SyntaxKind.PlusToken: return value;
case SyntaxKind.MinusToken: return -value;
case SyntaxKind.TildeToken: return enumIsConst ? ~value : undefined;
case SyntaxKind.TildeToken: return ~value;
}
return undefined;
case SyntaxKind.BinaryExpression:
if (!enumIsConst) {
return undefined;
}

let left = evalConstant((<BinaryExpression>e).left);
if (left === undefined) {
return undefined;
Expand All @@ -9828,14 +9824,10 @@ module ts {
case SyntaxKind.NumericLiteral:
return +(<LiteralExpression>e).text;
case SyntaxKind.ParenthesizedExpression:
return enumIsConst ? evalConstant((<ParenthesizedExpression>e).expression) : undefined;
return evalConstant((<ParenthesizedExpression>e).expression);
case SyntaxKind.Identifier:
case SyntaxKind.ElementAccessExpression:
case SyntaxKind.PropertyAccessExpression:
if (!enumIsConst) {
return undefined;
}

let member = initializer.parent;
let currentType = getTypeOfSymbol(getSymbolOfNode(member.parent));
let enumType: Type;
Expand All @@ -9848,30 +9840,50 @@ module ts {
propertyName = (<Identifier>e).text;
}
else {
let expression: Expression;
if (e.kind === SyntaxKind.ElementAccessExpression) {
if ((<ElementAccessExpression>e).argumentExpression === undefined ||
(<ElementAccessExpression>e).argumentExpression.kind !== SyntaxKind.StringLiteral) {
return undefined;
}
enumType = getTypeOfNode((<ElementAccessExpression>e).expression);
expression = (<ElementAccessExpression>e).expression;
propertyName = (<LiteralExpression>(<ElementAccessExpression>e).argumentExpression).text;
}
else {
enumType = getTypeOfNode((<PropertyAccessExpression>e).expression);
expression = (<PropertyAccessExpression>e).expression;
propertyName = (<PropertyAccessExpression>e).name.text;
}
if (enumType !== currentType) {

// expression part in ElementAccess\PropertyAccess should be either identifier or dottedName
var current = expression;
while (current) {
if (current.kind === SyntaxKind.Identifier) {
break;
}
else if (current.kind === SyntaxKind.PropertyAccessExpression) {
current = (<ElementAccessExpression>current).expression;
}
else {
return undefined;
}
}

enumType = checkExpression(expression);
// allow references to constant members of other enums
if (!(enumType.symbol && (enumType.symbol.flags & SymbolFlags.Enum))) {
return undefined;
}
}

if (propertyName === undefined) {
return undefined;
}

let property = getPropertyOfObjectType(enumType, propertyName);
if (!property || !(property.flags & SymbolFlags.EnumMember)) {
return undefined;
}

let propertyDecl = property.valueDeclaration;
// self references are illegal
if (member === propertyDecl) {
Expand All @@ -9882,6 +9894,7 @@ module ts {
if (!isDefinedBefore(propertyDecl, member)) {
return undefined;
}

return <number>getNodeLinks(propertyDecl).enumMemberValue;
}
}
Expand Down Expand Up @@ -11132,10 +11145,9 @@ module ts {

let symbol = getNodeLinks(node).resolvedSymbol;
if (symbol && (symbol.flags & SymbolFlags.EnumMember)) {
let declaration = symbol.valueDeclaration;
let constantValue: number;
if (declaration.kind === SyntaxKind.EnumMember) {
return getEnumMemberValue(<EnumMember>declaration);
// inline property\index accesses only for const enums
if (isConstEnumDeclaration(symbol.valueDeclaration.parent)) {
return getEnumMemberValue(<EnumMember>symbol.valueDeclaration);
}
}

Expand Down
13 changes: 5 additions & 8 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5077,15 +5077,12 @@ module ts {
}

function writeEnumMemberDeclarationValue(member: EnumMember) {
if (!member.initializer || isConst(member.parent)) {
let value = resolver.getConstantValue(member);
if (value !== undefined) {
write(value.toString());
return;
}
let value = resolver.getConstantValue(member);
if (value !== undefined) {
write(value.toString());
return;
}

if (member.initializer) {
else if (member.initializer) {
emit(member.initializer);
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ var enumdule;
enumdule.Point = Point;
})(enumdule || (enumdule = {}));
var x;
var x = 0 /* Red */;
var x = enumdule.Red;
var y;
var y = new enumdule.Point(0, 0);
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ var enumdule;
enumdule[enumdule["Blue"] = 1] = "Blue";
})(enumdule || (enumdule = {}));
var x;
var x = 0 /* Red */;
var x = enumdule.Red;
var y;
var y = new enumdule.Point(0, 0);
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ var A;
})(Day || (Day = {}));
})(A || (A = {}));
// not an error since exported
var a = 0 /* Red */;
var a = A.Color.Red;
// error not exported
var b = A.Day.Monday;
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ var r11 = a + foo();
var r12 = a + C;
var r13 = a + new C();
var r14 = a + E;
var r15 = a + 0 /* a */;
var r15 = a + E.a;
var r16 = a + M;
var r17 = a + '';
var r18 = a + 123;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ var r14 = b + d;
var r15 = b + foo;
var r16 = b + foo();
var r17 = b + C;
var r18 = 0 /* a */ + new C();
var r19 = 0 /* a */ + C.foo();
var r20 = 0 /* a */ + M;
var r18 = E.a + new C();
var r19 = E.a + C.foo();
var r20 = E.a + M;
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ var r2 = a + null;
var r3 = null + b;
var r4 = null + 1;
var r5 = null + c;
var r6 = null + 0 /* a */;
var r7 = null + 0 /* 'a' */;
var r6 = null + E.a;
var r7 = null + E['a'];
var r8 = b + null;
var r9 = 1 + null;
var r10 = c + null;
var r11 = 0 /* a */ + null;
var r12 = 0 /* 'a' */ + null;
var r11 = E.a + null;
var r12 = E['a'] + null;
// null + string
var r13 = null + d;
var r14 = null + '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ var r2 = a + b;
var r3 = b + a;
var r4 = b + b;
var r5 = 0 + a;
var r6 = 0 /* a */ + 0;
var r7 = 0 /* a */ + 1 /* b */;
var r8 = 0 /* 'a' */ + 1 /* 'b' */;
var r9 = 0 /* 'a' */ + 0 /* 'c' */;
var r6 = E.a + 0;
var r7 = E.a + E.b;
var r8 = E['a'] + E['b'];
var r9 = E['a'] + F['c'];
var r10 = a + c;
var r11 = c + a;
var r12 = b + c;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var r13 = f + x;
var r14 = g + x;
// other cases
var r15 = x + E;
var r16 = x + 0 /* a */;
var r16 = x + E.a;
var r17 = x + '';
var r18 = x + 0;
var r19 = x + {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ var r2 = a + undefined;
var r3 = undefined + b;
var r4 = undefined + 1;
var r5 = undefined + c;
var r6 = undefined + 0 /* a */;
var r7 = undefined + 0 /* 'a' */;
var r6 = undefined + E.a;
var r7 = undefined + E['a'];
var r8 = b + undefined;
var r9 = 1 + undefined;
var r10 = c + undefined;
var r11 = 0 /* a */ + undefined;
var r12 = 0 /* 'a' */ + undefined;
var r11 = E.a + undefined;
var r12 = E['a'] + undefined;
// undefined + string
var r13 = undefined + d;
var r14 = undefined + '';
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/amdImportAsPrimaryExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ define(["require", "exports"], function (require, exports) {
});
//// [foo_1.js]
define(["require", "exports", "./foo_0"], function (require, exports, foo) {
if (0 /* A */ === 0) {
if (foo.E1.A === 0) {
}
});
Loading