Skip to content
This repository was archived by the owner on Aug 15, 2024. It is now read-only.

Commit c647f65

Browse files
corbinuilyavolodin
authored andcommitted
Update: Add check for node.body in referencer (#2)
* Add check for node.body in referencer * Add comment explaining the node.body check * Allow tests to run with babel We will remove this soon but need to add tests for new features in the mean time. * Add typescript-eslint-parser as dev dependency This used in tests for typescript features. * Strict scope should be false when there is no body This fixes an issue with typescript having an empty body for some functions * Add tests for typescript scope analysis This includes a test for multiple call signatures. * Add check for node.body in referencer Add comment explaining the node.body check Allow tests to run with babel We will remove this soon but need to add tests for new features in the mean time. Add typescript-eslint-parser as dev dependency This used in tests for typescript features. Strict scope should be false when there is no body This fixes an issue with typescript having an empty body for some functions Add tests for typescript scope analysis This includes a test for multiple call signatures. Add comment explaining the node.body check Allow tests to run with babel We will remove this soon but need to add tests for new features in the mean time. Strict scope should be false when there is no body This fixes an issue with typescript having an empty body for some functions Add tests for typescript scope analysis This includes a test for multiple call signatures.
1 parent eb5c9db commit c647f65

File tree

4 files changed

+83
-7
lines changed

4 files changed

+83
-7
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"gulp-sourcemaps": "^1.6.0",
4949
"gulp-tag-version": "^1.3.0",
5050
"lazypipe": "^1.0.1",
51-
"vinyl-source-stream": "^1.1.0"
51+
"vinyl-source-stream": "^1.1.0",
52+
"typescript-eslint-parser": "^1.0.0"
5253
}
53-
}
54+
}

src/referencer.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,15 @@ export default class Referencer extends esrecurse.Visitor {
222222
});
223223
}
224224

225-
// Skip BlockStatement to prevent creating BlockStatement scope.
226-
if (node.body.type === Syntax.BlockStatement) {
227-
this.visitChildren(node.body);
228-
} else {
229-
this.visit(node.body);
225+
// In TypeScript there are a number of function-like constructs which have no body,
226+
// so check it exists before traversing
227+
if (node.body) {
228+
// Skip BlockStatement to prevent creating BlockStatement scope.
229+
if (node.body.type === Syntax.BlockStatement) {
230+
this.visitChildren(node.body);
231+
} else {
232+
this.visit(node.body);
233+
}
230234
}
231235

232236
this.close(node);

src/scope.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) {
6161
} else {
6262
body = block.body;
6363
}
64+
65+
if (!body) {
66+
return false;
67+
}
6468
} else if (scope.type === 'global') {
6569
body = block;
6670
} else {

test/typescript.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @fileoverview Typescript scope tests
3+
* @author Reyad Attiyat
4+
*/
5+
"use strict";
6+
7+
//------------------------------------------------------------------------------
8+
// Requirements
9+
//------------------------------------------------------------------------------
10+
11+
require("babel-register");
12+
13+
const expect = require('chai').expect,
14+
parse = require('typescript-eslint-parser').parse,
15+
analyze = require('../src').analyze;
16+
17+
//------------------------------------------------------------------------------
18+
// Tests
19+
//------------------------------------------------------------------------------
20+
21+
describe('typescript', () => {
22+
describe('multiple call signatures', () => {
23+
it('should create a function scope', () => {
24+
const ast = parse(`
25+
function foo(bar: number): number;
26+
function foo(bar: string): string;
27+
function foo(bar: string | number): string | number {
28+
return bar;
29+
}
30+
`);
31+
32+
const scopeManager = analyze(ast);
33+
34+
expect(scopeManager.scopes).to.have.length(4);
35+
36+
const globalScope = scopeManager.scopes[0];
37+
expect(globalScope.type).to.be.equal('global');
38+
expect(globalScope.variables).to.have.length(1);
39+
expect(globalScope.references).to.have.length(0);
40+
expect(globalScope.isArgumentsMaterialized()).to.be.true;
41+
42+
// Function scopes
43+
let scope = scopeManager.scopes[1];
44+
expect(scope.type).to.be.equal('function');
45+
expect(scope.variables).to.have.length(2);
46+
expect(scope.variables[0].name).to.be.equal('arguments');
47+
expect(scope.isArgumentsMaterialized()).to.be.false;
48+
expect(scope.references).to.have.length(0);
49+
50+
scope = scopeManager.scopes[2];
51+
expect(scope.type).to.be.equal('function');
52+
expect(scope.variables).to.have.length(2);
53+
expect(scope.variables[0].name).to.be.equal('arguments');
54+
expect(scope.isArgumentsMaterialized()).to.be.false;
55+
expect(scope.references).to.have.length(0);
56+
57+
scope = scopeManager.scopes[3];
58+
expect(scope.type).to.be.equal('function');
59+
expect(scope.variables).to.have.length(2);
60+
expect(scope.variables[0].name).to.be.equal('arguments');
61+
expect(scope.isArgumentsMaterialized()).to.be.false;
62+
expect(scope.references).to.have.length(1);
63+
64+
65+
});
66+
});
67+
});

0 commit comments

Comments
 (0)