Skip to content

Commit 7ab7198

Browse files
maennchenbuehler
authored andcommitted
feat(parser): Use iterative BTree Walker
1 parent 3646355 commit 7ab7198

File tree

4 files changed

+118
-40
lines changed

4 files changed

+118
-40
lines changed

src/TypescriptParser.ts

Lines changed: 63 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
EnumDeclaration,
66
ExportAssignment,
77
ExportDeclaration,
8+
forEachChild,
89
FunctionDeclaration,
910
Identifier,
1011
ImportDeclaration,
@@ -29,6 +30,7 @@ import { parseIdentifier } from './node-parser/identifier-parser';
2930
import { parseImport } from './node-parser/import-parser';
3031
import { parseInterface } from './node-parser/interface-parser';
3132
import { parseModule } from './node-parser/module-parser';
33+
import { traverseAst } from './node-parser/traverse-ast';
3234
import { parseTypeAlias } from './node-parser/type-alias-parser';
3335
import { parseVariable } from './node-parser/variable-parser';
3436
import { File } from './resources/File';
@@ -140,6 +142,7 @@ export class TypescriptParser {
140142
return file;
141143
}
142144

145+
143146
/**
144147
* Recursive function that runs through the AST of a source and parses the nodes.
145148
* Creates the class / function / etc declarations and instanciates a new module / namespace
@@ -151,46 +154,66 @@ export class TypescriptParser {
151154
*
152155
* @memberof TsResourceParser
153156
*/
154-
private parse(resource: Resource, node: Node): void {
155-
for (const child of node.getChildren()) {
156-
switch (child.kind) {
157-
case SyntaxKind.ImportDeclaration:
158-
case SyntaxKind.ImportEqualsDeclaration:
159-
parseImport(resource, <ImportDeclaration | ImportEqualsDeclaration>child);
160-
break;
161-
case SyntaxKind.ExportDeclaration:
162-
case SyntaxKind.ExportAssignment:
163-
parseExport(resource, <ExportAssignment | ExportDeclaration>child);
164-
break;
165-
case SyntaxKind.EnumDeclaration:
166-
parseEnum(resource, <EnumDeclaration>child);
167-
break;
168-
case SyntaxKind.TypeAliasDeclaration:
169-
parseTypeAlias(resource, <TypeAliasDeclaration>child);
170-
break;
171-
case SyntaxKind.FunctionDeclaration:
172-
parseFunction(resource, <FunctionDeclaration>child);
173-
continue;
174-
case SyntaxKind.VariableStatement:
175-
parseVariable(resource, <VariableStatement>child);
176-
break;
177-
case SyntaxKind.InterfaceDeclaration:
178-
parseInterface(resource, <InterfaceDeclaration>child);
179-
break;
180-
case SyntaxKind.ClassDeclaration:
181-
parseClass(resource, <ClassDeclaration>child);
182-
continue;
183-
case SyntaxKind.Identifier:
184-
parseIdentifier(resource, <Identifier>child);
185-
break;
186-
case SyntaxKind.ModuleDeclaration:
187-
const newResource = parseModule(resource, <ModuleDeclaration>child);
188-
this.parse(newResource, child);
189-
continue;
190-
default:
191-
break;
192-
}
193-
this.parse(resource, child);
157+
private parse(resource: Resource, root: Node): void {
158+
const modules = [{ moduleRoot: root, moduleResource: resource }];
159+
160+
for (let iter = modules.shift(); iter !== undefined; iter = modules.shift()) {
161+
const { moduleRoot, moduleResource } = iter;
162+
163+
traverseAst(
164+
moduleRoot,
165+
(node) => {
166+
switch (node.kind) {
167+
case SyntaxKind.ImportDeclaration:
168+
case SyntaxKind.ImportEqualsDeclaration:
169+
parseImport(moduleResource, <ImportDeclaration | ImportEqualsDeclaration>node);
170+
break;
171+
case SyntaxKind.ExportDeclaration:
172+
case SyntaxKind.ExportAssignment:
173+
parseExport(moduleResource, <ExportAssignment | ExportDeclaration>node);
174+
break;
175+
case SyntaxKind.EnumDeclaration:
176+
parseEnum(moduleResource, <EnumDeclaration>node);
177+
break;
178+
case SyntaxKind.TypeAliasDeclaration:
179+
parseTypeAlias(moduleResource, <TypeAliasDeclaration>node);
180+
break;
181+
case SyntaxKind.FunctionDeclaration:
182+
parseFunction(moduleResource, <FunctionDeclaration>node);
183+
break;
184+
case SyntaxKind.VariableStatement:
185+
parseVariable(moduleResource, <VariableStatement>node);
186+
break;
187+
case SyntaxKind.InterfaceDeclaration:
188+
parseInterface(moduleResource, <InterfaceDeclaration>node);
189+
break;
190+
case SyntaxKind.ClassDeclaration:
191+
parseClass(moduleResource, <ClassDeclaration>node);
192+
break;
193+
case SyntaxKind.Identifier:
194+
parseIdentifier(moduleResource, <Identifier>node);
195+
break;
196+
case SyntaxKind.ModuleDeclaration:
197+
modules.push({
198+
moduleRoot: node,
199+
moduleResource: parseModule(moduleResource, <ModuleDeclaration>node),
200+
});
201+
break;
202+
default:
203+
break;
204+
}
205+
},
206+
(node) => {
207+
switch (node.kind) {
208+
case SyntaxKind.ClassDeclaration:
209+
case SyntaxKind.ModuleDeclaration:
210+
case SyntaxKind.FunctionDeclaration:
211+
return true;
212+
default:
213+
return false;
214+
}
215+
},
216+
);
194217
}
195218
}
196219
}

src/node-parser/traverse-ast.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export function traverseAst(root: Node, visit: (node: Node) => void, skipContents?: (node: Node) => boolean): void {
2+
const stack = root.getChildren();
3+
4+
for (let node = stack.shift(); node !== undefined; node = stack.shift()) {
5+
visit(node);
6+
7+
if (skipContents && skipContents(node)) {
8+
continue;
9+
}
10+
11+
stack.unshift(...node.getChildren());
12+
}
13+
}

test/TypescriptParser.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,4 +785,14 @@ describe('TypescriptParser', () => {
785785

786786
});
787787

788+
describe('Parses Webpack Bundle', () => {
789+
790+
const file = getWorkspaceFile('typescript-parser/webpack-bundle.js');
791+
792+
it('should parse the whole webpack bundle', async () => {
793+
await parser.parseFile(file, rootPath);
794+
});
795+
796+
});
797+
788798
});

test/_workspace/typescript-parser/webpack-bundle.js

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)