feat(parser): Use iterative BTree Walker · buehler/node-typescript-parser@7ab7198
@@ -5,6 +5,7 @@ import {
55EnumDeclaration,
66ExportAssignment,
77ExportDeclaration,
8+forEachChild,
89FunctionDeclaration,
910Identifier,
1011ImportDeclaration,
@@ -29,6 +30,7 @@ import { parseIdentifier } from './node-parser/identifier-parser';
2930import { parseImport } from './node-parser/import-parser';
3031import { parseInterface } from './node-parser/interface-parser';
3132import { parseModule } from './node-parser/module-parser';
33+import { traverseAst } from './node-parser/traverse-ast';
3234import { parseTypeAlias } from './node-parser/type-alias-parser';
3335import { parseVariable } from './node-parser/variable-parser';
3436import { File } from './resources/File';
@@ -140,6 +142,7 @@ export class TypescriptParser {
140142return file;
141143}
142144145+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}