Skip to content

Commit f8b6a8f

Browse files
authored
Introduce literal freshness for literal enum member types (#26556)
* Introduce literal freshness for literal enum members, allow enum references in ambient const initializers * Merge statements * Add enum literal readonly property test case * Accept better baselines post-merge
1 parent cf2f339 commit f8b6a8f

File tree

161 files changed

+583
-266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+583
-266
lines changed

src/compiler/checker.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5907,9 +5907,9 @@ namespace ts {
59075907
for (const declaration of symbol.declarations) {
59085908
if (declaration.kind === SyntaxKind.EnumDeclaration) {
59095909
for (const member of (<EnumDeclaration>declaration).members) {
5910-
const memberType = getLiteralType(getEnumMemberValue(member)!, enumCount, getSymbolOfNode(member)); // TODO: GH#18217
5910+
const memberType = getFreshTypeOfLiteralType(getLiteralType(getEnumMemberValue(member)!, enumCount, getSymbolOfNode(member))); // TODO: GH#18217
59115911
getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
5912-
memberTypeList.push(memberType);
5912+
memberTypeList.push(getRegularTypeOfLiteralType(memberType));
59135913
}
59145914
}
59155915
}
@@ -8242,7 +8242,7 @@ namespace ts {
82428242
const res = tryGetDeclaredTypeOfSymbol(symbol);
82438243
if (res) {
82448244
return checkNoTypeArguments(node, symbol) ?
8245-
res.flags & TypeFlags.TypeParameter ? getConstrainedTypeVariable(<TypeParameter>res, node) : res :
8245+
res.flags & TypeFlags.TypeParameter ? getConstrainedTypeVariable(<TypeParameter>res, node) : getRegularTypeOfLiteralType(res) :
82468246
errorType;
82478247
}
82488248

@@ -12736,7 +12736,7 @@ namespace ts {
1273612736
}
1273712737

1273812738
function getWidenedLiteralType(type: Type): Type {
12739-
return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
12739+
return type.flags & TypeFlags.EnumLiteral && type.flags & TypeFlags.FreshLiteral ? getBaseTypeOfEnumLiteralType(<LiteralType>type) :
1274012740
type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType :
1274112741
type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType :
1274212742
type.flags & TypeFlags.BooleanLiteral ? booleanType :
@@ -28274,13 +28274,14 @@ namespace ts {
2827428274
return false;
2827528275
}
2827628276

28277-
function literalTypeToNode(type: LiteralType): Expression {
28278-
return createLiteral(type.value);
28277+
function literalTypeToNode(type: LiteralType, enclosing: Node): Expression {
28278+
const enumResult = type.flags & TypeFlags.EnumLiteral && nodeBuilder.symbolToExpression(type.symbol, SymbolFlags.Value, enclosing);
28279+
return enumResult || createLiteral(type.value);
2827928280
}
2828028281

2828128282
function createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
2828228283
const type = getTypeOfSymbol(getSymbolOfNode(node));
28283-
return literalTypeToNode(<LiteralType>type);
28284+
return literalTypeToNode(<LiteralType>type, node);
2828428285
}
2828528286

2828628287
function createResolver(): EmitResolver {
@@ -29643,13 +29644,20 @@ namespace ts {
2964329644
(<PrefixUnaryExpression>expr).operand.kind === SyntaxKind.NumericLiteral;
2964429645
}
2964529646

29647+
function isSimpleLiteralEnumReference(expr: Expression) {
29648+
if (
29649+
(isPropertyAccessExpression(expr) || (isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression))) &&
29650+
isEntityNameExpression(expr.expression)
29651+
) return !!(checkExpressionCached(expr).flags & TypeFlags.EnumLiteral);
29652+
}
29653+
2964629654
function checkAmbientInitializer(node: VariableDeclaration | PropertyDeclaration | PropertySignature) {
2964729655
if (node.initializer) {
29648-
const isInvalidInitializer = !isStringOrNumberLiteralExpression(node.initializer);
29656+
const isInvalidInitializer = !(isStringOrNumberLiteralExpression(node.initializer) || isSimpleLiteralEnumReference(node.initializer));
2964929657
const isConstOrReadonly = isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node);
2965029658
if (isConstOrReadonly && !node.type) {
2965129659
if (isInvalidInitializer) {
29652-
return grammarErrorOnNode(node.initializer!, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal);
29660+
return grammarErrorOnNode(node.initializer!, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference);
2965329661
}
2965429662
}
2965529663
else {

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@
835835
"category": "Error",
836836
"code": 1253
837837
},
838-
"A 'const' initializer in an ambient context must be a string or numeric literal.": {
838+
"A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.": {
839839
"category": "Error",
840840
"code": 1254
841841
},

tests/baselines/reference/ambientConstLiterals.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ function f<T>(x: T): T {
33
return x;
44
}
55

6-
enum E { A, B, C }
6+
enum E { A, B, C, "non identifier" }
77

88
const c1 = "abc";
99
const c2 = 123;
@@ -13,6 +13,7 @@ const c5 = f(123);
1313
const c6 = f(-123);
1414
const c7 = true;
1515
const c8 = E.A;
16+
const c8b = E["non identifier"];
1617
const c9 = { x: "abc" };
1718
const c10 = [123];
1819
const c11 = "abc" + "def";
@@ -29,6 +30,7 @@ var E;
2930
E[E["A"] = 0] = "A";
3031
E[E["B"] = 1] = "B";
3132
E[E["C"] = 2] = "C";
33+
E[E["non identifier"] = 3] = "non identifier";
3234
})(E || (E = {}));
3335
var c1 = "abc";
3436
var c2 = 123;
@@ -38,6 +40,7 @@ var c5 = f(123);
3840
var c6 = f(-123);
3941
var c7 = true;
4042
var c8 = E.A;
43+
var c8b = E["non identifier"];
4144
var c9 = { x: "abc" };
4245
var c10 = [123];
4346
var c11 = "abc" + "def";
@@ -51,7 +54,8 @@ declare function f<T>(x: T): T;
5154
declare enum E {
5255
A = 0,
5356
B = 1,
54-
C = 2
57+
C = 2,
58+
"non identifier" = 3
5559
}
5660
declare const c1 = "abc";
5761
declare const c2 = 123;
@@ -60,7 +64,8 @@ declare const c4 = 123;
6064
declare const c5 = 123;
6165
declare const c6 = -123;
6266
declare const c7: boolean;
63-
declare const c8: E;
67+
declare const c8 = E.A;
68+
declare const c8b = E["non identifier"];
6469
declare const c9: {
6570
x: string;
6671
};

tests/baselines/reference/ambientConstLiterals.symbols

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ function f<T>(x: T): T {
1010
>x : Symbol(x, Decl(ambientConstLiterals.ts, 0, 14))
1111
}
1212

13-
enum E { A, B, C }
13+
enum E { A, B, C, "non identifier" }
1414
>E : Symbol(E, Decl(ambientConstLiterals.ts, 2, 1))
1515
>A : Symbol(E.A, Decl(ambientConstLiterals.ts, 4, 8))
1616
>B : Symbol(E.B, Decl(ambientConstLiterals.ts, 4, 11))
1717
>C : Symbol(E.C, Decl(ambientConstLiterals.ts, 4, 14))
18+
>"non identifier" : Symbol(E["non identifier"], Decl(ambientConstLiterals.ts, 4, 17))
1819

1920
const c1 = "abc";
2021
>c1 : Symbol(c1, Decl(ambientConstLiterals.ts, 6, 5))
@@ -47,27 +48,32 @@ const c8 = E.A;
4748
>E : Symbol(E, Decl(ambientConstLiterals.ts, 2, 1))
4849
>A : Symbol(E.A, Decl(ambientConstLiterals.ts, 4, 8))
4950

51+
const c8b = E["non identifier"];
52+
>c8b : Symbol(c8b, Decl(ambientConstLiterals.ts, 14, 5))
53+
>E : Symbol(E, Decl(ambientConstLiterals.ts, 2, 1))
54+
>"non identifier" : Symbol(E["non identifier"], Decl(ambientConstLiterals.ts, 4, 17))
55+
5056
const c9 = { x: "abc" };
51-
>c9 : Symbol(c9, Decl(ambientConstLiterals.ts, 14, 5))
52-
>x : Symbol(x, Decl(ambientConstLiterals.ts, 14, 12))
57+
>c9 : Symbol(c9, Decl(ambientConstLiterals.ts, 15, 5))
58+
>x : Symbol(x, Decl(ambientConstLiterals.ts, 15, 12))
5359

5460
const c10 = [123];
55-
>c10 : Symbol(c10, Decl(ambientConstLiterals.ts, 15, 5))
61+
>c10 : Symbol(c10, Decl(ambientConstLiterals.ts, 16, 5))
5662

5763
const c11 = "abc" + "def";
58-
>c11 : Symbol(c11, Decl(ambientConstLiterals.ts, 16, 5))
64+
>c11 : Symbol(c11, Decl(ambientConstLiterals.ts, 17, 5))
5965

6066
const c12 = 123 + 456;
61-
>c12 : Symbol(c12, Decl(ambientConstLiterals.ts, 17, 5))
67+
>c12 : Symbol(c12, Decl(ambientConstLiterals.ts, 18, 5))
6268

6369
const c13 = Math.random() > 0.5 ? "abc" : "def";
64-
>c13 : Symbol(c13, Decl(ambientConstLiterals.ts, 18, 5))
70+
>c13 : Symbol(c13, Decl(ambientConstLiterals.ts, 19, 5))
6571
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
6672
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
6773
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
6874

6975
const c14 = Math.random() > 0.5 ? 123 : 456;
70-
>c14 : Symbol(c14, Decl(ambientConstLiterals.ts, 19, 5))
76+
>c14 : Symbol(c14, Decl(ambientConstLiterals.ts, 20, 5))
7177
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
7278
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
7379
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))

tests/baselines/reference/ambientConstLiterals.types

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ function f<T>(x: T): T {
77
>x : T
88
}
99

10-
enum E { A, B, C }
10+
enum E { A, B, C, "non identifier" }
1111
>E : E
1212
>A : E.A
1313
>B : E.B
1414
>C : E.C
15+
>"non identifier" : E.non identifier
1516

1617
const c1 = "abc";
1718
>c1 : "abc"
@@ -52,6 +53,12 @@ const c8 = E.A;
5253
>E : typeof E
5354
>A : E.A
5455

56+
const c8b = E["non identifier"];
57+
>c8b : E.non identifier
58+
>E["non identifier"] : E.non identifier
59+
>E : typeof E
60+
>"non identifier" : "non identifier"
61+
5562
const c9 = { x: "abc" };
5663
>c9 : { x: string; }
5764
>{ x: "abc" } : { x: string; }

tests/baselines/reference/ambientEnum1.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
>E1 : E1
44

55
y = 4.23
6-
>y : E1
6+
>y : E1.y
77
>4.23 : 4.23
88
}
99

tests/baselines/reference/ambientEnumElementInitializer1.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ declare enum E {
33
>E : E
44

55
e = 3
6-
>e : E
6+
>e : E.e
77
>3 : 3
88
}

tests/baselines/reference/ambientEnumElementInitializer2.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ declare enum E {
33
>E : E
44

55
e = -3 // Negative
6-
>e : E
6+
>e : E.e
77
>-3 : -3
88
>3 : 3
99
}

tests/baselines/reference/ambientEnumElementInitializer3.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ declare enum E {
33
>E : E
44

55
e = 3.3 // Decimal
6-
>e : E
6+
>e : E.e
77
>3.3 : 3.3
88
}

tests/baselines/reference/ambientEnumElementInitializer4.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ declare enum E {
33
>E : E
44

55
e = 0xA
6-
>e : E
6+
>e : E.e
77
>0xA : 10
88
}

tests/baselines/reference/ambientEnumElementInitializer5.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ declare enum E {
33
>E : E
44

55
e = -0xA
6-
>e : E
6+
>e : E.e
77
>-0xA : -10
88
>0xA : 10
99
}

tests/baselines/reference/ambientEnumElementInitializer6.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ declare module M {
66
>E : E
77

88
e = 3
9-
>e : E
9+
>e : E.e
1010
>3 : 3
1111
}
1212
}

