inline enum constant values for indexed access when index is string literal

This commit is contained in:
Vladimir Matveev
2014-11-01 18:16:48 -07:00
parent 0b738e86c4
commit 2d94030f58
19 changed files with 56 additions and 46 deletions
+2 -1
View File
@@ -5136,6 +5136,7 @@ module ts {
var name = (<LiteralExpression>node.index).text;
var prop = getPropertyOfType(objectType, name);
if (prop) {
getNodeLinks(node).resolvedSymbol = prop;
return getTypeOfSymbol(prop);
}
}
@@ -8833,7 +8834,7 @@ module ts {
return getNodeLinks(node).enumMemberValue;
}
function getConstantValue(node: PropertyAccess): number {
function getConstantValue(node: PropertyAccess | IndexedAccess): number {
var symbol = getNodeLinks(node).resolvedSymbol;
if (symbol && (symbol.flags & SymbolFlags.EnumMember)) {
var declaration = symbol.valueDeclaration;
+16 -6
View File
@@ -1031,19 +1031,29 @@ module ts {
emitTrailingComments(node);
}
function emitPropertyAccess(node: PropertyAccess) {
function tryEmitConstantValue(node: PropertyAccess | IndexedAccess): boolean {
var constantValue = resolver.getConstantValue(node);
if (constantValue !== undefined) {
write(constantValue.toString() + " /* " + identifierToString(node.right) + " */");
var propertyName = node.kind === SyntaxKind.PropertyAccess ? identifierToString((<PropertyAccess>node).right) : getTextOfNode((<IndexedAccess>node).index);
write(constantValue.toString() + " /* " + propertyName + " */");
return true;
}
else {
emit(node.left);
write(".");
emit(node.right);
return false;
}
function emitPropertyAccess(node: PropertyAccess) {
if (tryEmitConstantValue(node)) {
return;
}
emit(node.left);
write(".");
emit(node.right);
}
function emitIndexedAccess(node: IndexedAccess) {
if (tryEmitConstantValue(node)) {
return;
}
emit(node.object);
write("[");
emit(node.index);
+1 -1
View File
@@ -774,7 +774,7 @@ module ts {
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult;
isImportDeclarationEntityNameReferenceDeclarationVisibile(entityName: EntityName): SymbolAccessiblityResult;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: PropertyAccess): number;
getConstantValue(node: PropertyAccess | IndexedAccess): number;
hasEarlyErrors(sourceFile?: SourceFile): boolean;
}
@@ -50,12 +50,12 @@ var r3 = null + b;
var r4 = null + 1;
var r5 = null + c;
var r6 = null + 0 /* a */;
var r7 = null + E['a'];
var r7 = null + 0 /* 'a' */;
var r8 = b + null;
var r9 = 1 + null;
var r10 = c + null;
var r11 = 0 /* a */ + null;
var r12 = E['a'] + null;
var r12 = 0 /* 'a' */ + null;
// null + string
var r13 = null + d;
var r14 = null + '';
@@ -29,4 +29,4 @@ var r4 = b + b;
var r5 = 0 + a;
var r6 = 0 /* a */ + 0;
var r7 = 0 /* a */ + 1 /* b */;
var r8 = E['a'] + E['b'];
var r8 = 0 /* 'a' */ + 1 /* 'b' */;
@@ -50,12 +50,12 @@ var r3 = undefined + b;
var r4 = undefined + 1;
var r5 = undefined + c;
var r6 = undefined + 0 /* a */;
var r7 = undefined + E['a'];
var r7 = undefined + 0 /* 'a' */;
var r8 = b + undefined;
var r9 = 1 + undefined;
var r10 = c + undefined;
var r11 = 0 /* a */ + undefined;
var r12 = E['a'] + undefined;
var r12 = 0 /* 'a' */ + undefined;
// undefined + string
var r13 = undefined + d;
var r14 = undefined + '';
@@ -30,11 +30,11 @@ var ENUM1;
// enum type var
var ResultIsNumber1 = ~ENUM1;
// enum type expressions
var ResultIsNumber2 = ~ENUM1["A"];
var ResultIsNumber3 = ~(0 /* A */ + ENUM1["B"]);
var ResultIsNumber2 = ~0 /* "A" */;
var ResultIsNumber3 = ~(0 /* A */ + 1 /* "B" */);
// multiple ~ operators
var ResultIsNumber4 = ~~~(ENUM1["A"] + 1 /* B */);
var ResultIsNumber4 = ~~~(0 /* "A" */ + 1 /* B */);
// miss assignment operators
~ENUM1;
~ENUM1["A"];
~0 /* A */, ~ENUM1["B"];
~0 /* "A" */;
~0 /* A */, ~1 /* "B" */;
+2 -2
View File
@@ -131,7 +131,7 @@ function foo(x: Enum1) {
case Enum1.Q:
case Enum1.R:
case Enum1.S:
case Enum1.T:
case Enum1["T"]:
case Enum1.U:
case Enum1.V:
case Enum1.W:
@@ -203,7 +203,7 @@ function foo(x) {
case -1 /* Q */:
case 0 /* R */:
case 0 /* S */:
case 11 /* T */:
case 11 /* "T" */:
case 11 /* U */:
case 11 /* V */:
case 11 /* W */:
+2 -3
View File
@@ -466,10 +466,9 @@ function foo(x: Enum1) {
>Enum1 : typeof Enum1
>S : Enum1
case Enum1.T:
>Enum1.T : Enum1
case Enum1["T"]:
>Enum1["T"] : Enum1
>Enum1 : typeof Enum1
>T : Enum1
case Enum1.U:
>Enum1.U : Enum1
@@ -22,8 +22,8 @@ var ENUM1;
})(ENUM1 || (ENUM1 = {}));
;
// expression
var ResultIsNumber1 = --ENUM1["A"];
var ResultIsNumber1 = --0 /* "A" */;
var ResultIsNumber2 = 0 /* A */--;
// miss assignment operator
--ENUM1["A"];
--0 /* "A" */;
ENUM1[A]--;
@@ -39,11 +39,11 @@ var ENUM1;
var ResultIsBoolean1 = delete ENUM;
var ResultIsBoolean2 = delete ENUM1;
// enum type expressions
var ResultIsBoolean3 = delete ENUM1["A"];
var ResultIsBoolean4 = delete (ENUM[0] + ENUM1["B"]);
var ResultIsBoolean3 = delete 0 /* "A" */;
var ResultIsBoolean4 = delete (ENUM[0] + 1 /* "B" */);
// multiple delete operators
var ResultIsBoolean5 = delete delete ENUM;
var ResultIsBoolean6 = delete delete delete (ENUM[0] + ENUM1["B"]);
var ResultIsBoolean6 = delete delete delete (ENUM[0] + 1 /* "B" */);
// miss assignment operators
delete ENUM;
delete ENUM1;
@@ -22,8 +22,8 @@ var ENUM1;
})(ENUM1 || (ENUM1 = {}));
;
// expression
var ResultIsNumber1 = ++ENUM1["B"];
var ResultIsNumber1 = ++1 /* "B" */;
var ResultIsNumber2 = 1 /* B */++;
// miss assignment operator
++ENUM1["B"];
++1 /* "B" */;
1 /* B */++;
@@ -37,11 +37,11 @@ var ENUM1;
// enum type var
var ResultIsBoolean1 = !ENUM;
// enum type expressions
var ResultIsBoolean2 = !ENUM["B"];
var ResultIsBoolean3 = !(1 /* B */ + ENUM["C"]);
var ResultIsBoolean2 = !1 /* "B" */;
var ResultIsBoolean3 = !(1 /* B */ + 2 /* "C" */);
// multiple ! operators
var ResultIsBoolean4 = !!ENUM;
var ResultIsBoolean5 = !!!(ENUM["B"] + 2 /* C */);
var ResultIsBoolean5 = !!!(1 /* "B" */ + 2 /* C */);
// miss assignment operators
!ENUM;
!ENUM1;
@@ -33,10 +33,10 @@ var ENUM1;
// enum type var
var ResultIsNumber1 = -ENUM;
// expressions
var ResultIsNumber2 = -ENUM1["B"];
var ResultIsNumber3 = -(1 /* B */ + ENUM1[""]);
var ResultIsNumber2 = -1 /* "B" */;
var ResultIsNumber3 = -(1 /* B */ + 2 /* "" */);
// miss assignment operators
-ENUM;
-ENUM1;
-ENUM1["B"];
-1 /* "B" */;
-ENUM, ENUM1;
@@ -61,7 +61,7 @@ var strRepresentation2 = MyEmusEnum[0 /* emu */];
// Should be implicit 'any' ; property access fails, no string indexer.
var strRepresentation3 = MyEmusEnum["monehh"];
// Should be okay; should be a MyEmusEnum
var strRepresentation4 = MyEmusEnum["emu"];
var strRepresentation4 = 0 /* "emu" */;
// Should report an implicit 'any'.
var x = {}["hi"];
// Should report an implicit 'any'.
@@ -35,8 +35,8 @@ var ENUM1;
var ResultIsNumber1 = +ENUM;
var ResultIsNumber2 = +ENUM1;
// enum type expressions
var ResultIsNumber3 = +ENUM1["A"];
var ResultIsNumber4 = +(ENUM[0] + ENUM1["B"]);
var ResultIsNumber3 = +0 /* "A" */;
var ResultIsNumber4 = +(ENUM[0] + 1 /* "B" */);
// miss assignment operators
+ENUM;
+ENUM1;
@@ -44,15 +44,15 @@ var ENUM1;
var ResultIsString1 = typeof ENUM;
var ResultIsString2 = typeof ENUM1;
// enum type expressions
var ResultIsString3 = typeof ENUM1["A"];
var ResultIsString4 = typeof (ENUM[0] + ENUM1["B"]);
var ResultIsString3 = typeof 0 /* "A" */;
var ResultIsString4 = typeof (ENUM[0] + 1 /* "B" */);
// multiple typeof operators
var ResultIsString5 = typeof typeof ENUM;
var ResultIsString6 = typeof typeof typeof (ENUM[0] + 1 /* B */);
// miss assignment operators
typeof ENUM;
typeof ENUM1;
typeof ENUM1["B"];
typeof 1 /* "B" */;
typeof ENUM, ENUM1;
// use typeof in type query
var z;
@@ -39,13 +39,13 @@ var ENUM1;
var ResultIsAny1 = void ENUM;
var ResultIsAny2 = void ENUM1;
// enum type expressions
var ResultIsAny3 = void ENUM1["A"];
var ResultIsAny4 = void (ENUM[0] + ENUM1["B"]);
var ResultIsAny3 = void 0 /* "A" */;
var ResultIsAny4 = void (ENUM[0] + 1 /* "B" */);
// multiple void operators
var ResultIsAny5 = void void ENUM;
var ResultIsAny6 = void void void (ENUM[0] + 1 /* B */);
// miss assignment operators
void ENUM;
void ENUM1;
void ENUM1["B"];
void 1 /* "B" */;
void ENUM, ENUM1;
+1 -1
View File
@@ -130,7 +130,7 @@ function foo(x: Enum1) {
case Enum1.Q:
case Enum1.R:
case Enum1.S:
case Enum1.T:
case Enum1["T"]:
case Enum1.U:
case Enum1.V:
case Enum1.W: