Parser.jsm 63 KB

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