1// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. 2// See LICENSE.txt in the project root for complete license information. 3 4///<reference path='typescript.ts' /> 5 6module TypeScript { 7 export interface IAstWalker { 8 walk(ast: AST, parent: AST): AST; 9 options: AstWalkOptions; 10 state: any; // user state object 11 } 12 13 export class AstWalkOptions { 14 public goChildren = true; 15 public goNextSibling = true; 16 public reverseSiblings = false; // visit siblings in reverse execution order 17 18 public stopWalk(stop:boolean = true) { 19 this.goChildren = !stop; 20 this.goNextSibling = !stop; 21 } 22 } 23 24 export interface IAstWalkCallback { 25 (ast: AST, parent: AST, walker: IAstWalker): AST; 26 } 27 28 export interface IAstWalkChildren { 29 (preAst: AST, parent: AST, walker: IAstWalker): void; 30 } 31 32 class AstWalker implements IAstWalker { 33 constructor ( 34 private childrenWalkers: IAstWalkChildren[], 35 private pre: IAstWalkCallback, 36 private post: IAstWalkCallback, 37 public options: AstWalkOptions, 38 public state: any) { 39 } 40 41 public walk(ast: AST, parent: AST): AST { 42 var preAst = this.pre(ast, parent, this); 43 if (preAst === undefined) { 44 preAst = ast; 45 } 46 if (this.options.goChildren) { 47 var svGoSib = this.options.goNextSibling; 48 this.options.goNextSibling = true; 49 // Call the "walkChildren" function corresponding to "nodeType". 50 this.childrenWalkers[ast.nodeType](ast, parent, this); 51 this.options.goNextSibling = svGoSib; 52 } 53 else { 54 // no go only applies to children of node issuing it 55 this.options.goChildren = true; 56 } 57 if (this.post) { 58 var postAst = this.post(preAst, parent, this); 59 if (postAst === undefined) { 60 postAst = preAst; 61 } 62 return postAst; 63 } 64 else { 65 return preAst; 66 } 67 } 68 } 69 70 export class AstWalkerFactory { 71 private childrenWalkers: IAstWalkChildren[] = []; 72 73 constructor () { 74 this.initChildrenWalkers(); 75 } 76 77 public walk(ast: AST, pre: IAstWalkCallback, post?: IAstWalkCallback, options?: AstWalkOptions, state?: any): AST { 78 return this.getWalker(pre, post, options, state).walk(ast, null) 79 } 80 81 public getWalker(pre: IAstWalkCallback, post?: IAstWalkCallback, options?: AstWalkOptions, state?: any): IAstWalker { 82 return this.getSlowWalker(pre, post, options, state); 83 } 84 85 private getSlowWalker(pre: IAstWalkCallback, post?: IAstWalkCallback, options?: AstWalkOptions, state?: any): IAstWalker { 86 if (!options) { 87 options = new AstWalkOptions(); 88 } 89 90 return new AstWalker(this.childrenWalkers, pre, post, options, state); 91 } 92 93 private initChildrenWalkers(): void { 94 this.childrenWalkers[NodeType.None] = ChildrenWalkers.walkNone; 95 this.childrenWalkers[NodeType.Empty] = ChildrenWalkers.walkNone; 96 this.childrenWalkers[NodeType.EmptyExpr] = ChildrenWalkers.walkNone; 97 this.childrenWalkers[NodeType.True] = ChildrenWalkers.walkNone; 98 this.childrenWalkers[NodeType.False] = ChildrenWalkers.walkNone; 99 this.childrenWalkers[NodeType.This] = ChildrenWalkers.walkNone; 100 this.childrenWalkers[NodeType.Super] = ChildrenWalkers.walkNone; 101 this.childrenWalkers[NodeType.QString] = ChildrenWalkers.walkNone; 102 this.childrenWalkers[NodeType.Regex] = ChildrenWalkers.walkNone; 103 this.childrenWalkers[NodeType.Null] = ChildrenWalkers.walkNone; 104 this.childrenWalkers[NodeType.ArrayLit] = ChildrenWalkers.walkUnaryExpressionChildren; 105 this.childrenWalkers[NodeType.ObjectLit] = ChildrenWalkers.walkUnaryExpressionChildren; 106 this.childrenWalkers[NodeType.Void] = ChildrenWalkers.walkUnaryExpressionChildren; 107 this.childrenWalkers[NodeType.Comma] = ChildrenWalkers.walkBinaryExpressionChildren; 108 this.childrenWalkers[NodeType.Pos] = ChildrenWalkers.walkUnaryExpressionChildren; 109 this.childrenWalkers[NodeType.Neg] = ChildrenWalkers.walkUnaryExpressionChildren; 110 this.childrenWalkers[NodeType.Delete] = ChildrenWalkers.walkUnaryExpressionChildren; 111 this.childrenWalkers[NodeType.Await] = ChildrenWalkers.walkUnaryExpressionChildren; 112 this.childrenWalkers[NodeType.In] = ChildrenWalkers.walkBinaryExpressionChildren; 113 this.childrenWalkers[NodeType.Dot] = ChildrenWalkers.walkBinaryExpressionChildren; 114 this.childrenWalkers[NodeType.From] = ChildrenWalkers.walkBinaryExpressionChildren; 115 this.childrenWalkers[NodeType.Is] = ChildrenWalkers.walkBinaryExpressionChildren; 116 this.childrenWalkers[NodeType.InstOf] = ChildrenWalkers.walkBinaryExpressionChildren; 117 this.childrenWalkers[NodeType.Typeof] = ChildrenWalkers.walkUnaryExpressionChildren; 118 this.childrenWalkers[NodeType.NumberLit] = ChildrenWalkers.walkNone; 119 this.childrenWalkers[NodeType.Name] = ChildrenWalkers.walkNone; 120 this.childrenWalkers[NodeType.TypeRef] = ChildrenWalkers.walkTypeReferenceChildren; 121 this.childrenWalkers[NodeType.Index] = ChildrenWalkers.walkBinaryExpressionChildren; 122 this.childrenWalkers[NodeType.Call] = ChildrenWalkers.walkCallExpressionChildren; 123 this.childrenWalkers[NodeType.New] = ChildrenWalkers.walkCallExpressionChildren; 124 this.childrenWalkers[NodeType.Asg] = ChildrenWalkers.walkBinaryExpressionChildren; 125 this.childrenWalkers[NodeType.AsgAdd] = ChildrenWalkers.walkBinaryExpressionChildren; 126 this.childrenWalkers[NodeType.AsgSub] = ChildrenWalkers.walkBinaryExpressionChildren; 127 this.childrenWalkers[NodeType.AsgDiv] = ChildrenWalkers.walkBinaryExpressionChildren; 128 this.childrenWalkers[NodeType.AsgMul] = ChildrenWalkers.walkBinaryExpressionChildren; 129 this.childrenWalkers[NodeType.AsgMod] = ChildrenWalkers.walkBinaryExpressionChildren; 130 this.childrenWalkers[NodeType.AsgAnd] = ChildrenWalkers.walkBinaryExpressionChildren; 131 this.childrenWalkers[NodeType.AsgXor] = ChildrenWalkers.walkBinaryExpressionChildren; 132 this.childrenWalkers[NodeType.AsgOr] = ChildrenWalkers.walkBinaryExpressionChildren; 133 this.childrenWalkers[NodeType.AsgLsh] = ChildrenWalkers.walkBinaryExpressionChildren; 134 this.childrenWalkers[NodeType.AsgRsh] = ChildrenWalkers.walkBinaryExpressionChildren; 135 this.childrenWalkers[NodeType.AsgRs2] = ChildrenWalkers.walkBinaryExpressionChildren; 136 this.childrenWalkers[NodeType.ConditionalExpression] = ChildrenWalkers.walkTrinaryExpressionChildren; 137 this.childrenWalkers[NodeType.LogOr] = ChildrenWalkers.walkBinaryExpressionChildren; 138 this.childrenWalkers[NodeType.LogAnd] = ChildrenWalkers.walkBinaryExpressionChildren; 139 this.childrenWalkers[NodeType.Or] = ChildrenWalkers.walkBinaryExpressionChildren; 140 this.childrenWalkers[NodeType.Xor] = ChildrenWalkers.walkBinaryExpressionChildren; 141 this.childrenWalkers[NodeType.And] = ChildrenWalkers.walkBinaryExpressionChildren; 142 this.childrenWalkers[NodeType.Eq] = ChildrenWalkers.walkBinaryExpressionChildren; 143 this.childrenWalkers[NodeType.Ne] = ChildrenWalkers.walkBinaryExpressionChildren; 144 this.childrenWalkers[NodeType.Eqv] = ChildrenWalkers.walkBinaryExpressionChildren; 145 this.childrenWalkers[NodeType.NEqv] = ChildrenWalkers.walkBinaryExpressionChildren; 146 this.childrenWalkers[NodeType.Lt] = ChildrenWalkers.walkBinaryExpressionChildren; 147 this.childrenWalkers[NodeType.Le] = ChildrenWalkers.walkBinaryExpressionChildren; 148 this.childrenWalkers[NodeType.Gt] = ChildrenWalkers.walkBinaryExpressionChildren; 149 this.childrenWalkers[NodeType.Ge] = ChildrenWalkers.walkBinaryExpressionChildren; 150 this.childrenWalkers[NodeType.Add] = ChildrenWalkers.walkBinaryExpressionChildren; 151 this.childrenWalkers[NodeType.Sub] = ChildrenWalkers.walkBinaryExpressionChildren; 152 this.childrenWalkers[NodeType.Mul] = ChildrenWalkers.walkBinaryExpressionChildren; 153 this.childrenWalkers[NodeType.Div] = ChildrenWalkers.walkBinaryExpressionChildren; 154 this.childrenWalkers[NodeType.Mod] = ChildrenWalkers.walkBinaryExpressionChildren; 155 this.childrenWalkers[NodeType.Lsh] = ChildrenWalkers.walkBinaryExpressionChildren; 156 this.childrenWalkers[NodeType.Rsh] = ChildrenWalkers.walkBinaryExpressionChildren; 157 this.childrenWalkers[NodeType.Rs2] = ChildrenWalkers.walkBinaryExpressionChildren; 158 this.childrenWalkers[NodeType.Not] = ChildrenWalkers.walkUnaryExpressionChildren; 159 this.childrenWalkers[NodeType.LogNot] = ChildrenWalkers.walkUnaryExpressionChildren; 160 this.childrenWalkers[NodeType.IncPre] = ChildrenWalkers.walkUnaryExpressionChildren; 161 this.childrenWalkers[NodeType.DecPre] = ChildrenWalkers.walkUnaryExpressionChildren; 162 this.childrenWalkers[NodeType.IncPost] = ChildrenWalkers.walkUnaryExpressionChildren; 163 this.childrenWalkers[NodeType.DecPost] = ChildrenWalkers.walkUnaryExpressionChildren; 164 this.childrenWalkers[NodeType.TypeAssertion] = ChildrenWalkers.walkUnaryExpressionChildren; 165 this.childrenWalkers[NodeType.FuncDecl] = ChildrenWalkers.walkFuncDeclChildren; 166 this.childrenWalkers[NodeType.Member] = ChildrenWalkers.walkBinaryExpressionChildren; 167 this.childrenWalkers[NodeType.VarDecl] = ChildrenWalkers.walkBoundDeclChildren; 168 this.childrenWalkers[NodeType.ArgDecl] = ChildrenWalkers.walkBoundDeclChildren; 169 this.childrenWalkers[NodeType.Return] = ChildrenWalkers.walkReturnStatementChildren; 170 this.childrenWalkers[NodeType.Break] = ChildrenWalkers.walkNone; 171 this.childrenWalkers[NodeType.Continue] = ChildrenWalkers.walkNone; 172 this.childrenWalkers[NodeType.Throw] = ChildrenWalkers.walkUnaryExpressionChildren; 173 this.childrenWalkers[NodeType.For] = ChildrenWalkers.walkForStatementChildren; 174 this.childrenWalkers[NodeType.ForIn] = ChildrenWalkers.walkForInStatementChildren; 175 this.childrenWalkers[NodeType.If] = ChildrenWalkers.walkIfStatementChildren; 176 this.childrenWalkers[NodeType.While] = ChildrenWalkers.walkWhileStatementChildren; 177 this.childrenWalkers[NodeType.DoWhile] = ChildrenWalkers.walkDoWhileStatementChildren; 178 this.childrenWalkers[NodeType.Block] = ChildrenWalkers.walkBlockChildren; 179 this.childrenWalkers[NodeType.Case] = ChildrenWalkers.walkCaseStatementChildren; 180 this.childrenWalkers[NodeType.Switch] = ChildrenWalkers.walkSwitchStatementChildren; 181 this.childrenWalkers[NodeType.Try] = ChildrenWalkers.walkTryChildren; 182 this.childrenWalkers[NodeType.TryCatch] = ChildrenWalkers.walkTryCatchChildren; 183 this.childrenWalkers[NodeType.TryFinally] = ChildrenWalkers.walkTryFinallyChildren; 184 this.childrenWalkers[NodeType.Finally] = ChildrenWalkers.walkFinallyChildren; 185 this.childrenWalkers[NodeType.Catch] = ChildrenWalkers.walkCatchChildren; 186 this.childrenWalkers[NodeType.List] = ChildrenWalkers.walkListChildren; 187 this.childrenWalkers[NodeType.Script] = ChildrenWalkers.walkScriptChildren; 188 this.childrenWalkers[NodeType.ClassDeclaration] = ChildrenWalkers.walkClassDeclChildren; 189 this.childrenWalkers[NodeType.InterfaceDeclaration] = ChildrenWalkers.walkTypeDeclChildren; 190 this.childrenWalkers[NodeType.ModuleDeclaration] = ChildrenWalkers.walkModuleDeclChildren; 191 this.childrenWalkers[NodeType.ImportDeclaration] = ChildrenWalkers.walkImportDeclChildren; 192 this.childrenWalkers[NodeType.With] = ChildrenWalkers.walkWithStatementChildren; 193 this.childrenWalkers[NodeType.Label] = ChildrenWalkers.walkLabelChildren; 194 this.childrenWalkers[NodeType.LabeledStatement] = ChildrenWalkers.walkLabeledStatementChildren; 195 this.childrenWalkers[NodeType.EBStart] = ChildrenWalkers.walkNone; 196 this.childrenWalkers[NodeType.GotoEB] = ChildrenWalkers.walkNone; 197 this.childrenWalkers[NodeType.EndCode] = ChildrenWalkers.walkNone; 198 this.childrenWalkers[NodeType.Error] = ChildrenWalkers.walkNone; 199 this.childrenWalkers[NodeType.Comment] = ChildrenWalkers.walkNone; 200 this.childrenWalkers[NodeType.Debugger] = ChildrenWalkers.walkNone; 201 202 // Verify the code is up to date with the enum 203 for (var e in (<any>NodeType)._map) { 204 if ((<any>this.childrenWalkers)[e] === undefined) { 205 throw new Error("initWalkers function is not up to date with enum content!"); 206 } 207 } 208 } 209 } 210 211 var globalAstWalkerFactory: AstWalkerFactory; 212 213 export function getAstWalkerFactory(): AstWalkerFactory { 214 if (!globalAstWalkerFactory) { 215 globalAstWalkerFactory = new AstWalkerFactory(); 216 } 217 return globalAstWalkerFactory; 218 } 219 220 module ChildrenWalkers { 221 export function walkNone(preAst: ASTList, parent: AST, walker: IAstWalker): void { 222 // Nothing to do 223 } 224 225 export function walkListChildren(preAst: ASTList, parent: AST, walker: IAstWalker): void { 226 var len = preAst.members.length; 227 if (walker.options.reverseSiblings) { 228 for (var i = len - 1; i >= 0; i--) { 229 if (walker.options.goNextSibling) { 230 preAst.members[i] = walker.walk(preAst.members[i], preAst); 231 } 232 } 233 } 234 else { 235 for (var i = 0; i < len; i++) { 236 if (walker.options.goNextSibling) { 237 preAst.members[i] = walker.walk(preAst.members[i], preAst); 238 } 239 } 240 } 241 } 242 243 export function walkUnaryExpressionChildren(preAst: UnaryExpression, parent: AST, walker: IAstWalker): void { 244 if (preAst.castTerm) { 245 preAst.castTerm = walker.walk(preAst.castTerm, preAst); 246 } 247 if (preAst.operand) { 248 preAst.operand = walker.walk(preAst.operand, preAst); 249 } 250 } 251 252 export function walkBinaryExpressionChildren(preAst: BinaryExpression, parent: AST, walker: IAstWalker): void { 253 if (walker.options.reverseSiblings) { 254 if (preAst.operand2) { 255 preAst.operand2 = walker.walk(preAst.operand2, preAst); 256 } 257 if ((preAst.operand1) && (walker.options.goNextSibling)) { 258 preAst.operand1 = walker.walk(preAst.operand1, preAst); 259 } 260 } else { 261 if (preAst.operand1) { 262 preAst.operand1 = walker.walk(preAst.operand1, preAst); 263 } 264 if ((preAst.operand2) && (walker.options.goNextSibling)) { 265 preAst.operand2 = walker.walk(preAst.operand2, preAst); 266 } 267 } 268 } 269 270 export function walkTypeReferenceChildren(preAst: TypeReference, parent: AST, walker: IAstWalker): void { 271 if (preAst.term) { 272 preAst.term = walker.walk(preAst.term, preAst); 273 } 274 } 275 276 export function walkCallExpressionChildren(preAst: CallExpression, parent: AST, walker: IAstWalker): void { 277 if (!walker.options.reverseSiblings) { 278 preAst.target = walker.walk(preAst.target, preAst); 279 } 280 if (preAst.arguments && (walker.options.goNextSibling)) { 281 preAst.arguments = <ASTList> walker.walk(preAst.arguments, preAst); 282 } 283 if ((walker.options.reverseSiblings) && (walker.options.goNextSibling)) { 284 preAst.target = walker.walk(preAst.target, preAst); 285 } 286 } 287 288 export function walkTrinaryExpressionChildren(preAst: ConditionalExpression, parent: AST, walker: IAstWalker): void { 289 if (preAst.operand1) { 290 preAst.operand1 = walker.walk(preAst.operand1, preAst); 291 } 292 if (preAst.operand2 && (walker.options.goNextSibling)) { 293 preAst.operand2 = walker.walk(preAst.operand2, preAst); 294 } 295 if (preAst.operand3 && (walker.options.goNextSibling)) { 296 preAst.operand3 = walker.walk(preAst.operand3, preAst); 297 } 298 } 299 300 export function walkFuncDeclChildren(preAst: FuncDecl, parent: AST, walker: IAstWalker): void { 301 if (preAst.name) { 302 preAst.name = <Identifier>walker.walk(preAst.name, preAst); 303 } 304 if (preAst.arguments && (preAst.arguments.members.length > 0) && (walker.options.goNextSibling)) { 305 preAst.arguments = <ASTList>walker.walk(preAst.arguments, preAst); 306 } 307 if (preAst.returnTypeAnnotation && (walker.options.goNextSibling)) { 308 preAst.returnTypeAnnotation = walker.walk(preAst.returnTypeAnnotation, preAst); 309 } 310 if (preAst.bod && (preAst.bod.members.length > 0) && (walker.options.goNextSibling)) { 311 preAst.bod = <ASTList>walker.walk(preAst.bod, preAst); 312 } 313 } 314 315 export function walkBoundDeclChildren(preAst: BoundDecl, parent: AST, walker: IAstWalker): void { 316 if (preAst.id) { 317 preAst.id = <Identifier>walker.walk(preAst.id, preAst); 318 } 319 if (preAst.init) { 320 preAst.init = walker.walk(preAst.init, preAst); 321 } 322 if ((preAst.typeExpr) && (walker.options.goNextSibling)) { 323 preAst.typeExpr = walker.walk(preAst.typeExpr, preAst); 324 } 325 } 326 327 export function walkReturnStatementChildren(preAst: ReturnStatement, parent: AST, walker: IAstWalker): void { 328 if (preAst.returnExpression) { 329 preAst.returnExpression = walker.walk(preAst.returnExpression, preAst); 330 } 331 } 332 333 export function walkForStatementChildren(preAst: ForStatement, parent: AST, walker: IAstWalker): void { 334 if (preAst.init) { 335 preAst.init = walker.walk(preAst.init, preAst); 336 } 337 338 if (preAst.cond && walker.options.goNextSibling) { 339 preAst.cond = walker.walk(preAst.cond, preAst); 340 } 341 342 if (preAst.incr && walker.options.goNextSibling) { 343 preAst.incr = walker.walk(preAst.incr, preAst); 344 } 345 346 if (preAst.body && walker.options.goNextSibling) { 347 preAst.body = walker.walk(preAst.body, preAst); 348 } 349 } 350 351 export function walkForInStatementChildren(preAst: ForInStatement, parent: AST, walker: IAstWalker): void { 352 preAst.lval = walker.walk(preAst.lval, preAst); 353 if (walker.options.goNextSibling) { 354 preAst.obj = walker.walk(preAst.obj, preAst); 355 } 356 if (preAst.body && (walker.options.goNextSibling)) { 357 preAst.body = walker.walk(preAst.body, preAst); 358 } 359 } 360 361 export function walkIfStatementChildren(preAst: IfStatement, parent: AST, walker: IAstWalker): void { 362 preAst.cond = walker.walk(preAst.cond, preAst); 363 if (preAst.thenBod && (walker.options.goNextSibling)) { 364 preAst.thenBod = walker.walk(preAst.thenBod, preAst); 365 } 366 if (preAst.elseBod && (walker.options.goNextSibling)) { 367 preAst.elseBod = walker.walk(preAst.elseBod, preAst); 368 } 369 } 370 371 export function walkWhileStatementChildren(preAst: WhileStatement, parent: AST, walker: IAstWalker): void { 372 preAst.cond = walker.walk(preAst.cond, preAst); 373 if (preAst.body && (walker.options.goNextSibling)) { 374 preAst.body = walker.walk(preAst.body, preAst); 375 } 376 } 377 378 export function walkDoWhileStatementChildren(preAst: DoWhileStatement, parent: AST, walker: IAstWalker): void { 379 preAst.cond = walker.walk(preAst.cond, preAst); 380 if (preAst.body && (walker.options.goNextSibling)) { 381 preAst.body = walker.walk(preAst.body, preAst); 382 } 383 } 384 385 export function walkBlockChildren(preAst: Block, parent: AST, walker: IAstWalker): void { 386 if (preAst.statements) { 387 preAst.statements = <ASTList>walker.walk(preAst.statements, preAst); 388 } 389 } 390 391 export function walkCaseStatementChildren(preAst: CaseStatement, parent: AST, walker: IAstWalker): void { 392 if (preAst.expr) { 393 preAst.expr = walker.walk(preAst.expr, preAst); 394 } 395 396 if (preAst.body && walker.options.goNextSibling) { 397 preAst.body = <ASTList>walker.walk(preAst.body, preAst); 398 } 399 } 400 401 export function walkSwitchStatementChildren(preAst: SwitchStatement, parent: AST, walker: IAstWalker): void { 402 if (preAst.val) { 403 preAst.val = walker.walk(preAst.val, preAst); 404 } 405 406 if ((preAst.caseList) && walker.options.goNextSibling) { 407 preAst.caseList = <ASTList>walker.walk(preAst.caseList, preAst); 408 } 409 } 410 411 export function walkTryChildren(preAst: Try, parent: AST, walker: IAstWalker): void { 412 if (preAst.body) { 413 preAst.body = walker.walk(preAst.body, preAst); 414 } 415 } 416 417 export function walkTryCatchChildren(preAst: TryCatch, parent: AST, walker: IAstWalker): void { 418 if (preAst.tryNode) { 419 preAst.tryNode = <Try>walker.walk(preAst.tryNode, preAst); 420 } 421 422 if ((preAst.catchNode) && walker.options.goNextSibling) { 423 preAst.catchNode = <Catch>walker.walk(preAst.catchNode, preAst); 424 } 425 } 426 427 export function walkTryFinallyChildren(preAst: TryFinally, parent: AST, walker: IAstWalker): void { 428 if (preAst.tryNode) { 429 preAst.tryNode = walker.walk(preAst.tryNode, preAst); 430 } 431 432 if (preAst.finallyNode && walker.options.goNextSibling) { 433 preAst.finallyNode = <Finally>walker.walk(preAst.finallyNode, preAst); 434 } 435 } 436 437 export function walkFinallyChildren(preAst: Finally, parent: AST, walker: IAstWalker): void { 438 if (preAst.body) { 439 preAst.body = walker.walk(preAst.body, preAst); 440 } 441 } 442 443 export function walkCatchChildren(preAst: Catch, parent: AST, walker: IAstWalker): void { 444 if (preAst.param) { 445 preAst.param = <VarDecl>walker.walk(preAst.param, preAst); 446 } 447 448 if ((preAst.body) && walker.options.goNextSibling) { 449 preAst.body = walker.walk(preAst.body, preAst); 450 } 451 } 452 453 export function walkRecordChildren(preAst: NamedDeclaration, parent: AST, walker: IAstWalker): void { 454 preAst.name = <Identifier>walker.walk(preAst.name, preAst); 455 if (walker.options.goNextSibling && preAst.members) { 456 preAst.members = <ASTList>walker.walk(preAst.members, preAst); 457 } 458 459 } 460 461 export function walkNamedTypeChildren(preAst: TypeDeclaration, parent: AST, walker: IAstWalker): void { 462 walkRecordChildren(preAst, parent, walker); 463 } 464 465 export function walkClassDeclChildren(preAst: ClassDeclaration, parent: AST, walker: IAstWalker): void { 466 walkNamedTypeChildren(preAst, parent, walker); 467 468 if (walker.options.goNextSibling && preAst.extendsList) { 469 preAst.extendsList = <ASTList>walker.walk(preAst.extendsList, preAst); 470 } 471 472 if (walker.options.goNextSibling && preAst.implementsList) { 473 preAst.implementsList = <ASTList>walker.walk(preAst.implementsList, preAst); 474 } 475 } 476 477 export function walkScriptChildren(preAst: Script, parent: AST, walker: IAstWalker): void { 478 if (preAst.bod) { 479 preAst.bod = <ASTList>walker.walk(preAst.bod, preAst); 480 } 481 } 482 483 export function walkTypeDeclChildren(preAst: InterfaceDeclaration, parent: AST, walker: IAstWalker): void { 484 walkNamedTypeChildren(preAst, parent, walker); 485 486 // walked arguments as part of members 487 if (walker.options.goNextSibling && preAst.extendsList) { 488 preAst.extendsList = <ASTList>walker.walk(preAst.extendsList, preAst); 489 } 490 491 if (walker.options.goNextSibling && preAst.implementsList) { 492 preAst.implementsList = <ASTList>walker.walk(preAst.implementsList, preAst); 493 } 494 } 495 496 export function walkModuleDeclChildren(preAst: ModuleDeclaration, parent: AST, walker: IAstWalker): void { 497 walkRecordChildren(preAst, parent, walker); 498 } 499 500 export function walkImportDeclChildren(preAst: ImportDeclaration, parent: AST, walker: IAstWalker): void { 501 if (preAst.id) { 502 preAst.id = <Identifier>walker.walk(preAst.id, preAst); 503 } 504 if (preAst.alias) { 505 preAst.alias = walker.walk(preAst.alias, preAst); 506 } 507 } 508 509 export function walkWithStatementChildren(preAst: WithStatement, parent: AST, walker: IAstWalker): void { 510 if (preAst.expr) { 511 preAst.expr = walker.walk(preAst.expr, preAst); 512 } 513 514 if (preAst.body && walker.options.goNextSibling) { 515 preAst.body = walker.walk(preAst.body, preAst); 516 } 517 } 518 519 export function walkLabelChildren(preAst: Label, parent: AST, walker: IAstWalker): void { 520 //TODO: Walk "id"? 521 } 522 523 export function walkLabeledStatementChildren(preAst: LabeledStatement, parent: AST, walker: IAstWalker): void { 524 preAst.labels = <ASTList>walker.walk(preAst.labels, preAst); 525 if (walker.options.goNextSibling) { 526 preAst.stmt = walker.walk(preAst.stmt, preAst); 527 } 528 } 529 } 530}