• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}