From 58059a2c48445a49977a1e9b2e8356d3245a1d39 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 5 Jun 2015 07:52:57 +0100 Subject: [PATCH] add deoptValue method to Binding that ignores all subsequent setValue calls --- src/babel/traversal/scope/binding.js | 15 +++++++++-- src/babel/traversal/scope/index.js | 37 ++++++++++++++++++---------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/babel/traversal/scope/binding.js b/src/babel/traversal/scope/binding.js index 9f202a0612..ab4bb36b90 100644 --- a/src/babel/traversal/scope/binding.js +++ b/src/babel/traversal/scope/binding.js @@ -14,11 +14,21 @@ export default class Binding { this.clearValue(); } + /** + * Description + */ + + deoptValue(value) { + this.clearValue(); + this.deoptValue = true; + } + /** * Description */ setValue(value) { + if (this.deoptValue) return; this.hasValue = true; this.value = value; } @@ -28,8 +38,9 @@ export default class Binding { */ clearValue() { - this.hasValue = false; - this.value = null; + this.deoptValue = false; + this.hasValue = false; + this.value = null; } /** diff --git a/src/babel/traversal/scope/index.js b/src/babel/traversal/scope/index.js index 7c3eff027d..c8b371843b 100644 --- a/src/babel/traversal/scope/index.js +++ b/src/babel/traversal/scope/index.js @@ -30,44 +30,55 @@ var collectorVisitor = { scope.getFunctionParent().registerDeclaration(this); }, - ReferencedIdentifier(node, parent, scope) { - var bindingInfo = scope.getBinding(node.name); + ReferencedIdentifier(node) { + var bindingInfo = this.scope.getBinding(node.name); if (bindingInfo) { bindingInfo.reference(); } else { - scope.getProgramParent().addGlobal(node); + this.scope.getProgramParent().addGlobal(node); } }, - ForXStatement(node, parent, scope) { + ForXStatement() { var left = this.get("left"); if (left.isPattern() || left.isIdentifier()) { - scope.registerConstantViolation(left); + this.scope.registerConstantViolation(left); } }, ExportDeclaration: { - exit(node, parent, scope) { + exit(node) { var declar = node.declaration; if (t.isClassDeclaration(declar) || t.isFunctionDeclaration(declar)) { - scope.getBinding(declar.id.name).reference(); + this.scope.getBinding(declar.id.name).reference(); } else if (t.isVariableDeclaration(declar)) { for (var decl of (declar.declarations: Array)) { var ids = t.getBindingIdentifiers(decl); for (var name in ids) { - scope.getBinding(name).reference(); + this.scope.getBinding(name).reference(); } } } } }, - LabeledStatement(node, parent, scope) { - scope.getProgramParent().addGlobal(node); + LabeledStatement(node) { + this.scope.getProgramParent().addGlobal(node); }, - AssignmentExpression(node, parent, scope) { - scope.registerConstantViolation(this.get("left"), this.get("right")); + AssignmentExpression() { + // register undeclared bindings as globals + var ids = this.getBindingIdentifiers(); + var programParent; + for (var name in ids) { + if (this.scope.getBinding(name)) continue; + + programParent = programParent || this.scope.getProgramParent(); + programParent.addGlobal(ids[name]); + } + + // register as constant violation + this.scope.registerConstantViolation(this.get("left"), this.get("right")); }, UpdateExpression(node, parent, scope) { @@ -95,7 +106,7 @@ var collectorVisitor = { scope.getBlockParent().registerDeclaration(path); } } - }, + } }; var renameVisitor = {