Fix: merge conflict
[myslice.git] / to-be-integrated / third-party / codemirror-3.15 / test / lint / walk.js
1 // AST walker module for Mozilla Parser API compatible trees
2
3 (function(exports) {
4   "use strict";
5
6   // A simple walk is one where you simply specify callbacks to be
7   // called on specific nodes. The last two arguments are optional. A
8   // simple use would be
9   //
10   //     walk.simple(myTree, {
11   //         Expression: function(node) { ... }
12   //     });
13   //
14   // to do something with all expressions. All Parser API node types
15   // can be used to identify node types, as well as Expression,
16   // Statement, and ScopeBody, which denote categories of nodes.
17   //
18   // The base argument can be used to pass a custom (recursive)
19   // walker, and state can be used to give this walked an initial
20   // state.
21   exports.simple = function(node, visitors, base, state) {
22     if (!base) base = exports;
23     function c(node, st, override) {
24       var type = override || node.type, found = visitors[type];
25       if (found) found(node, st);
26       base[type](node, st, c);
27     }
28     c(node, state);
29   };
30
31   // A recursive walk is one where your functions override the default
32   // walkers. They can modify and replace the state parameter that's
33   // threaded through the walk, and can opt how and whether to walk
34   // their child nodes (by calling their third argument on these
35   // nodes).
36   exports.recursive = function(node, state, funcs, base) {
37     var visitor = exports.make(funcs, base);
38     function c(node, st, override) {
39       visitor[override || node.type](node, st, c);
40     }
41     c(node, state);
42   };
43
44   // Used to create a custom walker. Will fill in all missing node
45   // type properties with the defaults.
46   exports.make = function(funcs, base) {
47     if (!base) base = exports;
48     var visitor = {};
49     for (var type in base)
50       visitor[type] = funcs.hasOwnProperty(type) ? funcs[type] : base[type];
51     return visitor;
52   };
53
54   function skipThrough(node, st, c) { c(node, st); }
55   function ignore(node, st, c) {}
56
57   // Node walkers.
58
59   exports.Program = exports.BlockStatement = function(node, st, c) {
60     for (var i = 0; i < node.body.length; ++i)
61       c(node.body[i], st, "Statement");
62   };
63   exports.Statement = skipThrough;
64   exports.EmptyStatement = ignore;
65   exports.ExpressionStatement = function(node, st, c) {
66     c(node.expression, st, "Expression");
67   };
68   exports.IfStatement = function(node, st, c) {
69     c(node.test, st, "Expression");
70     c(node.consequent, st, "Statement");
71     if (node.alternate) c(node.alternate, st, "Statement");
72   };
73   exports.LabeledStatement = function(node, st, c) {
74     c(node.body, st, "Statement");
75   };
76   exports.BreakStatement = exports.ContinueStatement = ignore;
77   exports.WithStatement = function(node, st, c) {
78     c(node.object, st, "Expression");
79     c(node.body, st, "Statement");
80   };
81   exports.SwitchStatement = function(node, st, c) {
82     c(node.discriminant, st, "Expression");
83     for (var i = 0; i < node.cases.length; ++i) {
84       var cs = node.cases[i];
85       if (cs.test) c(cs.test, st, "Expression");
86       for (var j = 0; j < cs.consequent.length; ++j)
87         c(cs.consequent[j], st, "Statement");
88     }
89   };
90   exports.ReturnStatement = function(node, st, c) {
91     if (node.argument) c(node.argument, st, "Expression");
92   };
93   exports.ThrowStatement = function(node, st, c) {
94     c(node.argument, st, "Expression");
95   };
96   exports.TryStatement = function(node, st, c) {
97     c(node.block, st, "Statement");
98     for (var i = 0; i < node.handlers.length; ++i)
99       c(node.handlers[i].body, st, "ScopeBody");
100     if (node.finalizer) c(node.finalizer, st, "Statement");
101   };
102   exports.WhileStatement = function(node, st, c) {
103     c(node.test, st, "Expression");
104     c(node.body, st, "Statement");
105   };
106   exports.DoWhileStatement = exports.WhileStatement;
107   exports.ForStatement = function(node, st, c) {
108     if (node.init) c(node.init, st, "ForInit");
109     if (node.test) c(node.test, st, "Expression");
110     if (node.update) c(node.update, st, "Expression");
111     c(node.body, st, "Statement");
112   };
113   exports.ForInStatement = function(node, st, c) {
114     c(node.left, st, "ForInit");
115     c(node.right, st, "Expression");
116     c(node.body, st, "Statement");
117   };
118   exports.ForInit = function(node, st, c) {
119     if (node.type == "VariableDeclaration") c(node, st);
120     else c(node, st, "Expression");
121   };
122   exports.DebuggerStatement = ignore;
123
124   exports.FunctionDeclaration = function(node, st, c) {
125     c(node, st, "Function");
126   };
127   exports.VariableDeclaration = function(node, st, c) {
128     for (var i = 0; i < node.declarations.length; ++i) {
129       var decl = node.declarations[i];
130       if (decl.init) c(decl.init, st, "Expression");
131     }
132   };
133
134   exports.Function = function(node, st, c) {
135     c(node.body, st, "ScopeBody");
136   };
137   exports.ScopeBody = function(node, st, c) {
138     c(node, st, "Statement");
139   };
140
141   exports.Expression = skipThrough;
142   exports.ThisExpression = ignore;
143   exports.ArrayExpression = function(node, st, c) {
144     for (var i = 0; i < node.elements.length; ++i) {
145       var elt = node.elements[i];
146       if (elt) c(elt, st, "Expression");
147     }
148   };
149   exports.ObjectExpression = function(node, st, c) {
150     for (var i = 0; i < node.properties.length; ++i)
151       c(node.properties[i].value, st, "Expression");
152   };
153   exports.FunctionExpression = exports.FunctionDeclaration;
154   exports.SequenceExpression = function(node, st, c) {
155     for (var i = 0; i < node.expressions.length; ++i)
156       c(node.expressions[i], st, "Expression");
157   };
158   exports.UnaryExpression = exports.UpdateExpression = function(node, st, c) {
159     c(node.argument, st, "Expression");
160   };
161   exports.BinaryExpression = exports.AssignmentExpression = exports.LogicalExpression = function(node, st, c) {
162     c(node.left, st, "Expression");
163     c(node.right, st, "Expression");
164   };
165   exports.ConditionalExpression = function(node, st, c) {
166     c(node.test, st, "Expression");
167     c(node.consequent, st, "Expression");
168     c(node.alternate, st, "Expression");
169   };
170   exports.NewExpression = exports.CallExpression = function(node, st, c) {
171     c(node.callee, st, "Expression");
172     if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
173       c(node.arguments[i], st, "Expression");
174   };
175   exports.MemberExpression = function(node, st, c) {
176     c(node.object, st, "Expression");
177     if (node.computed) c(node.property, st, "Expression");
178   };
179   exports.Identifier = exports.Literal = ignore;
180
181   // A custom walker that keeps track of the scope chain and the
182   // variables defined in it.
183   function makeScope(prev) {
184     return {vars: Object.create(null), prev: prev};
185   }
186   exports.scopeVisitor = exports.make({
187     Function: function(node, scope, c) {
188       var inner = makeScope(scope);
189       for (var i = 0; i < node.params.length; ++i)
190         inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
191       if (node.id) {
192         var decl = node.type == "FunctionDeclaration";
193         (decl ? scope : inner).vars[node.id.name] =
194           {type: decl ? "function" : "function name", node: node.id};
195       }
196       c(node.body, inner, "ScopeBody");
197     },
198     TryStatement: function(node, scope, c) {
199       c(node.block, scope, "Statement");
200       for (var i = 0; i < node.handlers.length; ++i) {
201         var handler = node.handlers[i], inner = makeScope(scope);
202         inner.vars[handler.param.name] = {type: "catch clause", node: handler.param};
203         c(handler.body, inner, "ScopeBody");
204       }
205       if (node.finalizer) c(node.finalizer, scope, "Statement");
206     },
207     VariableDeclaration: function(node, scope, c) {
208       for (var i = 0; i < node.declarations.length; ++i) {
209         var decl = node.declarations[i];
210         scope.vars[decl.id.name] = {type: "var", node: decl.id};
211         if (decl.init) c(decl.init, scope, "Expression");
212       }
213     }
214   });
215
216 })(typeof exports == "undefined" ? acorn.walk = {} : exports);