Skip to content

Commit b35e223

Browse files
committed
fix(parserUtils): Add support for duplicate ast (#119)
The parser utils is responsible to add id's to ast nodes. I add support for having properties which refer to the same part of the ast. This happens for example with a try catch: http://esprima.org/demo/parse.html?code=try%7B%0D%0A%7Dcatch(error)%7B%0D%0A%7D
1 parent 305481a commit b35e223

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

src/utils/parserUtils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ export function parse(code: string): any {
4141
export function collectFrozenNodes(abstractSyntaxTree: any, nodes?: any[]): any[] {
4242
nodes = nodes || [];
4343

44-
if (abstractSyntaxTree instanceof Object && !(abstractSyntaxTree instanceof Array) && abstractSyntaxTree.type) {
44+
if (!_.isArray(abstractSyntaxTree) && _.isObject(abstractSyntaxTree) && abstractSyntaxTree.type && _.isUndefined(abstractSyntaxTree.nodeID)) {
4545
abstractSyntaxTree.nodeID = nodes.length;
4646
nodes.push(abstractSyntaxTree);
4747
}
4848

4949
Object.freeze(abstractSyntaxTree);
50-
51-
_.forOwn(abstractSyntaxTree, (childNode) => {
50+
51+
_.forOwn(abstractSyntaxTree, (childNode, i) => {
5252
if (childNode instanceof Object && !(childNode instanceof Array)) {
5353
collectFrozenNodes(childNode, nodes);
5454
} else if (childNode instanceof Array) {

test/unit/utils/parserUtilsSpec.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,40 @@ var expect = require('chai').expect;
44
import * as parserUtils from '../../../src/utils/parserUtils';
55
require('mocha-sinon');
66

7-
describe('parserUtils', function() {
7+
describe('parserUtils', () => {
88

9-
describe('should throw an error', function(){
10-
it('if no code is provided when parsing', function() {
11-
expect(parserUtils.parse).to.throw(Error);
12-
});
9+
describe('collectFrozenNodes', () => {
10+
11+
it('when provided a try catch block', () => {
12+
// A try catch block has recursion. See
13+
// http://esprima.org/demo/parse.html?code=try%20%7B%0D%0A%20%20%20%20%20%20%20%20configModule(config)%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20catch%20(e)%20%7B%0D%0A%20%20%20%20%20%20%20%20process.exit(1)%3B%0D%0A%20%20%20%20%20%20%7D
1314

15+
let parsedTryCatch = parserUtils.parse(`try {
16+
configModule(config);
17+
}
18+
catch (e) {
19+
process.exit(1);
20+
}`);
21+
parserUtils.collectFrozenNodes(parsedTryCatch);
22+
});
1423
});
1524

16-
it('should return an empty object if an empty string is parsed', function() {
17-
var emptyObject = {};
25+
describe('parse', () => {
1826

19-
var result = parserUtils.parse('');
20-
expect(JSON.stringify(result)).to.equal(JSON.stringify(emptyObject));
27+
describe('should throw an error', () => {
28+
it('if no code is provided when parsing', () => {
29+
expect(parserUtils.parse).to.throw(Error);
30+
});
31+
32+
});
33+
34+
35+
it('should return an empty object if an empty string is parsed', () => {
36+
var emptyObject = {};
37+
38+
var result = parserUtils.parse('');
39+
expect(JSON.stringify(result)).to.equal(JSON.stringify(emptyObject));
40+
});
2141
});
2242

2343
});

0 commit comments

Comments
 (0)