Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2af62a9

Browse files
committed
Error for more than one enum omitting an initial initializer
1 parent 17563f3 commit 2af62a9

11 files changed

+150
-7
lines changed

src/compiler/checker.ts

+34-2
Original file line numberDiff line numberDiff line change
@@ -5260,7 +5260,8 @@ module ts {
52605260
function checkEnumDeclaration(node: EnumDeclaration) {
52615261
checkDeclarationModifiers(node);
52625262
checkNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
5263-
var enumType = getDeclaredTypeOfSymbol(getSymbolOfNode(node));
5263+
var enumSymbol = getSymbolOfNode(node);
5264+
var enumType = getDeclaredTypeOfSymbol(enumSymbol);
52645265
var autoValue = 0;
52655266
var ambient = isInAmbientContext(node);
52665267
forEach(node.members, member => {
@@ -5283,7 +5284,38 @@ module ts {
52835284
getNodeLinks(member).enumMemberValue = autoValue++;
52845285
}
52855286
});
5286-
// TODO: Only one enum declaration can omit the initial value
5287+
5288+
// Spec 2014 - Section 9.3:
5289+
// It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
5290+
// and when an enum type has multiple declarations, only one declaration is permitted to omit a value
5291+
// for the first member.
5292+
//
5293+
// Only perform this check once per symbol
5294+
var firstDeclaration = getDeclarationOfKind(enumSymbol, node.kind);
5295+
if (node === firstDeclaration) {
5296+
var seenEnumMissingInitialInitializer = false;
5297+
forEach(enumSymbol.declarations, declaration => {
5298+
// return true if we hit a violation of the rule, false otherwise
5299+
if (declaration.kind !== SyntaxKind.EnumDeclaration) {
5300+
return false;
5301+
}
5302+
5303+
var enumDeclaration = <EnumDeclaration>declaration;
5304+
if (!enumDeclaration.members.length) {
5305+
return false;
5306+
}
5307+
5308+
var firstEnumMember = enumDeclaration.members[0];
5309+
if (!firstEnumMember.initializer) {
5310+
if (seenEnumMissingInitialInitializer) {
5311+
error(firstEnumMember.name, Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
5312+
}
5313+
else {
5314+
seenEnumMissingInitialInitializer = true;
5315+
}
5316+
}
5317+
});
5318+
}
52875319
}
52885320

52895321
function checkModuleDeclaration(node: ModuleDeclaration) {

src/compiler/diagnosticInformationMap.generated.ts

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ module ts {
191191
Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 4017, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function." },
192192
Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: { code: 4018, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor." },
193193
Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: { code: 4019, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property." },
194+
In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: { code: 4024, category: DiagnosticCategory.Error, key: "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element." },
194195
Named_properties_0_of_types_1_and_2_are_not_identical: { code: 4032, category: DiagnosticCategory.NoPrefix, key: "Named properties '{0}' of types '{1}' and '{2}' are not identical." },
195196
Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: DiagnosticCategory.Error, key: "Cannot find the common subdirectory path for the input files." },
196197
Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" },

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,10 @@
761761
"category": "NoPrefix",
762762
"code": 4019
763763
},
764+
"In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.": {
765+
"category": "Error",
766+
"code": 4024
767+
},
764768
"Named properties '{0}' of types '{1}' and '{2}' are not identical.": {
765769
"category": "NoPrefix",
766770
"code": 4032

tests/baselines/reference/augmentedTypesEnum.errors.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
==== tests/cases/compiler/augmentedTypesEnum.ts (5 errors) ====
1+
==== tests/cases/compiler/augmentedTypesEnum.ts (7 errors) ====
22
// enum then var
33
enum e1111 { One }
44
var e1111 = 1; // error
@@ -25,11 +25,15 @@
2525
// enum then enum
2626
enum e5 { One }
2727
enum e5 { Two }
28+
~~~
29+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
2830

2931
enum e5a { One }
3032
enum e5a { One } // error
3133
~~~
3234
!!! Duplicate identifier 'One'.
35+
~~~
36+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
3337

3438
// enum then internal module
3539
enum e6 { One }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
==== tests/cases/compiler/augmentedTypesEnum3.ts (1 errors) ====
2+
module E {
3+
var t;
4+
}
5+
enum E { }
6+
7+
enum F { }
8+
module F { var t; }
9+
10+
module A {
11+
var o;
12+
}
13+
enum A {
14+
b
15+
}
16+
enum A {
17+
c
18+
~
19+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
20+
}
21+
module A {
22+
var p;
23+
}

tests/baselines/reference/enumBasics1.errors.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
==== tests/cases/compiler/enumBasics1.ts (1 errors) ====
1+
==== tests/cases/compiler/enumBasics1.ts (2 errors) ====
22
enum E {
33
A = 1,
44
B,
@@ -34,7 +34,9 @@
3434
B,
3535
}
3636

37-
enum E2 { // shouldn't error
37+
enum E2 { // should error for continued autonumbering
3838
C,
39+
~
40+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
3941
D,
4042
}

tests/baselines/reference/enumBasics1.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ enum E2 {
3232
B,
3333
}
3434

35-
enum E2 { // shouldn't error
35+
enum E2 { // should error for continued autonumbering
3636
C,
3737
D,
3838
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
==== tests/cases/conformance/enums/enumMergingErrors.ts (2 errors) ====
2+
// Enum with constant, computed, constant members split across 3 declarations with the same root module
3+
module M {
4+
export enum E1 { A = 0 }
5+
export enum E2 { C }
6+
export enum E3 { A = 0 }
7+
}
8+
module M {
9+
export enum E1 { B = 'foo'.length }
10+
export enum E2 { B = 'foo'.length }
11+
export enum E3 { C }
12+
}
13+
module M {
14+
export enum E1 { C }
15+
export enum E2 { A = 0 }
16+
export enum E3 { B = 'foo'.length }
17+
}
18+
19+
// Enum with no initializer in either declaration with constant members with the same root module
20+
module M1 {
21+
export enum E1 { A = 0 }
22+
}
23+
module M1 {
24+
export enum E1 { B }
25+
}
26+
module M1 {
27+
export enum E1 { C }
28+
~
29+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
30+
}
31+
32+
33+
// Enum with initializer in only one of three declarations with constant members with the same root module
34+
module M2 {
35+
export enum E1 { A }
36+
}
37+
module M2 {
38+
export enum E1 { B = 0 }
39+
}
40+
module M2 {
41+
export enum E1 { C }
42+
~
43+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
44+
}
45+
46+
47+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
==== tests/cases/compiler/enumsWithMultipleDeclarations1.ts (2 errors) ====
2+
enum E {
3+
A
4+
}
5+
6+
enum E {
7+
B
8+
~
9+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
10+
}
11+
12+
enum E {
13+
C
14+
~
15+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
==== tests/cases/compiler/enumsWithMultipleDeclarations2.ts (1 errors) ====
2+
enum E {
3+
A
4+
}
5+
6+
enum E {
7+
B = 1
8+
}
9+
10+
enum E {
11+
C
12+
~
13+
!!! In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
14+
}

tests/cases/compiler/enumBasics1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ enum E2 {
3131
B,
3232
}
3333

34-
enum E2 { // shouldn't error
34+
enum E2 { // should error for continued autonumbering
3535
C,
3636
D,
3737
}

0 commit comments

Comments
 (0)