feat(parser): Use iterative BTree Walker · buehler/node-typescript-parser@7ab7198

@@ -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

}

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

}