Fix missing ClassDeclaration references after scope#crawl (#11011)

* Bug replication test

* Simplify test

* Fixes #10896

* Merge path.crawl `ClassDeclaration` and `Declaration` visitors

Merged to avoid subtle assumption that `Declaration` is called before `ClassDeclaration`

* Move registartion of class id in crawl to BlockScoped

* Add some assertions to crawl test
This commit is contained in:
Erlend Tobiassen 2020-01-20 03:32:05 +01:00 committed by Huáng Jùnliàng
parent 2b23c283dd
commit 740064ced7
2 changed files with 23 additions and 7 deletions

View File

@ -128,15 +128,17 @@ const collectorVisitor = {
BlockScoped(path) {
let scope = path.scope;
if (scope.path === path) scope = scope.parent;
scope.getBlockParent().registerDeclaration(path);
},
ClassDeclaration(path) {
const parent = scope.getBlockParent();
parent.registerDeclaration(path);
// Register class identifier in class' scope if this is a class declaration.
if (path.isClassDeclaration() && path.node.id) {
const id = path.node.id;
if (!id) return;
const name = id.name;
path.scope.bindings[name] = path.scope.getBinding(name);
path.scope.bindings[name] = path.scope.parent.getBinding(name);
}
},
Block(path) {

View File

@ -289,6 +289,20 @@ describe("scope", () => {
column: 32,
});
});
it("class identifier available in class scope after crawl", function() {
const path = getPath("class a { build() { return new a(); } }");
path.scope.crawl();
let referencePaths = path.scope.bindings.a.referencePaths;
expect(referencePaths).toHaveLength(1);
referencePaths = path.get("body[0]").scope.bindings.a.referencePaths;
expect(referencePaths).toHaveLength(1);
expect(path.scope.bindings.a).toBe(path.get("body[0]").scope.bindings.a);
});
});
describe("duplicate bindings", () => {