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.
This commit is contained in:
Ruben Verborgh
2017-09-08 23:02:26 -04:00
committed by Justin Ridgewell
parent 4e612058c0
commit 6560a29c36
4 changed files with 30 additions and 18 deletions

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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,
});
}
}
}
}

View File

@@ -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 })")