acorn_loose.es.js 46 KB

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