From 6560a29c36fd0f9ef84e78738de11e0477b1384f Mon Sep 17 00:00:00 2001 From: Ruben Verborgh Date: Fri, 8 Sep 2017 23:02:26 -0400 Subject: [PATCH] Redeclaring a variable counts as a modification (#6219) * Redeclaring a variable counts as a modification. Fixes #6217. * Remove "existing" logic from Binding. Was added in #5745, but no longer triggered since 6536e605a. --- .../expected.js | 6 ++++-- packages/babel-traverse/src/scope/binding.js | 10 +--------- packages/babel-traverse/src/scope/index.js | 18 +++++++++++------- packages/babel-traverse/test/scope.js | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js index 9c5fe01993..ae1a6d4ecb 100644 --- a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/expected.js @@ -141,9 +141,11 @@ function arrayDestructure() { rest[_key15] = arguments[_key15]; } - var _x = babelHelpers.slicedToArray(x, 1); + var _x = x; - rest[0] = _x[0]; + var _x2 = babelHelpers.slicedToArray(_x, 1); + + rest[0] = _x2[0]; } function forOf() { diff --git a/packages/babel-traverse/src/scope/binding.js b/packages/babel-traverse/src/scope/binding.js index 3c5c645dfb..1f52201c51 100644 --- a/packages/babel-traverse/src/scope/binding.js +++ b/packages/babel-traverse/src/scope/binding.js @@ -12,15 +12,7 @@ import type NodePath from "../path"; */ export default class Binding { - constructor({ existing, identifier, scope, path, kind }) { - // this if condition is true only if the re-binding does not result in an error - // e.g. if rebinding kind is 'var' or 'hoisted', and previous was 'param' - if (existing) { - // we maintain the original binding but update constantViolations - existing.constantViolations = existing.constantViolations.concat(path); - return existing; - } - + constructor({ identifier, scope, path, kind }) { this.identifier = identifier; this.scope = scope; this.path = path; diff --git a/packages/babel-traverse/src/scope/index.js b/packages/babel-traverse/src/scope/index.js index 40d62a84fb..113191d95c 100644 --- a/packages/babel-traverse/src/scope/index.js +++ b/packages/babel-traverse/src/scope/index.js @@ -535,13 +535,17 @@ export default class Scope { parent.references[name] = true; - this.bindings[name] = new Binding({ - identifier: id, - existing: local, - scope: this, - path: bindingPath, - kind: kind, - }); + // A redeclaration of an existing variable is a modification + if (local) { + this.registerConstantViolation(bindingPath); + } else { + this.bindings[name] = new Binding({ + identifier: id, + scope: this, + path: bindingPath, + kind: kind, + }); + } } } } diff --git a/packages/babel-traverse/test/scope.js b/packages/babel-traverse/test/scope.js index 0f95e97130..e28c47696d 100644 --- a/packages/babel-traverse/test/scope.js +++ b/packages/babel-traverse/test/scope.js @@ -73,6 +73,20 @@ describe("scope", function() { ); }); + it("variable constantness", function() { + assert.ok(getPath("var a = 1;").scope.getBinding("a").constant === true); + assert.ok( + getPath("var a = 1; a = 2;").scope.getBinding("a").constant === false, + ); + assert.ok( + getPath("var a = 1, a = 2;").scope.getBinding("a").constant === false, + ); + assert.ok( + getPath("var a = 1; var a = 2;").scope.getBinding("a").constant === + false, + ); + }); + it("purity", function() { assert.ok( getPath("({ x: 1 })")