Skip to content

Commit 4ac676f

Browse files
Added checking for switch statements with multiple default clauses.
1 parent c3624c9 commit 4ac676f

File tree

6 files changed

+87
-6
lines changed

6 files changed

+87
-6
lines changed

src/compiler/core.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ module ts {
1919
if (array) {
2020
var len = array.length;
2121
for (var i = 0; i < len; i++) {
22-
if (array[i] === value) return true;
22+
if (array[i] === value) {
23+
return true;
24+
}
2325
}
2426
}
2527
return false;
@@ -29,7 +31,9 @@ module ts {
2931
if (array) {
3032
var len = array.length;
3133
for (var i = 0; i < len; i++) {
32-
if (array[i] === value) return i;
34+
if (array[i] === value) {
35+
return i;
36+
}
3337
}
3438
}
3539
return -1;
@@ -41,7 +45,9 @@ module ts {
4145
result = [];
4246
for (var i = 0, len = array.length; i < len; i++) {
4347
var item = array[i];
44-
if (f(item)) result.push(item);
48+
if (f(item)) {
49+
result.push(item);
50+
}
4551
}
4652
}
4753
return result;

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ module ts {
9898
Type_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Type expected." },
9999
A_constructor_implementation_cannot_be_declared_in_an_ambient_context: { code: 1111, category: DiagnosticCategory.Error, key: "A constructor implementation cannot be declared in an ambient context." },
100100
A_class_member_cannot_be_declared_optional: { code: 1112, category: DiagnosticCategory.Error, key: "A class member cannot be declared optional." },
101+
A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: { code: 1113, category: DiagnosticCategory.Error, key: "A 'default' clause cannot appear more than once in a 'switch' statement." },
101102
Duplicate_identifier_0: { code: 2000, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
102103
new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 2068, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
103104
Multiple_constructor_implementations_are_not_allowed: { code: 2070, category: DiagnosticCategory.Error, key: "Multiple constructor implementations are not allowed." },

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,10 @@
384384
"category": "Error",
385385
"code": 1112
386386
},
387-
387+
"A 'default' clause cannot appear more than once in a 'switch' statement.": {
388+
"category": "Error",
389+
"code": 1113
390+
},
388391

389392
"Duplicate identifier '{0}'.": {
390393
"category": "Error",

src/compiler/parser.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ module ts {
766766
return false;
767767
}
768768

769-
// Parses a list of elements
769+
// Parses a semicolon-delimited list of elements
770770
function parseList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
771771
var saveParsingContext = parsingContext;
772772
parsingContext |= 1 << kind;
@@ -789,7 +789,7 @@ module ts {
789789
return result;
790790
}
791791

792-
// Parses a comma delimited list of elements
792+
// Parses a comma-delimited list of elements
793793
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, trailingCommaBehavior: TrailingCommaBehavior): NodeArray<T> {
794794
var saveParsingContext = parsingContext;
795795
parsingContext |= 1 << kind;
@@ -2063,6 +2063,13 @@ module ts {
20632063
parseExpected(SyntaxKind.OpenBraceToken);
20642064
node.clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause);
20652065
parseExpected(SyntaxKind.CloseBraceToken);
2066+
2067+
// Error on duplicate 'default' clauses.
2068+
var defaultClauses = filter(node.clauses, clause => clause.kind === SyntaxKind.DefaultClause);
2069+
for (var i = 1, len = defaultClauses.length; i < len; i++) {
2070+
grammarErrorOnNode(defaultClauses[i], Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
2071+
}
2072+
20662073
return finishNode(node);
20672074
}
20682075

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
==== tests/cases/compiler/switchStatementsWithMultipleDefaults.ts (4 errors) ====
2+
3+
var x = 10;
4+
5+
switch (x) {
6+
case 1:
7+
case 2:
8+
default: // No issues.
9+
break;
10+
default: // Error; second 'default' clause.
11+
~~~~~~~~
12+
!!! A 'default' clause cannot appear more than once in a 'switch' statement.
13+
default: // Error; third 'default' clause.
14+
~~~~~~~~
15+
!!! A 'default' clause cannot appear more than once in a 'switch' statement.
16+
case 3:
17+
x *= x;
18+
}
19+
20+
switch (x) {
21+
default: // No issues.
22+
break;
23+
case 100:
24+
switch (x * x) {
25+
default: // No issues.
26+
default: // Error; second 'default' clause.
27+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28+
break;
29+
~~~~~~~~~~~~~~~~~~~~~~
30+
!!! A 'default' clause cannot appear more than once in a 'switch' statement.
31+
case 10000:
32+
x /= x;
33+
default:
34+
~~~~~~~~
35+
!!! A 'default' clause cannot appear more than once in a 'switch' statement.
36+
}
37+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
var x = 10;
3+
4+
switch (x) {
5+
case 1:
6+
case 2:
7+
default: // No issues.
8+
break;
9+
default: // Error; second 'default' clause.
10+
default: // Error; third 'default' clause.
11+
case 3:
12+
x *= x;
13+
}
14+
15+
switch (x) {
16+
default: // No issues.
17+
break;
18+
case 100:
19+
switch (x * x) {
20+
default: // No issues.
21+
default: // Error; second 'default' clause.
22+
break;
23+
case 10000:
24+
x /= x;
25+
default:
26+
}
27+
}

0 commit comments

Comments
 (0)