1/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6"use strict";
7
8const Cu = Components.utils;
9
10const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
11const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
12const { console } = require("resource://gre/modules/Console.jsm");
13const DevToolsUtils = require("devtools/shared/DevToolsUtils");
14
15XPCOMUtils.defineLazyModuleGetter(this,
16  "Reflect", "resource://gre/modules/reflect.jsm");
17
18this.EXPORTED_SYMBOLS = ["Parser", "ParserHelpers", "SyntaxTreeVisitor"];
19
20/**
21 * A JS parser using the reflection API.
22 */
23this.Parser = function Parser() {
24  this._cache = new Map();
25  this.errors = [];
26  this.logExceptions = true;
27};
28
29Parser.prototype = {
30  /**
31   * Gets a collection of parser methods for a specified source.
32   *
33   * @param string source
34   *        The source text content.
35   * @param string url [optional]
36   *        The source url. The AST nodes will be cached, so you can use this
37   *        identifier to avoid parsing the whole source again.
38   */
39  get(source, url = "") {
40    // Try to use the cached AST nodes, to avoid useless parsing operations.
41    if (this._cache.has(url)) {
42      return this._cache.get(url);
43    }
44
45    // The source may not necessarily be JS, in which case we need to extract
46    // all the scripts. Fastest/easiest way is with a regular expression.
47    // Don't worry, the rules of using a <script> tag are really strict,
48    // this will work.
49    let regexp = /<script[^>]*?(?:>([^]*?)<\/script\s*>|\/>)/gim;
50    let syntaxTrees = [];
51    let scriptMatches = [];
52    let scriptMatch;
53
54    if (source.match(/^\s*</)) {
55      // First non whitespace character is &lt, so most definitely HTML.
56      while ((scriptMatch = regexp.exec(source))) {
57        // Contents are captured at index 1 or nothing: Self-closing scripts
58        // won't capture code content
59        scriptMatches.push(scriptMatch[1] || "");
60      }
61    }
62
63    // If there are no script matches, send the whole source directly to the
64    // reflection API to generate the AST nodes.
65    if (!scriptMatches.length) {
66      // Reflect.parse throws when encounters a syntax error.
67      try {
68        let nodes = Reflect.parse(source);
69        let length = source.length;
70        syntaxTrees.push(new SyntaxTree(nodes, url, length));
71      } catch (e) {
72        this.errors.push(e);
73        if (this.logExceptions) {
74          DevToolsUtils.reportException(url, e);
75        }
76      }
77    } else {
78      // Generate the AST nodes for each script.
79      for (let script of scriptMatches) {
80        // Reflect.parse throws when encounters a syntax error.
81        try {
82          let nodes = Reflect.parse(script);
83          let offset = source.indexOf(script);
84          let length = script.length;
85          syntaxTrees.push(new SyntaxTree(nodes, url, length, offset));
86        } catch (e) {
87          this.errors.push(e);
88          if (this.logExceptions) {
89            DevToolsUtils.reportException(url, e);
90          }
91        }
92      }
93    }
94
95    let pool = new SyntaxTreesPool(syntaxTrees, url);
96
97    // Cache the syntax trees pool by the specified url. This is entirely
98    // optional, but it's strongly encouraged to cache ASTs because
99    // generating them can be costly with big/complex sources.
100    if (url) {
101      this._cache.set(url, pool);
102    }
103
104    return pool;
105  },
106
107  /**
108   * Clears all the parsed sources from cache.
109   */
110  clearCache() {
111    this._cache.clear();
112  },
113
114  /**
115   * Clears the AST for a particular source.
116   *
117   * @param String url
118   *        The URL of the source that is being cleared.
119   */
120  clearSource(url) {
121    this._cache.delete(url);
122  },
123
124  _cache: null,
125  errors: null
126};
127
128/**
129 * A pool handling a collection of AST nodes generated by the reflection API.
130 *
131 * @param object syntaxTrees
132 *        A collection of AST nodes generated for a source.
133 * @param string url [optional]
134 *        The source url.
135 */
136function SyntaxTreesPool(syntaxTrees, url = "<unknown>") {
137  this._trees = syntaxTrees;
138  this._url = url;
139  this._cache = new Map();
140}
141
142SyntaxTreesPool.prototype = {
143  /**
144   * @see SyntaxTree.prototype.getIdentifierAt
145   */
146  getIdentifierAt({ line, column, scriptIndex, ignoreLiterals }) {
147    return this._call("getIdentifierAt",
148      scriptIndex, line, column, ignoreLiterals)[0];
149  },
150
151  /**
152   * @see SyntaxTree.prototype.getNamedFunctionDefinitions
153   */
154  getNamedFunctionDefinitions(substring) {
155    return this._call("getNamedFunctionDefinitions", -1, substring);
156  },
157
158  /**
159   * @return SyntaxTree
160   *         The last tree in this._trees
161   */
162  getLastSyntaxTree() {
163    return this._trees[this._trees.length - 1];
164  },
165
166  /**
167   * Gets the total number of scripts in the parent source.
168   * @return number
169   */
170  get scriptCount() {
171    return this._trees.length;
172  },
173
174  /**
175   * Finds the start and length of the script containing the specified offset
176   * relative to its parent source.
177   *
178   * @param number atOffset
179   *        The offset relative to the parent source.
180   * @return object
181   *         The offset and length relative to the enclosing script.
182   */
183  getScriptInfo(atOffset) {
184    let info = { start: -1, length: -1, index: -1 };
185
186    for (let { offset, length } of this._trees) {
187      info.index++;
188      if (offset <= atOffset && offset + length >= atOffset) {
189        info.start = offset;
190        info.length = length;
191        return info;
192      }
193    }
194
195    info.index = -1;
196    return info;
197  },
198
199  /**
200   * Handles a request for a specific or all known syntax trees.
201   *
202   * @param string functionName
203   *        The function name to call on the SyntaxTree instances.
204   * @param number syntaxTreeIndex
205   *        The syntax tree for which to handle the request. If the tree at
206   *        the specified index isn't found, the accumulated results for all
207   *        syntax trees are returned.
208   * @param any params
209   *        Any kind params to pass to the request function.
210   * @return array
211   *         The results given by all known syntax trees.
212   */
213  _call(functionName, syntaxTreeIndex, ...params) {
214    let results = [];
215    let requestId = [functionName, syntaxTreeIndex, params].toSource();
216
217    if (this._cache.has(requestId)) {
218      return this._cache.get(requestId);
219    }
220
221    let requestedTree = this._trees[syntaxTreeIndex];
222    let targettedTrees = requestedTree ? [requestedTree] : this._trees;
223
224    for (let syntaxTree of targettedTrees) {
225      try {
226        let parseResults = syntaxTree[functionName].apply(syntaxTree, params);
227        if (parseResults) {
228          parseResults.sourceUrl = syntaxTree.url;
229          parseResults.scriptLength = syntaxTree.length;
230          parseResults.scriptOffset = syntaxTree.offset;
231          results.push(parseResults);
232        }
233      } catch (e) {
234        // Can't guarantee that the tree traversal logic is forever perfect :)
235        // Language features may be added, in which case the recursive methods
236        // need to be updated. If an exception is thrown here, file a bug.
237        DevToolsUtils.reportException(
238          `Syntax tree visitor for ${this._url}`, e);
239      }
240    }
241    this._cache.set(requestId, results);
242    return results;
243  },
244
245  _trees: null,
246  _cache: null
247};
248
249/**
250 * A collection of AST nodes generated by the reflection API.
251 *
252 * @param object nodes
253 *        The AST nodes.
254 * @param string url
255 *        The source url.
256 * @param number length
257 *        The total number of chars of the parsed script in the parent source.
258 * @param number offset [optional]
259 *        The char offset of the parsed script in the parent source.
260 */
261function SyntaxTree(nodes, url, length, offset = 0) {
262  this.AST = nodes;
263  this.url = url;
264  this.length = length;
265  this.offset = offset;
266}
267
268SyntaxTree.prototype = {
269  /**
270   * Gets the identifier at the specified location.
271   *
272   * @param number line
273   *        The line in the source.
274   * @param number column
275   *        The column in the source.
276   * @param boolean ignoreLiterals
277   *        Specifies if alone literals should be ignored.
278   * @return object
279   *         An object containing identifier information as { name, location,
280   *         evalString } properties, or null if nothing is found.
281   */
282  getIdentifierAt(line, column, ignoreLiterals) {
283    let info = null;
284
285    SyntaxTreeVisitor.walk(this.AST, {
286      /**
287       * Callback invoked for each identifier node.
288       * @param Node node
289       */
290      onIdentifier(node) {
291        if (ParserHelpers.nodeContainsPoint(node, line, column)) {
292          info = {
293            name: node.name,
294            location: ParserHelpers.getNodeLocation(node),
295            evalString: ParserHelpers.getIdentifierEvalString(node)
296          };
297
298          // Abruptly halt walking the syntax tree.
299          SyntaxTreeVisitor.break = true;
300        }
301      },
302
303      /**
304       * Callback invoked for each literal node.
305       * @param Node node
306       */
307      onLiteral(node) {
308        if (!ignoreLiterals) {
309          this.onIdentifier(node);
310        }
311      },
312
313      /**
314       * Callback invoked for each 'this' node.
315       * @param Node node
316       */
317      onThisExpression(node) {
318        this.onIdentifier(node);
319      }
320    });
321
322    return info;
323  },
324
325  /**
326   * Searches for all function definitions (declarations and expressions)
327   * whose names (or inferred names) contain a string.
328   *
329   * @param string substring
330   *        The string to be contained in the function name (or inferred name).
331   *        Can be an empty string to match all functions.
332   * @return array
333   *         All the matching function declarations and expressions, as
334   *         { functionName, functionLocation ... } object hashes.
335   */
336  getNamedFunctionDefinitions(substring) {
337    let lowerCaseToken = substring.toLowerCase();
338    let store = [];
339
340    function includesToken(name) {
341      return name && name.toLowerCase().includes(lowerCaseToken);
342    }
343
344    SyntaxTreeVisitor.walk(this.AST, {
345      /**
346       * Callback invoked for each function declaration node.
347       * @param Node node
348       */
349      onFunctionDeclaration(node) {
350        let functionName = node.id.name;
351        if (includesToken(functionName)) {
352          store.push({
353            functionName: functionName,
354            functionLocation: ParserHelpers.getNodeLocation(node)
355          });
356        }
357      },
358
359      /**
360       * Callback invoked for each function expression node.
361       * @param Node node
362       */
363      onFunctionExpression(node) {
364        // Function expressions don't necessarily have a name.
365        let functionName = node.id ? node.id.name : "";
366        let functionLocation = ParserHelpers.getNodeLocation(node);
367
368        // Infer the function's name from an enclosing syntax tree node.
369        let inferredInfo = ParserHelpers.inferFunctionExpressionInfo(node);
370        let inferredName = inferredInfo.name;
371        let inferredChain = inferredInfo.chain;
372        let inferredLocation = inferredInfo.loc;
373
374        // Current node may be part of a larger assignment expression stack.
375        if (node._parent.type == "AssignmentExpression") {
376          this.onFunctionExpression(node._parent);
377        }
378
379        if (includesToken(functionName) || includesToken(inferredName)) {
380          store.push({
381            functionName: functionName,
382            functionLocation: functionLocation,
383            inferredName: inferredName,
384            inferredChain: inferredChain,
385            inferredLocation: inferredLocation
386          });
387        }
388      },
389
390      /**
391       * Callback invoked for each arrow expression node.
392       * @param Node node
393       */
394      onArrowFunctionExpression(node) {
395        // Infer the function's name from an enclosing syntax tree node.
396        let inferredInfo = ParserHelpers.inferFunctionExpressionInfo(node);
397        let inferredName = inferredInfo.name;
398        let inferredChain = inferredInfo.chain;
399        let inferredLocation = inferredInfo.loc;
400
401        // Current node may be part of a larger assignment expression stack.
402        if (node._parent.type == "AssignmentExpression") {
403          this.onFunctionExpression(node._parent);
404        }
405
406        if (includesToken(inferredName)) {
407          store.push({
408            inferredName: inferredName,
409            inferredChain: inferredChain,
410            inferredLocation: inferredLocation
411          });
412        }
413      }
414    });
415
416    return store;
417  },
418
419  AST: null,
420  url: "",
421  length: 0,
422  offset: 0
423};
424
425/**
426 * Parser utility methods.
427 */
428var ParserHelpers = {
429  /**
430   * Gets the location information for a node. Not all nodes have a
431   * location property directly attached, or the location information
432   * is incorrect, in which cases it's accessible via the parent.
433   *
434   * @param Node node
435   *        The node who's location needs to be retrieved.
436   * @return object
437   *         An object containing { line, column } information.
438   */
439  getNodeLocation(node) {
440    if (node.type != "Identifier") {
441      return node.loc;
442    }
443    // Work around the fact that some identifier nodes don't have the
444    // correct location attached.
445    let { loc: parentLocation, type: parentType } = node._parent;
446    let { loc: nodeLocation } = node;
447    if (!nodeLocation) {
448      if (parentType == "FunctionDeclaration" ||
449          parentType == "FunctionExpression") {
450        // e.g. "function foo() {}" or "{ bar: function foo() {} }"
451        // The location is unavailable for the identifier node "foo".
452        let loc = Cu.cloneInto(parentLocation, {});
453        loc.end.line = loc.start.line;
454        loc.end.column = loc.start.column + node.name.length;
455        return loc;
456      }
457      if (parentType == "MemberExpression") {
458        // e.g. "foo.bar"
459        // The location is unavailable for the identifier node "bar".
460        let loc = Cu.cloneInto(parentLocation, {});
461        loc.start.line = loc.end.line;
462        loc.start.column = loc.end.column - node.name.length;
463        return loc;
464      }
465      if (parentType == "LabeledStatement") {
466        // e.g. label: ...
467        // The location is unavailable for the identifier node "label".
468        let loc = Cu.cloneInto(parentLocation, {});
469        loc.end.line = loc.start.line;
470        loc.end.column = loc.start.column + node.name.length;
471        return loc;
472      }
473      if (parentType == "ContinueStatement" || parentType == "BreakStatement") {
474        // e.g. continue label; or break label;
475        // The location is unavailable for the identifier node "label".
476        let loc = Cu.cloneInto(parentLocation, {});
477        loc.start.line = loc.end.line;
478        loc.start.column = loc.end.column - node.name.length;
479        return loc;
480      }
481    } else if (parentType == "VariableDeclarator") {
482      // e.g. "let foo = 42"
483      // The location incorrectly spans across the whole variable declaration,
484      // not just the identifier node "foo".
485      let loc = Cu.cloneInto(nodeLocation, {});
486      loc.end.line = loc.start.line;
487      loc.end.column = loc.start.column + node.name.length;
488      return loc;
489    }
490    return node.loc;
491  },
492
493  /**
494   * Checks if a node's bounds contains a specified line.
495   *
496   * @param Node node
497   *        The node's bounds used as reference.
498   * @param number line
499   *        The line number to check.
500   * @return boolean
501   *         True if the line and column is contained in the node's bounds.
502   */
503  nodeContainsLine(node, line) {
504    let { start: s, end: e } = this.getNodeLocation(node);
505    return s.line <= line && e.line >= line;
506  },
507
508  /**
509   * Checks if a node's bounds contains a specified line and column.
510   *
511   * @param Node node
512   *        The node's bounds used as reference.
513   * @param number line
514   *        The line number to check.
515   * @param number column
516   *        The column number to check.
517   * @return boolean
518   *         True if the line and column is contained in the node's bounds.
519   */
520  nodeContainsPoint(node, line, column) {
521    let { start: s, end: e } = this.getNodeLocation(node);
522    return s.line == line && e.line == line &&
523           s.column <= column && e.column >= column;
524  },
525
526  /**
527   * Try to infer a function expression's name & other details based on the
528   * enclosing VariableDeclarator, AssignmentExpression or ObjectExpression.
529   *
530   * @param Node node
531   *        The function expression node to get the name for.
532   * @return object
533   *         The inferred function name, or empty string can't infer the name,
534   *         along with the chain (a generic "context", like a prototype chain)
535   *         and location if available.
536   */
537  inferFunctionExpressionInfo(node) {
538    let parent = node._parent;
539
540    // A function expression may be defined in a variable declarator,
541    // e.g. var foo = function(){}, in which case it is possible to infer
542    // the variable name.
543    if (parent.type == "VariableDeclarator") {
544      return {
545        name: parent.id.name,
546        chain: null,
547        loc: this.getNodeLocation(parent.id)
548      };
549    }
550
551    // Function expressions can also be defined in assignment expressions,
552    // e.g. foo = function(){} or foo.bar = function(){}, in which case it is
553    // possible to infer the assignee name ("foo" and "bar" respectively).
554    if (parent.type == "AssignmentExpression") {
555      let propertyChain = this._getMemberExpressionPropertyChain(parent.left);
556      let propertyLeaf = propertyChain.pop();
557      return {
558        name: propertyLeaf,
559        chain: propertyChain,
560        loc: this.getNodeLocation(parent.left)
561      };
562    }
563
564    // If a function expression is defined in an object expression,
565    // e.g. { foo: function(){} }, then it is possible to infer the name
566    // from the corresponding property.
567    if (parent.type == "ObjectExpression") {
568      let propertyKey = this._getObjectExpressionPropertyKeyForValue(node);
569      let propertyChain = this._getObjectExpressionPropertyChain(parent);
570      let propertyLeaf = propertyKey.name;
571      return {
572        name: propertyLeaf,
573        chain: propertyChain,
574        loc: this.getNodeLocation(propertyKey)
575      };
576    }
577
578    // Can't infer the function expression's name.
579    return {
580      name: "",
581      chain: null,
582      loc: null
583    };
584  },
585
586  /**
587   * Gets the name of an object expression's property to which a specified
588   * value is assigned.
589   *
590   * Used for inferring function expression information and retrieving
591   * an identifier evaluation string.
592   *
593   * For example, if "node" represents the "bar" identifier in a hypothetical
594   * "{ foo: bar }" object expression, the returned node is the "foo"
595   * identifier.
596   *
597   * @param Node node
598   *        The value node in an object expression.
599   * @return object
600   *         The key identifier node in the object expression.
601   */
602  _getObjectExpressionPropertyKeyForValue(node) {
603    let parent = node._parent;
604    if (parent.type != "ObjectExpression") {
605      return null;
606    }
607    for (let property of parent.properties) {
608      if (property.value == node) {
609        return property.key;
610      }
611    }
612    return null;
613  },
614
615  /**
616   * Gets an object expression's property chain to its parent
617   * variable declarator or assignment expression, if available.
618   *
619   * Used for inferring function expression information and retrieving
620   * an identifier evaluation string.
621   *
622   * For example, if node represents the "baz: {}" object expression in a
623   * hypothetical "foo = { bar: { baz: {} } }" assignment expression, the
624   * returned chain is ["foo", "bar", "baz"].
625   *
626   * @param Node node
627   *        The object expression node to begin the scan from.
628   * @param array aStore [optional]
629   *        The chain to store the nodes into.
630   * @return array
631   *         The chain to the parent variable declarator, as strings.
632   */
633  _getObjectExpressionPropertyChain(node, aStore = []) {
634    switch (node.type) {
635      case "ObjectExpression":
636        this._getObjectExpressionPropertyChain(node._parent, aStore);
637        let propertyKey = this._getObjectExpressionPropertyKeyForValue(node);
638        if (propertyKey) {
639          aStore.push(propertyKey.name);
640        }
641        break;
642      // Handle "var foo = { ... }" variable declarators.
643      case "VariableDeclarator":
644        aStore.push(node.id.name);
645        break;
646      // Handle "foo.bar = { ... }" assignment expressions, since they're
647      // commonly used when defining an object's prototype methods; e.g:
648      // "Foo.prototype = { ... }".
649      case "AssignmentExpression":
650        this._getMemberExpressionPropertyChain(node.left, aStore);
651        break;
652      // Additionally handle stuff like "foo = bar.baz({ ... })", because it's
653      // commonly used in prototype-based inheritance in many libraries; e.g:
654      // "Foo = Bar.extend({ ... })".
655      case "NewExpression":
656      case "CallExpression":
657        this._getObjectExpressionPropertyChain(node._parent, aStore);
658        break;
659    }
660    return aStore;
661  },
662
663  /**
664   * Gets a member expression's property chain.
665   *
666   * Used for inferring function expression information and retrieving
667   * an identifier evaluation string.
668   *
669   * For example, if node represents a hypothetical "foo.bar.baz"
670   * member expression, the returned chain ["foo", "bar", "baz"].
671   *
672   * More complex expressions like foo.bar().baz are intentionally not handled.
673   *
674   * @param Node node
675   *        The member expression node to begin the scan from.
676   * @param array store [optional]
677   *        The chain to store the nodes into.
678   * @return array
679   *         The full member chain, as strings.
680   */
681  _getMemberExpressionPropertyChain(node, store = []) {
682    switch (node.type) {
683      case "MemberExpression":
684        this._getMemberExpressionPropertyChain(node.object, store);
685        this._getMemberExpressionPropertyChain(node.property, store);
686        break;
687      case "ThisExpression":
688        store.push("this");
689        break;
690      case "Identifier":
691        store.push(node.name);
692        break;
693    }
694    return store;
695  },
696
697  /**
698   * Returns an evaluation string which can be used to obtain the
699   * current value for the respective identifier.
700   *
701   * @param Node node
702   *        The leaf node (e.g. Identifier, Literal) to begin the scan from.
703   * @return string
704   *         The corresponding evaluation string, or empty string if
705   *         the specified leaf node can't be used.
706   */
707  getIdentifierEvalString(node) {
708    switch (node._parent.type) {
709      case "ObjectExpression":
710        // If the identifier is the actual property value, it can be used
711        // directly as an evaluation string. Otherwise, construct the property
712        // access chain, since the value might have changed.
713        if (!this._getObjectExpressionPropertyKeyForValue(node)) {
714          let propertyChain =
715            this._getObjectExpressionPropertyChain(node._parent);
716          let propertyLeaf = node.name;
717          return [...propertyChain, propertyLeaf].join(".");
718        }
719        break;
720      case "MemberExpression":
721        // Make sure this is a property identifier, not the parent object.
722        if (node._parent.property == node) {
723          return this._getMemberExpressionPropertyChain(node._parent).join(".");
724        }
725        break;
726    }
727    switch (node.type) {
728      case "ThisExpression":
729        return "this";
730      case "Identifier":
731        return node.name;
732      case "Literal":
733        return uneval(node.value);
734      default:
735        return "";
736    }
737  }
738};
739
740/**
741 * A visitor for a syntax tree generated by the reflection API.
742 * See https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API.
743 *
744 * All node types implement the following interface:
745 * interface Node {
746 *   type: string;
747 *   loc: SourceLocation | null;
748 * }
749 */
750var SyntaxTreeVisitor = {
751  /**
752   * Walks a syntax tree.
753   *
754   * @param object tree
755   *        The AST nodes generated by the reflection API
756   * @param object callbacks
757   *        A map of all the callbacks to invoke when passing through certain
758   *        types of noes (e.g: onFunctionDeclaration, onBlockStatement etc.).
759   */
760  walk(tree, callbacks) {
761    this.break = false;
762    this[tree.type](tree, callbacks);
763  },
764
765  /**
766   * Filters all the nodes in this syntax tree based on a predicate.
767   *
768   * @param object tree
769   *        The AST nodes generated by the reflection API
770   * @param function predicate
771   *        The predicate ran on each node.
772   * @return array
773   *         An array of nodes validating the predicate.
774   */
775  filter(tree, predicate) {
776    let store = [];
777    this.walk(tree, {
778      onNode: e => {
779        if (predicate(e)) {
780          store.push(e);
781        }
782      }
783    });
784    return store;
785  },
786
787  /**
788   * A flag checked on each node in the syntax tree. If true, walking is
789   * abruptly halted.
790   */
791  break: false,
792
793  /**
794   * A complete program source tree.
795   *
796   * interface Program <: Node {
797   *   type: "Program";
798   *   body: [ Statement ];
799   * }
800   */
801  Program(node, callbacks) {
802    if (callbacks.onProgram) {
803      callbacks.onProgram(node);
804    }
805    for (let statement of node.body) {
806      this[statement.type](statement, node, callbacks);
807    }
808  },
809
810  /**
811   * Any statement.
812   *
813   * interface Statement <: Node { }
814   */
815  Statement(node, parent, callbacks) {
816    node._parent = parent;
817
818    if (this.break) {
819      return;
820    }
821    if (callbacks.onNode) {
822      if (callbacks.onNode(node, parent) === false) {
823        return;
824      }
825    }
826    if (callbacks.onStatement) {
827      callbacks.onStatement(node);
828    }
829  },
830
831  /**
832   * An empty statement, i.e., a solitary semicolon.
833   *
834   * interface EmptyStatement <: Statement {
835   *   type: "EmptyStatement";
836   * }
837   */
838  EmptyStatement(node, parent, callbacks) {
839    node._parent = parent;
840
841    if (this.break) {
842      return;
843    }
844    if (callbacks.onNode) {
845      if (callbacks.onNode(node, parent) === false) {
846        return;
847      }
848    }
849    if (callbacks.onEmptyStatement) {
850      callbacks.onEmptyStatement(node);
851    }
852  },
853
854  /**
855   * A block statement, i.e., a sequence of statements surrounded by braces.
856   *
857   * interface BlockStatement <: Statement {
858   *   type: "BlockStatement";
859   *   body: [ Statement ];
860   * }
861   */
862  BlockStatement(node, parent, callbacks) {
863    node._parent = parent;
864
865    if (this.break) {
866      return;
867    }
868    if (callbacks.onNode) {
869      if (callbacks.onNode(node, parent) === false) {
870        return;
871      }
872    }
873    if (callbacks.onBlockStatement) {
874      callbacks.onBlockStatement(node);
875    }
876    for (let statement of node.body) {
877      this[statement.type](statement, node, callbacks);
878    }
879  },
880
881  /**
882   * An expression statement, i.e., a statement consisting of a single
883   * expression.
884   *
885   * interface ExpressionStatement <: Statement {
886   *   type: "ExpressionStatement";
887   *   expression: Expression;
888   * }
889   */
890  ExpressionStatement(node, parent, callbacks) {
891    node._parent = parent;
892
893    if (this.break) {
894      return;
895    }
896    if (callbacks.onNode) {
897      if (callbacks.onNode(node, parent) === false) {
898        return;
899      }
900    }
901    if (callbacks.onExpressionStatement) {
902      callbacks.onExpressionStatement(node);
903    }
904    this[node.expression.type](node.expression, node, callbacks);
905  },
906
907  /**
908   * An if statement.
909   *
910   * interface IfStatement <: Statement {
911   *   type: "IfStatement";
912   *   test: Expression;
913   *   consequent: Statement;
914   *   alternate: Statement | null;
915   * }
916   */
917  IfStatement(node, parent, callbacks) {
918    node._parent = parent;
919
920    if (this.break) {
921      return;
922    }
923    if (callbacks.onNode) {
924      if (callbacks.onNode(node, parent) === false) {
925        return;
926      }
927    }
928    if (callbacks.onIfStatement) {
929      callbacks.onIfStatement(node);
930    }
931    this[node.test.type](node.test, node, callbacks);
932    this[node.consequent.type](node.consequent, node, callbacks);
933    if (node.alternate) {
934      this[node.alternate.type](node.alternate, node, callbacks);
935    }
936  },
937
938  /**
939   * A labeled statement, i.e., a statement prefixed by a break/continue label.
940   *
941   * interface LabeledStatement <: Statement {
942   *   type: "LabeledStatement";
943   *   label: Identifier;
944   *   body: Statement;
945   * }
946   */
947  LabeledStatement(node, parent, callbacks) {
948    node._parent = parent;
949
950    if (this.break) {
951      return;
952    }
953    if (callbacks.onNode) {
954      if (callbacks.onNode(node, parent) === false) {
955        return;
956      }
957    }
958    if (callbacks.onLabeledStatement) {
959      callbacks.onLabeledStatement(node);
960    }
961    this[node.label.type](node.label, node, callbacks);
962    this[node.body.type](node.body, node, callbacks);
963  },
964
965  /**
966   * A break statement.
967   *
968   * interface BreakStatement <: Statement {
969   *   type: "BreakStatement";
970   *   label: Identifier | null;
971   * }
972   */
973  BreakStatement(node, parent, callbacks) {
974    node._parent = parent;
975
976    if (this.break) {
977      return;
978    }
979    if (callbacks.onNode) {
980      if (callbacks.onNode(node, parent) === false) {
981        return;
982      }
983    }
984    if (callbacks.onBreakStatement) {
985      callbacks.onBreakStatement(node);
986    }
987    if (node.label) {
988      this[node.label.type](node.label, node, callbacks);
989    }
990  },
991
992  /**
993   * A continue statement.
994   *
995   * interface ContinueStatement <: Statement {
996   *   type: "ContinueStatement";
997   *   label: Identifier | null;
998   * }
999   */
1000  ContinueStatement(node, parent, callbacks) {
1001    node._parent = parent;
1002
1003    if (this.break) {
1004      return;
1005    }
1006    if (callbacks.onNode) {
1007      if (callbacks.onNode(node, parent) === false) {
1008        return;
1009      }
1010    }
1011    if (callbacks.onContinueStatement) {
1012      callbacks.onContinueStatement(node);
1013    }
1014    if (node.label) {
1015      this[node.label.type](node.label, node, callbacks);
1016    }
1017  },
1018
1019  /**
1020   * A with statement.
1021   *
1022   * interface WithStatement <: Statement {
1023   *   type: "WithStatement";
1024   *   object: Expression;
1025   *   body: Statement;
1026   * }
1027   */
1028  WithStatement(node, parent, callbacks) {
1029    node._parent = parent;
1030
1031    if (this.break) {
1032      return;
1033    }
1034    if (callbacks.onNode) {
1035      if (callbacks.onNode(node, parent) === false) {
1036        return;
1037      }
1038    }
1039    if (callbacks.onWithStatement) {
1040      callbacks.onWithStatement(node);
1041    }
1042    this[node.object.type](node.object, node, callbacks);
1043    this[node.body.type](node.body, node, callbacks);
1044  },
1045
1046  /**
1047   * A switch statement. The lexical flag is metadata indicating whether the
1048   * switch statement contains any unnested let declarations (and therefore
1049   * introduces a new lexical scope).
1050   *
1051   * interface SwitchStatement <: Statement {
1052   *   type: "SwitchStatement";
1053   *   discriminant: Expression;
1054   *   cases: [ SwitchCase ];
1055   *   lexical: boolean;
1056   * }
1057   */
1058  SwitchStatement(node, parent, callbacks) {
1059    node._parent = parent;
1060
1061    if (this.break) {
1062      return;
1063    }
1064    if (callbacks.onNode) {
1065      if (callbacks.onNode(node, parent) === false) {
1066        return;
1067      }
1068    }
1069    if (callbacks.onSwitchStatement) {
1070      callbacks.onSwitchStatement(node);
1071    }
1072    this[node.discriminant.type](node.discriminant, node, callbacks);
1073    for (let _case of node.cases) {
1074      this[_case.type](_case, node, callbacks);
1075    }
1076  },
1077
1078  /**
1079   * A return statement.
1080   *
1081   * interface ReturnStatement <: Statement {
1082   *   type: "ReturnStatement";
1083   *   argument: Expression | null;
1084   * }
1085   */
1086  ReturnStatement(node, parent, callbacks) {
1087    node._parent = parent;
1088
1089    if (this.break) {
1090      return;
1091    }
1092    if (callbacks.onNode) {
1093      if (callbacks.onNode(node, parent) === false) {
1094        return;
1095      }
1096    }
1097    if (callbacks.onReturnStatement) {
1098      callbacks.onReturnStatement(node);
1099    }
1100    if (node.argument) {
1101      this[node.argument.type](node.argument, node, callbacks);
1102    }
1103  },
1104
1105  /**
1106   * A throw statement.
1107   *
1108   * interface ThrowStatement <: Statement {
1109   *   type: "ThrowStatement";
1110   *   argument: Expression;
1111   * }
1112   */
1113  ThrowStatement(node, parent, callbacks) {
1114    node._parent = parent;
1115
1116    if (this.break) {
1117      return;
1118    }
1119    if (callbacks.onNode) {
1120      if (callbacks.onNode(node, parent) === false) {
1121        return;
1122      }
1123    }
1124    if (callbacks.onThrowStatement) {
1125      callbacks.onThrowStatement(node);
1126    }
1127    this[node.argument.type](node.argument, node, callbacks);
1128  },
1129
1130  /**
1131   * A try statement.
1132   *
1133   * interface TryStatement <: Statement {
1134   *   type: "TryStatement";
1135   *   block: BlockStatement;
1136   *   handler: CatchClause | null;
1137   *   guardedHandlers: [ CatchClause ];
1138   *   finalizer: BlockStatement | null;
1139   * }
1140   */
1141  TryStatement(node, parent, callbacks) {
1142    node._parent = parent;
1143
1144    if (this.break) {
1145      return;
1146    }
1147    if (callbacks.onNode) {
1148      if (callbacks.onNode(node, parent) === false) {
1149        return;
1150      }
1151    }
1152    if (callbacks.onTryStatement) {
1153      callbacks.onTryStatement(node);
1154    }
1155    this[node.block.type](node.block, node, callbacks);
1156    if (node.handler) {
1157      this[node.handler.type](node.handler, node, callbacks);
1158    }
1159    for (let guardedHandler of node.guardedHandlers) {
1160      this[guardedHandler.type](guardedHandler, node, callbacks);
1161    }
1162    if (node.finalizer) {
1163      this[node.finalizer.type](node.finalizer, node, callbacks);
1164    }
1165  },
1166
1167  /**
1168   * A while statement.
1169   *
1170   * interface WhileStatement <: Statement {
1171   *   type: "WhileStatement";
1172   *   test: Expression;
1173   *   body: Statement;
1174   * }
1175   */
1176  WhileStatement(node, parent, callbacks) {
1177    node._parent = parent;
1178
1179    if (this.break) {
1180      return;
1181    }
1182    if (callbacks.onNode) {
1183      if (callbacks.onNode(node, parent) === false) {
1184        return;
1185      }
1186    }
1187    if (callbacks.onWhileStatement) {
1188      callbacks.onWhileStatement(node);
1189    }
1190    this[node.test.type](node.test, node, callbacks);
1191    this[node.body.type](node.body, node, callbacks);
1192  },
1193
1194  /**
1195   * A do/while statement.
1196   *
1197   * interface DoWhileStatement <: Statement {
1198   *   type: "DoWhileStatement";
1199   *   body: Statement;
1200   *   test: Expression;
1201   * }
1202   */
1203  DoWhileStatement(node, parent, callbacks) {
1204    node._parent = parent;
1205
1206    if (this.break) {
1207      return;
1208    }
1209    if (callbacks.onNode) {
1210      if (callbacks.onNode(node, parent) === false) {
1211        return;
1212      }
1213    }
1214    if (callbacks.onDoWhileStatement) {
1215      callbacks.onDoWhileStatement(node);
1216    }
1217    this[node.body.type](node.body, node, callbacks);
1218    this[node.test.type](node.test, node, callbacks);
1219  },
1220
1221  /**
1222   * A for statement.
1223   *
1224   * interface ForStatement <: Statement {
1225   *   type: "ForStatement";
1226   *   init: VariableDeclaration | Expression | null;
1227   *   test: Expression | null;
1228   *   update: Expression | null;
1229   *   body: Statement;
1230   * }
1231   */
1232  ForStatement(node, parent, callbacks) {
1233    node._parent = parent;
1234
1235    if (this.break) {
1236      return;
1237    }
1238    if (callbacks.onNode) {
1239      if (callbacks.onNode(node, parent) === false) {
1240        return;
1241      }
1242    }
1243    if (callbacks.onForStatement) {
1244      callbacks.onForStatement(node);
1245    }
1246    if (node.init) {
1247      this[node.init.type](node.init, node, callbacks);
1248    }
1249    if (node.test) {
1250      this[node.test.type](node.test, node, callbacks);
1251    }
1252    if (node.update) {
1253      this[node.update.type](node.update, node, callbacks);
1254    }
1255    this[node.body.type](node.body, node, callbacks);
1256  },
1257
1258  /**
1259   * A for/in statement, or, if each is true, a for each/in statement.
1260   *
1261   * interface ForInStatement <: Statement {
1262   *   type: "ForInStatement";
1263   *   left: VariableDeclaration | Expression;
1264   *   right: Expression;
1265   *   body: Statement;
1266   *   each: boolean;
1267   * }
1268   */
1269  ForInStatement(node, parent, callbacks) {
1270    node._parent = parent;
1271
1272    if (this.break) {
1273      return;
1274    }
1275    if (callbacks.onNode) {
1276      if (callbacks.onNode(node, parent) === false) {
1277        return;
1278      }
1279    }
1280    if (callbacks.onForInStatement) {
1281      callbacks.onForInStatement(node);
1282    }
1283    this[node.left.type](node.left, node, callbacks);
1284    this[node.right.type](node.right, node, callbacks);
1285    this[node.body.type](node.body, node, callbacks);
1286  },
1287
1288  /**
1289   * A for/of statement.
1290   *
1291   * interface ForOfStatement <: Statement {
1292   *   type: "ForOfStatement";
1293   *   left: VariableDeclaration | Expression;
1294   *   right: Expression;
1295   *   body: Statement;
1296   * }
1297   */
1298  ForOfStatement(node, parent, callbacks) {
1299    node._parent = parent;
1300
1301    if (this.break) {
1302      return;
1303    }
1304    if (callbacks.onNode) {
1305      if (callbacks.onNode(node, parent) === false) {
1306        return;
1307      }
1308    }
1309    if (callbacks.onForOfStatement) {
1310      callbacks.onForOfStatement(node);
1311    }
1312    this[node.left.type](node.left, node, callbacks);
1313    this[node.right.type](node.right, node, callbacks);
1314    this[node.body.type](node.body, node, callbacks);
1315  },
1316
1317  /**
1318   * A let statement.
1319   *
1320   * interface LetStatement <: Statement {
1321   *   type: "LetStatement";
1322   *   head: [ { id: Pattern, init: Expression | null } ];
1323   *   body: Statement;
1324   * }
1325   */
1326  LetStatement(node, parent, callbacks) {
1327    node._parent = parent;
1328
1329    if (this.break) {
1330      return;
1331    }
1332    if (callbacks.onNode) {
1333      if (callbacks.onNode(node, parent) === false) {
1334        return;
1335      }
1336    }
1337    if (callbacks.onLetStatement) {
1338      callbacks.onLetStatement(node);
1339    }
1340    for (let { id, init } of node.head) {
1341      this[id.type](id, node, callbacks);
1342      if (init) {
1343        this[init.type](init, node, callbacks);
1344      }
1345    }
1346    this[node.body.type](node.body, node, callbacks);
1347  },
1348
1349  /**
1350   * A debugger statement.
1351   *
1352   * interface DebuggerStatement <: Statement {
1353   *   type: "DebuggerStatement";
1354   * }
1355   */
1356  DebuggerStatement(node, parent, callbacks) {
1357    node._parent = parent;
1358
1359    if (this.break) {
1360      return;
1361    }
1362    if (callbacks.onNode) {
1363      if (callbacks.onNode(node, parent) === false) {
1364        return;
1365      }
1366    }
1367    if (callbacks.onDebuggerStatement) {
1368      callbacks.onDebuggerStatement(node);
1369    }
1370  },
1371
1372  /**
1373   * Any declaration node. Note that declarations are considered statements;
1374   * this is because declarations can appear in any statement context in the
1375   * language recognized by the SpiderMonkey parser.
1376   *
1377   * interface Declaration <: Statement { }
1378   */
1379  Declaration(node, parent, callbacks) {
1380    node._parent = parent;
1381
1382    if (this.break) {
1383      return;
1384    }
1385    if (callbacks.onNode) {
1386      if (callbacks.onNode(node, parent) === false) {
1387        return;
1388      }
1389    }
1390    if (callbacks.onDeclaration) {
1391      callbacks.onDeclaration(node);
1392    }
1393  },
1394
1395  /**
1396   * A function declaration.
1397   *
1398   * interface FunctionDeclaration <: Function, Declaration {
1399   *   type: "FunctionDeclaration";
1400   *   id: Identifier;
1401   *   params: [ Pattern ];
1402   *   defaults: [ Expression ];
1403   *   rest: Identifier | null;
1404   *   body: BlockStatement | Expression;
1405   *   generator: boolean;
1406   *   expression: boolean;
1407   * }
1408   */
1409  FunctionDeclaration(node, parent, callbacks) {
1410    node._parent = parent;
1411
1412    if (this.break) {
1413      return;
1414    }
1415    if (callbacks.onNode) {
1416      if (callbacks.onNode(node, parent) === false) {
1417        return;
1418      }
1419    }
1420    if (callbacks.onFunctionDeclaration) {
1421      callbacks.onFunctionDeclaration(node);
1422    }
1423    this[node.id.type](node.id, node, callbacks);
1424    for (let param of node.params) {
1425      this[param.type](param, node, callbacks);
1426    }
1427    for (let _default of node.defaults) {
1428      if (_default) {
1429        this[_default.type](_default, node, callbacks);
1430      }
1431    }
1432    if (node.rest) {
1433      this[node.rest.type](node.rest, node, callbacks);
1434    }
1435    this[node.body.type](node.body, node, callbacks);
1436  },
1437
1438  /**
1439   * A variable declaration, via one of var, let, or const.
1440   *
1441   * interface VariableDeclaration <: Declaration {
1442   *   type: "VariableDeclaration";
1443   *   declarations: [ VariableDeclarator ];
1444   *   kind: "var" | "let" | "const";
1445   * }
1446   */
1447  VariableDeclaration(node, parent, callbacks) {
1448    node._parent = parent;
1449
1450    if (this.break) {
1451      return;
1452    }
1453    if (callbacks.onNode) {
1454      if (callbacks.onNode(node, parent) === false) {
1455        return;
1456      }
1457    }
1458    if (callbacks.onVariableDeclaration) {
1459      callbacks.onVariableDeclaration(node);
1460    }
1461    for (let declaration of node.declarations) {
1462      this[declaration.type](declaration, node, callbacks);
1463    }
1464  },
1465
1466  /**
1467   * A variable declarator.
1468   *
1469   * interface VariableDeclarator <: Node {
1470   *   type: "VariableDeclarator";
1471   *   id: Pattern;
1472   *   init: Expression | null;
1473   * }
1474   */
1475  VariableDeclarator(node, parent, callbacks) {
1476    node._parent = parent;
1477
1478    if (this.break) {
1479      return;
1480    }
1481    if (callbacks.onNode) {
1482      if (callbacks.onNode(node, parent) === false) {
1483        return;
1484      }
1485    }
1486    if (callbacks.onVariableDeclarator) {
1487      callbacks.onVariableDeclarator(node);
1488    }
1489    this[node.id.type](node.id, node, callbacks);
1490    if (node.init) {
1491      this[node.init.type](node.init, node, callbacks);
1492    }
1493  },
1494
1495  /**
1496   * Any expression node. Since the left-hand side of an assignment may be any
1497   * expression in general, an expression can also be a pattern.
1498   *
1499   * interface Expression <: Node, Pattern { }
1500   */
1501  Expression(node, parent, callbacks) {
1502    node._parent = parent;
1503
1504    if (this.break) {
1505      return;
1506    }
1507    if (callbacks.onNode) {
1508      if (callbacks.onNode(node, parent) === false) {
1509        return;
1510      }
1511    }
1512    if (callbacks.onExpression) {
1513      callbacks.onExpression(node);
1514    }
1515  },
1516
1517  /**
1518   * A this expression.
1519   *
1520   * interface ThisExpression <: Expression {
1521   *   type: "ThisExpression";
1522   * }
1523   */
1524  ThisExpression(node, parent, callbacks) {
1525    node._parent = parent;
1526
1527    if (this.break) {
1528      return;
1529    }
1530    if (callbacks.onNode) {
1531      if (callbacks.onNode(node, parent) === false) {
1532        return;
1533      }
1534    }
1535    if (callbacks.onThisExpression) {
1536      callbacks.onThisExpression(node);
1537    }
1538  },
1539
1540  /**
1541   * An array expression.
1542   *
1543   * interface ArrayExpression <: Expression {
1544   *   type: "ArrayExpression";
1545   *   elements: [ Expression | null ];
1546   * }
1547   */
1548  ArrayExpression(node, parent, callbacks) {
1549    node._parent = parent;
1550
1551    if (this.break) {
1552      return;
1553    }
1554    if (callbacks.onNode) {
1555      if (callbacks.onNode(node, parent) === false) {
1556        return;
1557      }
1558    }
1559    if (callbacks.onArrayExpression) {
1560      callbacks.onArrayExpression(node);
1561    }
1562    for (let element of node.elements) {
1563      if (element) {
1564        this[element.type](element, node, callbacks);
1565      }
1566    }
1567  },
1568
1569  /**
1570   * A spread expression.
1571   *
1572   * interface SpreadExpression <: Expression {
1573   *   type: "SpreadExpression";
1574   *   expression: Expression;
1575   * }
1576   */
1577  SpreadExpression(node, parent, callbacks) {
1578    node._parent = parent;
1579
1580    if (this.break) {
1581      return;
1582    }
1583    if (callbacks.onNode) {
1584      if (callbacks.onNode(node, parent) === false) {
1585        return;
1586      }
1587    }
1588    if (callbacks.onSpreadExpression) {
1589      callbacks.onSpreadExpression(node);
1590    }
1591    this[node.expression.type](node.expression, node, callbacks);
1592  },
1593
1594  /**
1595   * An object expression. A literal property in an object expression can have
1596   * either a string or number as its value. Ordinary property initializers
1597   * have a kind value "init"; getters and setters have the kind values "get"
1598   * and "set", respectively.
1599   *
1600   * interface ObjectExpression <: Expression {
1601   *   type: "ObjectExpression";
1602   *   properties: [ { key: Literal | Identifier | ComputedName,
1603   *                   value: Expression,
1604   *                   kind: "init" | "get" | "set" } ];
1605   * }
1606   */
1607  ObjectExpression(node, parent, callbacks) {
1608    node._parent = parent;
1609
1610    if (this.break) {
1611      return;
1612    }
1613    if (callbacks.onNode) {
1614      if (callbacks.onNode(node, parent) === false) {
1615        return;
1616      }
1617    }
1618    if (callbacks.onObjectExpression) {
1619      callbacks.onObjectExpression(node);
1620    }
1621    for (let { key, value } of node.properties) {
1622      this[key.type](key, node, callbacks);
1623      this[value.type](value, node, callbacks);
1624    }
1625  },
1626
1627  /**
1628   * A computed property name in object expression, like in { [a]: b }
1629   *
1630   * interface ComputedName <: Node {
1631   *   type: "ComputedName";
1632   *   name: Expression;
1633   * }
1634   */
1635  ComputedName(node, parent, callbacks) {
1636    node._parent = parent;
1637
1638    if (this.break) {
1639      return;
1640    }
1641    if (callbacks.onNode) {
1642      if (callbacks.onNode(node, parent) === false) {
1643        return;
1644      }
1645    }
1646    if (callbacks.onComputedName) {
1647      callbacks.onComputedName(node);
1648    }
1649    this[node.name.type](node.name, node, callbacks);
1650  },
1651
1652  /**
1653   * A function expression.
1654   *
1655   * interface FunctionExpression <: Function, Expression {
1656   *   type: "FunctionExpression";
1657   *   id: Identifier | null;
1658   *   params: [ Pattern ];
1659   *   defaults: [ Expression ];
1660   *   rest: Identifier | null;
1661   *   body: BlockStatement | Expression;
1662   *   generator: boolean;
1663   *   expression: boolean;
1664   * }
1665   */
1666  FunctionExpression(node, parent, callbacks) {
1667    node._parent = parent;
1668
1669    if (this.break) {
1670      return;
1671    }
1672    if (callbacks.onNode) {
1673      if (callbacks.onNode(node, parent) === false) {
1674        return;
1675      }
1676    }
1677    if (callbacks.onFunctionExpression) {
1678      callbacks.onFunctionExpression(node);
1679    }
1680    if (node.id) {
1681      this[node.id.type](node.id, node, callbacks);
1682    }
1683    for (let param of node.params) {
1684      this[param.type](param, node, callbacks);
1685    }
1686    for (let _default of node.defaults) {
1687      if (_default) {
1688        this[_default.type](_default, node, callbacks);
1689      }
1690    }
1691    if (node.rest) {
1692      this[node.rest.type](node.rest, node, callbacks);
1693    }
1694    this[node.body.type](node.body, node, callbacks);
1695  },
1696
1697  /**
1698   * An arrow expression.
1699   *
1700   * interface ArrowFunctionExpression <: Function, Expression {
1701   *   type: "ArrowFunctionExpression";
1702   *   params: [ Pattern ];
1703   *   defaults: [ Expression ];
1704   *   rest: Identifier | null;
1705   *   body: BlockStatement | Expression;
1706   *   generator: boolean;
1707   *   expression: boolean;
1708   * }
1709   */
1710  ArrowFunctionExpression(node, parent, callbacks) {
1711    node._parent = parent;
1712
1713    if (this.break) {
1714      return;
1715    }
1716    if (callbacks.onNode) {
1717      if (callbacks.onNode(node, parent) === false) {
1718        return;
1719      }
1720    }
1721    if (callbacks.onArrowFunctionExpression) {
1722      callbacks.onArrowFunctionExpression(node);
1723    }
1724    for (let param of node.params) {
1725      this[param.type](param, node, callbacks);
1726    }
1727    for (let _default of node.defaults) {
1728      if (_default) {
1729        this[_default.type](_default, node, callbacks);
1730      }
1731    }
1732    if (node.rest) {
1733      this[node.rest.type](node.rest, node, callbacks);
1734    }
1735    this[node.body.type](node.body, node, callbacks);
1736  },
1737
1738  /**
1739   * A sequence expression, i.e., a comma-separated sequence of expressions.
1740   *
1741   * interface SequenceExpression <: Expression {
1742   *   type: "SequenceExpression";
1743   *   expressions: [ Expression ];
1744   * }
1745   */
1746  SequenceExpression(node, parent, callbacks) {
1747    node._parent = parent;
1748
1749    if (this.break) {
1750      return;
1751    }
1752    if (callbacks.onNode) {
1753      if (callbacks.onNode(node, parent) === false) {
1754        return;
1755      }
1756    }
1757    if (callbacks.onSequenceExpression) {
1758      callbacks.onSequenceExpression(node);
1759    }
1760    for (let expression of node.expressions) {
1761      this[expression.type](expression, node, callbacks);
1762    }
1763  },
1764
1765  /**
1766   * A unary operator expression.
1767   *
1768   * interface UnaryExpression <: Expression {
1769   *   type: "UnaryExpression";
1770   *   operator: UnaryOperator;
1771   *   prefix: boolean;
1772   *   argument: Expression;
1773   * }
1774   */
1775  UnaryExpression(node, parent, callbacks) {
1776    node._parent = parent;
1777
1778    if (this.break) {
1779      return;
1780    }
1781    if (callbacks.onNode) {
1782      if (callbacks.onNode(node, parent) === false) {
1783        return;
1784      }
1785    }
1786    if (callbacks.onUnaryExpression) {
1787      callbacks.onUnaryExpression(node);
1788    }
1789    this[node.argument.type](node.argument, node, callbacks);
1790  },
1791
1792  /**
1793   * A binary operator expression.
1794   *
1795   * interface BinaryExpression <: Expression {
1796   *   type: "BinaryExpression";
1797   *   operator: BinaryOperator;
1798   *   left: Expression;
1799   *   right: Expression;
1800   * }
1801   */
1802  BinaryExpression(node, parent, callbacks) {
1803    node._parent = parent;
1804
1805    if (this.break) {
1806      return;
1807    }
1808    if (callbacks.onNode) {
1809      if (callbacks.onNode(node, parent) === false) {
1810        return;
1811      }
1812    }
1813    if (callbacks.onBinaryExpression) {
1814      callbacks.onBinaryExpression(node);
1815    }
1816    this[node.left.type](node.left, node, callbacks);
1817    this[node.right.type](node.right, node, callbacks);
1818  },
1819
1820  /**
1821   * An assignment operator expression.
1822   *
1823   * interface AssignmentExpression <: Expression {
1824   *   type: "AssignmentExpression";
1825   *   operator: AssignmentOperator;
1826   *   left: Expression;
1827   *   right: Expression;
1828   * }
1829   */
1830  AssignmentExpression(node, parent, callbacks) {
1831    node._parent = parent;
1832
1833    if (this.break) {
1834      return;
1835    }
1836    if (callbacks.onNode) {
1837      if (callbacks.onNode(node, parent) === false) {
1838        return;
1839      }
1840    }
1841    if (callbacks.onAssignmentExpression) {
1842      callbacks.onAssignmentExpression(node);
1843    }
1844    this[node.left.type](node.left, node, callbacks);
1845    this[node.right.type](node.right, node, callbacks);
1846  },
1847
1848  /**
1849   * An update (increment or decrement) operator expression.
1850   *
1851   * interface UpdateExpression <: Expression {
1852   *   type: "UpdateExpression";
1853   *   operator: UpdateOperator;
1854   *   argument: Expression;
1855   *   prefix: boolean;
1856   * }
1857   */
1858  UpdateExpression(node, parent, callbacks) {
1859    node._parent = parent;
1860
1861    if (this.break) {
1862      return;
1863    }
1864    if (callbacks.onNode) {
1865      if (callbacks.onNode(node, parent) === false) {
1866        return;
1867      }
1868    }
1869    if (callbacks.onUpdateExpression) {
1870      callbacks.onUpdateExpression(node);
1871    }
1872    this[node.argument.type](node.argument, node, callbacks);
1873  },
1874
1875  /**
1876   * A logical operator expression.
1877   *
1878   * interface LogicalExpression <: Expression {
1879   *   type: "LogicalExpression";
1880   *   operator: LogicalOperator;
1881   *   left: Expression;
1882   *   right: Expression;
1883   * }
1884   */
1885  LogicalExpression(node, parent, callbacks) {
1886    node._parent = parent;
1887
1888    if (this.break) {
1889      return;
1890    }
1891    if (callbacks.onNode) {
1892      if (callbacks.onNode(node, parent) === false) {
1893        return;
1894      }
1895    }
1896    if (callbacks.onLogicalExpression) {
1897      callbacks.onLogicalExpression(node);
1898    }
1899    this[node.left.type](node.left, node, callbacks);
1900    this[node.right.type](node.right, node, callbacks);
1901  },
1902
1903  /**
1904   * A conditional expression, i.e., a ternary ?/: expression.
1905   *
1906   * interface ConditionalExpression <: Expression {
1907   *   type: "ConditionalExpression";
1908   *   test: Expression;
1909   *   alternate: Expression;
1910   *   consequent: Expression;
1911   * }
1912   */
1913  ConditionalExpression(node, parent, callbacks) {
1914    node._parent = parent;
1915
1916    if (this.break) {
1917      return;
1918    }
1919    if (callbacks.onNode) {
1920      if (callbacks.onNode(node, parent) === false) {
1921        return;
1922      }
1923    }
1924    if (callbacks.onConditionalExpression) {
1925      callbacks.onConditionalExpression(node);
1926    }
1927    this[node.test.type](node.test, node, callbacks);
1928    this[node.alternate.type](node.alternate, node, callbacks);
1929    this[node.consequent.type](node.consequent, node, callbacks);
1930  },
1931
1932  /**
1933   * A new expression.
1934   *
1935   * interface NewExpression <: Expression {
1936   *   type: "NewExpression";
1937   *   callee: Expression;
1938   *   arguments: [ Expression | null ];
1939   * }
1940   */
1941  NewExpression(node, parent, callbacks) {
1942    node._parent = parent;
1943
1944    if (this.break) {
1945      return;
1946    }
1947    if (callbacks.onNode) {
1948      if (callbacks.onNode(node, parent) === false) {
1949        return;
1950      }
1951    }
1952    if (callbacks.onNewExpression) {
1953      callbacks.onNewExpression(node);
1954    }
1955    this[node.callee.type](node.callee, node, callbacks);
1956    for (let argument of node.arguments) {
1957      if (argument) {
1958        this[argument.type](argument, node, callbacks);
1959      }
1960    }
1961  },
1962
1963  /**
1964   * A function or method call expression.
1965   *
1966   * interface CallExpression <: Expression {
1967   *   type: "CallExpression";
1968   *   callee: Expression;
1969   *   arguments: [ Expression | null ];
1970   * }
1971   */
1972  CallExpression(node, parent, callbacks) {
1973    node._parent = parent;
1974
1975    if (this.break) {
1976      return;
1977    }
1978    if (callbacks.onNode) {
1979      if (callbacks.onNode(node, parent) === false) {
1980        return;
1981      }
1982    }
1983    if (callbacks.onCallExpression) {
1984      callbacks.onCallExpression(node);
1985    }
1986    this[node.callee.type](node.callee, node, callbacks);
1987    for (let argument of node.arguments) {
1988      if (argument) {
1989        if (!this[argument.type]) {
1990          console.error("Unknown parser object:", argument.type);
1991        }
1992        this[argument.type](argument, node, callbacks);
1993      }
1994    }
1995  },
1996
1997  /**
1998   * A member expression. If computed is true, the node corresponds to a
1999   * computed e1[e2] expression and property is an Expression. If computed is
2000   * false, the node corresponds to a static e1.x expression and property is an
2001   * Identifier.
2002   *
2003   * interface MemberExpression <: Expression {
2004   *   type: "MemberExpression";
2005   *   object: Expression;
2006   *   property: Identifier | Expression;
2007   *   computed: boolean;
2008   * }
2009   */
2010  MemberExpression(node, parent, callbacks) {
2011    node._parent = parent;
2012
2013    if (this.break) {
2014      return;
2015    }
2016    if (callbacks.onNode) {
2017      if (callbacks.onNode(node, parent) === false) {
2018        return;
2019      }
2020    }
2021    if (callbacks.onMemberExpression) {
2022      callbacks.onMemberExpression(node);
2023    }
2024    this[node.object.type](node.object, node, callbacks);
2025    this[node.property.type](node.property, node, callbacks);
2026  },
2027
2028  /**
2029   * A yield expression.
2030   *
2031   * interface YieldExpression <: Expression {
2032   *   argument: Expression | null;
2033   * }
2034   */
2035  YieldExpression(node, parent, callbacks) {
2036    node._parent = parent;
2037
2038    if (this.break) {
2039      return;
2040    }
2041    if (callbacks.onNode) {
2042      if (callbacks.onNode(node, parent) === false) {
2043        return;
2044      }
2045    }
2046    if (callbacks.onYieldExpression) {
2047      callbacks.onYieldExpression(node);
2048    }
2049    if (node.argument) {
2050      this[node.argument.type](node.argument, node, callbacks);
2051    }
2052  },
2053
2054  /**
2055   * An array comprehension. The blocks array corresponds to the sequence of
2056   * for and for each blocks. The optional filter expression corresponds to the
2057   * final if clause, if present.
2058   *
2059   * interface ComprehensionExpression <: Expression {
2060   *   body: Expression;
2061   *   blocks: [ ComprehensionBlock ];
2062   *   filter: Expression | null;
2063   * }
2064   */
2065  ComprehensionExpression(node, parent, callbacks) {
2066    node._parent = parent;
2067
2068    if (this.break) {
2069      return;
2070    }
2071    if (callbacks.onNode) {
2072      if (callbacks.onNode(node, parent) === false) {
2073        return;
2074      }
2075    }
2076    if (callbacks.onComprehensionExpression) {
2077      callbacks.onComprehensionExpression(node);
2078    }
2079    this[node.body.type](node.body, node, callbacks);
2080    for (let block of node.blocks) {
2081      this[block.type](block, node, callbacks);
2082    }
2083    if (node.filter) {
2084      this[node.filter.type](node.filter, node, callbacks);
2085    }
2086  },
2087
2088  /**
2089   * A generator expression. As with array comprehensions, the blocks array
2090   * corresponds to the sequence of for and for each blocks, and the optional
2091   * filter expression corresponds to the final if clause, if present.
2092   *
2093   * interface GeneratorExpression <: Expression {
2094   *   body: Expression;
2095   *   blocks: [ ComprehensionBlock ];
2096   *   filter: Expression | null;
2097   * }
2098   */
2099  GeneratorExpression(node, parent, callbacks) {
2100    node._parent = parent;
2101
2102    if (this.break) {
2103      return;
2104    }
2105    if (callbacks.onNode) {
2106      if (callbacks.onNode(node, parent) === false) {
2107        return;
2108      }
2109    }
2110    if (callbacks.onGeneratorExpression) {
2111      callbacks.onGeneratorExpression(node);
2112    }
2113    this[node.body.type](node.body, node, callbacks);
2114    for (let block of node.blocks) {
2115      this[block.type](block, node, callbacks);
2116    }
2117    if (node.filter) {
2118      this[node.filter.type](node.filter, node, callbacks);
2119    }
2120  },
2121
2122  /**
2123   * A graph expression, aka "sharp literal," such as #1={ self: #1# }.
2124   *
2125   * interface GraphExpression <: Expression {
2126   *   index: uint32;
2127   *   expression: Literal;
2128   * }
2129   */
2130  GraphExpression(node, parent, callbacks) {
2131    node._parent = parent;
2132
2133    if (this.break) {
2134      return;
2135    }
2136    if (callbacks.onNode) {
2137      if (callbacks.onNode(node, parent) === false) {
2138        return;
2139      }
2140    }
2141    if (callbacks.onGraphExpression) {
2142      callbacks.onGraphExpression(node);
2143    }
2144    this[node.expression.type](node.expression, node, callbacks);
2145  },
2146
2147  /**
2148   * A graph index expression, aka "sharp variable," such as #1#.
2149   *
2150   * interface GraphIndexExpression <: Expression {
2151   *   index: uint32;
2152   * }
2153   */
2154  GraphIndexExpression(node, parent, callbacks) {
2155    node._parent = parent;
2156
2157    if (this.break) {
2158      return;
2159    }
2160    if (callbacks.onNode) {
2161      if (callbacks.onNode(node, parent) === false) {
2162        return;
2163      }
2164    }
2165    if (callbacks.onGraphIndexExpression) {
2166      callbacks.onGraphIndexExpression(node);
2167    }
2168  },
2169
2170  /**
2171   * A let expression.
2172   *
2173   * interface LetExpression <: Expression {
2174   *   type: "LetExpression";
2175   *   head: [ { id: Pattern, init: Expression | null } ];
2176   *   body: Expression;
2177   * }
2178   */
2179  LetExpression(node, parent, callbacks) {
2180    node._parent = parent;
2181
2182    if (this.break) {
2183      return;
2184    }
2185    if (callbacks.onNode) {
2186      if (callbacks.onNode(node, parent) === false) {
2187        return;
2188      }
2189    }
2190    if (callbacks.onLetExpression) {
2191      callbacks.onLetExpression(node);
2192    }
2193    for (let { id, init } of node.head) {
2194      this[id.type](id, node, callbacks);
2195      if (init) {
2196        this[init.type](init, node, callbacks);
2197      }
2198    }
2199    this[node.body.type](node.body, node, callbacks);
2200  },
2201
2202  /**
2203   * Any pattern.
2204   *
2205   * interface Pattern <: Node { }
2206   */
2207  Pattern(node, parent, callbacks) {
2208    node._parent = parent;
2209
2210    if (this.break) {
2211      return;
2212    }
2213    if (callbacks.onNode) {
2214      if (callbacks.onNode(node, parent) === false) {
2215        return;
2216      }
2217    }
2218    if (callbacks.onPattern) {
2219      callbacks.onPattern(node);
2220    }
2221  },
2222
2223  /**
2224   * An object-destructuring pattern. A literal property in an object pattern
2225   * can have either a string or number as its value.
2226   *
2227   * interface ObjectPattern <: Pattern {
2228   *   type: "ObjectPattern";
2229   *   properties: [ { key: Literal | Identifier, value: Pattern } ];
2230   * }
2231   */
2232  ObjectPattern(node, parent, callbacks) {
2233    node._parent = parent;
2234
2235    if (this.break) {
2236      return;
2237    }
2238    if (callbacks.onNode) {
2239      if (callbacks.onNode(node, parent) === false) {
2240        return;
2241      }
2242    }
2243    if (callbacks.onObjectPattern) {
2244      callbacks.onObjectPattern(node);
2245    }
2246    for (let { key, value } of node.properties) {
2247      this[key.type](key, node, callbacks);
2248      this[value.type](value, node, callbacks);
2249    }
2250  },
2251
2252  /**
2253   * An array-destructuring pattern.
2254   *
2255   * interface ArrayPattern <: Pattern {
2256   *   type: "ArrayPattern";
2257   *   elements: [ Pattern | null ];
2258   * }
2259   */
2260  ArrayPattern(node, parent, callbacks) {
2261    node._parent = parent;
2262
2263    if (this.break) {
2264      return;
2265    }
2266    if (callbacks.onNode) {
2267      if (callbacks.onNode(node, parent) === false) {
2268        return;
2269      }
2270    }
2271    if (callbacks.onArrayPattern) {
2272      callbacks.onArrayPattern(node);
2273    }
2274    for (let element of node.elements) {
2275      if (element) {
2276        this[element.type](element, node, callbacks);
2277      }
2278    }
2279  },
2280
2281  /**
2282   * A case (if test is an Expression) or default (if test is null) clause in
2283   * the body of a switch statement.
2284   *
2285   * interface SwitchCase <: Node {
2286   *   type: "SwitchCase";
2287   *   test: Expression | null;
2288   *   consequent: [ Statement ];
2289   * }
2290   */
2291  SwitchCase(node, parent, callbacks) {
2292    node._parent = parent;
2293
2294    if (this.break) {
2295      return;
2296    }
2297    if (callbacks.onNode) {
2298      if (callbacks.onNode(node, parent) === false) {
2299        return;
2300      }
2301    }
2302    if (callbacks.onSwitchCase) {
2303      callbacks.onSwitchCase(node);
2304    }
2305    if (node.test) {
2306      this[node.test.type](node.test, node, callbacks);
2307    }
2308    for (let consequent of node.consequent) {
2309      this[consequent.type](consequent, node, callbacks);
2310    }
2311  },
2312
2313  /**
2314   * A catch clause following a try block. The optional guard property
2315   * corresponds to the optional expression guard on the bound variable.
2316   *
2317   * interface CatchClause <: Node {
2318   *   type: "CatchClause";
2319   *   param: Pattern;
2320   *   guard: Expression | null;
2321   *   body: BlockStatement;
2322   * }
2323   */
2324  CatchClause(node, parent, callbacks) {
2325    node._parent = parent;
2326
2327    if (this.break) {
2328      return;
2329    }
2330    if (callbacks.onNode) {
2331      if (callbacks.onNode(node, parent) === false) {
2332        return;
2333      }
2334    }
2335    if (callbacks.onCatchClause) {
2336      callbacks.onCatchClause(node);
2337    }
2338    this[node.param.type](node.param, node, callbacks);
2339    if (node.guard) {
2340      this[node.guard.type](node.guard, node, callbacks);
2341    }
2342    this[node.body.type](node.body, node, callbacks);
2343  },
2344
2345  /**
2346   * A for or for each block in an array comprehension or generator expression.
2347   *
2348   * interface ComprehensionBlock <: Node {
2349   *   left: Pattern;
2350   *   right: Expression;
2351   *   each: boolean;
2352   * }
2353   */
2354  ComprehensionBlock(node, parent, callbacks) {
2355    node._parent = parent;
2356
2357    if (this.break) {
2358      return;
2359    }
2360    if (callbacks.onNode) {
2361      if (callbacks.onNode(node, parent) === false) {
2362        return;
2363      }
2364    }
2365    if (callbacks.onComprehensionBlock) {
2366      callbacks.onComprehensionBlock(node);
2367    }
2368    this[node.left.type](node.left, node, callbacks);
2369    this[node.right.type](node.right, node, callbacks);
2370  },
2371
2372  /**
2373   * An identifier. Note that an identifier may be an expression or a
2374   * destructuring pattern.
2375   *
2376   * interface Identifier <: Node, Expression, Pattern {
2377   *   type: "Identifier";
2378   *   name: string;
2379   * }
2380   */
2381  Identifier(node, parent, callbacks) {
2382    node._parent = parent;
2383
2384    if (this.break) {
2385      return;
2386    }
2387    if (callbacks.onNode) {
2388      if (callbacks.onNode(node, parent) === false) {
2389        return;
2390      }
2391    }
2392    if (callbacks.onIdentifier) {
2393      callbacks.onIdentifier(node);
2394    }
2395  },
2396
2397  /**
2398   * A literal token. Note that a literal can be an expression.
2399   *
2400   * interface Literal <: Node, Expression {
2401   *   type: "Literal";
2402   *   value: string | boolean | null | number | RegExp;
2403   * }
2404   */
2405  Literal(node, parent, callbacks) {
2406    node._parent = parent;
2407
2408    if (this.break) {
2409      return;
2410    }
2411    if (callbacks.onNode) {
2412      if (callbacks.onNode(node, parent) === false) {
2413        return;
2414      }
2415    }
2416    if (callbacks.onLiteral) {
2417      callbacks.onLiteral(node);
2418    }
2419  },
2420
2421  /**
2422   * A template string literal.
2423   *
2424   * interface TemplateLiteral <: Node {
2425   *   type: "TemplateLiteral";
2426   *   elements: [ Expression ];
2427   * }
2428   */
2429  TemplateLiteral(node, parent, callbacks) {
2430    node._parent = parent;
2431
2432    if (this.break) {
2433      return;
2434    }
2435    if (callbacks.onNode) {
2436      if (callbacks.onNode(node, parent) === false) {
2437        return;
2438      }
2439    }
2440    if (callbacks.onTemplateLiteral) {
2441      callbacks.onTemplateLiteral(node);
2442    }
2443    for (let element of node.elements) {
2444      if (element) {
2445        this[element.type](element, node, callbacks);
2446      }
2447    }
2448  }
2449};
2450
2451XPCOMUtils.defineLazyGetter(Parser, "reflectionAPI", () => Reflect);
2452