From 568e2aab58395cc70161eec9e7111045694b269a Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 1 Mar 2016 15:58:59 -0800 Subject: [PATCH] allow fallthrough from the last case of the switch --- src/compiler/binder.ts | 8 ++- .../baselines/reference/fallFromLastCase1.js | 44 +++++++++++++++ .../reference/fallFromLastCase1.symbols | 42 ++++++++++++++ .../reference/fallFromLastCase1.types | 56 +++++++++++++++++++ .../reference/fallFromLastCase2.errors.txt | 36 ++++++++++++ .../baselines/reference/fallFromLastCase2.js | 52 +++++++++++++++++ tests/cases/compiler/fallFromLastCase1.ts | 24 ++++++++ tests/cases/compiler/fallFromLastCase2.ts | 28 ++++++++++ 8 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/fallFromLastCase1.js create mode 100644 tests/baselines/reference/fallFromLastCase1.symbols create mode 100644 tests/baselines/reference/fallFromLastCase1.types create mode 100644 tests/baselines/reference/fallFromLastCase2.errors.txt create mode 100644 tests/baselines/reference/fallFromLastCase2.js create mode 100644 tests/cases/compiler/fallFromLastCase1.ts create mode 100644 tests/cases/compiler/fallFromLastCase2.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1f19d01b9cb..504de084fb9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -708,10 +708,14 @@ namespace ts { function bindCaseBlock(n: CaseBlock): void { const startState = currentReachabilityState; - for (const clause of n.clauses) { + for (let i = 0; i < n.clauses.length; i++) { + const clause = n.clauses[i]; currentReachabilityState = startState; bind(clause); - if (clause.statements.length && currentReachabilityState === Reachability.Reachable && options.noFallthroughCasesInSwitch) { + if (clause.statements.length && + i !== n.clauses.length - 1 && // allow fallthrough from the last case + currentReachabilityState === Reachability.Reachable && + options.noFallthroughCasesInSwitch) { errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch); } } diff --git a/tests/baselines/reference/fallFromLastCase1.js b/tests/baselines/reference/fallFromLastCase1.js new file mode 100644 index 00000000000..3c2461db514 --- /dev/null +++ b/tests/baselines/reference/fallFromLastCase1.js @@ -0,0 +1,44 @@ +//// [fallFromLastCase1.ts] + +declare function use(a: string); + +function foo1(a: number) { + switch (a) { + case 1: + use("1"); + break; + case 2: + use("2"); + } +} + + +function foo2(a: number) { + switch (a) { + case 1: + use("1"); + break; + default: + use("2"); + } +} + +//// [fallFromLastCase1.js] +function foo1(a) { + switch (a) { + case 1: + use("1"); + break; + case 2: + use("2"); + } +} +function foo2(a) { + switch (a) { + case 1: + use("1"); + break; + default: + use("2"); + } +} diff --git a/tests/baselines/reference/fallFromLastCase1.symbols b/tests/baselines/reference/fallFromLastCase1.symbols new file mode 100644 index 00000000000..c4967e5e775 --- /dev/null +++ b/tests/baselines/reference/fallFromLastCase1.symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/fallFromLastCase1.ts === + +declare function use(a: string); +>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0)) +>a : Symbol(a, Decl(fallFromLastCase1.ts, 1, 21)) + +function foo1(a: number) { +>foo1 : Symbol(foo1, Decl(fallFromLastCase1.ts, 1, 32)) +>a : Symbol(a, Decl(fallFromLastCase1.ts, 3, 14)) + + switch (a) { +>a : Symbol(a, Decl(fallFromLastCase1.ts, 3, 14)) + + case 1: + use("1"); +>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0)) + + break; + case 2: + use("2"); +>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0)) + } +} + + +function foo2(a: number) { +>foo2 : Symbol(foo2, Decl(fallFromLastCase1.ts, 11, 1)) +>a : Symbol(a, Decl(fallFromLastCase1.ts, 14, 14)) + + switch (a) { +>a : Symbol(a, Decl(fallFromLastCase1.ts, 14, 14)) + + case 1: + use("1"); +>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0)) + + break; + default: + use("2"); +>use : Symbol(use, Decl(fallFromLastCase1.ts, 0, 0)) + } +} diff --git a/tests/baselines/reference/fallFromLastCase1.types b/tests/baselines/reference/fallFromLastCase1.types new file mode 100644 index 00000000000..47e444ee17d --- /dev/null +++ b/tests/baselines/reference/fallFromLastCase1.types @@ -0,0 +1,56 @@ +=== tests/cases/compiler/fallFromLastCase1.ts === + +declare function use(a: string); +>use : (a: string) => any +>a : string + +function foo1(a: number) { +>foo1 : (a: number) => void +>a : number + + switch (a) { +>a : number + + case 1: +>1 : number + + use("1"); +>use("1") : any +>use : (a: string) => any +>"1" : string + + break; + case 2: +>2 : number + + use("2"); +>use("2") : any +>use : (a: string) => any +>"2" : string + } +} + + +function foo2(a: number) { +>foo2 : (a: number) => void +>a : number + + switch (a) { +>a : number + + case 1: +>1 : number + + use("1"); +>use("1") : any +>use : (a: string) => any +>"1" : string + + break; + default: + use("2"); +>use("2") : any +>use : (a: string) => any +>"2" : string + } +} diff --git a/tests/baselines/reference/fallFromLastCase2.errors.txt b/tests/baselines/reference/fallFromLastCase2.errors.txt new file mode 100644 index 00000000000..ccf7f6ebc1b --- /dev/null +++ b/tests/baselines/reference/fallFromLastCase2.errors.txt @@ -0,0 +1,36 @@ +tests/cases/compiler/fallFromLastCase2.ts(9,9): error TS7029: Fallthrough case in switch. +tests/cases/compiler/fallFromLastCase2.ts(22,9): error TS7029: Fallthrough case in switch. + + +==== tests/cases/compiler/fallFromLastCase2.ts (2 errors) ==== + + declare function use(a: string); + + function foo1(a: number) { + switch (a) { + case 1: + use("1"); + break; + case 2: + ~~~~ +!!! error TS7029: Fallthrough case in switch. + use("2"); + case 3: + use("3"); + } + } + + + function foo2(a: number) { + switch (a) { + case 1: + use("1"); + break; + default: + ~~~~~~~ +!!! error TS7029: Fallthrough case in switch. + use("2"); + case 2: + use("3"); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/fallFromLastCase2.js b/tests/baselines/reference/fallFromLastCase2.js new file mode 100644 index 00000000000..fd1d7c20d07 --- /dev/null +++ b/tests/baselines/reference/fallFromLastCase2.js @@ -0,0 +1,52 @@ +//// [fallFromLastCase2.ts] + +declare function use(a: string); + +function foo1(a: number) { + switch (a) { + case 1: + use("1"); + break; + case 2: + use("2"); + case 3: + use("3"); + } +} + + +function foo2(a: number) { + switch (a) { + case 1: + use("1"); + break; + default: + use("2"); + case 2: + use("3"); + } +} + +//// [fallFromLastCase2.js] +function foo1(a) { + switch (a) { + case 1: + use("1"); + break; + case 2: + use("2"); + case 3: + use("3"); + } +} +function foo2(a) { + switch (a) { + case 1: + use("1"); + break; + default: + use("2"); + case 2: + use("3"); + } +} diff --git a/tests/cases/compiler/fallFromLastCase1.ts b/tests/cases/compiler/fallFromLastCase1.ts new file mode 100644 index 00000000000..d8037c61a96 --- /dev/null +++ b/tests/cases/compiler/fallFromLastCase1.ts @@ -0,0 +1,24 @@ +// @noFallthroughCasesInSwitch: true + +declare function use(a: string); + +function foo1(a: number) { + switch (a) { + case 1: + use("1"); + break; + case 2: + use("2"); + } +} + + +function foo2(a: number) { + switch (a) { + case 1: + use("1"); + break; + default: + use("2"); + } +} \ No newline at end of file diff --git a/tests/cases/compiler/fallFromLastCase2.ts b/tests/cases/compiler/fallFromLastCase2.ts new file mode 100644 index 00000000000..231d3512dbe --- /dev/null +++ b/tests/cases/compiler/fallFromLastCase2.ts @@ -0,0 +1,28 @@ +// @noFallthroughCasesInSwitch: true + +declare function use(a: string); + +function foo1(a: number) { + switch (a) { + case 1: + use("1"); + break; + case 2: + use("2"); + case 3: + use("3"); + } +} + + +function foo2(a: number) { + switch (a) { + case 1: + use("1"); + break; + default: + use("2"); + case 2: + use("3"); + } +} \ No newline at end of file