From df09db7518019c13c939805895501f6e390f9ece Mon Sep 17 00:00:00 2001 From: Alan Pierce Date: Mon, 14 Aug 2017 08:33:00 -0700 Subject: [PATCH] fix: don't convert `var` to `let` or `const` in a switch case (#136) Fixes https://github.com/decaffeinate/decaffeinate/issues/1171 Potentially add-variable-declarations and esnext could be smarter in this case, e.g. by declaring the variable outside the switch or even creating a block scope, but the easy thing is to just keep the declaration as `var`. Since `var` doesn't have a temporal dead zone, a declaration in any switch case will work for all switch cases. --- .../mostRestrictiveKindForDeclaration.js | 4 + .../var-in-switch/_expected/main.js | 10 +++ .../var-in-switch/_expected/metadata.json | 5 ++ .../var-in-switch/_expected/warnings.json | 76 +++++++++++++++++++ .../var-in-switch/config.json | 3 + .../var-in-switch/main.js | 10 +++ 6 files changed, 108 insertions(+) create mode 100644 test/form/declarations.block-scope/var-in-switch/_expected/main.js create mode 100644 test/form/declarations.block-scope/var-in-switch/_expected/metadata.json create mode 100644 test/form/declarations.block-scope/var-in-switch/_expected/warnings.json create mode 100644 test/form/declarations.block-scope/var-in-switch/config.json create mode 100644 test/form/declarations.block-scope/var-in-switch/main.js diff --git a/src/utils/mostRestrictiveKindForDeclaration.js b/src/utils/mostRestrictiveKindForDeclaration.js index c1fac537..3f8788ab 100644 --- a/src/utils/mostRestrictiveKindForDeclaration.js +++ b/src/utils/mostRestrictiveKindForDeclaration.js @@ -13,6 +13,10 @@ export default function mostRestrictiveKindForDeclaration(path: Path): Declarati let { scope } = path; let isConst = path.node.declarations.every(declaration => declaration.init); + if (t.isSwitchCase(path.parent)) { + return 'var'; + } + for (let id in ids) { let binding = scope.getBinding(id); diff --git a/test/form/declarations.block-scope/var-in-switch/_expected/main.js b/test/form/declarations.block-scope/var-in-switch/_expected/main.js new file mode 100644 index 00000000..1cd3ad0a --- /dev/null +++ b/test/form/declarations.block-scope/var-in-switch/_expected/main.js @@ -0,0 +1,10 @@ +switch (a) { + case 1: + var x = 1; + console.log(x); + break; + case 2: + x = 2; + console.log(x); + break; +} diff --git a/test/form/declarations.block-scope/var-in-switch/_expected/metadata.json b/test/form/declarations.block-scope/var-in-switch/_expected/metadata.json new file mode 100644 index 00000000..eb7dd968 --- /dev/null +++ b/test/form/declarations.block-scope/var-in-switch/_expected/metadata.json @@ -0,0 +1,5 @@ +{ + "declarations.block-scope": { + "declarations": [] + } +} \ No newline at end of file diff --git a/test/form/declarations.block-scope/var-in-switch/_expected/warnings.json b/test/form/declarations.block-scope/var-in-switch/_expected/warnings.json new file mode 100644 index 00000000..2f13f771 --- /dev/null +++ b/test/form/declarations.block-scope/var-in-switch/_expected/warnings.json @@ -0,0 +1,76 @@ +[ + { + "node": { + "type": "VariableDeclaration", + "start": 27, + "end": 37, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 14 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 31, + "end": 36, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "id": { + "type": "Identifier", + "start": 31, + "end": 32, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 9 + }, + "identifierName": "x" + }, + "name": "x" + }, + "init": { + "type": "NumericLiteral", + "start": 35, + "end": 36, + "loc": { + "start": { + "line": 3, + "column": 12 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + ], + "kind": "var" + }, + "type": "unsupported-declaration", + "message": "'var' declaration cannot be converted to block scope" + } +] \ No newline at end of file diff --git a/test/form/declarations.block-scope/var-in-switch/config.json b/test/form/declarations.block-scope/var-in-switch/config.json new file mode 100644 index 00000000..065dfd4a --- /dev/null +++ b/test/form/declarations.block-scope/var-in-switch/config.json @@ -0,0 +1,3 @@ +{ + "description": "does not convert `var` declarations within switch cases" +} diff --git a/test/form/declarations.block-scope/var-in-switch/main.js b/test/form/declarations.block-scope/var-in-switch/main.js new file mode 100644 index 00000000..1cd3ad0a --- /dev/null +++ b/test/form/declarations.block-scope/var-in-switch/main.js @@ -0,0 +1,10 @@ +switch (a) { + case 1: + var x = 1; + console.log(x); + break; + case 2: + x = 2; + console.log(x); + break; +}