From 4d1e897588816223fc3a9c831ca192e9c2cf69a0 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Sun, 20 Oct 2019 14:32:34 +0200 Subject: [PATCH] Handle conditional breaks in do-while loops with unconditional return --- src/ast/nodes/DoWhileStatement.ts | 14 ++---- .../_config.js | 3 -- .../_expected.js | 15 ------ .../break-statement-labels-do-while/main.js | 47 ------------------- .../loop-errors/_expected.js | 5 ++ .../break-control-flow/loop-errors/main.js | 6 ++- .../do-while-conditional-break/_config.js | 3 ++ .../do-while-conditional-break/main.js | 12 +++++ 8 files changed, 28 insertions(+), 77 deletions(-) delete mode 100644 test/form/samples/break-control-flow/break-statement-labels-do-while/_config.js delete mode 100644 test/form/samples/break-control-flow/break-statement-labels-do-while/_expected.js delete mode 100644 test/form/samples/break-control-flow/break-statement-labels-do-while/main.js create mode 100644 test/function/samples/do-while-conditional-break/_config.js create mode 100644 test/function/samples/do-while-conditional-break/main.js diff --git a/src/ast/nodes/DoWhileStatement.ts b/src/ast/nodes/DoWhileStatement.ts index d578895dcf5..d7892889581 100644 --- a/src/ast/nodes/DoWhileStatement.ts +++ b/src/ast/nodes/DoWhileStatement.ts @@ -1,8 +1,4 @@ -import { - BROKEN_FLOW_BREAK_CONTINUE, - HasEffectsContext, - InclusionContext -} from '../ExecutionContext'; +import { HasEffectsContext, InclusionContext } from '../ExecutionContext'; import * as NodeType from './NodeType'; import { ExpressionNode, IncludeChildren, StatementBase, StatementNode } from './shared/Node'; @@ -22,9 +18,7 @@ export default class DoWhileStatement extends StatementBase { if (this.body.hasEffects(context)) return true; context.ignore.breaks = breaks; context.ignore.continues = continues; - if (context.brokenFlow === BROKEN_FLOW_BREAK_CONTINUE) { - context.brokenFlow = brokenFlow; - } + context.brokenFlow = brokenFlow; return false; } @@ -33,8 +27,6 @@ export default class DoWhileStatement extends StatementBase { this.test.include(context, includeChildrenRecursively); const { brokenFlow } = context; this.body.include(context, includeChildrenRecursively); - if (context.brokenFlow === BROKEN_FLOW_BREAK_CONTINUE) { - context.brokenFlow = brokenFlow; - } + context.brokenFlow = brokenFlow; } } diff --git a/test/form/samples/break-control-flow/break-statement-labels-do-while/_config.js b/test/form/samples/break-control-flow/break-statement-labels-do-while/_config.js deleted file mode 100644 index 8b990af0d2f..00000000000 --- a/test/form/samples/break-control-flow/break-statement-labels-do-while/_config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - description: 'supports labels when breaking control flow from a do-while loop' -}; diff --git a/test/form/samples/break-control-flow/break-statement-labels-do-while/_expected.js b/test/form/samples/break-control-flow/break-statement-labels-do-while/_expected.js deleted file mode 100644 index a2119dbc632..00000000000 --- a/test/form/samples/break-control-flow/break-statement-labels-do-while/_expected.js +++ /dev/null @@ -1,15 +0,0 @@ -do { - console.log('retained'); -} while (globalThis.unknown); - -do { - console.log('retained'); -} while (globalThis.unknown); - - do { - console.log('retained'); -} while (globalThis.unknown); - -do { - console.log('retained'); -} while (globalThis.unknown); diff --git a/test/form/samples/break-control-flow/break-statement-labels-do-while/main.js b/test/form/samples/break-control-flow/break-statement-labels-do-while/main.js deleted file mode 100644 index d2862b47745..00000000000 --- a/test/form/samples/break-control-flow/break-statement-labels-do-while/main.js +++ /dev/null @@ -1,47 +0,0 @@ -label: do { - do { - break; - console.log('removed'); - } while (globalThis.unknown); - console.log('retained'); -} while (globalThis.unknown); - -do { - label: do { - break; - console.log('removed'); - } while (globalThis.unknown); - console.log('retained'); -} while (globalThis.unknown); - -label: do { - do { - break label; - console.log('removed'); - } while (globalThis.unknown); - console.log('removed'); -} while (globalThis.unknown); - -label: do { - do { - continue; - console.log('removed'); - } while (globalThis.unknown); - console.log('retained'); -} while (globalThis.unknown); - -do { - label: do { - continue; - console.log('removed'); - } while (globalThis.unknown); - console.log('retained'); -} while (globalThis.unknown); - -label: do { - do { - continue label; - console.log('removed'); - } while (globalThis.unknown); - console.log('removed'); -} while (globalThis.unknown); diff --git a/test/form/samples/break-control-flow/loop-errors/_expected.js b/test/form/samples/break-control-flow/loop-errors/_expected.js index 34484b2f1c7..cfe06058c39 100644 --- a/test/form/samples/break-control-flow/loop-errors/_expected.js +++ b/test/form/samples/break-control-flow/loop-errors/_expected.js @@ -17,8 +17,13 @@ try { function doWhileLoop() { console.log(hoisted); do { + if (globalThis.unknown) { + break; + } throw new Error(); } while (globalThis.unknown); + console.log('retained'); + throw new Error(); do { var hoisted; } while (globalThis.unknown); diff --git a/test/form/samples/break-control-flow/loop-errors/main.js b/test/form/samples/break-control-flow/loop-errors/main.js index b60cfb9ec62..951765e669a 100644 --- a/test/form/samples/break-control-flow/loop-errors/main.js +++ b/test/form/samples/break-control-flow/loop-errors/main.js @@ -20,10 +20,14 @@ try { function doWhileLoop() { console.log(hoisted); do { + if (globalThis.unknown) { + break; + } throw new Error(); console.log('removed'); } while (globalThis.unknown); - console.log('removed'); + console.log('retained'); + throw new Error(); do { var hoisted; console.log('removed'); diff --git a/test/function/samples/do-while-conditional-break/_config.js b/test/function/samples/do-while-conditional-break/_config.js new file mode 100644 index 00000000000..f239588d8a8 --- /dev/null +++ b/test/function/samples/do-while-conditional-break/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'handles conditional breaks in do-while loops with unconditional return' +}; diff --git a/test/function/samples/do-while-conditional-break/main.js b/test/function/samples/do-while-conditional-break/main.js new file mode 100644 index 00000000000..7ffadbdf7b3 --- /dev/null +++ b/test/function/samples/do-while-conditional-break/main.js @@ -0,0 +1,12 @@ +function test(condition) { + do { + if (condition) { + break; + } + return false; + } while (true); + return true; +} + +assert.equal(test(false), false); +assert.equal(test(true), true);