Make getBinding ignore labels; add Scope#getLabel, Scope#registerLabel (#4758)

* Make getBinding ignore labels; add Scope#getLabel, Scope#registerLabel

* generateUid: account for labels again
This commit is contained in:
Juriy Zaytsev 2016-10-21 17:19:59 -04:00 committed by Henry Zhu
parent 7bb430aeea
commit beda884f41
2 changed files with 38 additions and 2 deletions

View File

@ -161,6 +161,8 @@ export default class Scope {
this.parentBlock = path.parent; this.parentBlock = path.parent;
this.block = path.node; this.block = path.node;
this.path = path; this.path = path;
this.labels = new Map();
} }
/** /**
@ -218,7 +220,7 @@ export default class Scope {
do { do {
uid = this._generateUid(name, i); uid = this._generateUid(name, i);
i++; i++;
} while (this.hasBinding(uid) || this.hasGlobal(uid) || this.hasReference(uid)); } while (this.hasLabel(uid) || this.hasBinding(uid) || this.hasGlobal(uid) || this.hasReference(uid));
let program = this.getProgramParent(); let program = this.getProgramParent();
program.references[uid] = true; program.references[uid] = true;
@ -426,9 +428,21 @@ export default class Scope {
return t.callExpression(file.addHelper(helperName), args); return t.callExpression(file.addHelper(helperName), args);
} }
hasLabel(name: string) {
return !!this.getLabel(name);
}
getLabel(name: string) {
return this.labels.get(name);
}
registerLabel(path: NodePath) {
this.labels.set(path.node.label.name, path);
}
registerDeclaration(path: NodePath) { registerDeclaration(path: NodePath) {
if (path.isLabeledStatement()) { if (path.isLabeledStatement()) {
this.registerBinding("label", path); this.registerLabel(path);
} else if (path.isFunctionDeclaration()) { } else if (path.isFunctionDeclaration()) {
this.registerBinding("hoisted", path.get("id"), path); this.registerBinding("hoisted", path.get("id"), path);
} else if (path.isVariableDeclaration()) { } else if (path.isVariableDeclaration()) {

View File

@ -38,5 +38,27 @@ describe("scope", function () {
it("purity", function () { it("purity", function () {
assert.ok(getPath("({ x: 1 })").get("body")[0].get("expression").isPure()); assert.ok(getPath("({ x: 1 })").get("body")[0].get("expression").isPure());
}); });
test("label", function () {
assert.strictEqual(getPath("foo: { }").scope.getBinding("foo"), undefined);
assert.strictEqual(getPath("foo: { }").scope.getLabel("foo").type, "LabeledStatement");
assert.strictEqual(getPath("foo: { }").scope.getLabel("toString"), undefined);
assert.strictEqual(getPath(`
foo: { }
`).scope.generateUid("foo"), "_foo");
});
test("generateUid collision check with labels", function () {
assert.strictEqual(getPath(`
_foo: { }
`).scope.generateUid("foo"), "_foo2");
assert.strictEqual(getPath(`
_foo: { }
_foo1: { }
_foo2: { }
`).scope.generateUid("foo"), "_foo3");
});
}); });
}); });