Skip to content

Commit b3552c6

Browse files
committed
Merge pull request microsoft#7329 from Microsoft/allowFallFromLastCase
allow fallthrough from the last case of the switch
2 parents fe483a6 + 568e2aa commit b3552c6

File tree

8 files changed

+288
-2
lines changed

8 files changed

+288
-2
lines changed

src/compiler/binder.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,10 +708,14 @@ namespace ts {
708708
function bindCaseBlock(n: CaseBlock): void {
709709
const startState = currentReachabilityState;
710710

711-
for (const clause of n.clauses) {
711+
for (let i = 0; i < n.clauses.length; i++) {
712+
const clause = n.clauses[i];
712713
currentReachabilityState = startState;
713714
bind(clause);
714-
if (clause.statements.length && currentReachabilityState === Reachability.Reachable && options.noFallthroughCasesInSwitch) {
715+
if (clause.statements.length &&
716+
i !== n.clauses.length - 1 && // allow fallthrough from the last case
717+
currentReachabilityState === Reachability.Reachable &&
718+
options.noFallthroughCasesInSwitch) {
715719
errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch);
716720
}
717721
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [fallFromLastCase1.ts]
2+
3+
declare function use(a: string);
4+
5+
function foo1(a: number) {
6+
switch (a) {
7+
case 1:
8+
use("1");
9+
break;
10+
case 2:
11+
use("2");
12+
}
13+
}
14+
15+
16+
function foo2(a: number) {
17+
switch (a) {
18+
case 1:
19+
use("1");
20+
break;
21+
default:
22+
use("2");
23+
}
24+
}
25+
26+
//// [fallFromLastCase1.js]
27+
function foo1(a) {
28+
switch (a) {
29+
case 1:
30+
use("1");
31+
break;
32+
case 2:
33+
use("2");
34+
}
35+
}
36+
function foo2(a) {
37+
switch (a) {
38+
case 1:
39+
use("1");
40+
break;
41+
default:
42+
use("2");
43+
}
44+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
=== tests/cases/compiler/fallFromLastCase1.ts ===
2+
3+
declare function use(a: string);
4+
>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0))
5+
>a : Symbol(a, Decl(fallFromLastCase1.ts, 1, 21))
6+
7+
function foo1(a: number) {
8+
>foo1 : Symbol(foo1, Decl(fallFromLastCase1.ts, 1, 32))
9+
>a : Symbol(a, Decl(fallFromLastCase1.ts, 3, 14))
10+
11+
switch (a) {
12+
>a : Symbol(a, Decl(fallFromLastCase1.ts, 3, 14))
13+
14+
case 1:
15+
use("1");
16+
>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0))
17+
18+
break;
19+
case 2:
20+
use("2");
21+
>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0))
22+
}
23+
}
24+
25+
26+
function foo2(a: number) {
27+
>foo2 : Symbol(foo2, Decl(fallFromLastCase1.ts, 11, 1))
28+
>a : Symbol(a, Decl(fallFromLastCase1.ts, 14, 14))
29+
30+
switch (a) {
31+
>a : Symbol(a, Decl(fallFromLastCase1.ts, 14, 14))
32+
33+
case 1:
34+
use("1");
35+
>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0))
36+
37+
break;
38+
default:
39+
use("2");
40+
>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0))
41+
}
42+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
=== tests/cases/compiler/fallFromLastCase1.ts ===
2+
3+
declare function use(a: string);
4+
>use : (a: string) => any
5+
>a : string
6+
7+
function foo1(a: number) {
8+
>foo1 : (a: number) => void
9+
>a : number
10+
11+
switch (a) {
12+
>a : number
13+
14+
case 1:
15+
>1 : number
16+
17+
use("1");
18+
>use("1") : any
19+
>use : (a: string) => any
20+
>"1" : string
21+
22+
break;
23+
case 2:
24+
>2 : number
25+
26+
use("2");
27+
>use("2") : any
28+
>use : (a: string) => any
29+
>"2" : string
30+
}
31+
}
32+
33+
34+
function foo2(a: number) {
35+
>foo2 : (a: number) => void
36+
>a : number
37+
38+
switch (a) {
39+
>a : number
40+
41+
case 1:
42+
>1 : number
43+
44+
use("1");
45+
>use("1") : any
46+
>use : (a: string) => any
47+
>"1" : string
48+
49+
break;
50+
default:
51+
use("2");
52+
>use("2") : any
53+
>use : (a: string) => any
54+
>"2" : string
55+
}
56+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
tests/cases/compiler/fallFromLastCase2.ts(9,9): error TS7029: Fallthrough case in switch.
2+
tests/cases/compiler/fallFromLastCase2.ts(22,9): error TS7029: Fallthrough case in switch.
3+
4+
5+
==== tests/cases/compiler/fallFromLastCase2.ts (2 errors) ====
6+
7+
declare function use(a: string);
8+
9+
function foo1(a: number) {
10+
switch (a) {
11+
case 1:
12+
use("1");
13+
break;
14+
case 2:
15+
~~~~
16+
!!! error TS7029: Fallthrough case in switch.
17+
use("2");
18+
case 3:
19+
use("3");
20+
}
21+
}
22+
23+
24+
function foo2(a: number) {
25+
switch (a) {
26+
case 1:
27+
use("1");
28+
break;
29+
default:
30+
~~~~~~~
31+
!!! error TS7029: Fallthrough case in switch.
32+
use("2");
33+
case 2:
34+
use("3");
35+
}
36+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//// [fallFromLastCase2.ts]
2+
3+
declare function use(a: string);
4+
5+
function foo1(a: number) {
6+
switch (a) {
7+
case 1:
8+
use("1");
9+
break;
10+
case 2:
11+
use("2");
12+
case 3:
13+
use("3");
14+
}
15+
}
16+
17+
18+
function foo2(a: number) {
19+
switch (a) {
20+
case 1:
21+
use("1");
22+
break;
23+
default:
24+
use("2");
25+
case 2:
26+
use("3");
27+
}
28+
}
29+
30+
//// [fallFromLastCase2.js]
31+
function foo1(a) {
32+
switch (a) {
33+
case 1:
34+
use("1");
35+
break;
36+
case 2:
37+
use("2");
38+
case 3:
39+
use("3");
40+
}
41+
}
42+
function foo2(a) {
43+
switch (a) {
44+
case 1:
45+
use("1");
46+
break;
47+
default:
48+
use("2");
49+
case 2:
50+
use("3");
51+
}
52+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// @noFallthroughCasesInSwitch: true
2+
3+
declare function use(a: string);
4+
5+
function foo1(a: number) {
6+
switch (a) {
7+
case 1:
8+
use("1");
9+
break;
10+
case 2:
11+
use("2");
12+
}
13+
}
14+
15+
16+
function foo2(a: number) {
17+
switch (a) {
18+
case 1:
19+
use("1");
20+
break;
21+
default:
22+
use("2");
23+
}
24+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @noFallthroughCasesInSwitch: true
2+
3+
declare function use(a: string);
4+
5+
function foo1(a: number) {
6+
switch (a) {
7+
case 1:
8+
use("1");
9+
break;
10+
case 2:
11+
use("2");
12+
case 3:
13+
use("3");
14+
}
15+
}
16+
17+
18+
function foo2(a: number) {
19+
switch (a) {
20+
case 1:
21+
use("1");
22+
break;
23+
default:
24+
use("2");
25+
case 2:
26+
use("3");
27+
}
28+
}

0 commit comments

Comments
 (0)