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

Add check for node.body in referencer #2

Merged
merged 10 commits into from
Feb 11, 2017
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"gulp-sourcemaps": "^1.6.0",
"gulp-tag-version": "^1.3.0",
"lazypipe": "^1.0.1",
"vinyl-source-stream": "^1.1.0"
"vinyl-source-stream": "^1.1.0",
"typescript-eslint-parser": "^1.0.0"
}
}
}
14 changes: 9 additions & 5 deletions src/referencer.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,15 @@ export default class Referencer extends esrecurse.Visitor {
});
}

// Skip BlockStatement to prevent creating BlockStatement scope.
if (node.body.type === Syntax.BlockStatement) {
this.visitChildren(node.body);
} else {
this.visit(node.body);
// In TypeScript there are a number of function-like constructs which have no body,
// so check it exists before traversing
if (node.body) {
// Skip BlockStatement to prevent creating BlockStatement scope.
if (node.body.type === Syntax.BlockStatement) {
this.visitChildren(node.body);
} else {
this.visit(node.body);
}
}

this.close(node);
Expand Down
4 changes: 4 additions & 0 deletions src/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ function isStrictScope(scope, block, isMethodDefinition, useDirective) {
} else {
body = block.body;
}

if (!body) {
return false;
}
} else if (scope.type === 'global') {
body = block;
} else {
Expand Down
67 changes: 67 additions & 0 deletions test/typescript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @fileoverview Typescript scope tests
* @author Reyad Attiyat
*/
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

require("babel-register");

const expect = require('chai').expect,
parse = require('typescript-eslint-parser').parse,
analyze = require('../src').analyze;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

describe('typescript', () => {
describe('multiple call signatures', () => {
it('should create a function scope', () => {
const ast = parse(`
function foo(bar: number): number;
function foo(bar: string): string;
function foo(bar: string | number): string | number {
return bar;
}
`);

const scopeManager = analyze(ast);

expect(scopeManager.scopes).to.have.length(4);

const globalScope = scopeManager.scopes[0];
expect(globalScope.type).to.be.equal('global');
expect(globalScope.variables).to.have.length(1);
expect(globalScope.references).to.have.length(0);
expect(globalScope.isArgumentsMaterialized()).to.be.true;

// Function scopes
let scope = scopeManager.scopes[1];
expect(scope.type).to.be.equal('function');
expect(scope.variables).to.have.length(2);
expect(scope.variables[0].name).to.be.equal('arguments');
expect(scope.isArgumentsMaterialized()).to.be.false;
expect(scope.references).to.have.length(0);

scope = scopeManager.scopes[2];
expect(scope.type).to.be.equal('function');
expect(scope.variables).to.have.length(2);
expect(scope.variables[0].name).to.be.equal('arguments');
expect(scope.isArgumentsMaterialized()).to.be.false;
expect(scope.references).to.have.length(0);

scope = scopeManager.scopes[3];
expect(scope.type).to.be.equal('function');
expect(scope.variables).to.have.length(2);
expect(scope.variables[0].name).to.be.equal('arguments');
expect(scope.isArgumentsMaterialized()).to.be.false;
expect(scope.references).to.have.length(1);


});
});
});