tests/baselines/reference/ambientErrors.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ declare enum E1 {
4646
>E1 : E1
4747

4848
y = 4.23
49-
>y : E1
49+
>y : E1.y
5050
>4.23 : 4.23
5151
}
5252

tests/baselines/reference/anyAssignabilityInInheritance.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ var r3 = foo3(a); // any
199199

200200
enum E { A }
201201
>E : E
202-
>A : E
202+
>A : E.A
203203

204204
declare function foo14(x: E): E;
205205
>foo14 : { (x: E): E; (x: any): any; }

tests/baselines/reference/anyAssignableToEveryType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var ai: I;
2020

2121
enum E { A }
2222
>E : E
23-
>A : E
23+
>A : E.A
2424

2525
var ae: E;
2626
>ae : E

tests/baselines/reference/anyAssignableToEveryType2.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ interface I13 {
129129

130130
enum E { A }
131131
>E : E
132-
>A : E
132+
>A : E.A
133133

134134
interface I14 {
135135
[x: string]: E;

tests/baselines/reference/assignAnyToEveryType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ enum E {
4242
>E : E
4343

4444
A
45-
>A : E
45+
>A : E.A
4646
}
4747

4848
var g: E = x;

tests/baselines/reference/assignEveryTypeToAny.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ enum E {
7676
>E : E
7777

7878
A
79-
>A : E
79+
>A : E.A
8080
}
8181

8282
x = E.A;

tests/baselines/reference/assignmentToParenthesizedIdentifiers.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ enum E {
294294
>E : E
295295

296296
A
297-
>A : E
297+
>A : E.A
298298
}
299299
E = undefined; // Error
300300
>E = undefined : undefined

tests/baselines/reference/assignments.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ C = null; // Error
2424

2525
enum E { A }
2626
>E : E
27-
>A : E
27+
>A : E.A
2828

2929
E = null; // Error
3030
>E = null : null

tests/baselines/reference/asyncEnum_es5.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ async enum E {
33
>E : E
44

55
Value
6-
>Value : E
6+
>Value : E.Value
77
}

tests/baselines/reference/asyncEnum_es6.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ async enum E {
33
>E : E
44

55
Value
6-
>Value : E
6+
>Value : E.Value
77
}

tests/baselines/reference/augmentedTypesClass.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ class c4 { public foo() { } }
1515

1616
enum c4 { One } // error
1717
>c4 : c4
18-
>One : c4
18+
>One : c4.One
1919

tests/baselines/reference/augmentedTypesClass2.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class c33 {
3232
}
3333
enum c33 { One };
3434
>c33 : c33
35-
>One : c33
35+
>One : c33.One
3636

3737
// class then import
3838
class c44 {

0 commit comments

Comments
 (0)