Skip to content

Commit 8b6ec68

Browse files
committed
handle references to class from inner scope correctly
Create only a single variable to ClassDeclarations instead of two for inner and outer scope.
1 parent 1567e9d commit 8b6ec68

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

src/referencer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export default class Referencer extends esrecurse.Visitor {
250250

251251
this.scopeManager.__nestClassScope(node);
252252

253-
if (node.id) {
253+
if (node.id && node.type !== Syntax.ClassDeclaration) {
254254
this.currentScope().__define(node.id,
255255
new Definition(
256256
Variable.ClassName,

test/es6-class.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ describe('ES6 class', function() {
5252
expect(scope.type).to.be.equal('class');
5353
expect(scope.block.type).to.be.equal('ClassDeclaration');
5454
expect(scope.isStrict).to.be.true;
55-
expect(scope.variables).to.have.length(1);
56-
expect(scope.variables[0].name).to.be.equal('Derived');
55+
expect(scope.variables).to.have.length(0);
5756
expect(scope.references).to.have.length(0);
5857

5958
scope = scopeManager.scopes[2];
@@ -191,6 +190,45 @@ describe('ES6 class', function() {
191190
expect(scope.references[0].identifier.name).to.be.equal('shoe');
192191
expect(scope.references[1].identifier.name).to.be.equal('Shoe');
193192
});
193+
194+
it('reference in class', function() {
195+
const ast = parse(`
196+
class Foo {
197+
constructor() {
198+
Foo;
199+
}
200+
}
201+
`);
202+
203+
204+
const scopeManager = analyze(ast, {ecmaVersion: 6});
205+
expect(scopeManager.scopes).to.have.length(3);
206+
207+
let scope = scopeManager.scopes[0];
208+
expect(scope.type).to.be.equal('global');
209+
expect(scope.block.type).to.be.equal('Program');
210+
expect(scope.isStrict).to.be.false;
211+
expect(scope.variables).to.have.length(1);
212+
expect(scope.variables[0].name).to.be.equal('Foo');
213+
expect(scope.variables[0].references).to.have.length(1);
214+
expect(scope.variables[0].references[0].identifier.name).to.be.equal('Foo');
215+
216+
scope = scopeManager.scopes[1];
217+
expect(scope.type).to.be.equal('class');
218+
expect(scope.block.type).to.be.equal('ClassDeclaration');
219+
expect(scope.isStrict).to.be.true;
220+
expect(scope.variables).to.have.length(0);
221+
expect(scope.references).to.have.length(0);
222+
223+
scope = scopeManager.scopes[2];
224+
expect(scope.type).to.be.equal('function');
225+
expect(scope.block.type).to.be.equal('FunctionExpression');
226+
expect(scope.isStrict).to.be.true;
227+
expect(scope.variables).to.have.length(1);
228+
expect(scope.variables[0].name).to.be.equal('arguments');
229+
expect(scope.references).to.have.length(1);
230+
expect(scope.references[0].identifier.name).to.be.equal('Foo');
231+
});
194232
});
195233

196234
// vim: set sw=4 ts=4 et tw=80 :

test/es6-super.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ describe('ES6 super', function() {
5050

5151
scope = scopeManager.scopes[1];
5252
expect(scope.type).to.be.equal('class');
53-
expect(scope.variables).to.have.length(1);
54-
expect(scope.variables[0].name).to.be.equal('Hello');
53+
expect(scope.variables).to.have.length(0);
5554
expect(scope.references).to.have.length(0);
5655

5756
scope = scopeManager.scopes[2];

test/get-declared-variables.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ describe('ScopeManager.prototype.getDeclaredVariables', function() {
165165
`);
166166

167167
verify(ast, 'ClassDeclaration', [
168-
['A', 'A'], // outer scope's and inner scope's.
169-
['B', 'B']
168+
['A'],
169+
['B']
170170
]);
171171
});
172172

0 commit comments

Comments
 (0)