1 (function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = global || self, factory(global.acorn = {}));
5 }(this, (function (exports) { 'use strict';
7 // Reserved word lists for various dialects of the language
10 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
11 5: "class enum extends super const export import",
13 strict: "implements interface let package private protected public static yield",
14 strictBind: "eval arguments"
19 var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
22 5: ecma5AndLessKeywords,
23 "5module": ecma5AndLessKeywords + " export import",
24 6: ecma5AndLessKeywords + " const class extends export import super"
27 var keywordRelationalOperator = /^in(stanceof)?$/;
29 // ## Character categories
31 // Big ugly regular expressions that match characters in the
32 // whitespace, identifier, and identifier-start categories. These
33 // are only applied when a character is found to actually have a
34 // code point above 128.
35 // Generated by `bin/generate-identifier-regex.js`.
36 var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
37 var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
39 var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
40 var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
42 nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
44 // These are a run-length and offset encoded representation of the
45 // >0xffff code points that are a valid part of identifiers. The
46 // offset starts at 0x10000, and each pair of numbers represents an
47 // offset to the next range, and then a size of the range. They were
48 // generated by bin/generate-identifier-regex.js
50 // eslint-disable-next-line comma-spacing
51 var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,190,0,80,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8952,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938];
53 // eslint-disable-next-line comma-spacing
54 var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,370,1,154,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,82,0,12,1,19628,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,4759,9,787719,239];
56 // This has a complexity linear to the value of the code. The
57 // assumption is that looking up astral identifier characters is
59 function isInAstralSet(code, set) {
61 for (var i = 0; i < set.length; i += 2) {
63 if (pos > code) { return false }
65 if (pos >= code) { return true }
69 // Test whether a given character code starts an identifier.
71 function isIdentifierStart(code, astral) {
72 if (code < 65) { return code === 36 }
73 if (code < 91) { return true }
74 if (code < 97) { return code === 95 }
75 if (code < 123) { return true }
76 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
77 if (astral === false) { return false }
78 return isInAstralSet(code, astralIdentifierStartCodes)
81 // Test whether a given character is part of an identifier.
83 function isIdentifierChar(code, astral) {
84 if (code < 48) { return code === 36 }
85 if (code < 58) { return true }
86 if (code < 65) { return false }
87 if (code < 91) { return true }
88 if (code < 97) { return code === 95 }
89 if (code < 123) { return true }
90 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
91 if (astral === false) { return false }
92 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
97 // The assignment of fine-grained, information-carrying type objects
98 // allows the tokenizer to store the information it has about a
99 // token in a way that is very cheap for the parser to look up.
101 // All token type variables start with an underscore, to make them
102 // easy to recognize.
104 // The `beforeExpr` property is used to disambiguate between regular
105 // expressions and divisions. It is set on all token types that can
106 // be followed by an expression (thus, a slash after them would be a
107 // regular expression).
109 // The `startsExpr` property is used to check if the token ends a
110 // `yield` expression. It is set on all token types that either can
111 // directly start an expression (like a quotation mark) or can
112 // continue an expression (like the body of a string).
114 // `isLoop` marks a keyword as starting a loop, which is important
115 // to know when parsing a label, in order to allow or disallow
116 // continue jumps to that label.
118 var TokenType = function TokenType(label, conf) {
119 if ( conf === void 0 ) conf = {};
122 this.keyword = conf.keyword;
123 this.beforeExpr = !!conf.beforeExpr;
124 this.startsExpr = !!conf.startsExpr;
125 this.isLoop = !!conf.isLoop;
126 this.isAssign = !!conf.isAssign;
127 this.prefix = !!conf.prefix;
128 this.postfix = !!conf.postfix;
129 this.binop = conf.binop || null;
130 this.updateContext = null;
133 function binop(name, prec) {
134 return new TokenType(name, {beforeExpr: true, binop: prec})
136 var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
138 // Map keyword names to token types.
142 // Succinct definitions of keyword token types
143 function kw(name, options) {
144 if ( options === void 0 ) options = {};
146 options.keyword = name;
147 return keywords$1[name] = new TokenType(name, options)
151 num: new TokenType("num", startsExpr),
152 regexp: new TokenType("regexp", startsExpr),
153 string: new TokenType("string", startsExpr),
154 name: new TokenType("name", startsExpr),
155 eof: new TokenType("eof"),
157 // Punctuation token types.
158 bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
159 bracketR: new TokenType("]"),
160 braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
161 braceR: new TokenType("}"),
162 parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
163 parenR: new TokenType(")"),
164 comma: new TokenType(",", beforeExpr),
165 semi: new TokenType(";", beforeExpr),
166 colon: new TokenType(":", beforeExpr),
167 dot: new TokenType("."),
168 question: new TokenType("?", beforeExpr),
169 questionDot: new TokenType("?."),
170 arrow: new TokenType("=>", beforeExpr),
171 template: new TokenType("template"),
172 invalidTemplate: new TokenType("invalidTemplate"),
173 ellipsis: new TokenType("...", beforeExpr),
174 backQuote: new TokenType("`", startsExpr),
175 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
177 // Operators. These carry several kinds of properties to help the
178 // parser use them properly (the presence of these properties is
179 // what categorizes them as operators).
181 // `binop`, when present, specifies that this operator is a binary
182 // operator, and will refer to its precedence.
184 // `prefix` and `postfix` mark the operator as a prefix or postfix
187 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
188 // binary operators with a very low precedence, that should result
189 // in AssignmentExpression nodes.
191 eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
192 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
193 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
194 prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
195 logicalOR: binop("||", 1),
196 logicalAND: binop("&&", 2),
197 bitwiseOR: binop("|", 3),
198 bitwiseXOR: binop("^", 4),
199 bitwiseAND: binop("&", 5),
200 equality: binop("==/!=/===/!==", 6),
201 relational: binop("</>/<=/>=", 7),
202 bitShift: binop("<</>>/>>>", 8),
203 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
204 modulo: binop("%", 10),
205 star: binop("*", 10),
206 slash: binop("/", 10),
207 starstar: new TokenType("**", {beforeExpr: true}),
208 coalesce: binop("??", 1),
210 // Keyword token types.
212 _case: kw("case", beforeExpr),
214 _continue: kw("continue"),
215 _debugger: kw("debugger"),
216 _default: kw("default", beforeExpr),
217 _do: kw("do", {isLoop: true, beforeExpr: true}),
218 _else: kw("else", beforeExpr),
219 _finally: kw("finally"),
220 _for: kw("for", {isLoop: true}),
221 _function: kw("function", startsExpr),
223 _return: kw("return", beforeExpr),
224 _switch: kw("switch"),
225 _throw: kw("throw", beforeExpr),
229 _while: kw("while", {isLoop: true}),
231 _new: kw("new", {beforeExpr: true, startsExpr: true}),
232 _this: kw("this", startsExpr),
233 _super: kw("super", startsExpr),
234 _class: kw("class", startsExpr),
235 _extends: kw("extends", beforeExpr),
236 _export: kw("export"),
237 _import: kw("import", startsExpr),
238 _null: kw("null", startsExpr),
239 _true: kw("true", startsExpr),
240 _false: kw("false", startsExpr),
241 _in: kw("in", {beforeExpr: true, binop: 7}),
242 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
243 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
244 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
245 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
248 // Matches a whole line break (where CRLF is considered a single
249 // line break). Used to count lines.
251 var lineBreak = /\r\n?|\n|\u2028|\u2029/;
252 var lineBreakG = new RegExp(lineBreak.source, "g");
254 function isNewLine(code, ecma2019String) {
255 return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))
258 var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
260 var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
262 var ref = Object.prototype;
263 var hasOwnProperty = ref.hasOwnProperty;
264 var toString = ref.toString;
266 // Checks if an object has a property.
268 function has(obj, propName) {
269 return hasOwnProperty.call(obj, propName)
272 var isArray = Array.isArray || (function (obj) { return (
273 toString.call(obj) === "[object Array]"
276 function wordsRegexp(words) {
277 return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
280 // These are used when `options.locations` is on, for the
281 // `startLoc` and `endLoc` properties.
283 var Position = function Position(line, col) {
288 Position.prototype.offset = function offset (n) {
289 return new Position(this.line, this.column + n)
292 var SourceLocation = function SourceLocation(p, start, end) {
295 if (p.sourceFile !== null) { this.source = p.sourceFile; }
298 // The `getLineInfo` function is mostly useful when the
299 // `locations` option is off (for performance reasons) and you
300 // want to find the line/column position for a given character
301 // offset. `input` should be the code string that the offset refers
304 function getLineInfo(input, offset) {
305 for (var line = 1, cur = 0;;) {
306 lineBreakG.lastIndex = cur;
307 var match = lineBreakG.exec(input);
308 if (match && match.index < offset) {
310 cur = match.index + match[0].length;
312 return new Position(line, offset - cur)
317 // A second optional argument can be given to further configure
318 // the parser process. These options are recognized:
320 var defaultOptions = {
321 // `ecmaVersion` indicates the ECMAScript version to parse. Must be
322 // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10
323 // (2019). This influences support for strict mode, the set of
324 // reserved words, and support for new syntax features. The default
327 // `sourceType` indicates the mode the code should be parsed in.
328 // Can be either `"script"` or `"module"`. This influences global
329 // strict mode and parsing of `import` and `export` declarations.
330 sourceType: "script",
331 // `onInsertedSemicolon` can be a callback that will be called
332 // when a semicolon is automatically inserted. It will be passed
333 // the position of the comma as an offset, and if `locations` is
334 // enabled, it is given the location as a `{line, column}` object
335 // as second argument.
336 onInsertedSemicolon: null,
337 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
339 onTrailingComma: null,
340 // By default, reserved words are only enforced if ecmaVersion >= 5.
341 // Set `allowReserved` to a boolean value to explicitly turn this on
342 // an off. When this option has the value "never", reserved words
343 // and keywords can also not be used as property names.
345 // When enabled, a return at the top level is not considered an
347 allowReturnOutsideFunction: false,
348 // When enabled, import/export statements are not constrained to
349 // appearing at the top of the program.
350 allowImportExportEverywhere: false,
351 // When enabled, await identifiers are allowed to appear at the top-level scope,
352 // but they are still not allowed in non-async functions.
353 allowAwaitOutsideFunction: false,
354 // When enabled, hashbang directive in the beginning of file
355 // is allowed and treated as a line comment.
356 allowHashBang: false,
357 // When `locations` is on, `loc` properties holding objects with
358 // `start` and `end` properties in `{line, column}` form (with
359 // line being 1-based and column 0-based) will be attached to the
362 // A function can be passed as `onToken` option, which will
363 // cause Acorn to call that function with object in the same
364 // format as tokens returned from `tokenizer().getToken()`. Note
365 // that you are not allowed to call the parser from the
366 // callback—that will corrupt its internal state.
368 // A function can be passed as `onComment` option, which will
369 // cause Acorn to call that function with `(block, text, start,
370 // end)` parameters whenever a comment is skipped. `block` is a
371 // boolean indicating whether this is a block (`/* */`) comment,
372 // `text` is the content of the comment, and `start` and `end` are
373 // character offsets that denote the start and end of the comment.
374 // When the `locations` option is on, two more parameters are
375 // passed, the full `{line, column}` locations of the start and
376 // end of the comments. Note that you are not allowed to call the
377 // parser from the callback—that will corrupt its internal state.
379 // Nodes have their start and end characters offsets recorded in
380 // `start` and `end` properties (directly on the node, rather than
381 // the `loc` object, which holds line/column data. To also add a
382 // [semi-standardized][range] `range` property holding a `[start,
383 // end]` array with the same numbers, set the `ranges` option to
386 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
388 // It is possible to parse multiple files into a single AST by
389 // passing the tree produced by parsing the first file as
390 // `program` option in subsequent parses. This will add the
391 // toplevel forms of the parsed file to the `Program` (top) node
392 // of an existing parse tree.
394 // When `locations` is on, you can pass this to record the source
395 // file in every node's `loc` object.
397 // This value, if given, is stored in every node, whether
398 // `locations` is on or off.
399 directSourceFile: null,
400 // When enabled, parenthesized expressions are represented by
401 // (non-standard) ParenthesizedExpression nodes
402 preserveParens: false
405 // Interpret and default an options object
407 function getOptions(opts) {
410 for (var opt in defaultOptions)
411 { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
413 if (options.ecmaVersion >= 2015)
414 { options.ecmaVersion -= 2009; }
416 if (options.allowReserved == null)
417 { options.allowReserved = options.ecmaVersion < 5; }
419 if (isArray(options.onToken)) {
420 var tokens = options.onToken;
421 options.onToken = function (token) { return tokens.push(token); };
423 if (isArray(options.onComment))
424 { options.onComment = pushComment(options, options.onComment); }
429 function pushComment(options, array) {
430 return function(block, text, start, end, startLoc, endLoc) {
432 type: block ? "Block" : "Line",
437 if (options.locations)
438 { comment.loc = new SourceLocation(this, startLoc, endLoc); }
440 { comment.range = [start, end]; }
445 // Each scope gets a bitset that may contain these flags
449 SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION,
453 SCOPE_SIMPLE_CATCH = 32,
455 SCOPE_DIRECT_SUPER = 128;
457 function functionFlags(async, generator) {
458 return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
461 // Used in checkLVal and declareName to determine the type of a binding
463 BIND_NONE = 0, // Not a binding
464 BIND_VAR = 1, // Var-style binding
465 BIND_LEXICAL = 2, // Let- or const-style binding
466 BIND_FUNCTION = 3, // Function declaration
467 BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
468 BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
470 var Parser = function Parser(options, input, startPos) {
471 this.options = options = getOptions(options);
472 this.sourceFile = options.sourceFile;
473 this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
475 if (options.allowReserved !== true) {
476 for (var v = options.ecmaVersion;; v--)
477 { if (reserved = reservedWords[v]) { break } }
478 if (options.sourceType === "module") { reserved += " await"; }
480 this.reservedWords = wordsRegexp(reserved);
481 var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
482 this.reservedWordsStrict = wordsRegexp(reservedStrict);
483 this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
484 this.input = String(input);
486 // Used to signal to callers of `readWord1` whether the word
487 // contained any escape sequences. This is needed because words with
488 // escape sequences must not be interpreted as keywords.
489 this.containsEsc = false;
491 // Set up token state
493 // The current position of the tokenizer in the input.
496 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
497 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
499 this.pos = this.lineStart = 0;
503 // Properties of the current token:
505 this.type = types.eof;
506 // For tokens that include more information than their type, the value
508 // Its start and end offset
509 this.start = this.end = this.pos;
510 // And, if locations are used, the {line, column} object
511 // corresponding to those offsets
512 this.startLoc = this.endLoc = this.curPosition();
514 // Position information for the previous token
515 this.lastTokEndLoc = this.lastTokStartLoc = null;
516 this.lastTokStart = this.lastTokEnd = this.pos;
518 // The context stack is used to superficially track syntactic
519 // context to predict whether a regular expression is allowed in a
521 this.context = this.initialContext();
522 this.exprAllowed = true;
524 // Figure out if it's a module code.
525 this.inModule = options.sourceType === "module";
526 this.strict = this.inModule || this.strictDirective(this.pos);
528 // Used to signify the start of a potential arrow function
529 this.potentialArrowAt = -1;
531 // Positions to delayed-check that yield/await does not exist in default parameters.
532 this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
535 // Thus-far undefined exports.
536 this.undefinedExports = {};
538 // If enabled, skip leading hashbang line.
539 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
540 { this.skipLineComment(2); }
542 // Scope tracking for duplicate variable names (see scope.js)
543 this.scopeStack = [];
544 this.enterScope(SCOPE_TOP);
546 // For RegExp validation
547 this.regexpState = null;
550 var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } };
552 Parser.prototype.parse = function parse () {
553 var node = this.options.program || this.startNode();
555 return this.parseTopLevel(node)
558 prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
559 prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
560 prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
561 prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 };
562 prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
563 prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
565 // Switch to a getter for 7.0.0.
566 Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 };
568 Parser.extend = function extend () {
569 var plugins = [], len = arguments.length;
570 while ( len-- ) plugins[ len ] = arguments[ len ];
573 for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
577 Parser.parse = function parse (input, options) {
578 return new this(options, input).parse()
581 Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
582 var parser = new this(options, input, pos);
584 return parser.parseExpression()
587 Parser.tokenizer = function tokenizer (input, options) {
588 return new this(options, input)
591 Object.defineProperties( Parser.prototype, prototypeAccessors );
593 var pp = Parser.prototype;
595 // ## Parser utilities
597 var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)")/;
598 pp.strictDirective = function(start) {
600 // Try to find string literal.
601 skipWhiteSpace.lastIndex = start;
602 start += skipWhiteSpace.exec(this.input)[0].length;
603 var match = literal.exec(this.input.slice(start));
604 if (!match) { return false }
605 if ((match[1] || match[2]) === "use strict") {
606 skipWhiteSpace.lastIndex = start + match[0].length;
607 var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
608 var next = this.input.charAt(end);
609 return next === ";" || next === "}" ||
610 (lineBreak.test(spaceAfter[0]) &&
611 !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
613 start += match[0].length;
615 // Skip semicolon, if any.
616 skipWhiteSpace.lastIndex = start;
617 start += skipWhiteSpace.exec(this.input)[0].length;
618 if (this.input[start] === ";")
623 // Predicate that tests whether the next token is of the given
624 // type, and if yes, consumes it as a side effect.
626 pp.eat = function(type) {
627 if (this.type === type) {
635 // Tests whether parsed token is a contextual keyword.
637 pp.isContextual = function(name) {
638 return this.type === types.name && this.value === name && !this.containsEsc
641 // Consumes contextual keyword if possible.
643 pp.eatContextual = function(name) {
644 if (!this.isContextual(name)) { return false }
649 // Asserts that following token is given contextual keyword.
651 pp.expectContextual = function(name) {
652 if (!this.eatContextual(name)) { this.unexpected(); }
655 // Test whether a semicolon can be inserted at the current position.
657 pp.canInsertSemicolon = function() {
658 return this.type === types.eof ||
659 this.type === types.braceR ||
660 lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
663 pp.insertSemicolon = function() {
664 if (this.canInsertSemicolon()) {
665 if (this.options.onInsertedSemicolon)
666 { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
671 // Consume a semicolon, or, failing that, see if we are allowed to
672 // pretend that there is a semicolon at this position.
674 pp.semicolon = function() {
675 if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
678 pp.afterTrailingComma = function(tokType, notNext) {
679 if (this.type === tokType) {
680 if (this.options.onTrailingComma)
681 { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
688 // Expect a token of a given type. If found, consume it, otherwise,
689 // raise an unexpected token error.
691 pp.expect = function(type) {
692 this.eat(type) || this.unexpected();
695 // Raise an unexpected token error.
697 pp.unexpected = function(pos) {
698 this.raise(pos != null ? pos : this.start, "Unexpected token");
701 function DestructuringErrors() {
702 this.shorthandAssign =
704 this.parenthesizedAssign =
705 this.parenthesizedBind =
710 pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
711 if (!refDestructuringErrors) { return }
712 if (refDestructuringErrors.trailingComma > -1)
713 { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
714 var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
715 if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
718 pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
719 if (!refDestructuringErrors) { return false }
720 var shorthandAssign = refDestructuringErrors.shorthandAssign;
721 var doubleProto = refDestructuringErrors.doubleProto;
722 if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
723 if (shorthandAssign >= 0)
724 { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
725 if (doubleProto >= 0)
726 { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
729 pp.checkYieldAwaitInDefaultParams = function() {
730 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
731 { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
733 { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
736 pp.isSimpleAssignTarget = function(expr) {
737 if (expr.type === "ParenthesizedExpression")
738 { return this.isSimpleAssignTarget(expr.expression) }
739 return expr.type === "Identifier" || expr.type === "MemberExpression"
742 var pp$1 = Parser.prototype;
744 // ### Statement parsing
746 // Parse a program. Initializes the parser, reads any number of
747 // statements, and wraps them in a Program node. Optionally takes a
748 // `program` argument. If present, the statements will be appended
749 // to its body instead of creating a new node.
751 pp$1.parseTopLevel = function(node) {
753 if (!node.body) { node.body = []; }
754 while (this.type !== types.eof) {
755 var stmt = this.parseStatement(null, true, exports);
756 node.body.push(stmt);
759 { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
763 this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
765 this.adaptDirectivePrologue(node.body);
767 node.sourceType = this.options.sourceType;
768 return this.finishNode(node, "Program")
771 var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
773 pp$1.isLet = function(context) {
774 if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
775 skipWhiteSpace.lastIndex = this.pos;
776 var skip = skipWhiteSpace.exec(this.input);
777 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
778 // For ambiguous cases, determine if a LexicalDeclaration (or only a
779 // Statement) is allowed here. If context is not empty then only a Statement
780 // is allowed. However, `let [` is an explicit negative lookahead for
781 // ExpressionStatement, so special-case it first.
782 if (nextCh === 91) { return true } // '['
783 if (context) { return false }
785 if (nextCh === 123) { return true } // '{'
786 if (isIdentifierStart(nextCh, true)) {
788 while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
789 var ident = this.input.slice(next, pos);
790 if (!keywordRelationalOperator.test(ident)) { return true }
795 // check 'async [no LineTerminator here] function'
796 // - 'async /*foo*/ function' is OK.
797 // - 'async /*\n*/ function' is invalid.
798 pp$1.isAsyncFunction = function() {
799 if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
802 skipWhiteSpace.lastIndex = this.pos;
803 var skip = skipWhiteSpace.exec(this.input);
804 var next = this.pos + skip[0].length;
805 return !lineBreak.test(this.input.slice(this.pos, next)) &&
806 this.input.slice(next, next + 8) === "function" &&
807 (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
810 // Parse a single statement.
812 // If expecting a statement and finding a slash operator, parse a
813 // regular expression literal. This is to handle cases like
814 // `if (foo) /blah/.exec(foo)`, where looking at the previous token
817 pp$1.parseStatement = function(context, topLevel, exports) {
818 var starttype = this.type, node = this.startNode(), kind;
820 if (this.isLet(context)) {
821 starttype = types._var;
825 // Most types of statements are recognized by the keyword they
826 // start with. Many are trivial to parse, some require a bit of
830 case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
831 case types._debugger: return this.parseDebuggerStatement(node)
832 case types._do: return this.parseDoStatement(node)
833 case types._for: return this.parseForStatement(node)
834 case types._function:
835 // Function as sole body of either an if statement or a labeled statement
836 // works, but not when it is part of a labeled statement that is the sole
837 // body of an if statement.
838 if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
839 return this.parseFunctionStatement(node, false, !context)
841 if (context) { this.unexpected(); }
842 return this.parseClass(node, true)
843 case types._if: return this.parseIfStatement(node)
844 case types._return: return this.parseReturnStatement(node)
845 case types._switch: return this.parseSwitchStatement(node)
846 case types._throw: return this.parseThrowStatement(node)
847 case types._try: return this.parseTryStatement(node)
848 case types._const: case types._var:
849 kind = kind || this.value;
850 if (context && kind !== "var") { this.unexpected(); }
851 return this.parseVarStatement(node, kind)
852 case types._while: return this.parseWhileStatement(node)
853 case types._with: return this.parseWithStatement(node)
854 case types.braceL: return this.parseBlock(true, node)
855 case types.semi: return this.parseEmptyStatement(node)
858 if (this.options.ecmaVersion > 10 && starttype === types._import) {
859 skipWhiteSpace.lastIndex = this.pos;
860 var skip = skipWhiteSpace.exec(this.input);
861 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
862 if (nextCh === 40 || nextCh === 46) // '(' or '.'
863 { return this.parseExpressionStatement(node, this.parseExpression()) }
866 if (!this.options.allowImportExportEverywhere) {
868 { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
870 { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
872 return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
874 // If the statement does not start with a statement keyword or a
875 // brace, it's an ExpressionStatement or LabeledStatement. We
876 // simply start parsing an expression, and afterwards, if the
877 // next token is a colon and the expression was a simple
878 // Identifier node, we switch to interpreting it as a label.
880 if (this.isAsyncFunction()) {
881 if (context) { this.unexpected(); }
883 return this.parseFunctionStatement(node, true, !context)
886 var maybeName = this.value, expr = this.parseExpression();
887 if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
888 { return this.parseLabeledStatement(node, maybeName, expr, context) }
889 else { return this.parseExpressionStatement(node, expr) }
893 pp$1.parseBreakContinueStatement = function(node, keyword) {
894 var isBreak = keyword === "break";
896 if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
897 else if (this.type !== types.name) { this.unexpected(); }
899 node.label = this.parseIdent();
903 // Verify that there is an actual destination to break or
906 for (; i < this.labels.length; ++i) {
907 var lab = this.labels[i];
908 if (node.label == null || lab.name === node.label.name) {
909 if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
910 if (node.label && isBreak) { break }
913 if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
914 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
917 pp$1.parseDebuggerStatement = function(node) {
920 return this.finishNode(node, "DebuggerStatement")
923 pp$1.parseDoStatement = function(node) {
925 this.labels.push(loopLabel);
926 node.body = this.parseStatement("do");
928 this.expect(types._while);
929 node.test = this.parseParenExpression();
930 if (this.options.ecmaVersion >= 6)
931 { this.eat(types.semi); }
933 { this.semicolon(); }
934 return this.finishNode(node, "DoWhileStatement")
937 // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
938 // loop is non-trivial. Basically, we have to parse the init `var`
939 // statement or expression, disallowing the `in` operator (see
940 // the second parameter to `parseExpression`), and then check
941 // whether the next token is `in` or `of`. When there is no init
942 // part (semicolon immediately after the opening parenthesis), it
943 // is a regular `for` loop.
945 pp$1.parseForStatement = function(node) {
947 var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
948 this.labels.push(loopLabel);
950 this.expect(types.parenL);
951 if (this.type === types.semi) {
952 if (awaitAt > -1) { this.unexpected(awaitAt); }
953 return this.parseFor(node, null)
955 var isLet = this.isLet();
956 if (this.type === types._var || this.type === types._const || isLet) {
957 var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
959 this.parseVar(init$1, true, kind);
960 this.finishNode(init$1, "VariableDeclaration");
961 if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) {
962 if (this.options.ecmaVersion >= 9) {
963 if (this.type === types._in) {
964 if (awaitAt > -1) { this.unexpected(awaitAt); }
965 } else { node.await = awaitAt > -1; }
967 return this.parseForIn(node, init$1)
969 if (awaitAt > -1) { this.unexpected(awaitAt); }
970 return this.parseFor(node, init$1)
972 var refDestructuringErrors = new DestructuringErrors;
973 var init = this.parseExpression(true, refDestructuringErrors);
974 if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
975 if (this.options.ecmaVersion >= 9) {
976 if (this.type === types._in) {
977 if (awaitAt > -1) { this.unexpected(awaitAt); }
978 } else { node.await = awaitAt > -1; }
980 this.toAssignable(init, false, refDestructuringErrors);
981 this.checkLVal(init);
982 return this.parseForIn(node, init)
984 this.checkExpressionErrors(refDestructuringErrors, true);
986 if (awaitAt > -1) { this.unexpected(awaitAt); }
987 return this.parseFor(node, init)
990 pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) {
992 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
995 pp$1.parseIfStatement = function(node) {
997 node.test = this.parseParenExpression();
998 // allow function declarations in branches, but only in non-strict mode
999 node.consequent = this.parseStatement("if");
1000 node.alternate = this.eat(types._else) ? this.parseStatement("if") : null;
1001 return this.finishNode(node, "IfStatement")
1004 pp$1.parseReturnStatement = function(node) {
1005 if (!this.inFunction && !this.options.allowReturnOutsideFunction)
1006 { this.raise(this.start, "'return' outside of function"); }
1009 // In `return` (and `break`/`continue`), the keywords with
1010 // optional arguments, we eagerly look for a semicolon or the
1011 // possibility to insert one.
1013 if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
1014 else { node.argument = this.parseExpression(); this.semicolon(); }
1015 return this.finishNode(node, "ReturnStatement")
1018 pp$1.parseSwitchStatement = function(node) {
1020 node.discriminant = this.parseParenExpression();
1022 this.expect(types.braceL);
1023 this.labels.push(switchLabel);
1026 // Statements under must be grouped (by label) in SwitchCase
1027 // nodes. `cur` is used to keep the node that we are currently
1028 // adding statements to.
1031 for (var sawDefault = false; this.type !== types.braceR;) {
1032 if (this.type === types._case || this.type === types._default) {
1033 var isCase = this.type === types._case;
1034 if (cur) { this.finishNode(cur, "SwitchCase"); }
1035 node.cases.push(cur = this.startNode());
1036 cur.consequent = [];
1039 cur.test = this.parseExpression();
1041 if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
1045 this.expect(types.colon);
1047 if (!cur) { this.unexpected(); }
1048 cur.consequent.push(this.parseStatement(null));
1052 if (cur) { this.finishNode(cur, "SwitchCase"); }
1053 this.next(); // Closing brace
1055 return this.finishNode(node, "SwitchStatement")
1058 pp$1.parseThrowStatement = function(node) {
1060 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
1061 { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
1062 node.argument = this.parseExpression();
1064 return this.finishNode(node, "ThrowStatement")
1067 // Reused empty array added for node fields that are always empty.
1071 pp$1.parseTryStatement = function(node) {
1073 node.block = this.parseBlock();
1074 node.handler = null;
1075 if (this.type === types._catch) {
1076 var clause = this.startNode();
1078 if (this.eat(types.parenL)) {
1079 clause.param = this.parseBindingAtom();
1080 var simple = clause.param.type === "Identifier";
1081 this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
1082 this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
1083 this.expect(types.parenR);
1085 if (this.options.ecmaVersion < 10) { this.unexpected(); }
1086 clause.param = null;
1089 clause.body = this.parseBlock(false);
1091 node.handler = this.finishNode(clause, "CatchClause");
1093 node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
1094 if (!node.handler && !node.finalizer)
1095 { this.raise(node.start, "Missing catch or finally clause"); }
1096 return this.finishNode(node, "TryStatement")
1099 pp$1.parseVarStatement = function(node, kind) {
1101 this.parseVar(node, false, kind);
1103 return this.finishNode(node, "VariableDeclaration")
1106 pp$1.parseWhileStatement = function(node) {
1108 node.test = this.parseParenExpression();
1109 this.labels.push(loopLabel);
1110 node.body = this.parseStatement("while");
1112 return this.finishNode(node, "WhileStatement")
1115 pp$1.parseWithStatement = function(node) {
1116 if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
1118 node.object = this.parseParenExpression();
1119 node.body = this.parseStatement("with");
1120 return this.finishNode(node, "WithStatement")
1123 pp$1.parseEmptyStatement = function(node) {
1125 return this.finishNode(node, "EmptyStatement")
1128 pp$1.parseLabeledStatement = function(node, maybeName, expr, context) {
1129 for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
1131 var label = list[i$1];
1133 if (label.name === maybeName)
1134 { this.raise(expr.start, "Label '" + maybeName + "' is already declared");
1136 var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
1137 for (var i = this.labels.length - 1; i >= 0; i--) {
1138 var label$1 = this.labels[i];
1139 if (label$1.statementStart === node.start) {
1140 // Update information about previous labels on this node
1141 label$1.statementStart = this.start;
1142 label$1.kind = kind;
1145 this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
1146 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
1149 return this.finishNode(node, "LabeledStatement")
1152 pp$1.parseExpressionStatement = function(node, expr) {
1153 node.expression = expr;
1155 return this.finishNode(node, "ExpressionStatement")
1158 // Parse a semicolon-enclosed block of statements, handling `"use
1159 // strict"` declarations when `allowStrict` is true (used for
1160 // function bodies).
1162 pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) {
1163 if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
1164 if ( node === void 0 ) node = this.startNode();
1167 this.expect(types.braceL);
1168 if (createNewLexicalScope) { this.enterScope(0); }
1169 while (this.type !== types.braceR) {
1170 var stmt = this.parseStatement(null);
1171 node.body.push(stmt);
1173 if (exitStrict) { this.strict = false; }
1175 if (createNewLexicalScope) { this.exitScope(); }
1176 return this.finishNode(node, "BlockStatement")
1179 // Parse a regular `for` loop. The disambiguation code in
1180 // `parseStatement` will already have parsed the init statement or
1183 pp$1.parseFor = function(node, init) {
1185 this.expect(types.semi);
1186 node.test = this.type === types.semi ? null : this.parseExpression();
1187 this.expect(types.semi);
1188 node.update = this.type === types.parenR ? null : this.parseExpression();
1189 this.expect(types.parenR);
1190 node.body = this.parseStatement("for");
1193 return this.finishNode(node, "ForStatement")
1196 // Parse a `for`/`in` and `for`/`of` loop, which are almost
1197 // same from parser's perspective.
1199 pp$1.parseForIn = function(node, init) {
1200 var isForIn = this.type === types._in;
1204 init.type === "VariableDeclaration" &&
1205 init.declarations[0].init != null &&
1208 this.options.ecmaVersion < 8 ||
1210 init.kind !== "var" ||
1211 init.declarations[0].id.type !== "Identifier"
1216 ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
1218 } else if (init.type === "AssignmentPattern") {
1219 this.raise(init.start, "Invalid left-hand side in for-loop");
1222 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
1223 this.expect(types.parenR);
1224 node.body = this.parseStatement("for");
1227 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
1230 // Parse a list of variable declarations.
1232 pp$1.parseVar = function(node, isFor, kind) {
1233 node.declarations = [];
1236 var decl = this.startNode();
1237 this.parseVarId(decl, kind);
1238 if (this.eat(types.eq)) {
1239 decl.init = this.parseMaybeAssign(isFor);
1240 } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
1242 } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) {
1243 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
1247 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
1248 if (!this.eat(types.comma)) { break }
1253 pp$1.parseVarId = function(decl, kind) {
1254 decl.id = this.parseBindingAtom();
1255 this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
1258 var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
1260 // Parse a function declaration or literal (depending on the
1261 // `statement & FUNC_STATEMENT`).
1263 // Remove `allowExpressionBody` for 7.0.0, as it is only called with false
1264 pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) {
1265 this.initFunction(node);
1266 if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
1267 if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT))
1268 { this.unexpected(); }
1269 node.generator = this.eat(types.star);
1271 if (this.options.ecmaVersion >= 8)
1272 { node.async = !!isAsync; }
1274 if (statement & FUNC_STATEMENT) {
1275 node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent();
1276 if (node.id && !(statement & FUNC_HANGING_STATEMENT))
1277 // If it is a regular function declaration in sloppy mode, then it is
1278 // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
1279 // mode depends on properties of the current scope (see
1280 // treatFunctionsAsVar).
1281 { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
1284 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
1287 this.awaitIdentPos = 0;
1288 this.enterScope(functionFlags(node.async, node.generator));
1290 if (!(statement & FUNC_STATEMENT))
1291 { node.id = this.type === types.name ? this.parseIdent() : null; }
1293 this.parseFunctionParams(node);
1294 this.parseFunctionBody(node, allowExpressionBody, false);
1296 this.yieldPos = oldYieldPos;
1297 this.awaitPos = oldAwaitPos;
1298 this.awaitIdentPos = oldAwaitIdentPos;
1299 return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
1302 pp$1.parseFunctionParams = function(node) {
1303 this.expect(types.parenL);
1304 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
1305 this.checkYieldAwaitInDefaultParams();
1308 // Parse a class declaration or literal (depending on the
1309 // `isStatement` parameter).
1311 pp$1.parseClass = function(node, isStatement) {
1314 // ecma-262 14.6 Class Definitions
1315 // A class definition is always strict mode code.
1316 var oldStrict = this.strict;
1319 this.parseClassId(node, isStatement);
1320 this.parseClassSuper(node);
1321 var classBody = this.startNode();
1322 var hadConstructor = false;
1323 classBody.body = [];
1324 this.expect(types.braceL);
1325 while (this.type !== types.braceR) {
1326 var element = this.parseClassElement(node.superClass !== null);
1328 classBody.body.push(element);
1329 if (element.type === "MethodDefinition" && element.kind === "constructor") {
1330 if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
1331 hadConstructor = true;
1335 this.strict = oldStrict;
1337 node.body = this.finishNode(classBody, "ClassBody");
1338 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
1341 pp$1.parseClassElement = function(constructorAllowsSuper) {
1344 if (this.eat(types.semi)) { return null }
1346 var method = this.startNode();
1347 var tryContextual = function (k, noLineBreak) {
1348 if ( noLineBreak === void 0 ) noLineBreak = false;
1350 var start = this$1.start, startLoc = this$1.startLoc;
1351 if (!this$1.eatContextual(k)) { return false }
1352 if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
1353 if (method.key) { this$1.unexpected(); }
1354 method.computed = false;
1355 method.key = this$1.startNodeAt(start, startLoc);
1356 method.key.name = k;
1357 this$1.finishNode(method.key, "Identifier");
1361 method.kind = "method";
1362 method.static = tryContextual("static");
1363 var isGenerator = this.eat(types.star);
1364 var isAsync = false;
1366 if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
1368 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
1369 } else if (tryContextual("get")) {
1370 method.kind = "get";
1371 } else if (tryContextual("set")) {
1372 method.kind = "set";
1375 if (!method.key) { this.parsePropertyName(method); }
1376 var key = method.key;
1377 var allowsDirectSuper = false;
1378 if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
1379 key.type === "Literal" && key.value === "constructor")) {
1380 if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
1381 if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
1382 if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
1383 method.kind = "constructor";
1384 allowsDirectSuper = constructorAllowsSuper;
1385 } else if (method.static && key.type === "Identifier" && key.name === "prototype") {
1386 this.raise(key.start, "Classes may not have a static property named prototype");
1388 this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper);
1389 if (method.kind === "get" && method.value.params.length !== 0)
1390 { this.raiseRecoverable(method.value.start, "getter should have no params"); }
1391 if (method.kind === "set" && method.value.params.length !== 1)
1392 { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
1393 if (method.kind === "set" && method.value.params[0].type === "RestElement")
1394 { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
1398 pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
1399 method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
1400 return this.finishNode(method, "MethodDefinition")
1403 pp$1.parseClassId = function(node, isStatement) {
1404 if (this.type === types.name) {
1405 node.id = this.parseIdent();
1407 { this.checkLVal(node.id, BIND_LEXICAL, false); }
1409 if (isStatement === true)
1410 { this.unexpected(); }
1415 pp$1.parseClassSuper = function(node) {
1416 node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
1419 // Parses module export declaration.
1421 pp$1.parseExport = function(node, exports) {
1423 // export * from '...'
1424 if (this.eat(types.star)) {
1425 if (this.options.ecmaVersion >= 11) {
1426 if (this.eatContextual("as")) {
1427 node.exported = this.parseIdent(true);
1428 this.checkExport(exports, node.exported.name, this.lastTokStart);
1430 node.exported = null;
1433 this.expectContextual("from");
1434 if (this.type !== types.string) { this.unexpected(); }
1435 node.source = this.parseExprAtom();
1437 return this.finishNode(node, "ExportAllDeclaration")
1439 if (this.eat(types._default)) { // export default ...
1440 this.checkExport(exports, "default", this.lastTokStart);
1442 if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
1443 var fNode = this.startNode();
1445 if (isAsync) { this.next(); }
1446 node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
1447 } else if (this.type === types._class) {
1448 var cNode = this.startNode();
1449 node.declaration = this.parseClass(cNode, "nullableID");
1451 node.declaration = this.parseMaybeAssign();
1454 return this.finishNode(node, "ExportDefaultDeclaration")
1456 // export var|const|let|function|class ...
1457 if (this.shouldParseExportStatement()) {
1458 node.declaration = this.parseStatement(null);
1459 if (node.declaration.type === "VariableDeclaration")
1460 { this.checkVariableExport(exports, node.declaration.declarations); }
1462 { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
1463 node.specifiers = [];
1465 } else { // export { x, y as z } [from '...']
1466 node.declaration = null;
1467 node.specifiers = this.parseExportSpecifiers(exports);
1468 if (this.eatContextual("from")) {
1469 if (this.type !== types.string) { this.unexpected(); }
1470 node.source = this.parseExprAtom();
1472 for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
1473 // check for keywords used as local names
1476 this.checkUnreserved(spec.local);
1477 // check if export is defined
1478 this.checkLocalExport(spec.local);
1485 return this.finishNode(node, "ExportNamedDeclaration")
1488 pp$1.checkExport = function(exports, name, pos) {
1489 if (!exports) { return }
1490 if (has(exports, name))
1491 { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
1492 exports[name] = true;
1495 pp$1.checkPatternExport = function(exports, pat) {
1496 var type = pat.type;
1497 if (type === "Identifier")
1498 { this.checkExport(exports, pat.name, pat.start); }
1499 else if (type === "ObjectPattern")
1500 { for (var i = 0, list = pat.properties; i < list.length; i += 1)
1504 this.checkPatternExport(exports, prop);
1506 else if (type === "ArrayPattern")
1507 { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
1508 var elt = list$1[i$1];
1510 if (elt) { this.checkPatternExport(exports, elt); }
1512 else if (type === "Property")
1513 { this.checkPatternExport(exports, pat.value); }
1514 else if (type === "AssignmentPattern")
1515 { this.checkPatternExport(exports, pat.left); }
1516 else if (type === "RestElement")
1517 { this.checkPatternExport(exports, pat.argument); }
1518 else if (type === "ParenthesizedExpression")
1519 { this.checkPatternExport(exports, pat.expression); }
1522 pp$1.checkVariableExport = function(exports, decls) {
1523 if (!exports) { return }
1524 for (var i = 0, list = decls; i < list.length; i += 1)
1528 this.checkPatternExport(exports, decl.id);
1532 pp$1.shouldParseExportStatement = function() {
1533 return this.type.keyword === "var" ||
1534 this.type.keyword === "const" ||
1535 this.type.keyword === "class" ||
1536 this.type.keyword === "function" ||
1538 this.isAsyncFunction()
1541 // Parses a comma-separated list of module exports.
1543 pp$1.parseExportSpecifiers = function(exports) {
1544 var nodes = [], first = true;
1545 // export { x, y as z } [from '...']
1546 this.expect(types.braceL);
1547 while (!this.eat(types.braceR)) {
1549 this.expect(types.comma);
1550 if (this.afterTrailingComma(types.braceR)) { break }
1551 } else { first = false; }
1553 var node = this.startNode();
1554 node.local = this.parseIdent(true);
1555 node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
1556 this.checkExport(exports, node.exported.name, node.exported.start);
1557 nodes.push(this.finishNode(node, "ExportSpecifier"));
1562 // Parses import declaration.
1564 pp$1.parseImport = function(node) {
1567 if (this.type === types.string) {
1568 node.specifiers = empty;
1569 node.source = this.parseExprAtom();
1571 node.specifiers = this.parseImportSpecifiers();
1572 this.expectContextual("from");
1573 node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
1576 return this.finishNode(node, "ImportDeclaration")
1579 // Parses a comma-separated list of module imports.
1581 pp$1.parseImportSpecifiers = function() {
1582 var nodes = [], first = true;
1583 if (this.type === types.name) {
1584 // import defaultObj, { x, y as z } from '...'
1585 var node = this.startNode();
1586 node.local = this.parseIdent();
1587 this.checkLVal(node.local, BIND_LEXICAL);
1588 nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
1589 if (!this.eat(types.comma)) { return nodes }
1591 if (this.type === types.star) {
1592 var node$1 = this.startNode();
1594 this.expectContextual("as");
1595 node$1.local = this.parseIdent();
1596 this.checkLVal(node$1.local, BIND_LEXICAL);
1597 nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
1600 this.expect(types.braceL);
1601 while (!this.eat(types.braceR)) {
1603 this.expect(types.comma);
1604 if (this.afterTrailingComma(types.braceR)) { break }
1605 } else { first = false; }
1607 var node$2 = this.startNode();
1608 node$2.imported = this.parseIdent(true);
1609 if (this.eatContextual("as")) {
1610 node$2.local = this.parseIdent();
1612 this.checkUnreserved(node$2.imported);
1613 node$2.local = node$2.imported;
1615 this.checkLVal(node$2.local, BIND_LEXICAL);
1616 nodes.push(this.finishNode(node$2, "ImportSpecifier"));
1621 // Set `ExpressionStatement#directive` property for directive prologues.
1622 pp$1.adaptDirectivePrologue = function(statements) {
1623 for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
1624 statements[i].directive = statements[i].expression.raw.slice(1, -1);
1627 pp$1.isDirectiveCandidate = function(statement) {
1629 statement.type === "ExpressionStatement" &&
1630 statement.expression.type === "Literal" &&
1631 typeof statement.expression.value === "string" &&
1632 // Reject parenthesized strings.
1633 (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
1637 var pp$2 = Parser.prototype;
1639 // Convert existing expression atom to assignable pattern
1642 pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {
1643 if (this.options.ecmaVersion >= 6 && node) {
1644 switch (node.type) {
1646 if (this.inAsync && node.name === "await")
1647 { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
1650 case "ObjectPattern":
1651 case "ArrayPattern":
1655 case "ObjectExpression":
1656 node.type = "ObjectPattern";
1657 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1658 for (var i = 0, list = node.properties; i < list.length; i += 1) {
1661 this.toAssignable(prop, isBinding);
1663 // AssignmentRestProperty[Yield, Await] :
1664 // `...` DestructuringAssignmentTarget[Yield, Await]
1666 // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
1668 prop.type === "RestElement" &&
1669 (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
1671 this.raise(prop.argument.start, "Unexpected token");
1677 // AssignmentProperty has type === "Property"
1678 if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
1679 this.toAssignable(node.value, isBinding);
1682 case "ArrayExpression":
1683 node.type = "ArrayPattern";
1684 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1685 this.toAssignableList(node.elements, isBinding);
1688 case "SpreadElement":
1689 node.type = "RestElement";
1690 this.toAssignable(node.argument, isBinding);
1691 if (node.argument.type === "AssignmentPattern")
1692 { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
1695 case "AssignmentExpression":
1696 if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
1697 node.type = "AssignmentPattern";
1698 delete node.operator;
1699 this.toAssignable(node.left, isBinding);
1700 // falls through to AssignmentPattern
1702 case "AssignmentPattern":
1705 case "ParenthesizedExpression":
1706 this.toAssignable(node.expression, isBinding, refDestructuringErrors);
1709 case "ChainExpression":
1710 this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
1713 case "MemberExpression":
1714 if (!isBinding) { break }
1717 this.raise(node.start, "Assigning to rvalue");
1719 } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1723 // Convert list of expression atoms to binding list.
1725 pp$2.toAssignableList = function(exprList, isBinding) {
1726 var end = exprList.length;
1727 for (var i = 0; i < end; i++) {
1728 var elt = exprList[i];
1729 if (elt) { this.toAssignable(elt, isBinding); }
1732 var last = exprList[end - 1];
1733 if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
1734 { this.unexpected(last.argument.start); }
1739 // Parses spread element.
1741 pp$2.parseSpread = function(refDestructuringErrors) {
1742 var node = this.startNode();
1744 node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
1745 return this.finishNode(node, "SpreadElement")
1748 pp$2.parseRestBinding = function() {
1749 var node = this.startNode();
1752 // RestElement inside of a function parameter must be an identifier
1753 if (this.options.ecmaVersion === 6 && this.type !== types.name)
1754 { this.unexpected(); }
1756 node.argument = this.parseBindingAtom();
1758 return this.finishNode(node, "RestElement")
1761 // Parses lvalue (assignable) atom.
1763 pp$2.parseBindingAtom = function() {
1764 if (this.options.ecmaVersion >= 6) {
1765 switch (this.type) {
1766 case types.bracketL:
1767 var node = this.startNode();
1769 node.elements = this.parseBindingList(types.bracketR, true, true);
1770 return this.finishNode(node, "ArrayPattern")
1773 return this.parseObj(true)
1776 return this.parseIdent()
1779 pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
1780 var elts = [], first = true;
1781 while (!this.eat(close)) {
1782 if (first) { first = false; }
1783 else { this.expect(types.comma); }
1784 if (allowEmpty && this.type === types.comma) {
1786 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
1788 } else if (this.type === types.ellipsis) {
1789 var rest = this.parseRestBinding();
1790 this.parseBindingListItem(rest);
1792 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
1796 var elem = this.parseMaybeDefault(this.start, this.startLoc);
1797 this.parseBindingListItem(elem);
1804 pp$2.parseBindingListItem = function(param) {
1808 // Parses assignment pattern around given atom if possible.
1810 pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
1811 left = left || this.parseBindingAtom();
1812 if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
1813 var node = this.startNodeAt(startPos, startLoc);
1815 node.right = this.parseMaybeAssign();
1816 return this.finishNode(node, "AssignmentPattern")
1819 // Verify that a node is an lval — something that can be assigned
1821 // bindingType can be either:
1822 // 'var' indicating that the lval creates a 'var' binding
1823 // 'let' indicating that the lval creates a lexical ('let' or 'const') binding
1824 // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references
1826 pp$2.checkLVal = function(expr, bindingType, checkClashes) {
1827 if ( bindingType === void 0 ) bindingType = BIND_NONE;
1829 switch (expr.type) {
1831 if (bindingType === BIND_LEXICAL && expr.name === "let")
1832 { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
1833 if (this.strict && this.reservedWordsStrictBind.test(expr.name))
1834 { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
1836 if (has(checkClashes, expr.name))
1837 { this.raiseRecoverable(expr.start, "Argument name clash"); }
1838 checkClashes[expr.name] = true;
1840 if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
1843 case "ChainExpression":
1844 this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
1847 case "MemberExpression":
1848 if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); }
1851 case "ObjectPattern":
1852 for (var i = 0, list = expr.properties; i < list.length; i += 1)
1856 this.checkLVal(prop, bindingType, checkClashes);
1861 // AssignmentProperty has type === "Property"
1862 this.checkLVal(expr.value, bindingType, checkClashes);
1865 case "ArrayPattern":
1866 for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
1867 var elem = list$1[i$1];
1869 if (elem) { this.checkLVal(elem, bindingType, checkClashes); }
1873 case "AssignmentPattern":
1874 this.checkLVal(expr.left, bindingType, checkClashes);
1878 this.checkLVal(expr.argument, bindingType, checkClashes);
1881 case "ParenthesizedExpression":
1882 this.checkLVal(expr.expression, bindingType, checkClashes);
1886 this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
1890 // A recursive descent parser operates by defining functions for all
1892 var pp$3 = Parser.prototype;
1894 // Check if property name clashes with already added.
1895 // Object/class getters and setters are not allowed to clash —
1896 // either with each other or with an init property — and in
1897 // strict mode, init properties are also not allowed to be repeated.
1899 pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {
1900 if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
1902 if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
1907 case "Identifier": name = key.name; break
1908 case "Literal": name = String(key.value); break
1911 var kind = prop.kind;
1912 if (this.options.ecmaVersion >= 6) {
1913 if (name === "__proto__" && kind === "init") {
1914 if (propHash.proto) {
1915 if (refDestructuringErrors) {
1916 if (refDestructuringErrors.doubleProto < 0)
1917 { refDestructuringErrors.doubleProto = key.start; }
1918 // Backwards-compat kludge. Can be removed in version 6.0
1919 } else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
1921 propHash.proto = true;
1926 var other = propHash[name];
1929 if (kind === "init") {
1930 redefinition = this.strict && other.init || other.get || other.set;
1932 redefinition = other.init || other[kind];
1935 { this.raiseRecoverable(key.start, "Redefinition of property"); }
1937 other = propHash[name] = {
1946 // ### Expression parsing
1948 // These nest, from the most general expression type at the top to
1949 // 'atomic', nondivisible expression types at the bottom. Most of
1950 // the functions will simply let the function(s) below them parse,
1951 // and, *if* the syntactic construct they handle is present, wrap
1952 // the AST node that the inner parser gave them in another node.
1954 // Parse a full expression. The optional arguments are used to
1955 // forbid the `in` operator (in for loops initalization expressions)
1956 // and provide reference for storing '=' operator inside shorthand
1957 // property assignment in contexts where both object expression
1958 // and object pattern might appear (so it's possible to raise
1959 // delayed syntax error at correct position).
1961 pp$3.parseExpression = function(noIn, refDestructuringErrors) {
1962 var startPos = this.start, startLoc = this.startLoc;
1963 var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
1964 if (this.type === types.comma) {
1965 var node = this.startNodeAt(startPos, startLoc);
1966 node.expressions = [expr];
1967 while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); }
1968 return this.finishNode(node, "SequenceExpression")
1973 // Parse an assignment expression. This includes applications of
1974 // operators like `+=`.
1976 pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
1977 if (this.isContextual("yield")) {
1978 if (this.inGenerator) { return this.parseYield(noIn) }
1979 // The tokenizer will assume an expression is allowed after
1980 // `yield`, but this isn't that kind of yield
1981 else { this.exprAllowed = false; }
1984 var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;
1985 if (refDestructuringErrors) {
1986 oldParenAssign = refDestructuringErrors.parenthesizedAssign;
1987 oldTrailingComma = refDestructuringErrors.trailingComma;
1988 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
1990 refDestructuringErrors = new DestructuringErrors;
1991 ownDestructuringErrors = true;
1994 var startPos = this.start, startLoc = this.startLoc;
1995 if (this.type === types.parenL || this.type === types.name)
1996 { this.potentialArrowAt = this.start; }
1997 var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
1998 if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
1999 if (this.type.isAssign) {
2000 var node = this.startNodeAt(startPos, startLoc);
2001 node.operator = this.value;
2002 node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;
2003 if (!ownDestructuringErrors) {
2004 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
2006 if (refDestructuringErrors.shorthandAssign >= node.left.start)
2007 { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly
2008 this.checkLVal(left);
2010 node.right = this.parseMaybeAssign(noIn);
2011 return this.finishNode(node, "AssignmentExpression")
2013 if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
2015 if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
2016 if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
2020 // Parse a ternary conditional (`?:`) operator.
2022 pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
2023 var startPos = this.start, startLoc = this.startLoc;
2024 var expr = this.parseExprOps(noIn, refDestructuringErrors);
2025 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2026 if (this.eat(types.question)) {
2027 var node = this.startNodeAt(startPos, startLoc);
2029 node.consequent = this.parseMaybeAssign();
2030 this.expect(types.colon);
2031 node.alternate = this.parseMaybeAssign(noIn);
2032 return this.finishNode(node, "ConditionalExpression")
2037 // Start the precedence parser.
2039 pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
2040 var startPos = this.start, startLoc = this.startLoc;
2041 var expr = this.parseMaybeUnary(refDestructuringErrors, false);
2042 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2043 return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
2046 // Parse binary operators with the operator precedence parsing
2047 // algorithm. `left` is the left-hand side of the operator.
2048 // `minPrec` provides context that allows the function to stop and
2049 // defer further parser to one of its callers when it encounters an
2050 // operator that has a lower precedence than the set it is parsing.
2052 pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
2053 var prec = this.type.binop;
2054 if (prec != null && (!noIn || this.type !== types._in)) {
2055 if (prec > minPrec) {
2056 var logical = this.type === types.logicalOR || this.type === types.logicalAND;
2057 var coalesce = this.type === types.coalesce;
2059 // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.
2060 // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.
2061 prec = types.logicalAND.binop;
2063 var op = this.value;
2065 var startPos = this.start, startLoc = this.startLoc;
2066 var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
2067 var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
2068 if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) {
2069 this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
2071 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
2077 pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
2078 var node = this.startNodeAt(startPos, startLoc);
2082 return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
2085 // Parse unary operators, both prefix and postfix.
2087 pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
2088 var startPos = this.start, startLoc = this.startLoc, expr;
2089 if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
2090 expr = this.parseAwait();
2092 } else if (this.type.prefix) {
2093 var node = this.startNode(), update = this.type === types.incDec;
2094 node.operator = this.value;
2097 node.argument = this.parseMaybeUnary(null, true);
2098 this.checkExpressionErrors(refDestructuringErrors, true);
2099 if (update) { this.checkLVal(node.argument); }
2100 else if (this.strict && node.operator === "delete" &&
2101 node.argument.type === "Identifier")
2102 { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
2103 else { sawUnary = true; }
2104 expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
2106 expr = this.parseExprSubscripts(refDestructuringErrors);
2107 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2108 while (this.type.postfix && !this.canInsertSemicolon()) {
2109 var node$1 = this.startNodeAt(startPos, startLoc);
2110 node$1.operator = this.value;
2111 node$1.prefix = false;
2112 node$1.argument = expr;
2113 this.checkLVal(expr);
2115 expr = this.finishNode(node$1, "UpdateExpression");
2119 if (!sawUnary && this.eat(types.starstar))
2120 { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
2125 // Parse call, dot, and `[]`-subscript expressions.
2127 pp$3.parseExprSubscripts = function(refDestructuringErrors) {
2128 var startPos = this.start, startLoc = this.startLoc;
2129 var expr = this.parseExprAtom(refDestructuringErrors);
2130 if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
2132 var result = this.parseSubscripts(expr, startPos, startLoc);
2133 if (refDestructuringErrors && result.type === "MemberExpression") {
2134 if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
2135 if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
2140 pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
2141 var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
2142 this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
2143 this.potentialArrowAt === base.start;
2144 var optionalChained = false;
2147 var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained);
2149 if (element.optional) { optionalChained = true; }
2150 if (element === base || element.type === "ArrowFunctionExpression") {
2151 if (optionalChained) {
2152 var chainNode = this.startNodeAt(startPos, startLoc);
2153 chainNode.expression = element;
2154 element = this.finishNode(chainNode, "ChainExpression");
2163 pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) {
2164 var optionalSupported = this.options.ecmaVersion >= 11;
2165 var optional = optionalSupported && this.eat(types.questionDot);
2166 if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
2168 var computed = this.eat(types.bracketL);
2169 if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) {
2170 var node = this.startNodeAt(startPos, startLoc);
2172 node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never");
2173 node.computed = !!computed;
2174 if (computed) { this.expect(types.bracketR); }
2175 if (optionalSupported) {
2176 node.optional = optional;
2178 base = this.finishNode(node, "MemberExpression");
2179 } else if (!noCalls && this.eat(types.parenL)) {
2180 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2183 this.awaitIdentPos = 0;
2184 var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
2185 if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) {
2186 this.checkPatternErrors(refDestructuringErrors, false);
2187 this.checkYieldAwaitInDefaultParams();
2188 if (this.awaitIdentPos > 0)
2189 { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
2190 this.yieldPos = oldYieldPos;
2191 this.awaitPos = oldAwaitPos;
2192 this.awaitIdentPos = oldAwaitIdentPos;
2193 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true)
2195 this.checkExpressionErrors(refDestructuringErrors, true);
2196 this.yieldPos = oldYieldPos || this.yieldPos;
2197 this.awaitPos = oldAwaitPos || this.awaitPos;
2198 this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
2199 var node$1 = this.startNodeAt(startPos, startLoc);
2200 node$1.callee = base;
2201 node$1.arguments = exprList;
2202 if (optionalSupported) {
2203 node$1.optional = optional;
2205 base = this.finishNode(node$1, "CallExpression");
2206 } else if (this.type === types.backQuote) {
2207 if (optional || optionalChained) {
2208 this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
2210 var node$2 = this.startNodeAt(startPos, startLoc);
2212 node$2.quasi = this.parseTemplate({isTagged: true});
2213 base = this.finishNode(node$2, "TaggedTemplateExpression");
2218 // Parse an atomic expression — either a single token that is an
2219 // expression, an expression started by a keyword like `function` or
2220 // `new`, or an expression wrapped in punctuation like `()`, `[]`,
2223 pp$3.parseExprAtom = function(refDestructuringErrors) {
2224 // If a division operator appears in an expression position, the
2225 // tokenizer got confused, and we force it to read a regexp instead.
2226 if (this.type === types.slash) { this.readRegexp(); }
2228 var node, canBeArrow = this.potentialArrowAt === this.start;
2229 switch (this.type) {
2231 if (!this.allowSuper)
2232 { this.raise(this.start, "'super' keyword outside a method"); }
2233 node = this.startNode();
2235 if (this.type === types.parenL && !this.allowDirectSuper)
2236 { this.raise(node.start, "super() call outside constructor of a subclass"); }
2237 // The `super` keyword can appear at below:
2239 // super [ Expression ]
2240 // super . IdentifierName
2242 // super ( Arguments )
2243 if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)
2244 { this.unexpected(); }
2245 return this.finishNode(node, "Super")
2248 node = this.startNode();
2250 return this.finishNode(node, "ThisExpression")
2253 var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
2254 var id = this.parseIdent(false);
2255 if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
2256 { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true) }
2257 if (canBeArrow && !this.canInsertSemicolon()) {
2258 if (this.eat(types.arrow))
2259 { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
2260 if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
2261 id = this.parseIdent(false);
2262 if (this.canInsertSemicolon() || !this.eat(types.arrow))
2263 { this.unexpected(); }
2264 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
2270 var value = this.value;
2271 node = this.parseLiteral(value.value);
2272 node.regex = {pattern: value.pattern, flags: value.flags};
2275 case types.num: case types.string:
2276 return this.parseLiteral(this.value)
2278 case types._null: case types._true: case types._false:
2279 node = this.startNode();
2280 node.value = this.type === types._null ? null : this.type === types._true;
2281 node.raw = this.type.keyword;
2283 return this.finishNode(node, "Literal")
2286 var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
2287 if (refDestructuringErrors) {
2288 if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
2289 { refDestructuringErrors.parenthesizedAssign = start; }
2290 if (refDestructuringErrors.parenthesizedBind < 0)
2291 { refDestructuringErrors.parenthesizedBind = start; }
2295 case types.bracketL:
2296 node = this.startNode();
2298 node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
2299 return this.finishNode(node, "ArrayExpression")
2302 return this.parseObj(false, refDestructuringErrors)
2304 case types._function:
2305 node = this.startNode();
2307 return this.parseFunction(node, 0)
2310 return this.parseClass(this.startNode(), false)
2313 return this.parseNew()
2315 case types.backQuote:
2316 return this.parseTemplate()
2319 if (this.options.ecmaVersion >= 11) {
2320 return this.parseExprImport()
2322 return this.unexpected()
2330 pp$3.parseExprImport = function() {
2331 var node = this.startNode();
2333 // Consume `import` as an identifier for `import.meta`.
2334 // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.
2335 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
2336 var meta = this.parseIdent(true);
2338 switch (this.type) {
2340 return this.parseDynamicImport(node)
2343 return this.parseImportMeta(node)
2349 pp$3.parseDynamicImport = function(node) {
2350 this.next(); // skip `(`
2352 // Parse node.source.
2353 node.source = this.parseMaybeAssign();
2356 if (!this.eat(types.parenR)) {
2357 var errorPos = this.start;
2358 if (this.eat(types.comma) && this.eat(types.parenR)) {
2359 this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
2361 this.unexpected(errorPos);
2365 return this.finishNode(node, "ImportExpression")
2368 pp$3.parseImportMeta = function(node) {
2369 this.next(); // skip `.`
2371 var containsEsc = this.containsEsc;
2372 node.property = this.parseIdent(true);
2374 if (node.property.name !== "meta")
2375 { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
2377 { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
2378 if (this.options.sourceType !== "module")
2379 { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
2381 return this.finishNode(node, "MetaProperty")
2384 pp$3.parseLiteral = function(value) {
2385 var node = this.startNode();
2387 node.raw = this.input.slice(this.start, this.end);
2388 if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1); }
2390 return this.finishNode(node, "Literal")
2393 pp$3.parseParenExpression = function() {
2394 this.expect(types.parenL);
2395 var val = this.parseExpression();
2396 this.expect(types.parenR);
2400 pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
2401 var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
2402 if (this.options.ecmaVersion >= 6) {
2405 var innerStartPos = this.start, innerStartLoc = this.startLoc;
2406 var exprList = [], first = true, lastIsComma = false;
2407 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
2410 // Do not save awaitIdentPos to allow checking awaits nested in parameters
2411 while (this.type !== types.parenR) {
2412 first ? first = false : this.expect(types.comma);
2413 if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) {
2416 } else if (this.type === types.ellipsis) {
2417 spreadStart = this.start;
2418 exprList.push(this.parseParenItem(this.parseRestBinding()));
2419 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
2422 exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
2425 var innerEndPos = this.start, innerEndLoc = this.startLoc;
2426 this.expect(types.parenR);
2428 if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
2429 this.checkPatternErrors(refDestructuringErrors, false);
2430 this.checkYieldAwaitInDefaultParams();
2431 this.yieldPos = oldYieldPos;
2432 this.awaitPos = oldAwaitPos;
2433 return this.parseParenArrowList(startPos, startLoc, exprList)
2436 if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
2437 if (spreadStart) { this.unexpected(spreadStart); }
2438 this.checkExpressionErrors(refDestructuringErrors, true);
2439 this.yieldPos = oldYieldPos || this.yieldPos;
2440 this.awaitPos = oldAwaitPos || this.awaitPos;
2442 if (exprList.length > 1) {
2443 val = this.startNodeAt(innerStartPos, innerStartLoc);
2444 val.expressions = exprList;
2445 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
2450 val = this.parseParenExpression();
2453 if (this.options.preserveParens) {
2454 var par = this.startNodeAt(startPos, startLoc);
2455 par.expression = val;
2456 return this.finishNode(par, "ParenthesizedExpression")
2462 pp$3.parseParenItem = function(item) {
2466 pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
2467 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
2470 // New's precedence is slightly tricky. It must allow its argument to
2471 // be a `[]` or dot subscript expression, but not a call — at least,
2472 // not without wrapping it in parentheses. Thus, it uses the noCalls
2473 // argument to parseSubscripts to prevent it from consuming the
2478 pp$3.parseNew = function() {
2479 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
2480 var node = this.startNode();
2481 var meta = this.parseIdent(true);
2482 if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
2484 var containsEsc = this.containsEsc;
2485 node.property = this.parseIdent(true);
2486 if (node.property.name !== "target")
2487 { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
2489 { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
2490 if (!this.inNonArrowFunction())
2491 { this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); }
2492 return this.finishNode(node, "MetaProperty")
2494 var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import;
2495 node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
2496 if (isImport && node.callee.type === "ImportExpression") {
2497 this.raise(startPos, "Cannot use new with import()");
2499 if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }
2500 else { node.arguments = empty$1; }
2501 return this.finishNode(node, "NewExpression")
2504 // Parse template expression.
2506 pp$3.parseTemplateElement = function(ref) {
2507 var isTagged = ref.isTagged;
2509 var elem = this.startNode();
2510 if (this.type === types.invalidTemplate) {
2512 this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
2520 raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
2525 elem.tail = this.type === types.backQuote;
2526 return this.finishNode(elem, "TemplateElement")
2529 pp$3.parseTemplate = function(ref) {
2530 if ( ref === void 0 ) ref = {};
2531 var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
2533 var node = this.startNode();
2535 node.expressions = [];
2536 var curElt = this.parseTemplateElement({isTagged: isTagged});
2537 node.quasis = [curElt];
2538 while (!curElt.tail) {
2539 if (this.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); }
2540 this.expect(types.dollarBraceL);
2541 node.expressions.push(this.parseExpression());
2542 this.expect(types.braceR);
2543 node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
2546 return this.finishNode(node, "TemplateLiteral")
2549 pp$3.isAsyncProp = function(prop) {
2550 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
2551 (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&
2552 !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
2555 // Parse an object literal or binding pattern.
2557 pp$3.parseObj = function(isPattern, refDestructuringErrors) {
2558 var node = this.startNode(), first = true, propHash = {};
2559 node.properties = [];
2561 while (!this.eat(types.braceR)) {
2563 this.expect(types.comma);
2564 if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break }
2565 } else { first = false; }
2567 var prop = this.parseProperty(isPattern, refDestructuringErrors);
2568 if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
2569 node.properties.push(prop);
2571 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
2574 pp$3.parseProperty = function(isPattern, refDestructuringErrors) {
2575 var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
2576 if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {
2578 prop.argument = this.parseIdent(false);
2579 if (this.type === types.comma) {
2580 this.raise(this.start, "Comma is not permitted after the rest element");
2582 return this.finishNode(prop, "RestElement")
2584 // To disallow parenthesized identifier via `this.toAssignable()`.
2585 if (this.type === types.parenL && refDestructuringErrors) {
2586 if (refDestructuringErrors.parenthesizedAssign < 0) {
2587 refDestructuringErrors.parenthesizedAssign = this.start;
2589 if (refDestructuringErrors.parenthesizedBind < 0) {
2590 refDestructuringErrors.parenthesizedBind = this.start;
2594 prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
2595 // To disallow trailing comma via `this.toAssignable()`.
2596 if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
2597 refDestructuringErrors.trailingComma = this.start;
2600 return this.finishNode(prop, "SpreadElement")
2602 if (this.options.ecmaVersion >= 6) {
2603 prop.method = false;
2604 prop.shorthand = false;
2605 if (isPattern || refDestructuringErrors) {
2606 startPos = this.start;
2607 startLoc = this.startLoc;
2610 { isGenerator = this.eat(types.star); }
2612 var containsEsc = this.containsEsc;
2613 this.parsePropertyName(prop);
2614 if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
2616 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
2617 this.parsePropertyName(prop, refDestructuringErrors);
2621 this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
2622 return this.finishNode(prop, "Property")
2625 pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
2626 if ((isGenerator || isAsync) && this.type === types.colon)
2627 { this.unexpected(); }
2629 if (this.eat(types.colon)) {
2630 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
2632 } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
2633 if (isPattern) { this.unexpected(); }
2636 prop.value = this.parseMethod(isGenerator, isAsync);
2637 } else if (!isPattern && !containsEsc &&
2638 this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
2639 (prop.key.name === "get" || prop.key.name === "set") &&
2640 (this.type !== types.comma && this.type !== types.braceR && this.type !== types.eq)) {
2641 if (isGenerator || isAsync) { this.unexpected(); }
2642 prop.kind = prop.key.name;
2643 this.parsePropertyName(prop);
2644 prop.value = this.parseMethod(false);
2645 var paramCount = prop.kind === "get" ? 0 : 1;
2646 if (prop.value.params.length !== paramCount) {
2647 var start = prop.value.start;
2648 if (prop.kind === "get")
2649 { this.raiseRecoverable(start, "getter should have no params"); }
2651 { this.raiseRecoverable(start, "setter should have exactly one param"); }
2653 if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
2654 { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
2656 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
2657 if (isGenerator || isAsync) { this.unexpected(); }
2658 this.checkUnreserved(prop.key);
2659 if (prop.key.name === "await" && !this.awaitIdentPos)
2660 { this.awaitIdentPos = startPos; }
2663 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
2664 } else if (this.type === types.eq && refDestructuringErrors) {
2665 if (refDestructuringErrors.shorthandAssign < 0)
2666 { refDestructuringErrors.shorthandAssign = this.start; }
2667 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
2669 prop.value = prop.key;
2671 prop.shorthand = true;
2672 } else { this.unexpected(); }
2675 pp$3.parsePropertyName = function(prop) {
2676 if (this.options.ecmaVersion >= 6) {
2677 if (this.eat(types.bracketL)) {
2678 prop.computed = true;
2679 prop.key = this.parseMaybeAssign();
2680 this.expect(types.bracketR);
2683 prop.computed = false;
2686 return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
2689 // Initialize empty function node.
2691 pp$3.initFunction = function(node) {
2693 if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
2694 if (this.options.ecmaVersion >= 8) { node.async = false; }
2697 // Parse object or class method.
2699 pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
2700 var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2702 this.initFunction(node);
2703 if (this.options.ecmaVersion >= 6)
2704 { node.generator = isGenerator; }
2705 if (this.options.ecmaVersion >= 8)
2706 { node.async = !!isAsync; }
2710 this.awaitIdentPos = 0;
2711 this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
2713 this.expect(types.parenL);
2714 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
2715 this.checkYieldAwaitInDefaultParams();
2716 this.parseFunctionBody(node, false, true);
2718 this.yieldPos = oldYieldPos;
2719 this.awaitPos = oldAwaitPos;
2720 this.awaitIdentPos = oldAwaitIdentPos;
2721 return this.finishNode(node, "FunctionExpression")
2724 // Parse arrow function expression with given parameters.
2726 pp$3.parseArrowExpression = function(node, params, isAsync) {
2727 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2729 this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
2730 this.initFunction(node);
2731 if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
2735 this.awaitIdentPos = 0;
2737 node.params = this.toAssignableList(params, true);
2738 this.parseFunctionBody(node, true, false);
2740 this.yieldPos = oldYieldPos;
2741 this.awaitPos = oldAwaitPos;
2742 this.awaitIdentPos = oldAwaitIdentPos;
2743 return this.finishNode(node, "ArrowFunctionExpression")
2746 // Parse function body and check parameters.
2748 pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) {
2749 var isExpression = isArrowFunction && this.type !== types.braceL;
2750 var oldStrict = this.strict, useStrict = false;
2753 node.body = this.parseMaybeAssign();
2754 node.expression = true;
2755 this.checkParams(node, false);
2757 var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
2758 if (!oldStrict || nonSimple) {
2759 useStrict = this.strictDirective(this.end);
2760 // If this is a strict mode function, verify that argument names
2761 // are not repeated, and it does not try to bind the words `eval`
2763 if (useStrict && nonSimple)
2764 { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
2766 // Start a new scope with regard to labels and the `inFunction`
2767 // flag (restore them to their old value afterwards).
2768 var oldLabels = this.labels;
2770 if (useStrict) { this.strict = true; }
2772 // Add the params to varDeclaredNames to ensure that an error is thrown
2773 // if a let/const declaration in the function clashes with one of the params.
2774 this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
2775 // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
2776 if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); }
2777 node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
2778 node.expression = false;
2779 this.adaptDirectivePrologue(node.body.body);
2780 this.labels = oldLabels;
2785 pp$3.isSimpleParamList = function(params) {
2786 for (var i = 0, list = params; i < list.length; i += 1)
2788 var param = list[i];
2790 if (param.type !== "Identifier") { return false
2795 // Checks function params for various disallowed patterns such as using "eval"
2796 // or "arguments" and duplicate parameters.
2798 pp$3.checkParams = function(node, allowDuplicates) {
2800 for (var i = 0, list = node.params; i < list.length; i += 1)
2802 var param = list[i];
2804 this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash);
2808 // Parses a comma-separated list of expressions, and returns them as
2809 // an array. `close` is the token type that ends the list, and
2810 // `allowEmpty` can be turned on to allow subsequent commas with
2811 // nothing in between them to be parsed as `null` (which is needed
2812 // for array literals).
2814 pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
2815 var elts = [], first = true;
2816 while (!this.eat(close)) {
2818 this.expect(types.comma);
2819 if (allowTrailingComma && this.afterTrailingComma(close)) { break }
2820 } else { first = false; }
2823 if (allowEmpty && this.type === types.comma)
2825 else if (this.type === types.ellipsis) {
2826 elt = this.parseSpread(refDestructuringErrors);
2827 if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0)
2828 { refDestructuringErrors.trailingComma = this.start; }
2830 elt = this.parseMaybeAssign(false, refDestructuringErrors);
2837 pp$3.checkUnreserved = function(ref) {
2838 var start = ref.start;
2840 var name = ref.name;
2842 if (this.inGenerator && name === "yield")
2843 { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
2844 if (this.inAsync && name === "await")
2845 { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
2846 if (this.keywords.test(name))
2847 { this.raise(start, ("Unexpected keyword '" + name + "'")); }
2848 if (this.options.ecmaVersion < 6 &&
2849 this.input.slice(start, end).indexOf("\\") !== -1) { return }
2850 var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
2851 if (re.test(name)) {
2852 if (!this.inAsync && name === "await")
2853 { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
2854 this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
2858 // Parse the next token as an identifier. If `liberal` is true (used
2859 // when parsing properties), it will also convert keywords into
2862 pp$3.parseIdent = function(liberal, isBinding) {
2863 var node = this.startNode();
2864 if (this.type === types.name) {
2865 node.name = this.value;
2866 } else if (this.type.keyword) {
2867 node.name = this.type.keyword;
2869 // To fix https://github.com/acornjs/acorn/issues/575
2870 // `class` and `function` keywords push new context into this.context.
2871 // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
2872 // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
2873 if ((node.name === "class" || node.name === "function") &&
2874 (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
2880 this.next(!!liberal);
2881 this.finishNode(node, "Identifier");
2883 this.checkUnreserved(node);
2884 if (node.name === "await" && !this.awaitIdentPos)
2885 { this.awaitIdentPos = node.start; }
2890 // Parses yield expression inside generator.
2892 pp$3.parseYield = function(noIn) {
2893 if (!this.yieldPos) { this.yieldPos = this.start; }
2895 var node = this.startNode();
2897 if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {
2898 node.delegate = false;
2899 node.argument = null;
2901 node.delegate = this.eat(types.star);
2902 node.argument = this.parseMaybeAssign(noIn);
2904 return this.finishNode(node, "YieldExpression")
2907 pp$3.parseAwait = function() {
2908 if (!this.awaitPos) { this.awaitPos = this.start; }
2910 var node = this.startNode();
2912 node.argument = this.parseMaybeUnary(null, false);
2913 return this.finishNode(node, "AwaitExpression")
2916 var pp$4 = Parser.prototype;
2918 // This function is used to raise exceptions on parse errors. It
2919 // takes an offset integer (into the current `input`) to indicate
2920 // the location of the error, attaches the position to the end
2921 // of the error message, and then raises a `SyntaxError` with that
2924 pp$4.raise = function(pos, message) {
2925 var loc = getLineInfo(this.input, pos);
2926 message += " (" + loc.line + ":" + loc.column + ")";
2927 var err = new SyntaxError(message);
2928 err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
2932 pp$4.raiseRecoverable = pp$4.raise;
2934 pp$4.curPosition = function() {
2935 if (this.options.locations) {
2936 return new Position(this.curLine, this.pos - this.lineStart)
2940 var pp$5 = Parser.prototype;
2942 var Scope = function Scope(flags) {
2944 // A list of var-declared names in the current lexical scope
2946 // A list of lexically-declared names in the current lexical scope
2948 // A list of lexically-declared FunctionDeclaration names in the current lexical scope
2949 this.functions = [];
2952 // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
2954 pp$5.enterScope = function(flags) {
2955 this.scopeStack.push(new Scope(flags));
2958 pp$5.exitScope = function() {
2959 this.scopeStack.pop();
2963 // > At the top level of a function, or script, function declarations are
2964 // > treated like var declarations rather than like lexical declarations.
2965 pp$5.treatFunctionsAsVarInScope = function(scope) {
2966 return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
2969 pp$5.declareName = function(name, bindingType, pos) {
2970 var redeclared = false;
2971 if (bindingType === BIND_LEXICAL) {
2972 var scope = this.currentScope();
2973 redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
2974 scope.lexical.push(name);
2975 if (this.inModule && (scope.flags & SCOPE_TOP))
2976 { delete this.undefinedExports[name]; }
2977 } else if (bindingType === BIND_SIMPLE_CATCH) {
2978 var scope$1 = this.currentScope();
2979 scope$1.lexical.push(name);
2980 } else if (bindingType === BIND_FUNCTION) {
2981 var scope$2 = this.currentScope();
2982 if (this.treatFunctionsAsVar)
2983 { redeclared = scope$2.lexical.indexOf(name) > -1; }
2985 { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
2986 scope$2.functions.push(name);
2988 for (var i = this.scopeStack.length - 1; i >= 0; --i) {
2989 var scope$3 = this.scopeStack[i];
2990 if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
2991 !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
2995 scope$3.var.push(name);
2996 if (this.inModule && (scope$3.flags & SCOPE_TOP))
2997 { delete this.undefinedExports[name]; }
2998 if (scope$3.flags & SCOPE_VAR) { break }
3001 if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
3004 pp$5.checkLocalExport = function(id) {
3005 // scope.functions must be empty as Module code is always strict.
3006 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
3007 this.scopeStack[0].var.indexOf(id.name) === -1) {
3008 this.undefinedExports[id.name] = id;
3012 pp$5.currentScope = function() {
3013 return this.scopeStack[this.scopeStack.length - 1]
3016 pp$5.currentVarScope = function() {
3017 for (var i = this.scopeStack.length - 1;; i--) {
3018 var scope = this.scopeStack[i];
3019 if (scope.flags & SCOPE_VAR) { return scope }
3023 // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
3024 pp$5.currentThisScope = function() {
3025 for (var i = this.scopeStack.length - 1;; i--) {
3026 var scope = this.scopeStack[i];
3027 if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }
3031 var Node = function Node(parser, pos, loc) {
3035 if (parser.options.locations)
3036 { this.loc = new SourceLocation(parser, loc); }
3037 if (parser.options.directSourceFile)
3038 { this.sourceFile = parser.options.directSourceFile; }
3039 if (parser.options.ranges)
3040 { this.range = [pos, 0]; }
3043 // Start an AST node, attaching a start offset.
3045 var pp$6 = Parser.prototype;
3047 pp$6.startNode = function() {
3048 return new Node(this, this.start, this.startLoc)
3051 pp$6.startNodeAt = function(pos, loc) {
3052 return new Node(this, pos, loc)
3055 // Finish an AST node, adding `type` and `end` properties.
3057 function finishNodeAt(node, type, pos, loc) {
3060 if (this.options.locations)
3061 { node.loc.end = loc; }
3062 if (this.options.ranges)
3063 { node.range[1] = pos; }
3067 pp$6.finishNode = function(node, type) {
3068 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
3071 // Finish node at given position
3073 pp$6.finishNodeAt = function(node, type, pos, loc) {
3074 return finishNodeAt.call(this, node, type, pos, loc)
3077 // The algorithm used to determine whether a regexp can appear at a
3079 var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
3081 this.isExpr = !!isExpr;
3082 this.preserveSpace = !!preserveSpace;
3083 this.override = override;
3084 this.generator = !!generator;
3088 b_stat: new TokContext("{", false),
3089 b_expr: new TokContext("{", true),
3090 b_tmpl: new TokContext("${", false),
3091 p_stat: new TokContext("(", false),
3092 p_expr: new TokContext("(", true),
3093 q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
3094 f_stat: new TokContext("function", false),
3095 f_expr: new TokContext("function", true),
3096 f_expr_gen: new TokContext("function", true, false, null, true),
3097 f_gen: new TokContext("function", false, false, null, true)
3100 var pp$7 = Parser.prototype;
3102 pp$7.initialContext = function() {
3103 return [types$1.b_stat]
3106 pp$7.braceIsBlock = function(prevType) {
3107 var parent = this.curContext();
3108 if (parent === types$1.f_expr || parent === types$1.f_stat)
3110 if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
3111 { return !parent.isExpr }
3113 // The check for `tt.name && exprAllowed` detects whether we are
3114 // after a `yield` or `of` construct. See the `updateContext` for
3116 if (prevType === types._return || prevType === types.name && this.exprAllowed)
3117 { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
3118 if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)
3120 if (prevType === types.braceL)
3121 { return parent === types$1.b_stat }
3122 if (prevType === types._var || prevType === types._const || prevType === types.name)
3124 return !this.exprAllowed
3127 pp$7.inGeneratorContext = function() {
3128 for (var i = this.context.length - 1; i >= 1; i--) {
3129 var context = this.context[i];
3130 if (context.token === "function")
3131 { return context.generator }
3136 pp$7.updateContext = function(prevType) {
3137 var update, type = this.type;
3138 if (type.keyword && prevType === types.dot)
3139 { this.exprAllowed = false; }
3140 else if (update = type.updateContext)
3141 { update.call(this, prevType); }
3143 { this.exprAllowed = type.beforeExpr; }
3146 // Token-specific context update code
3148 types.parenR.updateContext = types.braceR.updateContext = function() {
3149 if (this.context.length === 1) {
3150 this.exprAllowed = true;
3153 var out = this.context.pop();
3154 if (out === types$1.b_stat && this.curContext().token === "function") {
3155 out = this.context.pop();
3157 this.exprAllowed = !out.isExpr;
3160 types.braceL.updateContext = function(prevType) {
3161 this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
3162 this.exprAllowed = true;
3165 types.dollarBraceL.updateContext = function() {
3166 this.context.push(types$1.b_tmpl);
3167 this.exprAllowed = true;
3170 types.parenL.updateContext = function(prevType) {
3171 var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
3172 this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
3173 this.exprAllowed = true;
3176 types.incDec.updateContext = function() {
3177 // tokExprAllowed stays unchanged
3180 types._function.updateContext = types._class.updateContext = function(prevType) {
3181 if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
3182 !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
3183 !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
3184 { this.context.push(types$1.f_expr); }
3186 { this.context.push(types$1.f_stat); }
3187 this.exprAllowed = false;
3190 types.backQuote.updateContext = function() {
3191 if (this.curContext() === types$1.q_tmpl)
3192 { this.context.pop(); }
3194 { this.context.push(types$1.q_tmpl); }
3195 this.exprAllowed = false;
3198 types.star.updateContext = function(prevType) {
3199 if (prevType === types._function) {
3200 var index = this.context.length - 1;
3201 if (this.context[index] === types$1.f_expr)
3202 { this.context[index] = types$1.f_expr_gen; }
3204 { this.context[index] = types$1.f_gen; }
3206 this.exprAllowed = true;
3209 types.name.updateContext = function(prevType) {
3210 var allowed = false;
3211 if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {
3212 if (this.value === "of" && !this.exprAllowed ||
3213 this.value === "yield" && this.inGeneratorContext())
3216 this.exprAllowed = allowed;
3219 // This file contains Unicode properties extracted from the ECMAScript
3220 // specification. The lists are extracted like so:
3221 // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
3223 // #table-binary-unicode-properties
3224 var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS";
3225 var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
3226 var ecma11BinaryProperties = ecma10BinaryProperties;
3227 var unicodeBinaryProperties = {
3228 9: ecma9BinaryProperties,
3229 10: ecma10BinaryProperties,
3230 11: ecma11BinaryProperties
3233 // #table-unicode-general-category-values
3234 var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu";
3236 // #table-unicode-script-values
3237 var ecma9ScriptValues = "Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb";
3238 var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
3239 var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
3240 var unicodeScriptValues = {
3241 9: ecma9ScriptValues,
3242 10: ecma10ScriptValues,
3243 11: ecma11ScriptValues
3247 function buildUnicodeData(ecmaVersion) {
3248 var d = data[ecmaVersion] = {
3249 binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
3251 General_Category: wordsRegexp(unicodeGeneralCategoryValues),
3252 Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
3255 d.nonBinary.Script_Extensions = d.nonBinary.Script;
3257 d.nonBinary.gc = d.nonBinary.General_Category;
3258 d.nonBinary.sc = d.nonBinary.Script;
3259 d.nonBinary.scx = d.nonBinary.Script_Extensions;
3261 buildUnicodeData(9);
3262 buildUnicodeData(10);
3263 buildUnicodeData(11);
3265 var pp$8 = Parser.prototype;
3267 var RegExpValidationState = function RegExpValidationState(parser) {
3268 this.parser = parser;
3269 this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
3270 this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion];
3274 this.switchU = false;
3275 this.switchN = false;
3277 this.lastIntValue = 0;
3278 this.lastStringValue = "";
3279 this.lastAssertionIsQuantifiable = false;
3280 this.numCapturingParens = 0;
3281 this.maxBackReference = 0;
3282 this.groupNames = [];
3283 this.backReferenceNames = [];
3286 RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
3287 var unicode = flags.indexOf("u") !== -1;
3288 this.start = start | 0;
3289 this.source = pattern + "";
3291 this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
3292 this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
3295 RegExpValidationState.prototype.raise = function raise (message) {
3296 this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
3299 // If u flag is given, this returns the code point at the index (it combines a surrogate pair).
3300 // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
3301 RegExpValidationState.prototype.at = function at (i, forceU) {
3302 if ( forceU === void 0 ) forceU = false;
3304 var s = this.source;
3309 var c = s.charCodeAt(i);
3310 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
3313 var next = s.charCodeAt(i + 1);
3314 return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
3317 RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
3318 if ( forceU === void 0 ) forceU = false;
3320 var s = this.source;
3325 var c = s.charCodeAt(i), next;
3326 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
3327 (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
3333 RegExpValidationState.prototype.current = function current (forceU) {
3334 if ( forceU === void 0 ) forceU = false;
3336 return this.at(this.pos, forceU)
3339 RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
3340 if ( forceU === void 0 ) forceU = false;
3342 return this.at(this.nextIndex(this.pos, forceU), forceU)
3345 RegExpValidationState.prototype.advance = function advance (forceU) {
3346 if ( forceU === void 0 ) forceU = false;
3348 this.pos = this.nextIndex(this.pos, forceU);
3351 RegExpValidationState.prototype.eat = function eat (ch, forceU) {
3352 if ( forceU === void 0 ) forceU = false;
3354 if (this.current(forceU) === ch) {
3355 this.advance(forceU);
3361 function codePointToString(ch) {
3362 if (ch <= 0xFFFF) { return String.fromCharCode(ch) }
3364 return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
3368 * Validate the flags part of a given RegExpLiteral.
3370 * @param {RegExpValidationState} state The state to validate RegExp.
3373 pp$8.validateRegExpFlags = function(state) {
3374 var validFlags = state.validFlags;
3375 var flags = state.flags;
3377 for (var i = 0; i < flags.length; i++) {
3378 var flag = flags.charAt(i);
3379 if (validFlags.indexOf(flag) === -1) {
3380 this.raise(state.start, "Invalid regular expression flag");
3382 if (flags.indexOf(flag, i + 1) > -1) {
3383 this.raise(state.start, "Duplicate regular expression flag");
3389 * Validate the pattern part of a given RegExpLiteral.
3391 * @param {RegExpValidationState} state The state to validate RegExp.
3394 pp$8.validateRegExpPattern = function(state) {
3395 this.regexp_pattern(state);
3397 // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
3398 // parsing contains a |GroupName|, reparse with the goal symbol
3399 // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
3400 // exception if _P_ did not conform to the grammar, if any elements of _P_
3401 // were not matched by the parse, or if any Early Error conditions exist.
3402 if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
3403 state.switchN = true;
3404 this.regexp_pattern(state);
3408 // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
3409 pp$8.regexp_pattern = function(state) {
3411 state.lastIntValue = 0;
3412 state.lastStringValue = "";
3413 state.lastAssertionIsQuantifiable = false;
3414 state.numCapturingParens = 0;
3415 state.maxBackReference = 0;
3416 state.groupNames.length = 0;
3417 state.backReferenceNames.length = 0;
3419 this.regexp_disjunction(state);
3421 if (state.pos !== state.source.length) {
3422 // Make the same messages as V8.
3423 if (state.eat(0x29 /* ) */)) {
3424 state.raise("Unmatched ')'");
3426 if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {
3427 state.raise("Lone quantifier brackets");
3430 if (state.maxBackReference > state.numCapturingParens) {
3431 state.raise("Invalid escape");
3433 for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
3436 if (state.groupNames.indexOf(name) === -1) {
3437 state.raise("Invalid named capture referenced");
3442 // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
3443 pp$8.regexp_disjunction = function(state) {
3444 this.regexp_alternative(state);
3445 while (state.eat(0x7C /* | */)) {
3446 this.regexp_alternative(state);
3449 // Make the same message as V8.
3450 if (this.regexp_eatQuantifier(state, true)) {
3451 state.raise("Nothing to repeat");
3453 if (state.eat(0x7B /* { */)) {
3454 state.raise("Lone quantifier brackets");
3458 // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
3459 pp$8.regexp_alternative = function(state) {
3460 while (state.pos < state.source.length && this.regexp_eatTerm(state))
3464 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
3465 pp$8.regexp_eatTerm = function(state) {
3466 if (this.regexp_eatAssertion(state)) {
3467 // Handle `QuantifiableAssertion Quantifier` alternative.
3468 // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
3469 // is a QuantifiableAssertion.
3470 if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
3471 // Make the same message as V8.
3472 if (state.switchU) {
3473 state.raise("Invalid quantifier");
3479 if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
3480 this.regexp_eatQuantifier(state);
3487 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
3488 pp$8.regexp_eatAssertion = function(state) {
3489 var start = state.pos;
3490 state.lastAssertionIsQuantifiable = false;
3493 if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
3498 if (state.eat(0x5C /* \ */)) {
3499 if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
3505 // Lookahead / Lookbehind
3506 if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
3507 var lookbehind = false;
3508 if (this.options.ecmaVersion >= 9) {
3509 lookbehind = state.eat(0x3C /* < */);
3511 if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
3512 this.regexp_disjunction(state);
3513 if (!state.eat(0x29 /* ) */)) {
3514 state.raise("Unterminated group");
3516 state.lastAssertionIsQuantifiable = !lookbehind;
3525 // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
3526 pp$8.regexp_eatQuantifier = function(state, noError) {
3527 if ( noError === void 0 ) noError = false;
3529 if (this.regexp_eatQuantifierPrefix(state, noError)) {
3530 state.eat(0x3F /* ? */);
3536 // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
3537 pp$8.regexp_eatQuantifierPrefix = function(state, noError) {
3539 state.eat(0x2A /* * */) ||
3540 state.eat(0x2B /* + */) ||
3541 state.eat(0x3F /* ? */) ||
3542 this.regexp_eatBracedQuantifier(state, noError)
3545 pp$8.regexp_eatBracedQuantifier = function(state, noError) {
3546 var start = state.pos;
3547 if (state.eat(0x7B /* { */)) {
3548 var min = 0, max = -1;
3549 if (this.regexp_eatDecimalDigits(state)) {
3550 min = state.lastIntValue;
3551 if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
3552 max = state.lastIntValue;
3554 if (state.eat(0x7D /* } */)) {
3555 // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
3556 if (max !== -1 && max < min && !noError) {
3557 state.raise("numbers out of order in {} quantifier");
3562 if (state.switchU && !noError) {
3563 state.raise("Incomplete quantifier");
3570 // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
3571 pp$8.regexp_eatAtom = function(state) {
3573 this.regexp_eatPatternCharacters(state) ||
3574 state.eat(0x2E /* . */) ||
3575 this.regexp_eatReverseSolidusAtomEscape(state) ||
3576 this.regexp_eatCharacterClass(state) ||
3577 this.regexp_eatUncapturingGroup(state) ||
3578 this.regexp_eatCapturingGroup(state)
3581 pp$8.regexp_eatReverseSolidusAtomEscape = function(state) {
3582 var start = state.pos;
3583 if (state.eat(0x5C /* \ */)) {
3584 if (this.regexp_eatAtomEscape(state)) {
3591 pp$8.regexp_eatUncapturingGroup = function(state) {
3592 var start = state.pos;
3593 if (state.eat(0x28 /* ( */)) {
3594 if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
3595 this.regexp_disjunction(state);
3596 if (state.eat(0x29 /* ) */)) {
3599 state.raise("Unterminated group");
3605 pp$8.regexp_eatCapturingGroup = function(state) {
3606 if (state.eat(0x28 /* ( */)) {
3607 if (this.options.ecmaVersion >= 9) {
3608 this.regexp_groupSpecifier(state);
3609 } else if (state.current() === 0x3F /* ? */) {
3610 state.raise("Invalid group");
3612 this.regexp_disjunction(state);
3613 if (state.eat(0x29 /* ) */)) {
3614 state.numCapturingParens += 1;
3617 state.raise("Unterminated group");
3622 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
3623 pp$8.regexp_eatExtendedAtom = function(state) {
3625 state.eat(0x2E /* . */) ||
3626 this.regexp_eatReverseSolidusAtomEscape(state) ||
3627 this.regexp_eatCharacterClass(state) ||
3628 this.regexp_eatUncapturingGroup(state) ||
3629 this.regexp_eatCapturingGroup(state) ||
3630 this.regexp_eatInvalidBracedQuantifier(state) ||
3631 this.regexp_eatExtendedPatternCharacter(state)
3635 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
3636 pp$8.regexp_eatInvalidBracedQuantifier = function(state) {
3637 if (this.regexp_eatBracedQuantifier(state, true)) {
3638 state.raise("Nothing to repeat");
3643 // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
3644 pp$8.regexp_eatSyntaxCharacter = function(state) {
3645 var ch = state.current();
3646 if (isSyntaxCharacter(ch)) {
3647 state.lastIntValue = ch;
3653 function isSyntaxCharacter(ch) {
3655 ch === 0x24 /* $ */ ||
3656 ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
3657 ch === 0x2E /* . */ ||
3658 ch === 0x3F /* ? */ ||
3659 ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
3660 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
3664 // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
3666 pp$8.regexp_eatPatternCharacters = function(state) {
3667 var start = state.pos;
3669 while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
3672 return state.pos !== start
3675 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
3676 pp$8.regexp_eatExtendedPatternCharacter = function(state) {
3677 var ch = state.current();
3680 ch !== 0x24 /* $ */ &&
3681 !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
3682 ch !== 0x2E /* . */ &&
3683 ch !== 0x3F /* ? */ &&
3684 ch !== 0x5B /* [ */ &&
3685 ch !== 0x5E /* ^ */ &&
3694 // GroupSpecifier ::
3697 pp$8.regexp_groupSpecifier = function(state) {
3698 if (state.eat(0x3F /* ? */)) {
3699 if (this.regexp_eatGroupName(state)) {
3700 if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
3701 state.raise("Duplicate capture group name");
3703 state.groupNames.push(state.lastStringValue);
3706 state.raise("Invalid group");
3711 // `<` RegExpIdentifierName `>`
3712 // Note: this updates `state.lastStringValue` property with the eaten name.
3713 pp$8.regexp_eatGroupName = function(state) {
3714 state.lastStringValue = "";
3715 if (state.eat(0x3C /* < */)) {
3716 if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
3719 state.raise("Invalid capture group name");
3724 // RegExpIdentifierName ::
3725 // RegExpIdentifierStart
3726 // RegExpIdentifierName RegExpIdentifierPart
3727 // Note: this updates `state.lastStringValue` property with the eaten name.
3728 pp$8.regexp_eatRegExpIdentifierName = function(state) {
3729 state.lastStringValue = "";
3730 if (this.regexp_eatRegExpIdentifierStart(state)) {
3731 state.lastStringValue += codePointToString(state.lastIntValue);
3732 while (this.regexp_eatRegExpIdentifierPart(state)) {
3733 state.lastStringValue += codePointToString(state.lastIntValue);
3740 // RegExpIdentifierStart ::
3744 // `\` RegExpUnicodeEscapeSequence[+U]
3745 pp$8.regexp_eatRegExpIdentifierStart = function(state) {
3746 var start = state.pos;
3747 var forceU = this.options.ecmaVersion >= 11;
3748 var ch = state.current(forceU);
3749 state.advance(forceU);
3751 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
3752 ch = state.lastIntValue;
3754 if (isRegExpIdentifierStart(ch)) {
3755 state.lastIntValue = ch;
3762 function isRegExpIdentifierStart(ch) {
3763 return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
3766 // RegExpIdentifierPart ::
3767 // UnicodeIDContinue
3770 // `\` RegExpUnicodeEscapeSequence[+U]
3773 pp$8.regexp_eatRegExpIdentifierPart = function(state) {
3774 var start = state.pos;
3775 var forceU = this.options.ecmaVersion >= 11;
3776 var ch = state.current(forceU);
3777 state.advance(forceU);
3779 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
3780 ch = state.lastIntValue;
3782 if (isRegExpIdentifierPart(ch)) {
3783 state.lastIntValue = ch;
3790 function isRegExpIdentifierPart(ch) {
3791 return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
3794 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
3795 pp$8.regexp_eatAtomEscape = function(state) {
3797 this.regexp_eatBackReference(state) ||
3798 this.regexp_eatCharacterClassEscape(state) ||
3799 this.regexp_eatCharacterEscape(state) ||
3800 (state.switchN && this.regexp_eatKGroupName(state))
3804 if (state.switchU) {
3805 // Make the same message as V8.
3806 if (state.current() === 0x63 /* c */) {
3807 state.raise("Invalid unicode escape");
3809 state.raise("Invalid escape");
3813 pp$8.regexp_eatBackReference = function(state) {
3814 var start = state.pos;
3815 if (this.regexp_eatDecimalEscape(state)) {
3816 var n = state.lastIntValue;
3817 if (state.switchU) {
3818 // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
3819 if (n > state.maxBackReference) {
3820 state.maxBackReference = n;
3824 if (n <= state.numCapturingParens) {
3831 pp$8.regexp_eatKGroupName = function(state) {
3832 if (state.eat(0x6B /* k */)) {
3833 if (this.regexp_eatGroupName(state)) {
3834 state.backReferenceNames.push(state.lastStringValue);
3837 state.raise("Invalid named reference");
3842 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
3843 pp$8.regexp_eatCharacterEscape = function(state) {
3845 this.regexp_eatControlEscape(state) ||
3846 this.regexp_eatCControlLetter(state) ||
3847 this.regexp_eatZero(state) ||
3848 this.regexp_eatHexEscapeSequence(state) ||
3849 this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
3850 (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
3851 this.regexp_eatIdentityEscape(state)
3854 pp$8.regexp_eatCControlLetter = function(state) {
3855 var start = state.pos;
3856 if (state.eat(0x63 /* c */)) {
3857 if (this.regexp_eatControlLetter(state)) {
3864 pp$8.regexp_eatZero = function(state) {
3865 if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
3866 state.lastIntValue = 0;
3873 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
3874 pp$8.regexp_eatControlEscape = function(state) {
3875 var ch = state.current();
3876 if (ch === 0x74 /* t */) {
3877 state.lastIntValue = 0x09; /* \t */
3881 if (ch === 0x6E /* n */) {
3882 state.lastIntValue = 0x0A; /* \n */
3886 if (ch === 0x76 /* v */) {
3887 state.lastIntValue = 0x0B; /* \v */
3891 if (ch === 0x66 /* f */) {
3892 state.lastIntValue = 0x0C; /* \f */
3896 if (ch === 0x72 /* r */) {
3897 state.lastIntValue = 0x0D; /* \r */
3904 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
3905 pp$8.regexp_eatControlLetter = function(state) {
3906 var ch = state.current();
3907 if (isControlLetter(ch)) {
3908 state.lastIntValue = ch % 0x20;
3914 function isControlLetter(ch) {
3916 (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
3917 (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
3921 // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
3922 pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
3923 if ( forceU === void 0 ) forceU = false;
3925 var start = state.pos;
3926 var switchU = forceU || state.switchU;
3928 if (state.eat(0x75 /* u */)) {
3929 if (this.regexp_eatFixedHexDigits(state, 4)) {
3930 var lead = state.lastIntValue;
3931 if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
3932 var leadSurrogateEnd = state.pos;
3933 if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
3934 var trail = state.lastIntValue;
3935 if (trail >= 0xDC00 && trail <= 0xDFFF) {
3936 state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
3940 state.pos = leadSurrogateEnd;
3941 state.lastIntValue = lead;
3947 state.eat(0x7B /* { */) &&
3948 this.regexp_eatHexDigits(state) &&
3949 state.eat(0x7D /* } */) &&
3950 isValidUnicode(state.lastIntValue)
3955 state.raise("Invalid unicode escape");
3962 function isValidUnicode(ch) {
3963 return ch >= 0 && ch <= 0x10FFFF
3966 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
3967 pp$8.regexp_eatIdentityEscape = function(state) {
3968 if (state.switchU) {
3969 if (this.regexp_eatSyntaxCharacter(state)) {
3972 if (state.eat(0x2F /* / */)) {
3973 state.lastIntValue = 0x2F; /* / */
3979 var ch = state.current();
3980 if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
3981 state.lastIntValue = ch;
3989 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
3990 pp$8.regexp_eatDecimalEscape = function(state) {
3991 state.lastIntValue = 0;
3992 var ch = state.current();
3993 if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
3995 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
3997 } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
4003 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
4004 pp$8.regexp_eatCharacterClassEscape = function(state) {
4005 var ch = state.current();
4007 if (isCharacterClassEscape(ch)) {
4008 state.lastIntValue = -1;
4015 this.options.ecmaVersion >= 9 &&
4016 (ch === 0x50 /* P */ || ch === 0x70 /* p */)
4018 state.lastIntValue = -1;
4021 state.eat(0x7B /* { */) &&
4022 this.regexp_eatUnicodePropertyValueExpression(state) &&
4023 state.eat(0x7D /* } */)
4027 state.raise("Invalid property name");
4032 function isCharacterClassEscape(ch) {
4034 ch === 0x64 /* d */ ||
4035 ch === 0x44 /* D */ ||
4036 ch === 0x73 /* s */ ||
4037 ch === 0x53 /* S */ ||
4038 ch === 0x77 /* w */ ||
4043 // UnicodePropertyValueExpression ::
4044 // UnicodePropertyName `=` UnicodePropertyValue
4045 // LoneUnicodePropertyNameOrValue
4046 pp$8.regexp_eatUnicodePropertyValueExpression = function(state) {
4047 var start = state.pos;
4049 // UnicodePropertyName `=` UnicodePropertyValue
4050 if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
4051 var name = state.lastStringValue;
4052 if (this.regexp_eatUnicodePropertyValue(state)) {
4053 var value = state.lastStringValue;
4054 this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
4060 // LoneUnicodePropertyNameOrValue
4061 if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
4062 var nameOrValue = state.lastStringValue;
4063 this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
4068 pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
4069 if (!has(state.unicodeProperties.nonBinary, name))
4070 { state.raise("Invalid property name"); }
4071 if (!state.unicodeProperties.nonBinary[name].test(value))
4072 { state.raise("Invalid property value"); }
4074 pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
4075 if (!state.unicodeProperties.binary.test(nameOrValue))
4076 { state.raise("Invalid property name"); }
4079 // UnicodePropertyName ::
4080 // UnicodePropertyNameCharacters
4081 pp$8.regexp_eatUnicodePropertyName = function(state) {
4083 state.lastStringValue = "";
4084 while (isUnicodePropertyNameCharacter(ch = state.current())) {
4085 state.lastStringValue += codePointToString(ch);
4088 return state.lastStringValue !== ""
4090 function isUnicodePropertyNameCharacter(ch) {
4091 return isControlLetter(ch) || ch === 0x5F /* _ */
4094 // UnicodePropertyValue ::
4095 // UnicodePropertyValueCharacters
4096 pp$8.regexp_eatUnicodePropertyValue = function(state) {
4098 state.lastStringValue = "";
4099 while (isUnicodePropertyValueCharacter(ch = state.current())) {
4100 state.lastStringValue += codePointToString(ch);
4103 return state.lastStringValue !== ""
4105 function isUnicodePropertyValueCharacter(ch) {
4106 return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
4109 // LoneUnicodePropertyNameOrValue ::
4110 // UnicodePropertyValueCharacters
4111 pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
4112 return this.regexp_eatUnicodePropertyValue(state)
4115 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
4116 pp$8.regexp_eatCharacterClass = function(state) {
4117 if (state.eat(0x5B /* [ */)) {
4118 state.eat(0x5E /* ^ */);
4119 this.regexp_classRanges(state);
4120 if (state.eat(0x5D /* ] */)) {
4123 // Unreachable since it threw "unterminated regular expression" error before.
4124 state.raise("Unterminated character class");
4129 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
4130 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
4131 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
4132 pp$8.regexp_classRanges = function(state) {
4133 while (this.regexp_eatClassAtom(state)) {
4134 var left = state.lastIntValue;
4135 if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
4136 var right = state.lastIntValue;
4137 if (state.switchU && (left === -1 || right === -1)) {
4138 state.raise("Invalid character class");
4140 if (left !== -1 && right !== -1 && left > right) {
4141 state.raise("Range out of order in character class");
4147 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
4148 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
4149 pp$8.regexp_eatClassAtom = function(state) {
4150 var start = state.pos;
4152 if (state.eat(0x5C /* \ */)) {
4153 if (this.regexp_eatClassEscape(state)) {
4156 if (state.switchU) {
4157 // Make the same message as V8.
4158 var ch$1 = state.current();
4159 if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
4160 state.raise("Invalid class escape");
4162 state.raise("Invalid escape");
4167 var ch = state.current();
4168 if (ch !== 0x5D /* ] */) {
4169 state.lastIntValue = ch;
4177 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
4178 pp$8.regexp_eatClassEscape = function(state) {
4179 var start = state.pos;
4181 if (state.eat(0x62 /* b */)) {
4182 state.lastIntValue = 0x08; /* <BS> */
4186 if (state.switchU && state.eat(0x2D /* - */)) {
4187 state.lastIntValue = 0x2D; /* - */
4191 if (!state.switchU && state.eat(0x63 /* c */)) {
4192 if (this.regexp_eatClassControlLetter(state)) {
4199 this.regexp_eatCharacterClassEscape(state) ||
4200 this.regexp_eatCharacterEscape(state)
4204 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
4205 pp$8.regexp_eatClassControlLetter = function(state) {
4206 var ch = state.current();
4207 if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
4208 state.lastIntValue = ch % 0x20;
4215 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
4216 pp$8.regexp_eatHexEscapeSequence = function(state) {
4217 var start = state.pos;
4218 if (state.eat(0x78 /* x */)) {
4219 if (this.regexp_eatFixedHexDigits(state, 2)) {
4222 if (state.switchU) {
4223 state.raise("Invalid escape");
4230 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
4231 pp$8.regexp_eatDecimalDigits = function(state) {
4232 var start = state.pos;
4234 state.lastIntValue = 0;
4235 while (isDecimalDigit(ch = state.current())) {
4236 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
4239 return state.pos !== start
4241 function isDecimalDigit(ch) {
4242 return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
4245 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
4246 pp$8.regexp_eatHexDigits = function(state) {
4247 var start = state.pos;
4249 state.lastIntValue = 0;
4250 while (isHexDigit(ch = state.current())) {
4251 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
4254 return state.pos !== start
4256 function isHexDigit(ch) {
4258 (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
4259 (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
4260 (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
4263 function hexToInt(ch) {
4264 if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
4265 return 10 + (ch - 0x41 /* A */)
4267 if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
4268 return 10 + (ch - 0x61 /* a */)
4270 return ch - 0x30 /* 0 */
4273 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
4274 // Allows only 0-377(octal) i.e. 0-255(decimal).
4275 pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) {
4276 if (this.regexp_eatOctalDigit(state)) {
4277 var n1 = state.lastIntValue;
4278 if (this.regexp_eatOctalDigit(state)) {
4279 var n2 = state.lastIntValue;
4280 if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
4281 state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
4283 state.lastIntValue = n1 * 8 + n2;
4286 state.lastIntValue = n1;
4293 // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
4294 pp$8.regexp_eatOctalDigit = function(state) {
4295 var ch = state.current();
4296 if (isOctalDigit(ch)) {
4297 state.lastIntValue = ch - 0x30; /* 0 */
4301 state.lastIntValue = 0;
4304 function isOctalDigit(ch) {
4305 return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
4308 // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
4309 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
4310 // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
4311 pp$8.regexp_eatFixedHexDigits = function(state, length) {
4312 var start = state.pos;
4313 state.lastIntValue = 0;
4314 for (var i = 0; i < length; ++i) {
4315 var ch = state.current();
4316 if (!isHexDigit(ch)) {
4320 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
4326 // Object type used to represent tokens. Note that normally, tokens
4327 // simply exist as properties on the parser object. This is only
4328 // used for the onToken callback and the external tokenizer.
4330 var Token = function Token(p) {
4332 this.value = p.value;
4333 this.start = p.start;
4335 if (p.options.locations)
4336 { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
4337 if (p.options.ranges)
4338 { this.range = [p.start, p.end]; }
4343 var pp$9 = Parser.prototype;
4345 // Move to the next token
4347 pp$9.next = function(ignoreEscapeSequenceInKeyword) {
4348 if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
4349 { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
4350 if (this.options.onToken)
4351 { this.options.onToken(new Token(this)); }
4353 this.lastTokEnd = this.end;
4354 this.lastTokStart = this.start;
4355 this.lastTokEndLoc = this.endLoc;
4356 this.lastTokStartLoc = this.startLoc;
4360 pp$9.getToken = function() {
4362 return new Token(this)
4365 // If we're in an ES6 environment, make parsers iterable
4366 if (typeof Symbol !== "undefined")
4367 { pp$9[Symbol.iterator] = function() {
4372 var token = this$1.getToken();
4374 done: token.type === types.eof,
4381 // Toggle strict mode. Re-reads the next number or string to please
4382 // pedantic tests (`"use strict"; 010;` should fail).
4384 pp$9.curContext = function() {
4385 return this.context[this.context.length - 1]
4388 // Read a single token, updating the parser object's token-related
4391 pp$9.nextToken = function() {
4392 var curContext = this.curContext();
4393 if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
4395 this.start = this.pos;
4396 if (this.options.locations) { this.startLoc = this.curPosition(); }
4397 if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
4399 if (curContext.override) { return curContext.override(this) }
4400 else { this.readToken(this.fullCharCodeAtPos()); }
4403 pp$9.readToken = function(code) {
4404 // Identifier or keyword. '\uXXXX' sequences are allowed in
4405 // identifiers, so '\' also dispatches to that.
4406 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
4407 { return this.readWord() }
4409 return this.getTokenFromCode(code)
4412 pp$9.fullCharCodeAtPos = function() {
4413 var code = this.input.charCodeAt(this.pos);
4414 if (code <= 0xd7ff || code >= 0xe000) { return code }
4415 var next = this.input.charCodeAt(this.pos + 1);
4416 return (code << 10) + next - 0x35fdc00
4419 pp$9.skipBlockComment = function() {
4420 var startLoc = this.options.onComment && this.curPosition();
4421 var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
4422 if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
4424 if (this.options.locations) {
4425 lineBreakG.lastIndex = start;
4427 while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
4429 this.lineStart = match.index + match[0].length;
4432 if (this.options.onComment)
4433 { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
4434 startLoc, this.curPosition()); }
4437 pp$9.skipLineComment = function(startSkip) {
4438 var start = this.pos;
4439 var startLoc = this.options.onComment && this.curPosition();
4440 var ch = this.input.charCodeAt(this.pos += startSkip);
4441 while (this.pos < this.input.length && !isNewLine(ch)) {
4442 ch = this.input.charCodeAt(++this.pos);
4444 if (this.options.onComment)
4445 { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
4446 startLoc, this.curPosition()); }
4449 // Called at the start of the parse and after every token. Skips
4450 // whitespace and comments, and.
4452 pp$9.skipSpace = function() {
4453 loop: while (this.pos < this.input.length) {
4454 var ch = this.input.charCodeAt(this.pos);
4456 case 32: case 160: // ' '
4460 if (this.input.charCodeAt(this.pos + 1) === 10) {
4463 case 10: case 8232: case 8233:
4465 if (this.options.locations) {
4467 this.lineStart = this.pos;
4471 switch (this.input.charCodeAt(this.pos + 1)) {
4473 this.skipBlockComment();
4476 this.skipLineComment(2);
4483 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
4492 // Called at the end of every token. Sets `end`, `val`, and
4493 // maintains `context` and `exprAllowed`, and skips the space after
4494 // the token, so that the next one's `start` will point at the
4497 pp$9.finishToken = function(type, val) {
4498 this.end = this.pos;
4499 if (this.options.locations) { this.endLoc = this.curPosition(); }
4500 var prevType = this.type;
4504 this.updateContext(prevType);
4507 // ### Token reading
4509 // This is the function that is called to fetch the next token. It
4510 // is somewhat obscure, because it works in character codes rather
4511 // than characters, and because operator parsing has been inlined
4514 // All in the name of speed.
4516 pp$9.readToken_dot = function() {
4517 var next = this.input.charCodeAt(this.pos + 1);
4518 if (next >= 48 && next <= 57) { return this.readNumber(true) }
4519 var next2 = this.input.charCodeAt(this.pos + 2);
4520 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
4522 return this.finishToken(types.ellipsis)
4525 return this.finishToken(types.dot)
4529 pp$9.readToken_slash = function() { // '/'
4530 var next = this.input.charCodeAt(this.pos + 1);
4531 if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
4532 if (next === 61) { return this.finishOp(types.assign, 2) }
4533 return this.finishOp(types.slash, 1)
4536 pp$9.readToken_mult_modulo_exp = function(code) { // '%*'
4537 var next = this.input.charCodeAt(this.pos + 1);
4539 var tokentype = code === 42 ? types.star : types.modulo;
4541 // exponentiation operator ** and **=
4542 if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
4544 tokentype = types.starstar;
4545 next = this.input.charCodeAt(this.pos + 2);
4548 if (next === 61) { return this.finishOp(types.assign, size + 1) }
4549 return this.finishOp(tokentype, size)
4552 pp$9.readToken_pipe_amp = function(code) { // '|&'
4553 var next = this.input.charCodeAt(this.pos + 1);
4554 if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }
4555 if (next === 61) { return this.finishOp(types.assign, 2) }
4556 return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)
4559 pp$9.readToken_caret = function() { // '^'
4560 var next = this.input.charCodeAt(this.pos + 1);
4561 if (next === 61) { return this.finishOp(types.assign, 2) }
4562 return this.finishOp(types.bitwiseXOR, 1)
4565 pp$9.readToken_plus_min = function(code) { // '+-'
4566 var next = this.input.charCodeAt(this.pos + 1);
4567 if (next === code) {
4568 if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
4569 (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
4570 // A `-->` line comment
4571 this.skipLineComment(3);
4573 return this.nextToken()
4575 return this.finishOp(types.incDec, 2)
4577 if (next === 61) { return this.finishOp(types.assign, 2) }
4578 return this.finishOp(types.plusMin, 1)
4581 pp$9.readToken_lt_gt = function(code) { // '<>'
4582 var next = this.input.charCodeAt(this.pos + 1);
4584 if (next === code) {
4585 size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
4586 if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
4587 return this.finishOp(types.bitShift, size)
4589 if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
4590 this.input.charCodeAt(this.pos + 3) === 45) {
4591 // `<!--`, an XML-style comment that should be interpreted as a line comment
4592 this.skipLineComment(4);
4594 return this.nextToken()
4596 if (next === 61) { size = 2; }
4597 return this.finishOp(types.relational, size)
4600 pp$9.readToken_eq_excl = function(code) { // '=!'
4601 var next = this.input.charCodeAt(this.pos + 1);
4602 if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
4603 if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
4605 return this.finishToken(types.arrow)
4607 return this.finishOp(code === 61 ? types.eq : types.prefix, 1)
4610 pp$9.readToken_question = function() { // '?'
4611 if (this.options.ecmaVersion >= 11) {
4612 var next = this.input.charCodeAt(this.pos + 1);
4614 var next2 = this.input.charCodeAt(this.pos + 2);
4615 if (next2 < 48 || next2 > 57) { return this.finishOp(types.questionDot, 2) }
4617 if (next === 63) { return this.finishOp(types.coalesce, 2) }
4619 return this.finishOp(types.question, 1)
4622 pp$9.getTokenFromCode = function(code) {
4624 // The interpretation of a dot depends on whether it is followed
4625 // by a digit or another two dots.
4627 return this.readToken_dot()
4629 // Punctuation tokens.
4630 case 40: ++this.pos; return this.finishToken(types.parenL)
4631 case 41: ++this.pos; return this.finishToken(types.parenR)
4632 case 59: ++this.pos; return this.finishToken(types.semi)
4633 case 44: ++this.pos; return this.finishToken(types.comma)
4634 case 91: ++this.pos; return this.finishToken(types.bracketL)
4635 case 93: ++this.pos; return this.finishToken(types.bracketR)
4636 case 123: ++this.pos; return this.finishToken(types.braceL)
4637 case 125: ++this.pos; return this.finishToken(types.braceR)
4638 case 58: ++this.pos; return this.finishToken(types.colon)
4641 if (this.options.ecmaVersion < 6) { break }
4643 return this.finishToken(types.backQuote)
4646 var next = this.input.charCodeAt(this.pos + 1);
4647 if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
4648 if (this.options.ecmaVersion >= 6) {
4649 if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
4650 if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
4653 // Anything else beginning with a digit is an integer, octal
4654 // number, or float.
4655 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
4656 return this.readNumber(false)
4658 // Quotes produce strings.
4659 case 34: case 39: // '"', "'"
4660 return this.readString(code)
4662 // Operators are parsed inline in tiny state machines. '=' (61) is
4663 // often referred to. `finishOp` simply skips the amount of
4664 // characters it is given as second argument, and returns a token
4665 // of the type given by its first argument.
4668 return this.readToken_slash()
4670 case 37: case 42: // '%*'
4671 return this.readToken_mult_modulo_exp(code)
4673 case 124: case 38: // '|&'
4674 return this.readToken_pipe_amp(code)
4677 return this.readToken_caret()
4679 case 43: case 45: // '+-'
4680 return this.readToken_plus_min(code)
4682 case 60: case 62: // '<>'
4683 return this.readToken_lt_gt(code)
4685 case 61: case 33: // '=!'
4686 return this.readToken_eq_excl(code)
4689 return this.readToken_question()
4692 return this.finishOp(types.prefix, 1)
4695 this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
4698 pp$9.finishOp = function(type, size) {
4699 var str = this.input.slice(this.pos, this.pos + size);
4701 return this.finishToken(type, str)
4704 pp$9.readRegexp = function() {
4705 var escaped, inClass, start = this.pos;
4707 if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
4708 var ch = this.input.charAt(this.pos);
4709 if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
4711 if (ch === "[") { inClass = true; }
4712 else if (ch === "]" && inClass) { inClass = false; }
4713 else if (ch === "/" && !inClass) { break }
4714 escaped = ch === "\\";
4715 } else { escaped = false; }
4718 var pattern = this.input.slice(start, this.pos);
4720 var flagsStart = this.pos;
4721 var flags = this.readWord1();
4722 if (this.containsEsc) { this.unexpected(flagsStart); }
4725 var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
4726 state.reset(start, pattern, flags);
4727 this.validateRegExpFlags(state);
4728 this.validateRegExpPattern(state);
4730 // Create Literal#value property value.
4733 value = new RegExp(pattern, flags);
4735 // ESTree requires null if it failed to instantiate RegExp object.
4736 // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
4739 return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value})
4742 // Read an integer in the given radix. Return null if zero digits
4743 // were read, the integer value otherwise. When `len` is given, this
4744 // will return `null` unless the integer has exactly `len` digits.
4746 pp$9.readInt = function(radix, len) {
4747 var start = this.pos, total = 0;
4748 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
4749 var code = this.input.charCodeAt(this.pos), val = (void 0);
4750 if (code >= 97) { val = code - 97 + 10; } // a
4751 else if (code >= 65) { val = code - 65 + 10; } // A
4752 else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
4753 else { val = Infinity; }
4754 if (val >= radix) { break }
4756 total = total * radix + val;
4758 if (this.pos === start || len != null && this.pos - start !== len) { return null }
4763 pp$9.readRadixNumber = function(radix) {
4764 var start = this.pos;
4765 this.pos += 2; // 0x
4766 var val = this.readInt(radix);
4767 if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
4768 if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
4769 val = typeof BigInt !== "undefined" ? BigInt(this.input.slice(start, this.pos)) : null;
4771 } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4772 return this.finishToken(types.num, val)
4775 // Read an integer, octal integer, or floating-point number.
4777 pp$9.readNumber = function(startsWithDot) {
4778 var start = this.pos;
4779 if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); }
4780 var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
4781 if (octal && this.strict) { this.raise(start, "Invalid number"); }
4782 var next = this.input.charCodeAt(this.pos);
4783 if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
4784 var str$1 = this.input.slice(start, this.pos);
4785 var val$1 = typeof BigInt !== "undefined" ? BigInt(str$1) : null;
4787 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4788 return this.finishToken(types.num, val$1)
4790 if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
4791 if (next === 46 && !octal) { // '.'
4794 next = this.input.charCodeAt(this.pos);
4796 if ((next === 69 || next === 101) && !octal) { // 'eE'
4797 next = this.input.charCodeAt(++this.pos);
4798 if (next === 43 || next === 45) { ++this.pos; } // '+-'
4799 if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
4801 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4803 var str = this.input.slice(start, this.pos);
4804 var val = octal ? parseInt(str, 8) : parseFloat(str);
4805 return this.finishToken(types.num, val)
4808 // Read a string value, interpreting backslash-escapes.
4810 pp$9.readCodePoint = function() {
4811 var ch = this.input.charCodeAt(this.pos), code;
4813 if (ch === 123) { // '{'
4814 if (this.options.ecmaVersion < 6) { this.unexpected(); }
4815 var codePos = ++this.pos;
4816 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
4818 if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
4820 code = this.readHexChar(4);
4825 function codePointToString$1(code) {
4827 if (code <= 0xFFFF) { return String.fromCharCode(code) }
4829 return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
4832 pp$9.readString = function(quote) {
4833 var out = "", chunkStart = ++this.pos;
4835 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
4836 var ch = this.input.charCodeAt(this.pos);
4837 if (ch === quote) { break }
4838 if (ch === 92) { // '\'
4839 out += this.input.slice(chunkStart, this.pos);
4840 out += this.readEscapedChar(false);
4841 chunkStart = this.pos;
4843 if (isNewLine(ch, this.options.ecmaVersion >= 10)) { this.raise(this.start, "Unterminated string constant"); }
4847 out += this.input.slice(chunkStart, this.pos++);
4848 return this.finishToken(types.string, out)
4851 // Reads template string tokens.
4853 var INVALID_TEMPLATE_ESCAPE_ERROR = {};
4855 pp$9.tryReadTemplateToken = function() {
4856 this.inTemplateElement = true;
4858 this.readTmplToken();
4860 if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
4861 this.readInvalidTemplateToken();
4867 this.inTemplateElement = false;
4870 pp$9.invalidStringToken = function(position, message) {
4871 if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
4872 throw INVALID_TEMPLATE_ESCAPE_ERROR
4874 this.raise(position, message);
4878 pp$9.readTmplToken = function() {
4879 var out = "", chunkStart = this.pos;
4881 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
4882 var ch = this.input.charCodeAt(this.pos);
4883 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
4884 if (this.pos === this.start && (this.type === types.template || this.type === types.invalidTemplate)) {
4887 return this.finishToken(types.dollarBraceL)
4890 return this.finishToken(types.backQuote)
4893 out += this.input.slice(chunkStart, this.pos);
4894 return this.finishToken(types.template, out)
4896 if (ch === 92) { // '\'
4897 out += this.input.slice(chunkStart, this.pos);
4898 out += this.readEscapedChar(true);
4899 chunkStart = this.pos;
4900 } else if (isNewLine(ch)) {
4901 out += this.input.slice(chunkStart, this.pos);
4905 if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
4910 out += String.fromCharCode(ch);
4913 if (this.options.locations) {
4915 this.lineStart = this.pos;
4917 chunkStart = this.pos;
4924 // Reads a template token to search for the end, without validating any escape sequences
4925 pp$9.readInvalidTemplateToken = function() {
4926 for (; this.pos < this.input.length; this.pos++) {
4927 switch (this.input[this.pos]) {
4933 if (this.input[this.pos + 1] !== "{") {
4939 return this.finishToken(types.invalidTemplate, this.input.slice(this.start, this.pos))
4944 this.raise(this.start, "Unterminated template");
4947 // Used to read escaped characters
4949 pp$9.readEscapedChar = function(inTemplate) {
4950 var ch = this.input.charCodeAt(++this.pos);
4953 case 110: return "\n" // 'n' -> '\n'
4954 case 114: return "\r" // 'r' -> '\r'
4955 case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
4956 case 117: return codePointToString$1(this.readCodePoint()) // 'u'
4957 case 116: return "\t" // 't' -> '\t'
4958 case 98: return "\b" // 'b' -> '\b'
4959 case 118: return "\u000b" // 'v' -> '\u000b'
4960 case 102: return "\f" // 'f' -> '\f'
4961 case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
4963 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
4968 var codePos = this.pos - 1;
4970 this.invalidStringToken(
4972 "Invalid escape sequence in template string"
4978 if (ch >= 48 && ch <= 55) {
4979 var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
4980 var octal = parseInt(octalStr, 8);
4982 octalStr = octalStr.slice(0, -1);
4983 octal = parseInt(octalStr, 8);
4985 this.pos += octalStr.length - 1;
4986 ch = this.input.charCodeAt(this.pos);
4987 if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
4988 this.invalidStringToken(
4989 this.pos - 1 - octalStr.length,
4991 ? "Octal literal in template string"
4992 : "Octal literal in strict mode"
4995 return String.fromCharCode(octal)
4997 if (isNewLine(ch)) {
4998 // Unicode new line characters after \ get removed from output in both
4999 // template literals and strings
5002 return String.fromCharCode(ch)
5006 // Used to read character escape sequences ('\x', '\u', '\U').
5008 pp$9.readHexChar = function(len) {
5009 var codePos = this.pos;
5010 var n = this.readInt(16, len);
5011 if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
5015 // Read an identifier, and return it as a string. Sets `this.containsEsc`
5016 // to whether the word contained a '\u' escape.
5018 // Incrementally adds only escaped chars, adding other chunks as-is
5019 // as a micro-optimization.
5021 pp$9.readWord1 = function() {
5022 this.containsEsc = false;
5023 var word = "", first = true, chunkStart = this.pos;
5024 var astral = this.options.ecmaVersion >= 6;
5025 while (this.pos < this.input.length) {
5026 var ch = this.fullCharCodeAtPos();
5027 if (isIdentifierChar(ch, astral)) {
5028 this.pos += ch <= 0xffff ? 1 : 2;
5029 } else if (ch === 92) { // "\"
5030 this.containsEsc = true;
5031 word += this.input.slice(chunkStart, this.pos);
5032 var escStart = this.pos;
5033 if (this.input.charCodeAt(++this.pos) !== 117) // "u"
5034 { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
5036 var esc = this.readCodePoint();
5037 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
5038 { this.invalidStringToken(escStart, "Invalid Unicode escape"); }
5039 word += codePointToString$1(esc);
5040 chunkStart = this.pos;
5046 return word + this.input.slice(chunkStart, this.pos)
5049 // Read an identifier or keyword token. Will check for reserved
5050 // words when necessary.
5052 pp$9.readWord = function() {
5053 var word = this.readWord1();
5054 var type = types.name;
5055 if (this.keywords.test(word)) {
5056 type = keywords$1[word];
5058 return this.finishToken(type, word)
5061 // Acorn is a tiny, fast JavaScript parser written in JavaScript.
5063 var version = "7.3.1";
5068 defaultOptions: defaultOptions,
5070 SourceLocation: SourceLocation,
5071 getLineInfo: getLineInfo,
5073 TokenType: TokenType,
5075 keywordTypes: keywords$1,
5076 TokContext: TokContext,
5077 tokContexts: types$1,
5078 isIdentifierChar: isIdentifierChar,
5079 isIdentifierStart: isIdentifierStart,
5081 isNewLine: isNewLine,
5082 lineBreak: lineBreak,
5083 lineBreakG: lineBreakG,
5084 nonASCIIwhitespace: nonASCIIwhitespace
5087 // The main exported interface (under `self.acorn` when in the
5088 // browser) is a `parse` function that takes a code string and
5089 // returns an abstract syntax tree as specified by [Mozilla parser
5092 // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
5094 function parse(input, options) {
5095 return Parser.parse(input, options)
5098 // This function tries to parse a single expression at a given
5099 // offset in a string. Useful for parsing mixed-language formats
5100 // that embed JavaScript expressions.
5102 function parseExpressionAt(input, pos, options) {
5103 return Parser.parseExpressionAt(input, pos, options)
5106 // Acorn is organized as a tokenizer and a recursive-descent parser.
5107 // The `tokenizer` export provides an interface to the tokenizer.
5109 function tokenizer(input, options) {
5110 return Parser.tokenizer(input, options)
5113 exports.Node = Node;
5114 exports.Parser = Parser;
5115 exports.Position = Position;
5116 exports.SourceLocation = SourceLocation;
5117 exports.TokContext = TokContext;
5118 exports.Token = Token;
5119 exports.TokenType = TokenType;
5120 exports.defaultOptions = defaultOptions;
5121 exports.getLineInfo = getLineInfo;
5122 exports.isIdentifierChar = isIdentifierChar;
5123 exports.isIdentifierStart = isIdentifierStart;
5124 exports.isNewLine = isNewLine;
5125 exports.keywordTypes = keywords$1;
5126 exports.lineBreak = lineBreak;
5127 exports.lineBreakG = lineBreakG;
5128 exports.nonASCIIwhitespace = nonASCIIwhitespace;
5129 exports.parse = parse;
5130 exports.parseExpressionAt = parseExpressionAt;
5131 exports.tokContexts = types$1;
5132 exports.tokTypes = types;
5133 exports.tokenizer = tokenizer;
5134 exports.version = version;
5136 Object.defineProperty(exports, '__esModule', { value: true });