acorn_loose.es.js 47 KB

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