From 03123fe433ff220f6d5ac73b15b9d76ae4fbdc00 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 12 Feb 2019 22:25:43 -0800 Subject: [PATCH] Add try priors as finally lock label andecedents rather than pre finally label antecedents (#29790) (#29887) --- src/compiler/binder.ts | 8 +++- .../controlFlowFinallyNoCatchAssignments.js | 33 +++++++++++++ ...ntrolFlowFinallyNoCatchAssignments.symbols | 38 +++++++++++++++ ...controlFlowFinallyNoCatchAssignments.types | 46 +++++++++++++++++++ .../controlFlowFinallyNoCatchAssignments.ts | 15 ++++++ 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/controlFlowFinallyNoCatchAssignments.js create mode 100644 tests/baselines/reference/controlFlowFinallyNoCatchAssignments.symbols create mode 100644 tests/baselines/reference/controlFlowFinallyNoCatchAssignments.types create mode 100644 tests/cases/compiler/controlFlowFinallyNoCatchAssignments.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 27f85896a3b..457502f4c14 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1120,11 +1120,15 @@ namespace ts { // We add the nodes within the `try` block to the `finally`'s antecedents if there's no catch block // (If there is a `catch` block, it will have all these antecedents instead, and the `finally` will // have the end of the `try` block and the end of the `catch` block) + let preFinallyPrior = preTryFlow; if (!node.catchClause) { if (tryPriors.length) { + const preFinallyFlow = createBranchLabel(); + addAntecedent(preFinallyFlow, preTryFlow); for (const p of tryPriors) { - addAntecedent(preFinallyLabel, p); + addAntecedent(preFinallyFlow, p); } + preFinallyPrior = finishFlowLabel(preFinallyFlow); } } @@ -1156,7 +1160,7 @@ namespace ts { // // extra edges that we inject allows to control this behavior // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped. - const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preTryFlow, lock: {} }; + const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preFinallyPrior, lock: {} }; addAntecedent(preFinallyLabel, preFinallyFlow); currentFlow = finishFlowLabel(preFinallyLabel); diff --git a/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.js b/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.js new file mode 100644 index 00000000000..3821fd1b278 --- /dev/null +++ b/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.js @@ -0,0 +1,33 @@ +//// [controlFlowFinallyNoCatchAssignments.ts] +let x: number; +x = Math.random(); +let a: number; +try { + if (x) { + a = 1; + } else { + a = 2; + } +} finally { + console.log(x); +} + +console.log(a); // <- error here + +//// [controlFlowFinallyNoCatchAssignments.js] +"use strict"; +var x; +x = Math.random(); +var a; +try { + if (x) { + a = 1; + } + else { + a = 2; + } +} +finally { + console.log(x); +} +console.log(a); // <- error here diff --git a/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.symbols b/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.symbols new file mode 100644 index 00000000000..f66f3bbe4b7 --- /dev/null +++ b/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/controlFlowFinallyNoCatchAssignments.ts === +let x: number; +>x : Symbol(x, Decl(controlFlowFinallyNoCatchAssignments.ts, 0, 3)) + +x = Math.random(); +>x : Symbol(x, Decl(controlFlowFinallyNoCatchAssignments.ts, 0, 3)) +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + +let a: number; +>a : Symbol(a, Decl(controlFlowFinallyNoCatchAssignments.ts, 2, 3)) + +try { + if (x) { +>x : Symbol(x, Decl(controlFlowFinallyNoCatchAssignments.ts, 0, 3)) + + a = 1; +>a : Symbol(a, Decl(controlFlowFinallyNoCatchAssignments.ts, 2, 3)) + + } else { + a = 2; +>a : Symbol(a, Decl(controlFlowFinallyNoCatchAssignments.ts, 2, 3)) + } +} finally { + console.log(x); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>x : Symbol(x, Decl(controlFlowFinallyNoCatchAssignments.ts, 0, 3)) +} + +console.log(a); // <- error here +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(controlFlowFinallyNoCatchAssignments.ts, 2, 3)) + diff --git a/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.types b/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.types new file mode 100644 index 00000000000..7199969d6c3 --- /dev/null +++ b/tests/baselines/reference/controlFlowFinallyNoCatchAssignments.types @@ -0,0 +1,46 @@ +=== tests/cases/compiler/controlFlowFinallyNoCatchAssignments.ts === +let x: number; +>x : number + +x = Math.random(); +>x = Math.random() : number +>x : number +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number + +let a: number; +>a : number + +try { + if (x) { +>x : number + + a = 1; +>a = 1 : 1 +>a : number +>1 : 1 + + } else { + a = 2; +>a = 2 : 2 +>a : number +>2 : 2 + } +} finally { + console.log(x); +>console.log(x) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>x : number +} + +console.log(a); // <- error here +>console.log(a) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>a : number + diff --git a/tests/cases/compiler/controlFlowFinallyNoCatchAssignments.ts b/tests/cases/compiler/controlFlowFinallyNoCatchAssignments.ts new file mode 100644 index 00000000000..7f8201ade14 --- /dev/null +++ b/tests/cases/compiler/controlFlowFinallyNoCatchAssignments.ts @@ -0,0 +1,15 @@ +// @strict: true +let x: number; +x = Math.random(); +let a: number; +try { + if (x) { + a = 1; + } else { + a = 2; + } +} finally { + console.log(x); +} + +console.log(a); // <- error here \ No newline at end of file