acorn_loose.es.js 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. import { Node, SourceLocation, Token, addLooseExports, defaultOptions, getLineInfo, isNewLine, lineBreak, lineBreakG, tokTypes, tokenizer } from './acorn.es';
  2. // Registered plugins
  3. var pluginsLoose = {};
  4. var LooseParser = function LooseParser(input, options) {
  5. if ( options === void 0 ) options = {};
  6. this.toks = tokenizer(input, options);
  7. this.options = this.toks.options;
  8. this.input = this.toks.input;
  9. this.tok = this.last = {type: tokTypes.eof, start: 0, end: 0};
  10. if (this.options.locations) {
  11. var here = this.toks.curPosition();
  12. this.tok.loc = new SourceLocation(this.toks, here, here);
  13. }
  14. this.ahead = []; // Tokens ahead
  15. this.context = []; // Indentation contexted
  16. this.curIndent = 0;
  17. this.curLineStart = 0;
  18. this.nextLineStart = this.lineEnd(this.curLineStart) + 1;
  19. this.inAsync = false;
  20. // Load plugins
  21. this.options.pluginsLoose = options.pluginsLoose || {};
  22. this.loadPlugins(this.options.pluginsLoose);
  23. };
  24. LooseParser.prototype.startNode = function startNode () {
  25. return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null)
  26. };
  27. LooseParser.prototype.storeCurrentPos = function storeCurrentPos () {
  28. return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start
  29. };
  30. LooseParser.prototype.startNodeAt = function startNodeAt (pos) {
  31. if (this.options.locations) {
  32. return new Node(this.toks, pos[0], pos[1])
  33. } else {
  34. return new Node(this.toks, pos)
  35. }
  36. };
  37. LooseParser.prototype.finishNode = function finishNode (node, type) {
  38. node.type = type;
  39. node.end = this.last.end;
  40. if (this.options.locations)
  41. { node.loc.end = this.last.loc.end; }
  42. if (this.options.ranges)
  43. { node.range[1] = this.last.end; }
  44. return node
  45. };
  46. LooseParser.prototype.dummyNode = function dummyNode (type) {
  47. var dummy = this.startNode();
  48. dummy.type = type;
  49. dummy.end = dummy.start;
  50. if (this.options.locations)
  51. { dummy.loc.end = dummy.loc.start; }
  52. if (this.options.ranges)
  53. { dummy.range[1] = dummy.start; }
  54. this.last = {type: tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc};
  55. return dummy
  56. };
  57. LooseParser.prototype.dummyIdent = function dummyIdent () {
  58. var dummy = this.dummyNode("Identifier");
  59. dummy.name = "✖";
  60. return dummy
  61. };
  62. LooseParser.prototype.dummyString = function dummyString () {
  63. var dummy = this.dummyNode("Literal");
  64. dummy.value = dummy.raw = "✖";
  65. return dummy
  66. };
  67. LooseParser.prototype.eat = function eat (type) {
  68. if (this.tok.type === type) {
  69. this.next();
  70. return true
  71. } else {
  72. return false
  73. }
  74. };
  75. LooseParser.prototype.isContextual = function isContextual (name) {
  76. return this.tok.type === tokTypes.name && this.tok.value === name
  77. };
  78. LooseParser.prototype.eatContextual = function eatContextual (name) {
  79. return this.tok.value === name && this.eat(tokTypes.name)
  80. };
  81. LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon () {
  82. return this.tok.type === tokTypes.eof || this.tok.type === tokTypes.braceR ||
  83. lineBreak.test(this.input.slice(this.last.end, this.tok.start))
  84. };
  85. LooseParser.prototype.semicolon = function semicolon () {
  86. return this.eat(tokTypes.semi)
  87. };
  88. LooseParser.prototype.expect = function expect (type) {
  89. var this$1 = this;
  90. if (this.eat(type)) { return true }
  91. for (var i = 1; i <= 2; i++) {
  92. if (this$1.lookAhead(i).type == type) {
  93. for (var j = 0; j < i; j++) { this$1.next(); }
  94. return true
  95. }
  96. }
  97. };
  98. LooseParser.prototype.pushCx = function pushCx () {
  99. this.context.push(this.curIndent);
  100. };
  101. LooseParser.prototype.popCx = function popCx () {
  102. this.curIndent = this.context.pop();
  103. };
  104. LooseParser.prototype.lineEnd = function lineEnd (pos) {
  105. while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) { ++pos; }
  106. return pos
  107. };
  108. LooseParser.prototype.indentationAfter = function indentationAfter (pos) {
  109. var this$1 = this;
  110. for (var count = 0;; ++pos) {
  111. var ch = this$1.input.charCodeAt(pos);
  112. if (ch === 32) { ++count; }
  113. else if (ch === 9) { count += this$1.options.tabSize; }
  114. else { return count }
  115. }
  116. };
  117. LooseParser.prototype.closes = function closes (closeTok, indent, line, blockHeuristic) {
  118. if (this.tok.type === closeTok || this.tok.type === tokTypes.eof) { return true }
  119. return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() &&
  120. (!blockHeuristic || this.nextLineStart >= this.input.length ||
  121. this.indentationAfter(this.nextLineStart) < indent)
  122. };
  123. LooseParser.prototype.tokenStartsLine = function tokenStartsLine () {
  124. var this$1 = this;
  125. for (var p = this.tok.start - 1; p >= this.curLineStart; --p) {
  126. var ch = this$1.input.charCodeAt(p);
  127. if (ch !== 9 && ch !== 32) { return false }
  128. }
  129. return true
  130. };
  131. LooseParser.prototype.extend = function extend (name, f) {
  132. this[name] = f(this[name]);
  133. };
  134. LooseParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {
  135. var this$1 = this;
  136. for (var name in pluginConfigs) {
  137. var plugin = pluginsLoose[name];
  138. if (!plugin) { throw new Error("Plugin '" + name + "' not found") }
  139. plugin(this$1, pluginConfigs[name]);
  140. }
  141. };
  142. LooseParser.prototype.parse = function parse () {
  143. this.next();
  144. return this.parseTopLevel()
  145. };
  146. var lp = LooseParser.prototype;
  147. function isSpace(ch) {
  148. return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewLine(ch)
  149. }
  150. lp.next = function() {
  151. var this$1 = this;
  152. this.last = this.tok;
  153. if (this.ahead.length)
  154. { this.tok = this.ahead.shift(); }
  155. else
  156. { this.tok = this.readToken(); }
  157. if (this.tok.start >= this.nextLineStart) {
  158. while (this.tok.start >= this.nextLineStart) {
  159. this$1.curLineStart = this$1.nextLineStart;
  160. this$1.nextLineStart = this$1.lineEnd(this$1.curLineStart) + 1;
  161. }
  162. this.curIndent = this.indentationAfter(this.curLineStart);
  163. }
  164. };
  165. lp.readToken = function() {
  166. var this$1 = this;
  167. for (;;) {
  168. try {
  169. this$1.toks.next();
  170. if (this$1.toks.type === tokTypes.dot &&
  171. this$1.input.substr(this$1.toks.end, 1) === "." &&
  172. this$1.options.ecmaVersion >= 6) {
  173. this$1.toks.end++;
  174. this$1.toks.type = tokTypes.ellipsis;
  175. }
  176. return new Token(this$1.toks)
  177. } catch (e) {
  178. if (!(e instanceof SyntaxError)) { throw e }
  179. // Try to skip some text, based on the error message, and then continue
  180. var msg = e.message, pos = e.raisedAt, replace = true;
  181. if (/unterminated/i.test(msg)) {
  182. pos = this$1.lineEnd(e.pos + 1);
  183. if (/string/.test(msg)) {
  184. replace = {start: e.pos, end: pos, type: tokTypes.string, value: this$1.input.slice(e.pos + 1, pos)};
  185. } else if (/regular expr/i.test(msg)) {
  186. var re = this$1.input.slice(e.pos, pos);
  187. try { re = new RegExp(re); } catch (e) { /* ignore compilation error due to new syntax */ }
  188. replace = {start: e.pos, end: pos, type: tokTypes.regexp, value: re};
  189. } else if (/template/.test(msg)) {
  190. replace = {
  191. start: e.pos,
  192. end: pos,
  193. type: tokTypes.template,
  194. value: this$1.input.slice(e.pos, pos)
  195. };
  196. } else {
  197. replace = false;
  198. }
  199. } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) {
  200. while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) { ++pos; }
  201. } else if (/character escape|expected hexadecimal/i.test(msg)) {
  202. while (pos < this.input.length) {
  203. var ch = this$1.input.charCodeAt(pos++);
  204. if (ch === 34 || ch === 39 || isNewLine(ch)) { break }
  205. }
  206. } else if (/unexpected character/i.test(msg)) {
  207. pos++;
  208. replace = false;
  209. } else if (/regular expression/i.test(msg)) {
  210. replace = true;
  211. } else {
  212. throw e
  213. }
  214. this$1.resetTo(pos);
  215. if (replace === true) { replace = {start: pos, end: pos, type: tokTypes.name, value: "✖"}; }
  216. if (replace) {
  217. if (this$1.options.locations)
  218. { replace.loc = new SourceLocation(
  219. this$1.toks,
  220. getLineInfo(this$1.input, replace.start),
  221. getLineInfo(this$1.input, replace.end)); }
  222. return replace
  223. }
  224. }
  225. }
  226. };
  227. lp.resetTo = function(pos) {
  228. var this$1 = this;
  229. this.toks.pos = pos;
  230. var ch = this.input.charAt(pos - 1);
  231. this.toks.exprAllowed = !ch || /[[{(,;:?/*=+\-~!|&%^<>]/.test(ch) ||
  232. /[enwfd]/.test(ch) &&
  233. /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos));
  234. if (this.options.locations) {
  235. this.toks.curLine = 1;
  236. this.toks.lineStart = lineBreakG.lastIndex = 0;
  237. var match;
  238. while ((match = lineBreakG.exec(this.input)) && match.index < pos) {
  239. ++this$1.toks.curLine;
  240. this$1.toks.lineStart = match.index + match[0].length;
  241. }
  242. }
  243. };
  244. lp.lookAhead = function(n) {
  245. var this$1 = this;
  246. while (n > this.ahead.length)
  247. { this$1.ahead.push(this$1.readToken()); }
  248. return this.ahead[n - 1]
  249. };
  250. function isDummy(node) { return node.name == "✖" }
  251. var lp$1 = LooseParser.prototype;
  252. lp$1.parseTopLevel = function() {
  253. var this$1 = this;
  254. var node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0);
  255. node.body = [];
  256. while (this.tok.type !== tokTypes.eof) { node.body.push(this$1.parseStatement()); }
  257. this.last = this.tok;
  258. if (this.options.ecmaVersion >= 6) {
  259. node.sourceType = this.options.sourceType;
  260. }
  261. return this.finishNode(node, "Program")
  262. };
  263. lp$1.parseStatement = function() {
  264. var this$1 = this;
  265. var starttype = this.tok.type, node = this.startNode(), kind;
  266. if (this.toks.isLet()) {
  267. starttype = tokTypes._var;
  268. kind = "let";
  269. }
  270. switch (starttype) {
  271. case tokTypes._break: case tokTypes._continue:
  272. this.next();
  273. var isBreak = starttype === tokTypes._break;
  274. if (this.semicolon() || this.canInsertSemicolon()) {
  275. node.label = null;
  276. } else {
  277. node.label = this.tok.type === tokTypes.name ? this.parseIdent() : null;
  278. this.semicolon();
  279. }
  280. return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
  281. case tokTypes._debugger:
  282. this.next();
  283. this.semicolon();
  284. return this.finishNode(node, "DebuggerStatement")
  285. case tokTypes._do:
  286. this.next();
  287. node.body = this.parseStatement();
  288. node.test = this.eat(tokTypes._while) ? this.parseParenExpression() : this.dummyIdent();
  289. this.semicolon();
  290. return this.finishNode(node, "DoWhileStatement")
  291. case tokTypes._for:
  292. this.next();
  293. this.pushCx();
  294. this.expect(tokTypes.parenL);
  295. if (this.tok.type === tokTypes.semi) { return this.parseFor(node, null) }
  296. var isLet = this.toks.isLet();
  297. if (isLet || this.tok.type === tokTypes._var || this.tok.type === tokTypes._const) {
  298. var init$1 = this.parseVar(true, isLet ? "let" : this.tok.value);
  299. if (init$1.declarations.length === 1 && (this.tok.type === tokTypes._in || this.isContextual("of"))) {
  300. return this.parseForIn(node, init$1)
  301. }
  302. return this.parseFor(node, init$1)
  303. }
  304. var init = this.parseExpression(true);
  305. if (this.tok.type === tokTypes._in || this.isContextual("of"))
  306. { return this.parseForIn(node, this.toAssignable(init)) }
  307. return this.parseFor(node, init)
  308. case tokTypes._function:
  309. this.next();
  310. return this.parseFunction(node, true)
  311. case tokTypes._if:
  312. this.next();
  313. node.test = this.parseParenExpression();
  314. node.consequent = this.parseStatement();
  315. node.alternate = this.eat(tokTypes._else) ? this.parseStatement() : null;
  316. return this.finishNode(node, "IfStatement")
  317. case tokTypes._return:
  318. this.next();
  319. if (this.eat(tokTypes.semi) || this.canInsertSemicolon()) { node.argument = null; }
  320. else { node.argument = this.parseExpression(); this.semicolon(); }
  321. return this.finishNode(node, "ReturnStatement")
  322. case tokTypes._switch:
  323. var blockIndent = this.curIndent, line = this.curLineStart;
  324. this.next();
  325. node.discriminant = this.parseParenExpression();
  326. node.cases = [];
  327. this.pushCx();
  328. this.expect(tokTypes.braceL);
  329. var cur;
  330. while (!this.closes(tokTypes.braceR, blockIndent, line, true)) {
  331. if (this$1.tok.type === tokTypes._case || this$1.tok.type === tokTypes._default) {
  332. var isCase = this$1.tok.type === tokTypes._case;
  333. if (cur) { this$1.finishNode(cur, "SwitchCase"); }
  334. node.cases.push(cur = this$1.startNode());
  335. cur.consequent = [];
  336. this$1.next();
  337. if (isCase) { cur.test = this$1.parseExpression(); }
  338. else { cur.test = null; }
  339. this$1.expect(tokTypes.colon);
  340. } else {
  341. if (!cur) {
  342. node.cases.push(cur = this$1.startNode());
  343. cur.consequent = [];
  344. cur.test = null;
  345. }
  346. cur.consequent.push(this$1.parseStatement());
  347. }
  348. }
  349. if (cur) { this.finishNode(cur, "SwitchCase"); }
  350. this.popCx();
  351. this.eat(tokTypes.braceR);
  352. return this.finishNode(node, "SwitchStatement")
  353. case tokTypes._throw:
  354. this.next();
  355. node.argument = this.parseExpression();
  356. this.semicolon();
  357. return this.finishNode(node, "ThrowStatement")
  358. case tokTypes._try:
  359. this.next();
  360. node.block = this.parseBlock();
  361. node.handler = null;
  362. if (this.tok.type === tokTypes._catch) {
  363. var clause = this.startNode();
  364. this.next();
  365. this.expect(tokTypes.parenL);
  366. clause.param = this.toAssignable(this.parseExprAtom(), true);
  367. this.expect(tokTypes.parenR);
  368. clause.body = this.parseBlock();
  369. node.handler = this.finishNode(clause, "CatchClause");
  370. }
  371. node.finalizer = this.eat(tokTypes._finally) ? this.parseBlock() : null;
  372. if (!node.handler && !node.finalizer) { return node.block }
  373. return this.finishNode(node, "TryStatement")
  374. case tokTypes._var:
  375. case tokTypes._const:
  376. return this.parseVar(false, kind || this.tok.value)
  377. case tokTypes._while:
  378. this.next();
  379. node.test = this.parseParenExpression();
  380. node.body = this.parseStatement();
  381. return this.finishNode(node, "WhileStatement")
  382. case tokTypes._with:
  383. this.next();
  384. node.object = this.parseParenExpression();
  385. node.body = this.parseStatement();
  386. return this.finishNode(node, "WithStatement")
  387. case tokTypes.braceL:
  388. return this.parseBlock()
  389. case tokTypes.semi:
  390. this.next();
  391. return this.finishNode(node, "EmptyStatement")
  392. case tokTypes._class:
  393. return this.parseClass(true)
  394. case tokTypes._import:
  395. return this.parseImport()
  396. case tokTypes._export:
  397. return this.parseExport()
  398. default:
  399. if (this.toks.isAsyncFunction()) {
  400. this.next();
  401. this.next();
  402. return this.parseFunction(node, true, true)
  403. }
  404. var expr = this.parseExpression();
  405. if (isDummy(expr)) {
  406. this.next();
  407. if (this.tok.type === tokTypes.eof) { return this.finishNode(node, "EmptyStatement") }
  408. return this.parseStatement()
  409. } else if (starttype === tokTypes.name && expr.type === "Identifier" && this.eat(tokTypes.colon)) {
  410. node.body = this.parseStatement();
  411. node.label = expr;
  412. return this.finishNode(node, "LabeledStatement")
  413. } else {
  414. node.expression = expr;
  415. this.semicolon();
  416. return this.finishNode(node, "ExpressionStatement")
  417. }
  418. }
  419. };
  420. lp$1.parseBlock = function() {
  421. var this$1 = this;
  422. var node = this.startNode();
  423. this.pushCx();
  424. this.expect(tokTypes.braceL);
  425. var blockIndent = this.curIndent, line = this.curLineStart;
  426. node.body = [];
  427. while (!this.closes(tokTypes.braceR, blockIndent, line, true))
  428. { node.body.push(this$1.parseStatement()); }
  429. this.popCx();
  430. this.eat(tokTypes.braceR);
  431. return this.finishNode(node, "BlockStatement")
  432. };
  433. lp$1.parseFor = function(node, init) {
  434. node.init = init;
  435. node.test = node.update = null;
  436. if (this.eat(tokTypes.semi) && this.tok.type !== tokTypes.semi) { node.test = this.parseExpression(); }
  437. if (this.eat(tokTypes.semi) && this.tok.type !== tokTypes.parenR) { node.update = this.parseExpression(); }
  438. this.popCx();
  439. this.expect(tokTypes.parenR);
  440. node.body = this.parseStatement();
  441. return this.finishNode(node, "ForStatement")
  442. };
  443. lp$1.parseForIn = function(node, init) {
  444. var type = this.tok.type === tokTypes._in ? "ForInStatement" : "ForOfStatement";
  445. this.next();
  446. node.left = init;
  447. node.right = this.parseExpression();
  448. this.popCx();
  449. this.expect(tokTypes.parenR);
  450. node.body = this.parseStatement();
  451. return this.finishNode(node, type)
  452. };
  453. lp$1.parseVar = function(noIn, kind) {
  454. var this$1 = this;
  455. var node = this.startNode();
  456. node.kind = kind;
  457. this.next();
  458. node.declarations = [];
  459. do {
  460. var decl = this$1.startNode();
  461. decl.id = this$1.options.ecmaVersion >= 6 ? this$1.toAssignable(this$1.parseExprAtom(), true) : this$1.parseIdent();
  462. decl.init = this$1.eat(tokTypes.eq) ? this$1.parseMaybeAssign(noIn) : null;
  463. node.declarations.push(this$1.finishNode(decl, "VariableDeclarator"));
  464. } while (this.eat(tokTypes.comma))
  465. if (!node.declarations.length) {
  466. var decl$1 = this.startNode();
  467. decl$1.id = this.dummyIdent();
  468. node.declarations.push(this.finishNode(decl$1, "VariableDeclarator"));
  469. }
  470. if (!noIn) { this.semicolon(); }
  471. return this.finishNode(node, "VariableDeclaration")
  472. };
  473. lp$1.parseClass = function(isStatement) {
  474. var this$1 = this;
  475. var node = this.startNode();
  476. this.next();
  477. if (this.tok.type === tokTypes.name) { node.id = this.parseIdent(); }
  478. else if (isStatement === true) { node.id = this.dummyIdent(); }
  479. else { node.id = null; }
  480. node.superClass = this.eat(tokTypes._extends) ? this.parseExpression() : null;
  481. node.body = this.startNode();
  482. node.body.body = [];
  483. this.pushCx();
  484. var indent = this.curIndent + 1, line = this.curLineStart;
  485. this.eat(tokTypes.braceL);
  486. if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart; }
  487. while (!this.closes(tokTypes.braceR, indent, line)) {
  488. if (this$1.semicolon()) { continue }
  489. var method = this$1.startNode(), isGenerator = (void 0), isAsync = (void 0);
  490. if (this$1.options.ecmaVersion >= 6) {
  491. method.static = false;
  492. isGenerator = this$1.eat(tokTypes.star);
  493. }
  494. this$1.parsePropertyName(method);
  495. if (isDummy(method.key)) { if (isDummy(this$1.parseMaybeAssign())) { this$1.next(); } this$1.eat(tokTypes.comma); continue }
  496. if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" &&
  497. (this$1.tok.type != tokTypes.parenL && this$1.tok.type != tokTypes.braceL)) {
  498. method.static = true;
  499. isGenerator = this$1.eat(tokTypes.star);
  500. this$1.parsePropertyName(method);
  501. } else {
  502. method.static = false;
  503. }
  504. if (!method.computed &&
  505. method.key.type === "Identifier" && method.key.name === "async" && this$1.tok.type !== tokTypes.parenL &&
  506. !this$1.canInsertSemicolon()) {
  507. this$1.parsePropertyName(method);
  508. isAsync = true;
  509. } else {
  510. isAsync = false;
  511. }
  512. if (this$1.options.ecmaVersion >= 5 && method.key.type === "Identifier" &&
  513. !method.computed && (method.key.name === "get" || method.key.name === "set") &&
  514. this$1.tok.type !== tokTypes.parenL && this$1.tok.type !== tokTypes.braceL) {
  515. method.kind = method.key.name;
  516. this$1.parsePropertyName(method);
  517. method.value = this$1.parseMethod(false);
  518. } else {
  519. if (!method.computed && !method.static && !isGenerator && !isAsync && (
  520. method.key.type === "Identifier" && method.key.name === "constructor" ||
  521. method.key.type === "Literal" && method.key.value === "constructor")) {
  522. method.kind = "constructor";
  523. } else {
  524. method.kind = "method";
  525. }
  526. method.value = this$1.parseMethod(isGenerator, isAsync);
  527. }
  528. node.body.body.push(this$1.finishNode(method, "MethodDefinition"));
  529. }
  530. this.popCx();
  531. if (!this.eat(tokTypes.braceR)) {
  532. // If there is no closing brace, make the node span to the start
  533. // of the next token (this is useful for Tern)
  534. this.last.end = this.tok.start;
  535. if (this.options.locations) { this.last.loc.end = this.tok.loc.start; }
  536. }
  537. this.semicolon();
  538. this.finishNode(node.body, "ClassBody");
  539. return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
  540. };
  541. lp$1.parseFunction = function(node, isStatement, isAsync) {
  542. var oldInAsync = this.inAsync;
  543. this.initFunction(node);
  544. if (this.options.ecmaVersion >= 6) {
  545. node.generator = this.eat(tokTypes.star);
  546. }
  547. if (this.options.ecmaVersion >= 8) {
  548. node.async = !!isAsync;
  549. }
  550. if (this.tok.type === tokTypes.name) { node.id = this.parseIdent(); }
  551. else if (isStatement === true) { node.id = this.dummyIdent(); }
  552. this.inAsync = node.async;
  553. node.params = this.parseFunctionParams();
  554. node.body = this.parseBlock();
  555. this.inAsync = oldInAsync;
  556. return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
  557. };
  558. lp$1.parseExport = function() {
  559. var node = this.startNode();
  560. this.next();
  561. if (this.eat(tokTypes.star)) {
  562. node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString();
  563. return this.finishNode(node, "ExportAllDeclaration")
  564. }
  565. if (this.eat(tokTypes._default)) {
  566. // export default (function foo() {}) // This is FunctionExpression.
  567. var isAsync;
  568. if (this.tok.type === tokTypes._function || (isAsync = this.toks.isAsyncFunction())) {
  569. var fNode = this.startNode();
  570. this.next();
  571. if (isAsync) { this.next(); }
  572. node.declaration = this.parseFunction(fNode, "nullableID", isAsync);
  573. } else if (this.tok.type === tokTypes._class) {
  574. node.declaration = this.parseClass("nullableID");
  575. } else {
  576. node.declaration = this.parseMaybeAssign();
  577. this.semicolon();
  578. }
  579. return this.finishNode(node, "ExportDefaultDeclaration")
  580. }
  581. if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) {
  582. node.declaration = this.parseStatement();
  583. node.specifiers = [];
  584. node.source = null;
  585. } else {
  586. node.declaration = null;
  587. node.specifiers = this.parseExportSpecifierList();
  588. node.source = this.eatContextual("from") ? this.parseExprAtom() : null;
  589. this.semicolon();
  590. }
  591. return this.finishNode(node, "ExportNamedDeclaration")
  592. };
  593. lp$1.parseImport = function() {
  594. var node = this.startNode();
  595. this.next();
  596. if (this.tok.type === tokTypes.string) {
  597. node.specifiers = [];
  598. node.source = this.parseExprAtom();
  599. node.kind = "";
  600. } else {
  601. var elt;
  602. if (this.tok.type === tokTypes.name && this.tok.value !== "from") {
  603. elt = this.startNode();
  604. elt.local = this.parseIdent();
  605. this.finishNode(elt, "ImportDefaultSpecifier");
  606. this.eat(tokTypes.comma);
  607. }
  608. node.specifiers = this.parseImportSpecifierList();
  609. node.source = this.eatContextual("from") && this.tok.type == tokTypes.string ? this.parseExprAtom() : this.dummyString();
  610. if (elt) { node.specifiers.unshift(elt); }
  611. }
  612. this.semicolon();
  613. return this.finishNode(node, "ImportDeclaration")
  614. };
  615. lp$1.parseImportSpecifierList = function() {
  616. var this$1 = this;
  617. var elts = [];
  618. if (this.tok.type === tokTypes.star) {
  619. var elt = this.startNode();
  620. this.next();
  621. elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent();
  622. elts.push(this.finishNode(elt, "ImportNamespaceSpecifier"));
  623. } else {
  624. var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart;
  625. this.pushCx();
  626. this.eat(tokTypes.braceL);
  627. if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; }
  628. while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
  629. var elt$1 = this$1.startNode();
  630. if (this$1.eat(tokTypes.star)) {
  631. elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : this$1.dummyIdent();
  632. this$1.finishNode(elt$1, "ImportNamespaceSpecifier");
  633. } else {
  634. if (this$1.isContextual("from")) { break }
  635. elt$1.imported = this$1.parseIdent();
  636. if (isDummy(elt$1.imported)) { break }
  637. elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : elt$1.imported;
  638. this$1.finishNode(elt$1, "ImportSpecifier");
  639. }
  640. elts.push(elt$1);
  641. this$1.eat(tokTypes.comma);
  642. }
  643. this.eat(tokTypes.braceR);
  644. this.popCx();
  645. }
  646. return elts
  647. };
  648. lp$1.parseExportSpecifierList = function() {
  649. var this$1 = this;
  650. var elts = [];
  651. var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart;
  652. this.pushCx();
  653. this.eat(tokTypes.braceL);
  654. if (this.curLineStart > continuedLine) { continuedLine = this.curLineStart; }
  655. while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
  656. if (this$1.isContextual("from")) { break }
  657. var elt = this$1.startNode();
  658. elt.local = this$1.parseIdent();
  659. if (isDummy(elt.local)) { break }
  660. elt.exported = this$1.eatContextual("as") ? this$1.parseIdent() : elt.local;
  661. this$1.finishNode(elt, "ExportSpecifier");
  662. elts.push(elt);
  663. this$1.eat(tokTypes.comma);
  664. }
  665. this.eat(tokTypes.braceR);
  666. this.popCx();
  667. return elts
  668. };
  669. var lp$2 = LooseParser.prototype;
  670. lp$2.checkLVal = function(expr) {
  671. if (!expr) { return expr }
  672. switch (expr.type) {
  673. case "Identifier":
  674. case "MemberExpression":
  675. return expr
  676. case "ParenthesizedExpression":
  677. expr.expression = this.checkLVal(expr.expression);
  678. return expr
  679. default:
  680. return this.dummyIdent()
  681. }
  682. };
  683. lp$2.parseExpression = function(noIn) {
  684. var this$1 = this;
  685. var start = this.storeCurrentPos();
  686. var expr = this.parseMaybeAssign(noIn);
  687. if (this.tok.type === tokTypes.comma) {
  688. var node = this.startNodeAt(start);
  689. node.expressions = [expr];
  690. while (this.eat(tokTypes.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn)); }
  691. return this.finishNode(node, "SequenceExpression")
  692. }
  693. return expr
  694. };
  695. lp$2.parseParenExpression = function() {
  696. this.pushCx();
  697. this.expect(tokTypes.parenL);
  698. var val = this.parseExpression();
  699. this.popCx();
  700. this.expect(tokTypes.parenR);
  701. return val
  702. };
  703. lp$2.parseMaybeAssign = function(noIn) {
  704. if (this.toks.isContextual("yield")) {
  705. var node = this.startNode();
  706. this.next();
  707. if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type != tokTypes.star && !this.tok.type.startsExpr)) {
  708. node.delegate = false;
  709. node.argument = null;
  710. } else {
  711. node.delegate = this.eat(tokTypes.star);
  712. node.argument = this.parseMaybeAssign();
  713. }
  714. return this.finishNode(node, "YieldExpression")
  715. }
  716. var start = this.storeCurrentPos();
  717. var left = this.parseMaybeConditional(noIn);
  718. if (this.tok.type.isAssign) {
  719. var node$1 = this.startNodeAt(start);
  720. node$1.operator = this.tok.value;
  721. node$1.left = this.tok.type === tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left);
  722. this.next();
  723. node$1.right = this.parseMaybeAssign(noIn);
  724. return this.finishNode(node$1, "AssignmentExpression")
  725. }
  726. return left
  727. };
  728. lp$2.parseMaybeConditional = function(noIn) {
  729. var start = this.storeCurrentPos();
  730. var expr = this.parseExprOps(noIn);
  731. if (this.eat(tokTypes.question)) {
  732. var node = this.startNodeAt(start);
  733. node.test = expr;
  734. node.consequent = this.parseMaybeAssign();
  735. node.alternate = this.expect(tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent();
  736. return this.finishNode(node, "ConditionalExpression")
  737. }
  738. return expr
  739. };
  740. lp$2.parseExprOps = function(noIn) {
  741. var start = this.storeCurrentPos();
  742. var indent = this.curIndent, line = this.curLineStart;
  743. return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line)
  744. };
  745. lp$2.parseExprOp = function(left, start, minPrec, noIn, indent, line) {
  746. if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) { return left }
  747. var prec = this.tok.type.binop;
  748. if (prec != null && (!noIn || this.tok.type !== tokTypes._in)) {
  749. if (prec > minPrec) {
  750. var node = this.startNodeAt(start);
  751. node.left = left;
  752. node.operator = this.tok.value;
  753. this.next();
  754. if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) {
  755. node.right = this.dummyIdent();
  756. } else {
  757. var rightStart = this.storeCurrentPos();
  758. node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line);
  759. }
  760. this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression");
  761. return this.parseExprOp(node, start, minPrec, noIn, indent, line)
  762. }
  763. }
  764. return left
  765. };
  766. lp$2.parseMaybeUnary = function(sawUnary) {
  767. var this$1 = this;
  768. var start = this.storeCurrentPos(), expr;
  769. if (this.options.ecmaVersion >= 8 && this.inAsync && this.toks.isContextual("await")) {
  770. expr = this.parseAwait();
  771. sawUnary = true;
  772. } else if (this.tok.type.prefix) {
  773. var node = this.startNode(), update = this.tok.type === tokTypes.incDec;
  774. if (!update) { sawUnary = true; }
  775. node.operator = this.tok.value;
  776. node.prefix = true;
  777. this.next();
  778. node.argument = this.parseMaybeUnary(true);
  779. if (update) { node.argument = this.checkLVal(node.argument); }
  780. expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
  781. } else if (this.tok.type === tokTypes.ellipsis) {
  782. var node$1 = this.startNode();
  783. this.next();
  784. node$1.argument = this.parseMaybeUnary(sawUnary);
  785. expr = this.finishNode(node$1, "SpreadElement");
  786. } else {
  787. expr = this.parseExprSubscripts();
  788. while (this.tok.type.postfix && !this.canInsertSemicolon()) {
  789. var node$2 = this$1.startNodeAt(start);
  790. node$2.operator = this$1.tok.value;
  791. node$2.prefix = false;
  792. node$2.argument = this$1.checkLVal(expr);
  793. this$1.next();
  794. expr = this$1.finishNode(node$2, "UpdateExpression");
  795. }
  796. }
  797. if (!sawUnary && this.eat(tokTypes.starstar)) {
  798. var node$3 = this.startNodeAt(start);
  799. node$3.operator = "**";
  800. node$3.left = expr;
  801. node$3.right = this.parseMaybeUnary(false);
  802. return this.finishNode(node$3, "BinaryExpression")
  803. }
  804. return expr
  805. };
  806. lp$2.parseExprSubscripts = function() {
  807. var start = this.storeCurrentPos();
  808. return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart)
  809. };
  810. lp$2.parseSubscripts = function(base, start, noCalls, startIndent, line) {
  811. var this$1 = this;
  812. for (;;) {
  813. if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine()) {
  814. if (this$1.tok.type == tokTypes.dot && this$1.curIndent == startIndent)
  815. { --startIndent; }
  816. else
  817. { return base }
  818. }
  819. var maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this$1.canInsertSemicolon();
  820. if (this$1.eat(tokTypes.dot)) {
  821. var node = this$1.startNodeAt(start);
  822. node.object = base;
  823. if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine())
  824. { node.property = this$1.dummyIdent(); }
  825. else
  826. { node.property = this$1.parsePropertyAccessor() || this$1.dummyIdent(); }
  827. node.computed = false;
  828. base = this$1.finishNode(node, "MemberExpression");
  829. } else if (this$1.tok.type == tokTypes.bracketL) {
  830. this$1.pushCx();
  831. this$1.next();
  832. var node$1 = this$1.startNodeAt(start);
  833. node$1.object = base;
  834. node$1.property = this$1.parseExpression();
  835. node$1.computed = true;
  836. this$1.popCx();
  837. this$1.expect(tokTypes.bracketR);
  838. base = this$1.finishNode(node$1, "MemberExpression");
  839. } else if (!noCalls && this$1.tok.type == tokTypes.parenL) {
  840. var exprList = this$1.parseExprList(tokTypes.parenR);
  841. if (maybeAsyncArrow && this$1.eat(tokTypes.arrow))
  842. { return this$1.parseArrowExpression(this$1.startNodeAt(start), exprList, true) }
  843. var node$2 = this$1.startNodeAt(start);
  844. node$2.callee = base;
  845. node$2.arguments = exprList;
  846. base = this$1.finishNode(node$2, "CallExpression");
  847. } else if (this$1.tok.type == tokTypes.backQuote) {
  848. var node$3 = this$1.startNodeAt(start);
  849. node$3.tag = base;
  850. node$3.quasi = this$1.parseTemplate();
  851. base = this$1.finishNode(node$3, "TaggedTemplateExpression");
  852. } else {
  853. return base
  854. }
  855. }
  856. };
  857. lp$2.parseExprAtom = function() {
  858. var node;
  859. switch (this.tok.type) {
  860. case tokTypes._this:
  861. case tokTypes._super:
  862. var type = this.tok.type === tokTypes._this ? "ThisExpression" : "Super";
  863. node = this.startNode();
  864. this.next();
  865. return this.finishNode(node, type)
  866. case tokTypes.name:
  867. var start = this.storeCurrentPos();
  868. var id = this.parseIdent();
  869. var isAsync = false;
  870. if (id.name === "async" && !this.canInsertSemicolon()) {
  871. if (this.eat(tokTypes._function))
  872. { return this.parseFunction(this.startNodeAt(start), false, true) }
  873. if (this.tok.type === tokTypes.name) {
  874. id = this.parseIdent();
  875. isAsync = true;
  876. }
  877. }
  878. return this.eat(tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id
  879. case tokTypes.regexp:
  880. node = this.startNode();
  881. var val = this.tok.value;
  882. node.regex = {pattern: val.pattern, flags: val.flags};
  883. node.value = val.value;
  884. node.raw = this.input.slice(this.tok.start, this.tok.end);
  885. this.next();
  886. return this.finishNode(node, "Literal")
  887. case tokTypes.num: case tokTypes.string:
  888. node = this.startNode();
  889. node.value = this.tok.value;
  890. node.raw = this.input.slice(this.tok.start, this.tok.end);
  891. this.next();
  892. return this.finishNode(node, "Literal")
  893. case tokTypes._null: case tokTypes._true: case tokTypes._false:
  894. node = this.startNode();
  895. node.value = this.tok.type === tokTypes._null ? null : this.tok.type === tokTypes._true;
  896. node.raw = this.tok.type.keyword;
  897. this.next();
  898. return this.finishNode(node, "Literal")
  899. case tokTypes.parenL:
  900. var parenStart = this.storeCurrentPos();
  901. this.next();
  902. var inner = this.parseExpression();
  903. this.expect(tokTypes.parenR);
  904. if (this.eat(tokTypes.arrow)) {
  905. // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy.
  906. var params = inner.expressions || [inner];
  907. if (params.length && isDummy(params[params.length - 1]))
  908. { params.pop(); }
  909. return this.parseArrowExpression(this.startNodeAt(parenStart), params)
  910. }
  911. if (this.options.preserveParens) {
  912. var par = this.startNodeAt(parenStart);
  913. par.expression = inner;
  914. inner = this.finishNode(par, "ParenthesizedExpression");
  915. }
  916. return inner
  917. case tokTypes.bracketL:
  918. node = this.startNode();
  919. node.elements = this.parseExprList(tokTypes.bracketR, true);
  920. return this.finishNode(node, "ArrayExpression")
  921. case tokTypes.braceL:
  922. return this.parseObj()
  923. case tokTypes._class:
  924. return this.parseClass(false)
  925. case tokTypes._function:
  926. node = this.startNode();
  927. this.next();
  928. return this.parseFunction(node, false)
  929. case tokTypes._new:
  930. return this.parseNew()
  931. case tokTypes.backQuote:
  932. return this.parseTemplate()
  933. default:
  934. return this.dummyIdent()
  935. }
  936. };
  937. lp$2.parseNew = function() {
  938. var node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart;
  939. var meta = this.parseIdent(true);
  940. if (this.options.ecmaVersion >= 6 && this.eat(tokTypes.dot)) {
  941. node.meta = meta;
  942. node.property = this.parseIdent(true);
  943. return this.finishNode(node, "MetaProperty")
  944. }
  945. var start = this.storeCurrentPos();
  946. node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line);
  947. if (this.tok.type == tokTypes.parenL) {
  948. node.arguments = this.parseExprList(tokTypes.parenR);
  949. } else {
  950. node.arguments = [];
  951. }
  952. return this.finishNode(node, "NewExpression")
  953. };
  954. lp$2.parseTemplateElement = function() {
  955. var elem = this.startNode();
  956. // The loose parser accepts invalid unicode escapes even in untagged templates.
  957. if (this.tok.type === tokTypes.invalidTemplate) {
  958. elem.value = {
  959. raw: this.tok.value,
  960. cooked: null
  961. };
  962. } else {
  963. elem.value = {
  964. raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, "\n"),
  965. cooked: this.tok.value
  966. };
  967. }
  968. this.next();
  969. elem.tail = this.tok.type === tokTypes.backQuote;
  970. return this.finishNode(elem, "TemplateElement")
  971. };
  972. lp$2.parseTemplate = function() {
  973. var this$1 = this;
  974. var node = this.startNode();
  975. this.next();
  976. node.expressions = [];
  977. var curElt = this.parseTemplateElement();
  978. node.quasis = [curElt];
  979. while (!curElt.tail) {
  980. this$1.next();
  981. node.expressions.push(this$1.parseExpression());
  982. if (this$1.expect(tokTypes.braceR)) {
  983. curElt = this$1.parseTemplateElement();
  984. } else {
  985. curElt = this$1.startNode();
  986. curElt.value = {cooked: "", raw: ""};
  987. curElt.tail = true;
  988. this$1.finishNode(curElt, "TemplateElement");
  989. }
  990. node.quasis.push(curElt);
  991. }
  992. this.expect(tokTypes.backQuote);
  993. return this.finishNode(node, "TemplateLiteral")
  994. };
  995. lp$2.parseObj = function() {
  996. var this$1 = this;
  997. var node = this.startNode();
  998. node.properties = [];
  999. this.pushCx();
  1000. var indent = this.curIndent + 1, line = this.curLineStart;
  1001. this.eat(tokTypes.braceL);
  1002. if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart; }
  1003. while (!this.closes(tokTypes.braceR, indent, line)) {
  1004. var prop = this$1.startNode(), isGenerator = (void 0), isAsync = (void 0), start = (void 0);
  1005. if (this$1.options.ecmaVersion >= 6) {
  1006. start = this$1.storeCurrentPos();
  1007. prop.method = false;
  1008. prop.shorthand = false;
  1009. isGenerator = this$1.eat(tokTypes.star);
  1010. }
  1011. this$1.parsePropertyName(prop);
  1012. if (this$1.toks.isAsyncProp(prop)) {
  1013. this$1.parsePropertyName(prop);
  1014. isAsync = true;
  1015. } else {
  1016. isAsync = false;
  1017. }
  1018. if (isDummy(prop.key)) { if (isDummy(this$1.parseMaybeAssign())) { this$1.next(); } this$1.eat(tokTypes.comma); continue }
  1019. if (this$1.eat(tokTypes.colon)) {
  1020. prop.kind = "init";
  1021. prop.value = this$1.parseMaybeAssign();
  1022. } else if (this$1.options.ecmaVersion >= 6 && (this$1.tok.type === tokTypes.parenL || this$1.tok.type === tokTypes.braceL)) {
  1023. prop.kind = "init";
  1024. prop.method = true;
  1025. prop.value = this$1.parseMethod(isGenerator, isAsync);
  1026. } else if (this$1.options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
  1027. !prop.computed && (prop.key.name === "get" || prop.key.name === "set") &&
  1028. (this$1.tok.type != tokTypes.comma && this$1.tok.type != tokTypes.braceR)) {
  1029. prop.kind = prop.key.name;
  1030. this$1.parsePropertyName(prop);
  1031. prop.value = this$1.parseMethod(false);
  1032. } else {
  1033. prop.kind = "init";
  1034. if (this$1.options.ecmaVersion >= 6) {
  1035. if (this$1.eat(tokTypes.eq)) {
  1036. var assign = this$1.startNodeAt(start);
  1037. assign.operator = "=";
  1038. assign.left = prop.key;
  1039. assign.right = this$1.parseMaybeAssign();
  1040. prop.value = this$1.finishNode(assign, "AssignmentExpression");
  1041. } else {
  1042. prop.value = prop.key;
  1043. }
  1044. } else {
  1045. prop.value = this$1.dummyIdent();
  1046. }
  1047. prop.shorthand = true;
  1048. }
  1049. node.properties.push(this$1.finishNode(prop, "Property"));
  1050. this$1.eat(tokTypes.comma);
  1051. }
  1052. this.popCx();
  1053. if (!this.eat(tokTypes.braceR)) {
  1054. // If there is no closing brace, make the node span to the start
  1055. // of the next token (this is useful for Tern)
  1056. this.last.end = this.tok.start;
  1057. if (this.options.locations) { this.last.loc.end = this.tok.loc.start; }
  1058. }
  1059. return this.finishNode(node, "ObjectExpression")
  1060. };
  1061. lp$2.parsePropertyName = function(prop) {
  1062. if (this.options.ecmaVersion >= 6) {
  1063. if (this.eat(tokTypes.bracketL)) {
  1064. prop.computed = true;
  1065. prop.key = this.parseExpression();
  1066. this.expect(tokTypes.bracketR);
  1067. return
  1068. } else {
  1069. prop.computed = false;
  1070. }
  1071. }
  1072. var key = (this.tok.type === tokTypes.num || this.tok.type === tokTypes.string) ? this.parseExprAtom() : this.parseIdent();
  1073. prop.key = key || this.dummyIdent();
  1074. };
  1075. lp$2.parsePropertyAccessor = function() {
  1076. if (this.tok.type === tokTypes.name || this.tok.type.keyword) { return this.parseIdent() }
  1077. };
  1078. lp$2.parseIdent = function() {
  1079. var name = this.tok.type === tokTypes.name ? this.tok.value : this.tok.type.keyword;
  1080. if (!name) { return this.dummyIdent() }
  1081. var node = this.startNode();
  1082. this.next();
  1083. node.name = name;
  1084. return this.finishNode(node, "Identifier")
  1085. };
  1086. lp$2.initFunction = function(node) {
  1087. node.id = null;
  1088. node.params = [];
  1089. if (this.options.ecmaVersion >= 6) {
  1090. node.generator = false;
  1091. node.expression = false;
  1092. }
  1093. if (this.options.ecmaVersion >= 8)
  1094. { node.async = false; }
  1095. };
  1096. // Convert existing expression atom to assignable pattern
  1097. // if possible.
  1098. lp$2.toAssignable = function(node, binding) {
  1099. var this$1 = this;
  1100. if (!node || node.type == "Identifier" || (node.type == "MemberExpression" && !binding)) {
  1101. // Okay
  1102. } else if (node.type == "ParenthesizedExpression") {
  1103. this.toAssignable(node.expression, binding);
  1104. } else if (this.options.ecmaVersion < 6) {
  1105. return this.dummyIdent()
  1106. } else if (node.type == "ObjectExpression") {
  1107. node.type = "ObjectPattern";
  1108. var props = node.properties;
  1109. for (var i = 0, list = props; i < list.length; i += 1)
  1110. {
  1111. var prop = list[i];
  1112. this$1.toAssignable(prop.value, binding);
  1113. }
  1114. } else if (node.type == "ArrayExpression") {
  1115. node.type = "ArrayPattern";
  1116. this.toAssignableList(node.elements, binding);
  1117. } else if (node.type == "SpreadElement") {
  1118. node.type = "RestElement";
  1119. this.toAssignable(node.argument, binding);
  1120. } else if (node.type == "AssignmentExpression") {
  1121. node.type = "AssignmentPattern";
  1122. delete node.operator;
  1123. } else {
  1124. return this.dummyIdent()
  1125. }
  1126. return node
  1127. };
  1128. lp$2.toAssignableList = function(exprList, binding) {
  1129. var this$1 = this;
  1130. for (var i = 0, list = exprList; i < list.length; i += 1)
  1131. {
  1132. var expr = list[i];
  1133. this$1.toAssignable(expr, binding);
  1134. }
  1135. return exprList
  1136. };
  1137. lp$2.parseFunctionParams = function(params) {
  1138. params = this.parseExprList(tokTypes.parenR);
  1139. return this.toAssignableList(params, true)
  1140. };
  1141. lp$2.parseMethod = function(isGenerator, isAsync) {
  1142. var node = this.startNode(), oldInAsync = this.inAsync;
  1143. this.initFunction(node);
  1144. if (this.options.ecmaVersion >= 6)
  1145. { node.generator = !!isGenerator; }
  1146. if (this.options.ecmaVersion >= 8)
  1147. { node.async = !!isAsync; }
  1148. this.inAsync = node.async;
  1149. node.params = this.parseFunctionParams();
  1150. node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== tokTypes.braceL;
  1151. node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock();
  1152. this.inAsync = oldInAsync;
  1153. return this.finishNode(node, "FunctionExpression")
  1154. };
  1155. lp$2.parseArrowExpression = function(node, params, isAsync) {
  1156. var oldInAsync = this.inAsync;
  1157. this.initFunction(node);
  1158. if (this.options.ecmaVersion >= 8)
  1159. { node.async = !!isAsync; }
  1160. this.inAsync = node.async;
  1161. node.params = this.toAssignableList(params, true);
  1162. node.expression = this.tok.type !== tokTypes.braceL;
  1163. node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock();
  1164. this.inAsync = oldInAsync;
  1165. return this.finishNode(node, "ArrowFunctionExpression")
  1166. };
  1167. lp$2.parseExprList = function(close, allowEmpty) {
  1168. var this$1 = this;
  1169. this.pushCx();
  1170. var indent = this.curIndent, line = this.curLineStart, elts = [];
  1171. this.next(); // Opening bracket
  1172. while (!this.closes(close, indent + 1, line)) {
  1173. if (this$1.eat(tokTypes.comma)) {
  1174. elts.push(allowEmpty ? null : this$1.dummyIdent());
  1175. continue
  1176. }
  1177. var elt = this$1.parseMaybeAssign();
  1178. if (isDummy(elt)) {
  1179. if (this$1.closes(close, indent, line)) { break }
  1180. this$1.next();
  1181. } else {
  1182. elts.push(elt);
  1183. }
  1184. this$1.eat(tokTypes.comma);
  1185. }
  1186. this.popCx();
  1187. if (!this.eat(close)) {
  1188. // If there is no closing brace, make the node span to the start
  1189. // of the next token (this is useful for Tern)
  1190. this.last.end = this.tok.start;
  1191. if (this.options.locations) { this.last.loc.end = this.tok.loc.start; }
  1192. }
  1193. return elts
  1194. };
  1195. lp$2.parseAwait = function() {
  1196. var node = this.startNode();
  1197. this.next();
  1198. node.argument = this.parseMaybeUnary();
  1199. return this.finishNode(node, "AwaitExpression")
  1200. };
  1201. // Acorn: Loose parser
  1202. //
  1203. // This module provides an alternative parser (`parse_dammit`) that
  1204. // exposes that same interface as `parse`, but will try to parse
  1205. // anything as JavaScript, repairing syntax error the best it can.
  1206. // There are circumstances in which it will raise an error and give
  1207. // up, but they are very rare. The resulting AST will be a mostly
  1208. // valid JavaScript AST (as per the [Mozilla parser API][api], except
  1209. // that:
  1210. //
  1211. // - Return outside functions is allowed
  1212. //
  1213. // - Label consistency (no conflicts, break only to existing labels)
  1214. // is not enforced.
  1215. //
  1216. // - Bogus Identifier nodes with a name of `"✖"` are inserted whenever
  1217. // the parser got too confused to return anything meaningful.
  1218. //
  1219. // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
  1220. //
  1221. // The expected use for this is to *first* try `acorn.parse`, and only
  1222. // if that fails switch to `parse_dammit`. The loose parser might
  1223. // parse badly indented code incorrectly, so **don't** use it as
  1224. // your default parser.
  1225. //
  1226. // Quite a lot of acorn.js is duplicated here. The alternative was to
  1227. // add a *lot* of extra cruft to that file, making it less readable
  1228. // and slower. Copying and editing the code allowed me to make
  1229. // invasive changes and simplifications without creating a complicated
  1230. // tangle.
  1231. defaultOptions.tabSize = 4;
  1232. // eslint-disable-next-line camelcase
  1233. function parse_dammit(input, options) {
  1234. return new LooseParser(input, options).parse()
  1235. }
  1236. addLooseExports(parse_dammit, LooseParser, pluginsLoose);
  1237. export { parse_dammit, LooseParser, pluginsLoose };