Skip to content

Commit

Permalink
handle references to class from inner scope correctly
Browse files Browse the repository at this point in the history
Create only a single variable to ClassDeclarations instead
of two for inner and outer scope.
  • Loading branch information
sokra committed Jun 5, 2017
1 parent 1567e9d commit 8b6ec68
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/referencer.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export default class Referencer extends esrecurse.Visitor {

this.scopeManager.__nestClassScope(node);

if (node.id) {
if (node.id && node.type !== Syntax.ClassDeclaration) {
this.currentScope().__define(node.id,
new Definition(
Variable.ClassName,
Expand Down
42 changes: 40 additions & 2 deletions test/es6-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ describe('ES6 class', function() {
expect(scope.type).to.be.equal('class');
expect(scope.block.type).to.be.equal('ClassDeclaration');
expect(scope.isStrict).to.be.true;
expect(scope.variables).to.have.length(1);
expect(scope.variables[0].name).to.be.equal('Derived');
expect(scope.variables).to.have.length(0);
expect(scope.references).to.have.length(0);

scope = scopeManager.scopes[2];
Expand Down Expand Up @@ -191,6 +190,45 @@ describe('ES6 class', function() {
expect(scope.references[0].identifier.name).to.be.equal('shoe');
expect(scope.references[1].identifier.name).to.be.equal('Shoe');
});

it('reference in class', function() {
const ast = parse(`
class Foo {
constructor() {
Foo;
}
}
`);


const scopeManager = analyze(ast, {ecmaVersion: 6});
expect(scopeManager.scopes).to.have.length(3);

let scope = scopeManager.scopes[0];
expect(scope.type).to.be.equal('global');
expect(scope.block.type).to.be.equal('Program');
expect(scope.isStrict).to.be.false;
expect(scope.variables).to.have.length(1);
expect(scope.variables[0].name).to.be.equal('Foo');
expect(scope.variables[0].references).to.have.length(1);
expect(scope.variables[0].references[0].identifier.name).to.be.equal('Foo');

scope = scopeManager.scopes[1];
expect(scope.type).to.be.equal('class');
expect(scope.block.type).to.be.equal('ClassDeclaration');
expect(scope.isStrict).to.be.true;
expect(scope.variables).to.have.length(0);
expect(scope.references).to.have.length(0);

scope = scopeManager.scopes[2];
expect(scope.type).to.be.equal('function');
expect(scope.block.type).to.be.equal('FunctionExpression');
expect(scope.isStrict).to.be.true;
expect(scope.variables).to.have.length(1);
expect(scope.variables[0].name).to.be.equal('arguments');
expect(scope.references).to.have.length(1);
expect(scope.references[0].identifier.name).to.be.equal('Foo');
});
});

// vim: set sw=4 ts=4 et tw=80 :
3 changes: 1 addition & 2 deletions test/es6-super.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ describe('ES6 super', function() {

scope = scopeManager.scopes[1];
expect(scope.type).to.be.equal('class');
expect(scope.variables).to.have.length(1);
expect(scope.variables[0].name).to.be.equal('Hello');
expect(scope.variables).to.have.length(0);
expect(scope.references).to.have.length(0);

scope = scopeManager.scopes[2];
Expand Down
4 changes: 2 additions & 2 deletions test/get-declared-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() {
`);

verify(ast, 'ClassDeclaration', [
['A', 'A'], // outer scope's and inner scope's.
['B', 'B']
['A'],
['B']
]);
});

Expand Down

0 comments on commit 8b6ec68

Please sign in to comment.