1 // Reserved word lists for various dialects of the language
4 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",
5 5: "class enum extends super const export import",
7 strict: "implements interface let package private protected public static yield",
8 strictBind: "eval arguments"
13 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";
16 5: ecma5AndLessKeywords,
17 "5module": ecma5AndLessKeywords + " export import",
18 6: ecma5AndLessKeywords + " const class extends export import super"
21 var keywordRelationalOperator = /^in(stanceof)?$/;
23 // ## Character categories
25 // Big ugly regular expressions that match characters in the
26 // whitespace, identifier, and identifier-start categories. These
27 // are only applied when a character is found to actually have a
28 // code point above 128.
29 // Generated by `bin/generate-identifier-regex.js`.
30 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";
31 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";
33 var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
34 var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
36 nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
38 // These are a run-length and offset encoded representation of the
39 // >0xffff code points that are a valid part of identifiers. The
40 // offset starts at 0x10000, and each pair of numbers represents an
41 // offset to the next range, and then a size of the range. They were
42 // generated by bin/generate-identifier-regex.js
44 // eslint-disable-next-line comma-spacing
45 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];
47 // eslint-disable-next-line comma-spacing
48 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];
50 // This has a complexity linear to the value of the code. The
51 // assumption is that looking up astral identifier characters is
53 function isInAstralSet(code, set) {
55 for (var i = 0; i < set.length; i += 2) {
57 if (pos > code) { return false }
59 if (pos >= code) { return true }
63 // Test whether a given character code starts an identifier.
65 function isIdentifierStart(code, astral) {
66 if (code < 65) { return code === 36 }
67 if (code < 91) { return true }
68 if (code < 97) { return code === 95 }
69 if (code < 123) { return true }
70 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
71 if (astral === false) { return false }
72 return isInAstralSet(code, astralIdentifierStartCodes)
75 // Test whether a given character is part of an identifier.
77 function isIdentifierChar(code, astral) {
78 if (code < 48) { return code === 36 }
79 if (code < 58) { return true }
80 if (code < 65) { return false }
81 if (code < 91) { return true }
82 if (code < 97) { return code === 95 }
83 if (code < 123) { return true }
84 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
85 if (astral === false) { return false }
86 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
91 // The assignment of fine-grained, information-carrying type objects
92 // allows the tokenizer to store the information it has about a
93 // token in a way that is very cheap for the parser to look up.
95 // All token type variables start with an underscore, to make them
98 // The `beforeExpr` property is used to disambiguate between regular
99 // expressions and divisions. It is set on all token types that can
100 // be followed by an expression (thus, a slash after them would be a
101 // regular expression).
103 // The `startsExpr` property is used to check if the token ends a
104 // `yield` expression. It is set on all token types that either can
105 // directly start an expression (like a quotation mark) or can
106 // continue an expression (like the body of a string).
108 // `isLoop` marks a keyword as starting a loop, which is important
109 // to know when parsing a label, in order to allow or disallow
110 // continue jumps to that label.
112 var TokenType = function TokenType(label, conf) {
113 if ( conf === void 0 ) conf = {};
116 this.keyword = conf.keyword;
117 this.beforeExpr = !!conf.beforeExpr;
118 this.startsExpr = !!conf.startsExpr;
119 this.isLoop = !!conf.isLoop;
120 this.isAssign = !!conf.isAssign;
121 this.prefix = !!conf.prefix;
122 this.postfix = !!conf.postfix;
123 this.binop = conf.binop || null;
124 this.updateContext = null;
127 function binop(name, prec) {
128 return new TokenType(name, {beforeExpr: true, binop: prec})
130 var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
132 // Map keyword names to token types.
136 // Succinct definitions of keyword token types
137 function kw(name, options) {
138 if ( options === void 0 ) options = {};
140 options.keyword = name;
141 return keywords$1[name] = new TokenType(name, options)
145 num: new TokenType("num", startsExpr),
146 regexp: new TokenType("regexp", startsExpr),
147 string: new TokenType("string", startsExpr),
148 name: new TokenType("name", startsExpr),
149 eof: new TokenType("eof"),
151 // Punctuation token types.
152 bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
153 bracketR: new TokenType("]"),
154 braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
155 braceR: new TokenType("}"),
156 parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
157 parenR: new TokenType(")"),
158 comma: new TokenType(",", beforeExpr),
159 semi: new TokenType(";", beforeExpr),
160 colon: new TokenType(":", beforeExpr),
161 dot: new TokenType("."),
162 question: new TokenType("?", beforeExpr),
163 questionDot: new TokenType("?."),
164 arrow: new TokenType("=>", beforeExpr),
165 template: new TokenType("template"),
166 invalidTemplate: new TokenType("invalidTemplate"),
167 ellipsis: new TokenType("...", beforeExpr),
168 backQuote: new TokenType("`", startsExpr),
169 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
171 // Operators. These carry several kinds of properties to help the
172 // parser use them properly (the presence of these properties is
173 // what categorizes them as operators).
175 // `binop`, when present, specifies that this operator is a binary
176 // operator, and will refer to its precedence.
178 // `prefix` and `postfix` mark the operator as a prefix or postfix
181 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
182 // binary operators with a very low precedence, that should result
183 // in AssignmentExpression nodes.
185 eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
186 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
187 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
188 prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
189 logicalOR: binop("||", 1),
190 logicalAND: binop("&&", 2),
191 bitwiseOR: binop("|", 3),
192 bitwiseXOR: binop("^", 4),
193 bitwiseAND: binop("&", 5),
194 equality: binop("==/!=/===/!==", 6),
195 relational: binop("</>/<=/>=", 7),
196 bitShift: binop("<</>>/>>>", 8),
197 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
198 modulo: binop("%", 10),
199 star: binop("*", 10),
200 slash: binop("/", 10),
201 starstar: new TokenType("**", {beforeExpr: true}),
202 coalesce: binop("??", 1),
204 // Keyword token types.
206 _case: kw("case", beforeExpr),
208 _continue: kw("continue"),
209 _debugger: kw("debugger"),
210 _default: kw("default", beforeExpr),
211 _do: kw("do", {isLoop: true, beforeExpr: true}),
212 _else: kw("else", beforeExpr),
213 _finally: kw("finally"),
214 _for: kw("for", {isLoop: true}),
215 _function: kw("function", startsExpr),
217 _return: kw("return", beforeExpr),
218 _switch: kw("switch"),
219 _throw: kw("throw", beforeExpr),
223 _while: kw("while", {isLoop: true}),
225 _new: kw("new", {beforeExpr: true, startsExpr: true}),
226 _this: kw("this", startsExpr),
227 _super: kw("super", startsExpr),
228 _class: kw("class", startsExpr),
229 _extends: kw("extends", beforeExpr),
230 _export: kw("export"),
231 _import: kw("import", startsExpr),
232 _null: kw("null", startsExpr),
233 _true: kw("true", startsExpr),
234 _false: kw("false", startsExpr),
235 _in: kw("in", {beforeExpr: true, binop: 7}),
236 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
237 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
238 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
239 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
242 // Matches a whole line break (where CRLF is considered a single
243 // line break). Used to count lines.
245 var lineBreak = /\r\n?|\n|\u2028|\u2029/;
246 var lineBreakG = new RegExp(lineBreak.source, "g");
248 function isNewLine(code, ecma2019String) {
249 return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))
252 var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
254 var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
256 var ref = Object.prototype;
257 var hasOwnProperty = ref.hasOwnProperty;
258 var toString = ref.toString;
260 // Checks if an object has a property.
262 function has(obj, propName) {
263 return hasOwnProperty.call(obj, propName)
266 var isArray = Array.isArray || (function (obj) { return (
267 toString.call(obj) === "[object Array]"
270 function wordsRegexp(words) {
271 return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
274 // These are used when `options.locations` is on, for the
275 // `startLoc` and `endLoc` properties.
277 var Position = function Position(line, col) {
282 Position.prototype.offset = function offset (n) {
283 return new Position(this.line, this.column + n)
286 var SourceLocation = function SourceLocation(p, start, end) {
289 if (p.sourceFile !== null) { this.source = p.sourceFile; }
292 // The `getLineInfo` function is mostly useful when the
293 // `locations` option is off (for performance reasons) and you
294 // want to find the line/column position for a given character
295 // offset. `input` should be the code string that the offset refers
298 function getLineInfo(input, offset) {
299 for (var line = 1, cur = 0;;) {
300 lineBreakG.lastIndex = cur;
301 var match = lineBreakG.exec(input);
302 if (match && match.index < offset) {
304 cur = match.index + match[0].length;
306 return new Position(line, offset - cur)
311 // A second optional argument can be given to further configure
312 // the parser process. These options are recognized:
314 var defaultOptions = {
315 // `ecmaVersion` indicates the ECMAScript version to parse. Must be
316 // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10
317 // (2019). This influences support for strict mode, the set of
318 // reserved words, and support for new syntax features. The default
321 // `sourceType` indicates the mode the code should be parsed in.
322 // Can be either `"script"` or `"module"`. This influences global
323 // strict mode and parsing of `import` and `export` declarations.
324 sourceType: "script",
325 // `onInsertedSemicolon` can be a callback that will be called
326 // when a semicolon is automatically inserted. It will be passed
327 // the position of the comma as an offset, and if `locations` is
328 // enabled, it is given the location as a `{line, column}` object
329 // as second argument.
330 onInsertedSemicolon: null,
331 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
333 onTrailingComma: null,
334 // By default, reserved words are only enforced if ecmaVersion >= 5.
335 // Set `allowReserved` to a boolean value to explicitly turn this on
336 // an off. When this option has the value "never", reserved words
337 // and keywords can also not be used as property names.
339 // When enabled, a return at the top level is not considered an
341 allowReturnOutsideFunction: false,
342 // When enabled, import/export statements are not constrained to
343 // appearing at the top of the program.
344 allowImportExportEverywhere: false,
345 // When enabled, await identifiers are allowed to appear at the top-level scope,
346 // but they are still not allowed in non-async functions.
347 allowAwaitOutsideFunction: false,
348 // When enabled, hashbang directive in the beginning of file
349 // is allowed and treated as a line comment.
350 allowHashBang: false,
351 // When `locations` is on, `loc` properties holding objects with
352 // `start` and `end` properties in `{line, column}` form (with
353 // line being 1-based and column 0-based) will be attached to the
356 // A function can be passed as `onToken` option, which will
357 // cause Acorn to call that function with object in the same
358 // format as tokens returned from `tokenizer().getToken()`. Note
359 // that you are not allowed to call the parser from the
360 // callback—that will corrupt its internal state.
362 // A function can be passed as `onComment` option, which will
363 // cause Acorn to call that function with `(block, text, start,
364 // end)` parameters whenever a comment is skipped. `block` is a
365 // boolean indicating whether this is a block (`/* */`) comment,
366 // `text` is the content of the comment, and `start` and `end` are
367 // character offsets that denote the start and end of the comment.
368 // When the `locations` option is on, two more parameters are
369 // passed, the full `{line, column}` locations of the start and
370 // end of the comments. Note that you are not allowed to call the
371 // parser from the callback—that will corrupt its internal state.
373 // Nodes have their start and end characters offsets recorded in
374 // `start` and `end` properties (directly on the node, rather than
375 // the `loc` object, which holds line/column data. To also add a
376 // [semi-standardized][range] `range` property holding a `[start,
377 // end]` array with the same numbers, set the `ranges` option to
380 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
382 // It is possible to parse multiple files into a single AST by
383 // passing the tree produced by parsing the first file as
384 // `program` option in subsequent parses. This will add the
385 // toplevel forms of the parsed file to the `Program` (top) node
386 // of an existing parse tree.
388 // When `locations` is on, you can pass this to record the source
389 // file in every node's `loc` object.
391 // This value, if given, is stored in every node, whether
392 // `locations` is on or off.
393 directSourceFile: null,
394 // When enabled, parenthesized expressions are represented by
395 // (non-standard) ParenthesizedExpression nodes
396 preserveParens: false
399 // Interpret and default an options object
401 function getOptions(opts) {
404 for (var opt in defaultOptions)
405 { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
407 if (options.ecmaVersion >= 2015)
408 { options.ecmaVersion -= 2009; }
410 if (options.allowReserved == null)
411 { options.allowReserved = options.ecmaVersion < 5; }
413 if (isArray(options.onToken)) {
414 var tokens = options.onToken;
415 options.onToken = function (token) { return tokens.push(token); };
417 if (isArray(options.onComment))
418 { options.onComment = pushComment(options, options.onComment); }
423 function pushComment(options, array) {
424 return function(block, text, start, end, startLoc, endLoc) {
426 type: block ? "Block" : "Line",
431 if (options.locations)
432 { comment.loc = new SourceLocation(this, startLoc, endLoc); }
434 { comment.range = [start, end]; }
439 // Each scope gets a bitset that may contain these flags
443 SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION,
447 SCOPE_SIMPLE_CATCH = 32,
449 SCOPE_DIRECT_SUPER = 128;
451 function functionFlags(async, generator) {
452 return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
455 // Used in checkLVal and declareName to determine the type of a binding
457 BIND_NONE = 0, // Not a binding
458 BIND_VAR = 1, // Var-style binding
459 BIND_LEXICAL = 2, // Let- or const-style binding
460 BIND_FUNCTION = 3, // Function declaration
461 BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
462 BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
464 var Parser = function Parser(options, input, startPos) {
465 this.options = options = getOptions(options);
466 this.sourceFile = options.sourceFile;
467 this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
469 if (options.allowReserved !== true) {
470 for (var v = options.ecmaVersion;; v--)
471 { if (reserved = reservedWords[v]) { break } }
472 if (options.sourceType === "module") { reserved += " await"; }
474 this.reservedWords = wordsRegexp(reserved);
475 var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
476 this.reservedWordsStrict = wordsRegexp(reservedStrict);
477 this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
478 this.input = String(input);
480 // Used to signal to callers of `readWord1` whether the word
481 // contained any escape sequences. This is needed because words with
482 // escape sequences must not be interpreted as keywords.
483 this.containsEsc = false;
485 // Set up token state
487 // The current position of the tokenizer in the input.
490 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
491 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
493 this.pos = this.lineStart = 0;
497 // Properties of the current token:
499 this.type = types.eof;
500 // For tokens that include more information than their type, the value
502 // Its start and end offset
503 this.start = this.end = this.pos;
504 // And, if locations are used, the {line, column} object
505 // corresponding to those offsets
506 this.startLoc = this.endLoc = this.curPosition();
508 // Position information for the previous token
509 this.lastTokEndLoc = this.lastTokStartLoc = null;
510 this.lastTokStart = this.lastTokEnd = this.pos;
512 // The context stack is used to superficially track syntactic
513 // context to predict whether a regular expression is allowed in a
515 this.context = this.initialContext();
516 this.exprAllowed = true;
518 // Figure out if it's a module code.
519 this.inModule = options.sourceType === "module";
520 this.strict = this.inModule || this.strictDirective(this.pos);
522 // Used to signify the start of a potential arrow function
523 this.potentialArrowAt = -1;
525 // Positions to delayed-check that yield/await does not exist in default parameters.
526 this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
529 // Thus-far undefined exports.
530 this.undefinedExports = {};
532 // If enabled, skip leading hashbang line.
533 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
534 { this.skipLineComment(2); }
536 // Scope tracking for duplicate variable names (see scope.js)
537 this.scopeStack = [];
538 this.enterScope(SCOPE_TOP);
540 // For RegExp validation
541 this.regexpState = null;
544 var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } };
546 Parser.prototype.parse = function parse () {
547 var node = this.options.program || this.startNode();
549 return this.parseTopLevel(node)
552 prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
553 prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
554 prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
555 prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 };
556 prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
557 prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
559 // Switch to a getter for 7.0.0.
560 Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 };
562 Parser.extend = function extend () {
563 var plugins = [], len = arguments.length;
564 while ( len-- ) plugins[ len ] = arguments[ len ];
567 for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
571 Parser.parse = function parse (input, options) {
572 return new this(options, input).parse()
575 Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
576 var parser = new this(options, input, pos);
578 return parser.parseExpression()
581 Parser.tokenizer = function tokenizer (input, options) {
582 return new this(options, input)
585 Object.defineProperties( Parser.prototype, prototypeAccessors );
587 var pp = Parser.prototype;
589 // ## Parser utilities
591 var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/;
592 pp.strictDirective = function(start) {
594 // Try to find string literal.
595 skipWhiteSpace.lastIndex = start;
596 start += skipWhiteSpace.exec(this.input)[0].length;
597 var match = literal.exec(this.input.slice(start));
598 if (!match) { return false }
599 if ((match[1] || match[2]) === "use strict") {
600 skipWhiteSpace.lastIndex = start + match[0].length;
601 var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
602 var next = this.input.charAt(end);
603 return next === ";" || next === "}" ||
604 (lineBreak.test(spaceAfter[0]) &&
605 !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
607 start += match[0].length;
609 // Skip semicolon, if any.
610 skipWhiteSpace.lastIndex = start;
611 start += skipWhiteSpace.exec(this.input)[0].length;
612 if (this.input[start] === ";")
617 // Predicate that tests whether the next token is of the given
618 // type, and if yes, consumes it as a side effect.
620 pp.eat = function(type) {
621 if (this.type === type) {
629 // Tests whether parsed token is a contextual keyword.
631 pp.isContextual = function(name) {
632 return this.type === types.name && this.value === name && !this.containsEsc
635 // Consumes contextual keyword if possible.
637 pp.eatContextual = function(name) {
638 if (!this.isContextual(name)) { return false }
643 // Asserts that following token is given contextual keyword.
645 pp.expectContextual = function(name) {
646 if (!this.eatContextual(name)) { this.unexpected(); }
649 // Test whether a semicolon can be inserted at the current position.
651 pp.canInsertSemicolon = function() {
652 return this.type === types.eof ||
653 this.type === types.braceR ||
654 lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
657 pp.insertSemicolon = function() {
658 if (this.canInsertSemicolon()) {
659 if (this.options.onInsertedSemicolon)
660 { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
665 // Consume a semicolon, or, failing that, see if we are allowed to
666 // pretend that there is a semicolon at this position.
668 pp.semicolon = function() {
669 if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
672 pp.afterTrailingComma = function(tokType, notNext) {
673 if (this.type === tokType) {
674 if (this.options.onTrailingComma)
675 { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
682 // Expect a token of a given type. If found, consume it, otherwise,
683 // raise an unexpected token error.
685 pp.expect = function(type) {
686 this.eat(type) || this.unexpected();
689 // Raise an unexpected token error.
691 pp.unexpected = function(pos) {
692 this.raise(pos != null ? pos : this.start, "Unexpected token");
695 function DestructuringErrors() {
696 this.shorthandAssign =
698 this.parenthesizedAssign =
699 this.parenthesizedBind =
704 pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
705 if (!refDestructuringErrors) { return }
706 if (refDestructuringErrors.trailingComma > -1)
707 { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
708 var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
709 if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
712 pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
713 if (!refDestructuringErrors) { return false }
714 var shorthandAssign = refDestructuringErrors.shorthandAssign;
715 var doubleProto = refDestructuringErrors.doubleProto;
716 if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
717 if (shorthandAssign >= 0)
718 { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
719 if (doubleProto >= 0)
720 { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
723 pp.checkYieldAwaitInDefaultParams = function() {
724 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
725 { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
727 { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
730 pp.isSimpleAssignTarget = function(expr) {
731 if (expr.type === "ParenthesizedExpression")
732 { return this.isSimpleAssignTarget(expr.expression) }
733 return expr.type === "Identifier" || expr.type === "MemberExpression"
736 var pp$1 = Parser.prototype;
738 // ### Statement parsing
740 // Parse a program. Initializes the parser, reads any number of
741 // statements, and wraps them in a Program node. Optionally takes a
742 // `program` argument. If present, the statements will be appended
743 // to its body instead of creating a new node.
745 pp$1.parseTopLevel = function(node) {
747 if (!node.body) { node.body = []; }
748 while (this.type !== types.eof) {
749 var stmt = this.parseStatement(null, true, exports);
750 node.body.push(stmt);
753 { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
757 this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
759 this.adaptDirectivePrologue(node.body);
761 node.sourceType = this.options.sourceType;
762 return this.finishNode(node, "Program")
765 var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
767 pp$1.isLet = function(context) {
768 if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
769 skipWhiteSpace.lastIndex = this.pos;
770 var skip = skipWhiteSpace.exec(this.input);
771 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
772 // For ambiguous cases, determine if a LexicalDeclaration (or only a
773 // Statement) is allowed here. If context is not empty then only a Statement
774 // is allowed. However, `let [` is an explicit negative lookahead for
775 // ExpressionStatement, so special-case it first.
776 if (nextCh === 91) { return true } // '['
777 if (context) { return false }
779 if (nextCh === 123) { return true } // '{'
780 if (isIdentifierStart(nextCh, true)) {
782 while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
783 var ident = this.input.slice(next, pos);
784 if (!keywordRelationalOperator.test(ident)) { return true }
789 // check 'async [no LineTerminator here] function'
790 // - 'async /*foo*/ function' is OK.
791 // - 'async /*\n*/ function' is invalid.
792 pp$1.isAsyncFunction = function() {
793 if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
796 skipWhiteSpace.lastIndex = this.pos;
797 var skip = skipWhiteSpace.exec(this.input);
798 var next = this.pos + skip[0].length;
799 return !lineBreak.test(this.input.slice(this.pos, next)) &&
800 this.input.slice(next, next + 8) === "function" &&
801 (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
804 // Parse a single statement.
806 // If expecting a statement and finding a slash operator, parse a
807 // regular expression literal. This is to handle cases like
808 // `if (foo) /blah/.exec(foo)`, where looking at the previous token
811 pp$1.parseStatement = function(context, topLevel, exports) {
812 var starttype = this.type, node = this.startNode(), kind;
814 if (this.isLet(context)) {
815 starttype = types._var;
819 // Most types of statements are recognized by the keyword they
820 // start with. Many are trivial to parse, some require a bit of
824 case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
825 case types._debugger: return this.parseDebuggerStatement(node)
826 case types._do: return this.parseDoStatement(node)
827 case types._for: return this.parseForStatement(node)
828 case types._function:
829 // Function as sole body of either an if statement or a labeled statement
830 // works, but not when it is part of a labeled statement that is the sole
831 // body of an if statement.
832 if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
833 return this.parseFunctionStatement(node, false, !context)
835 if (context) { this.unexpected(); }
836 return this.parseClass(node, true)
837 case types._if: return this.parseIfStatement(node)
838 case types._return: return this.parseReturnStatement(node)
839 case types._switch: return this.parseSwitchStatement(node)
840 case types._throw: return this.parseThrowStatement(node)
841 case types._try: return this.parseTryStatement(node)
842 case types._const: case types._var:
843 kind = kind || this.value;
844 if (context && kind !== "var") { this.unexpected(); }
845 return this.parseVarStatement(node, kind)
846 case types._while: return this.parseWhileStatement(node)
847 case types._with: return this.parseWithStatement(node)
848 case types.braceL: return this.parseBlock(true, node)
849 case types.semi: return this.parseEmptyStatement(node)
852 if (this.options.ecmaVersion > 10 && starttype === types._import) {
853 skipWhiteSpace.lastIndex = this.pos;
854 var skip = skipWhiteSpace.exec(this.input);
855 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
856 if (nextCh === 40 || nextCh === 46) // '(' or '.'
857 { return this.parseExpressionStatement(node, this.parseExpression()) }
860 if (!this.options.allowImportExportEverywhere) {
862 { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
864 { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
866 return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
868 // If the statement does not start with a statement keyword or a
869 // brace, it's an ExpressionStatement or LabeledStatement. We
870 // simply start parsing an expression, and afterwards, if the
871 // next token is a colon and the expression was a simple
872 // Identifier node, we switch to interpreting it as a label.
874 if (this.isAsyncFunction()) {
875 if (context) { this.unexpected(); }
877 return this.parseFunctionStatement(node, true, !context)
880 var maybeName = this.value, expr = this.parseExpression();
881 if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
882 { return this.parseLabeledStatement(node, maybeName, expr, context) }
883 else { return this.parseExpressionStatement(node, expr) }
887 pp$1.parseBreakContinueStatement = function(node, keyword) {
888 var isBreak = keyword === "break";
890 if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
891 else if (this.type !== types.name) { this.unexpected(); }
893 node.label = this.parseIdent();
897 // Verify that there is an actual destination to break or
900 for (; i < this.labels.length; ++i) {
901 var lab = this.labels[i];
902 if (node.label == null || lab.name === node.label.name) {
903 if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
904 if (node.label && isBreak) { break }
907 if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
908 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
911 pp$1.parseDebuggerStatement = function(node) {
914 return this.finishNode(node, "DebuggerStatement")
917 pp$1.parseDoStatement = function(node) {
919 this.labels.push(loopLabel);
920 node.body = this.parseStatement("do");
922 this.expect(types._while);
923 node.test = this.parseParenExpression();
924 if (this.options.ecmaVersion >= 6)
925 { this.eat(types.semi); }
927 { this.semicolon(); }
928 return this.finishNode(node, "DoWhileStatement")
931 // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
932 // loop is non-trivial. Basically, we have to parse the init `var`
933 // statement or expression, disallowing the `in` operator (see
934 // the second parameter to `parseExpression`), and then check
935 // whether the next token is `in` or `of`. When there is no init
936 // part (semicolon immediately after the opening parenthesis), it
937 // is a regular `for` loop.
939 pp$1.parseForStatement = function(node) {
941 var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
942 this.labels.push(loopLabel);
944 this.expect(types.parenL);
945 if (this.type === types.semi) {
946 if (awaitAt > -1) { this.unexpected(awaitAt); }
947 return this.parseFor(node, null)
949 var isLet = this.isLet();
950 if (this.type === types._var || this.type === types._const || isLet) {
951 var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
953 this.parseVar(init$1, true, kind);
954 this.finishNode(init$1, "VariableDeclaration");
955 if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) {
956 if (this.options.ecmaVersion >= 9) {
957 if (this.type === types._in) {
958 if (awaitAt > -1) { this.unexpected(awaitAt); }
959 } else { node.await = awaitAt > -1; }
961 return this.parseForIn(node, init$1)
963 if (awaitAt > -1) { this.unexpected(awaitAt); }
964 return this.parseFor(node, init$1)
966 var refDestructuringErrors = new DestructuringErrors;
967 var init = this.parseExpression(true, refDestructuringErrors);
968 if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
969 if (this.options.ecmaVersion >= 9) {
970 if (this.type === types._in) {
971 if (awaitAt > -1) { this.unexpected(awaitAt); }
972 } else { node.await = awaitAt > -1; }
974 this.toAssignable(init, false, refDestructuringErrors);
975 this.checkLVal(init);
976 return this.parseForIn(node, init)
978 this.checkExpressionErrors(refDestructuringErrors, true);
980 if (awaitAt > -1) { this.unexpected(awaitAt); }
981 return this.parseFor(node, init)
984 pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) {
986 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
989 pp$1.parseIfStatement = function(node) {
991 node.test = this.parseParenExpression();
992 // allow function declarations in branches, but only in non-strict mode
993 node.consequent = this.parseStatement("if");
994 node.alternate = this.eat(types._else) ? this.parseStatement("if") : null;
995 return this.finishNode(node, "IfStatement")
998 pp$1.parseReturnStatement = function(node) {
999 if (!this.inFunction && !this.options.allowReturnOutsideFunction)
1000 { this.raise(this.start, "'return' outside of function"); }
1003 // In `return` (and `break`/`continue`), the keywords with
1004 // optional arguments, we eagerly look for a semicolon or the
1005 // possibility to insert one.
1007 if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
1008 else { node.argument = this.parseExpression(); this.semicolon(); }
1009 return this.finishNode(node, "ReturnStatement")
1012 pp$1.parseSwitchStatement = function(node) {
1014 node.discriminant = this.parseParenExpression();
1016 this.expect(types.braceL);
1017 this.labels.push(switchLabel);
1020 // Statements under must be grouped (by label) in SwitchCase
1021 // nodes. `cur` is used to keep the node that we are currently
1022 // adding statements to.
1025 for (var sawDefault = false; this.type !== types.braceR;) {
1026 if (this.type === types._case || this.type === types._default) {
1027 var isCase = this.type === types._case;
1028 if (cur) { this.finishNode(cur, "SwitchCase"); }
1029 node.cases.push(cur = this.startNode());
1030 cur.consequent = [];
1033 cur.test = this.parseExpression();
1035 if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
1039 this.expect(types.colon);
1041 if (!cur) { this.unexpected(); }
1042 cur.consequent.push(this.parseStatement(null));
1046 if (cur) { this.finishNode(cur, "SwitchCase"); }
1047 this.next(); // Closing brace
1049 return this.finishNode(node, "SwitchStatement")
1052 pp$1.parseThrowStatement = function(node) {
1054 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
1055 { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
1056 node.argument = this.parseExpression();
1058 return this.finishNode(node, "ThrowStatement")
1061 // Reused empty array added for node fields that are always empty.
1065 pp$1.parseTryStatement = function(node) {
1067 node.block = this.parseBlock();
1068 node.handler = null;
1069 if (this.type === types._catch) {
1070 var clause = this.startNode();
1072 if (this.eat(types.parenL)) {
1073 clause.param = this.parseBindingAtom();
1074 var simple = clause.param.type === "Identifier";
1075 this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
1076 this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
1077 this.expect(types.parenR);
1079 if (this.options.ecmaVersion < 10) { this.unexpected(); }
1080 clause.param = null;
1083 clause.body = this.parseBlock(false);
1085 node.handler = this.finishNode(clause, "CatchClause");
1087 node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
1088 if (!node.handler && !node.finalizer)
1089 { this.raise(node.start, "Missing catch or finally clause"); }
1090 return this.finishNode(node, "TryStatement")
1093 pp$1.parseVarStatement = function(node, kind) {
1095 this.parseVar(node, false, kind);
1097 return this.finishNode(node, "VariableDeclaration")
1100 pp$1.parseWhileStatement = function(node) {
1102 node.test = this.parseParenExpression();
1103 this.labels.push(loopLabel);
1104 node.body = this.parseStatement("while");
1106 return this.finishNode(node, "WhileStatement")
1109 pp$1.parseWithStatement = function(node) {
1110 if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
1112 node.object = this.parseParenExpression();
1113 node.body = this.parseStatement("with");
1114 return this.finishNode(node, "WithStatement")
1117 pp$1.parseEmptyStatement = function(node) {
1119 return this.finishNode(node, "EmptyStatement")
1122 pp$1.parseLabeledStatement = function(node, maybeName, expr, context) {
1123 for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
1125 var label = list[i$1];
1127 if (label.name === maybeName)
1128 { this.raise(expr.start, "Label '" + maybeName + "' is already declared");
1130 var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
1131 for (var i = this.labels.length - 1; i >= 0; i--) {
1132 var label$1 = this.labels[i];
1133 if (label$1.statementStart === node.start) {
1134 // Update information about previous labels on this node
1135 label$1.statementStart = this.start;
1136 label$1.kind = kind;
1139 this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
1140 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
1143 return this.finishNode(node, "LabeledStatement")
1146 pp$1.parseExpressionStatement = function(node, expr) {
1147 node.expression = expr;
1149 return this.finishNode(node, "ExpressionStatement")
1152 // Parse a semicolon-enclosed block of statements, handling `"use
1153 // strict"` declarations when `allowStrict` is true (used for
1154 // function bodies).
1156 pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) {
1157 if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
1158 if ( node === void 0 ) node = this.startNode();
1161 this.expect(types.braceL);
1162 if (createNewLexicalScope) { this.enterScope(0); }
1163 while (this.type !== types.braceR) {
1164 var stmt = this.parseStatement(null);
1165 node.body.push(stmt);
1167 if (exitStrict) { this.strict = false; }
1169 if (createNewLexicalScope) { this.exitScope(); }
1170 return this.finishNode(node, "BlockStatement")
1173 // Parse a regular `for` loop. The disambiguation code in
1174 // `parseStatement` will already have parsed the init statement or
1177 pp$1.parseFor = function(node, init) {
1179 this.expect(types.semi);
1180 node.test = this.type === types.semi ? null : this.parseExpression();
1181 this.expect(types.semi);
1182 node.update = this.type === types.parenR ? null : this.parseExpression();
1183 this.expect(types.parenR);
1184 node.body = this.parseStatement("for");
1187 return this.finishNode(node, "ForStatement")
1190 // Parse a `for`/`in` and `for`/`of` loop, which are almost
1191 // same from parser's perspective.
1193 pp$1.parseForIn = function(node, init) {
1194 var isForIn = this.type === types._in;
1198 init.type === "VariableDeclaration" &&
1199 init.declarations[0].init != null &&
1202 this.options.ecmaVersion < 8 ||
1204 init.kind !== "var" ||
1205 init.declarations[0].id.type !== "Identifier"
1210 ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
1212 } else if (init.type === "AssignmentPattern") {
1213 this.raise(init.start, "Invalid left-hand side in for-loop");
1216 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
1217 this.expect(types.parenR);
1218 node.body = this.parseStatement("for");
1221 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
1224 // Parse a list of variable declarations.
1226 pp$1.parseVar = function(node, isFor, kind) {
1227 node.declarations = [];
1230 var decl = this.startNode();
1231 this.parseVarId(decl, kind);
1232 if (this.eat(types.eq)) {
1233 decl.init = this.parseMaybeAssign(isFor);
1234 } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
1236 } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) {
1237 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
1241 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
1242 if (!this.eat(types.comma)) { break }
1247 pp$1.parseVarId = function(decl, kind) {
1248 decl.id = this.parseBindingAtom();
1249 this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
1252 var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
1254 // Parse a function declaration or literal (depending on the
1255 // `statement & FUNC_STATEMENT`).
1257 // Remove `allowExpressionBody` for 7.0.0, as it is only called with false
1258 pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) {
1259 this.initFunction(node);
1260 if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
1261 if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT))
1262 { this.unexpected(); }
1263 node.generator = this.eat(types.star);
1265 if (this.options.ecmaVersion >= 8)
1266 { node.async = !!isAsync; }
1268 if (statement & FUNC_STATEMENT) {
1269 node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent();
1270 if (node.id && !(statement & FUNC_HANGING_STATEMENT))
1271 // If it is a regular function declaration in sloppy mode, then it is
1272 // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
1273 // mode depends on properties of the current scope (see
1274 // treatFunctionsAsVar).
1275 { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
1278 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
1281 this.awaitIdentPos = 0;
1282 this.enterScope(functionFlags(node.async, node.generator));
1284 if (!(statement & FUNC_STATEMENT))
1285 { node.id = this.type === types.name ? this.parseIdent() : null; }
1287 this.parseFunctionParams(node);
1288 this.parseFunctionBody(node, allowExpressionBody, false);
1290 this.yieldPos = oldYieldPos;
1291 this.awaitPos = oldAwaitPos;
1292 this.awaitIdentPos = oldAwaitIdentPos;
1293 return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
1296 pp$1.parseFunctionParams = function(node) {
1297 this.expect(types.parenL);
1298 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
1299 this.checkYieldAwaitInDefaultParams();
1302 // Parse a class declaration or literal (depending on the
1303 // `isStatement` parameter).
1305 pp$1.parseClass = function(node, isStatement) {
1308 // ecma-262 14.6 Class Definitions
1309 // A class definition is always strict mode code.
1310 var oldStrict = this.strict;
1313 this.parseClassId(node, isStatement);
1314 this.parseClassSuper(node);
1315 var classBody = this.startNode();
1316 var hadConstructor = false;
1317 classBody.body = [];
1318 this.expect(types.braceL);
1319 while (this.type !== types.braceR) {
1320 var element = this.parseClassElement(node.superClass !== null);
1322 classBody.body.push(element);
1323 if (element.type === "MethodDefinition" && element.kind === "constructor") {
1324 if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
1325 hadConstructor = true;
1329 this.strict = oldStrict;
1331 node.body = this.finishNode(classBody, "ClassBody");
1332 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
1335 pp$1.parseClassElement = function(constructorAllowsSuper) {
1338 if (this.eat(types.semi)) { return null }
1340 var method = this.startNode();
1341 var tryContextual = function (k, noLineBreak) {
1342 if ( noLineBreak === void 0 ) noLineBreak = false;
1344 var start = this$1.start, startLoc = this$1.startLoc;
1345 if (!this$1.eatContextual(k)) { return false }
1346 if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
1347 if (method.key) { this$1.unexpected(); }
1348 method.computed = false;
1349 method.key = this$1.startNodeAt(start, startLoc);
1350 method.key.name = k;
1351 this$1.finishNode(method.key, "Identifier");
1355 method.kind = "method";
1356 method.static = tryContextual("static");
1357 var isGenerator = this.eat(types.star);
1358 var isAsync = false;
1360 if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
1362 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
1363 } else if (tryContextual("get")) {
1364 method.kind = "get";
1365 } else if (tryContextual("set")) {
1366 method.kind = "set";
1369 if (!method.key) { this.parsePropertyName(method); }
1370 var key = method.key;
1371 var allowsDirectSuper = false;
1372 if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
1373 key.type === "Literal" && key.value === "constructor")) {
1374 if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
1375 if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
1376 if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
1377 method.kind = "constructor";
1378 allowsDirectSuper = constructorAllowsSuper;
1379 } else if (method.static && key.type === "Identifier" && key.name === "prototype") {
1380 this.raise(key.start, "Classes may not have a static property named prototype");
1382 this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper);
1383 if (method.kind === "get" && method.value.params.length !== 0)
1384 { this.raiseRecoverable(method.value.start, "getter should have no params"); }
1385 if (method.kind === "set" && method.value.params.length !== 1)
1386 { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
1387 if (method.kind === "set" && method.value.params[0].type === "RestElement")
1388 { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
1392 pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
1393 method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
1394 return this.finishNode(method, "MethodDefinition")
1397 pp$1.parseClassId = function(node, isStatement) {
1398 if (this.type === types.name) {
1399 node.id = this.parseIdent();
1401 { this.checkLVal(node.id, BIND_LEXICAL, false); }
1403 if (isStatement === true)
1404 { this.unexpected(); }
1409 pp$1.parseClassSuper = function(node) {
1410 node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
1413 // Parses module export declaration.
1415 pp$1.parseExport = function(node, exports) {
1417 // export * from '...'
1418 if (this.eat(types.star)) {
1419 if (this.options.ecmaVersion >= 11) {
1420 if (this.eatContextual("as")) {
1421 node.exported = this.parseIdent(true);
1422 this.checkExport(exports, node.exported.name, this.lastTokStart);
1424 node.exported = null;
1427 this.expectContextual("from");
1428 if (this.type !== types.string) { this.unexpected(); }
1429 node.source = this.parseExprAtom();
1431 return this.finishNode(node, "ExportAllDeclaration")
1433 if (this.eat(types._default)) { // export default ...
1434 this.checkExport(exports, "default", this.lastTokStart);
1436 if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
1437 var fNode = this.startNode();
1439 if (isAsync) { this.next(); }
1440 node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
1441 } else if (this.type === types._class) {
1442 var cNode = this.startNode();
1443 node.declaration = this.parseClass(cNode, "nullableID");
1445 node.declaration = this.parseMaybeAssign();
1448 return this.finishNode(node, "ExportDefaultDeclaration")
1450 // export var|const|let|function|class ...
1451 if (this.shouldParseExportStatement()) {
1452 node.declaration = this.parseStatement(null);
1453 if (node.declaration.type === "VariableDeclaration")
1454 { this.checkVariableExport(exports, node.declaration.declarations); }
1456 { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
1457 node.specifiers = [];
1459 } else { // export { x, y as z } [from '...']
1460 node.declaration = null;
1461 node.specifiers = this.parseExportSpecifiers(exports);
1462 if (this.eatContextual("from")) {
1463 if (this.type !== types.string) { this.unexpected(); }
1464 node.source = this.parseExprAtom();
1466 for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
1467 // check for keywords used as local names
1470 this.checkUnreserved(spec.local);
1471 // check if export is defined
1472 this.checkLocalExport(spec.local);
1479 return this.finishNode(node, "ExportNamedDeclaration")
1482 pp$1.checkExport = function(exports, name, pos) {
1483 if (!exports) { return }
1484 if (has(exports, name))
1485 { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
1486 exports[name] = true;
1489 pp$1.checkPatternExport = function(exports, pat) {
1490 var type = pat.type;
1491 if (type === "Identifier")
1492 { this.checkExport(exports, pat.name, pat.start); }
1493 else if (type === "ObjectPattern")
1494 { for (var i = 0, list = pat.properties; i < list.length; i += 1)
1498 this.checkPatternExport(exports, prop);
1500 else if (type === "ArrayPattern")
1501 { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
1502 var elt = list$1[i$1];
1504 if (elt) { this.checkPatternExport(exports, elt); }
1506 else if (type === "Property")
1507 { this.checkPatternExport(exports, pat.value); }
1508 else if (type === "AssignmentPattern")
1509 { this.checkPatternExport(exports, pat.left); }
1510 else if (type === "RestElement")
1511 { this.checkPatternExport(exports, pat.argument); }
1512 else if (type === "ParenthesizedExpression")
1513 { this.checkPatternExport(exports, pat.expression); }
1516 pp$1.checkVariableExport = function(exports, decls) {
1517 if (!exports) { return }
1518 for (var i = 0, list = decls; i < list.length; i += 1)
1522 this.checkPatternExport(exports, decl.id);
1526 pp$1.shouldParseExportStatement = function() {
1527 return this.type.keyword === "var" ||
1528 this.type.keyword === "const" ||
1529 this.type.keyword === "class" ||
1530 this.type.keyword === "function" ||
1532 this.isAsyncFunction()
1535 // Parses a comma-separated list of module exports.
1537 pp$1.parseExportSpecifiers = function(exports) {
1538 var nodes = [], first = true;
1539 // export { x, y as z } [from '...']
1540 this.expect(types.braceL);
1541 while (!this.eat(types.braceR)) {
1543 this.expect(types.comma);
1544 if (this.afterTrailingComma(types.braceR)) { break }
1545 } else { first = false; }
1547 var node = this.startNode();
1548 node.local = this.parseIdent(true);
1549 node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
1550 this.checkExport(exports, node.exported.name, node.exported.start);
1551 nodes.push(this.finishNode(node, "ExportSpecifier"));
1556 // Parses import declaration.
1558 pp$1.parseImport = function(node) {
1561 if (this.type === types.string) {
1562 node.specifiers = empty;
1563 node.source = this.parseExprAtom();
1565 node.specifiers = this.parseImportSpecifiers();
1566 this.expectContextual("from");
1567 node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
1570 return this.finishNode(node, "ImportDeclaration")
1573 // Parses a comma-separated list of module imports.
1575 pp$1.parseImportSpecifiers = function() {
1576 var nodes = [], first = true;
1577 if (this.type === types.name) {
1578 // import defaultObj, { x, y as z } from '...'
1579 var node = this.startNode();
1580 node.local = this.parseIdent();
1581 this.checkLVal(node.local, BIND_LEXICAL);
1582 nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
1583 if (!this.eat(types.comma)) { return nodes }
1585 if (this.type === types.star) {
1586 var node$1 = this.startNode();
1588 this.expectContextual("as");
1589 node$1.local = this.parseIdent();
1590 this.checkLVal(node$1.local, BIND_LEXICAL);
1591 nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
1594 this.expect(types.braceL);
1595 while (!this.eat(types.braceR)) {
1597 this.expect(types.comma);
1598 if (this.afterTrailingComma(types.braceR)) { break }
1599 } else { first = false; }
1601 var node$2 = this.startNode();
1602 node$2.imported = this.parseIdent(true);
1603 if (this.eatContextual("as")) {
1604 node$2.local = this.parseIdent();
1606 this.checkUnreserved(node$2.imported);
1607 node$2.local = node$2.imported;
1609 this.checkLVal(node$2.local, BIND_LEXICAL);
1610 nodes.push(this.finishNode(node$2, "ImportSpecifier"));
1615 // Set `ExpressionStatement#directive` property for directive prologues.
1616 pp$1.adaptDirectivePrologue = function(statements) {
1617 for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
1618 statements[i].directive = statements[i].expression.raw.slice(1, -1);
1621 pp$1.isDirectiveCandidate = function(statement) {
1623 statement.type === "ExpressionStatement" &&
1624 statement.expression.type === "Literal" &&
1625 typeof statement.expression.value === "string" &&
1626 // Reject parenthesized strings.
1627 (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
1631 var pp$2 = Parser.prototype;
1633 // Convert existing expression atom to assignable pattern
1636 pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {
1637 if (this.options.ecmaVersion >= 6 && node) {
1638 switch (node.type) {
1640 if (this.inAsync && node.name === "await")
1641 { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
1644 case "ObjectPattern":
1645 case "ArrayPattern":
1649 case "ObjectExpression":
1650 node.type = "ObjectPattern";
1651 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1652 for (var i = 0, list = node.properties; i < list.length; i += 1) {
1655 this.toAssignable(prop, isBinding);
1657 // AssignmentRestProperty[Yield, Await] :
1658 // `...` DestructuringAssignmentTarget[Yield, Await]
1660 // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
1662 prop.type === "RestElement" &&
1663 (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
1665 this.raise(prop.argument.start, "Unexpected token");
1671 // AssignmentProperty has type === "Property"
1672 if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
1673 this.toAssignable(node.value, isBinding);
1676 case "ArrayExpression":
1677 node.type = "ArrayPattern";
1678 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1679 this.toAssignableList(node.elements, isBinding);
1682 case "SpreadElement":
1683 node.type = "RestElement";
1684 this.toAssignable(node.argument, isBinding);
1685 if (node.argument.type === "AssignmentPattern")
1686 { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
1689 case "AssignmentExpression":
1690 if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
1691 node.type = "AssignmentPattern";
1692 delete node.operator;
1693 this.toAssignable(node.left, isBinding);
1694 // falls through to AssignmentPattern
1696 case "AssignmentPattern":
1699 case "ParenthesizedExpression":
1700 this.toAssignable(node.expression, isBinding, refDestructuringErrors);
1703 case "ChainExpression":
1704 this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
1707 case "MemberExpression":
1708 if (!isBinding) { break }
1711 this.raise(node.start, "Assigning to rvalue");
1713 } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1717 // Convert list of expression atoms to binding list.
1719 pp$2.toAssignableList = function(exprList, isBinding) {
1720 var end = exprList.length;
1721 for (var i = 0; i < end; i++) {
1722 var elt = exprList[i];
1723 if (elt) { this.toAssignable(elt, isBinding); }
1726 var last = exprList[end - 1];
1727 if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
1728 { this.unexpected(last.argument.start); }
1733 // Parses spread element.
1735 pp$2.parseSpread = function(refDestructuringErrors) {
1736 var node = this.startNode();
1738 node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
1739 return this.finishNode(node, "SpreadElement")
1742 pp$2.parseRestBinding = function() {
1743 var node = this.startNode();
1746 // RestElement inside of a function parameter must be an identifier
1747 if (this.options.ecmaVersion === 6 && this.type !== types.name)
1748 { this.unexpected(); }
1750 node.argument = this.parseBindingAtom();
1752 return this.finishNode(node, "RestElement")
1755 // Parses lvalue (assignable) atom.
1757 pp$2.parseBindingAtom = function() {
1758 if (this.options.ecmaVersion >= 6) {
1759 switch (this.type) {
1760 case types.bracketL:
1761 var node = this.startNode();
1763 node.elements = this.parseBindingList(types.bracketR, true, true);
1764 return this.finishNode(node, "ArrayPattern")
1767 return this.parseObj(true)
1770 return this.parseIdent()
1773 pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
1774 var elts = [], first = true;
1775 while (!this.eat(close)) {
1776 if (first) { first = false; }
1777 else { this.expect(types.comma); }
1778 if (allowEmpty && this.type === types.comma) {
1780 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
1782 } else if (this.type === types.ellipsis) {
1783 var rest = this.parseRestBinding();
1784 this.parseBindingListItem(rest);
1786 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
1790 var elem = this.parseMaybeDefault(this.start, this.startLoc);
1791 this.parseBindingListItem(elem);
1798 pp$2.parseBindingListItem = function(param) {
1802 // Parses assignment pattern around given atom if possible.
1804 pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
1805 left = left || this.parseBindingAtom();
1806 if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
1807 var node = this.startNodeAt(startPos, startLoc);
1809 node.right = this.parseMaybeAssign();
1810 return this.finishNode(node, "AssignmentPattern")
1813 // Verify that a node is an lval — something that can be assigned
1815 // bindingType can be either:
1816 // 'var' indicating that the lval creates a 'var' binding
1817 // 'let' indicating that the lval creates a lexical ('let' or 'const') binding
1818 // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references
1820 pp$2.checkLVal = function(expr, bindingType, checkClashes) {
1821 if ( bindingType === void 0 ) bindingType = BIND_NONE;
1823 switch (expr.type) {
1825 if (bindingType === BIND_LEXICAL && expr.name === "let")
1826 { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
1827 if (this.strict && this.reservedWordsStrictBind.test(expr.name))
1828 { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
1830 if (has(checkClashes, expr.name))
1831 { this.raiseRecoverable(expr.start, "Argument name clash"); }
1832 checkClashes[expr.name] = true;
1834 if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
1837 case "ChainExpression":
1838 this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
1841 case "MemberExpression":
1842 if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); }
1845 case "ObjectPattern":
1846 for (var i = 0, list = expr.properties; i < list.length; i += 1)
1850 this.checkLVal(prop, bindingType, checkClashes);
1855 // AssignmentProperty has type === "Property"
1856 this.checkLVal(expr.value, bindingType, checkClashes);
1859 case "ArrayPattern":
1860 for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
1861 var elem = list$1[i$1];
1863 if (elem) { this.checkLVal(elem, bindingType, checkClashes); }
1867 case "AssignmentPattern":
1868 this.checkLVal(expr.left, bindingType, checkClashes);
1872 this.checkLVal(expr.argument, bindingType, checkClashes);
1875 case "ParenthesizedExpression":
1876 this.checkLVal(expr.expression, bindingType, checkClashes);
1880 this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
1884 // A recursive descent parser operates by defining functions for all
1886 var pp$3 = Parser.prototype;
1888 // Check if property name clashes with already added.
1889 // Object/class getters and setters are not allowed to clash —
1890 // either with each other or with an init property — and in
1891 // strict mode, init properties are also not allowed to be repeated.
1893 pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {
1894 if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
1896 if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
1901 case "Identifier": name = key.name; break
1902 case "Literal": name = String(key.value); break
1905 var kind = prop.kind;
1906 if (this.options.ecmaVersion >= 6) {
1907 if (name === "__proto__" && kind === "init") {
1908 if (propHash.proto) {
1909 if (refDestructuringErrors) {
1910 if (refDestructuringErrors.doubleProto < 0)
1911 { refDestructuringErrors.doubleProto = key.start; }
1912 // Backwards-compat kludge. Can be removed in version 6.0
1913 } else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
1915 propHash.proto = true;
1920 var other = propHash[name];
1923 if (kind === "init") {
1924 redefinition = this.strict && other.init || other.get || other.set;
1926 redefinition = other.init || other[kind];
1929 { this.raiseRecoverable(key.start, "Redefinition of property"); }
1931 other = propHash[name] = {
1940 // ### Expression parsing
1942 // These nest, from the most general expression type at the top to
1943 // 'atomic', nondivisible expression types at the bottom. Most of
1944 // the functions will simply let the function(s) below them parse,
1945 // and, *if* the syntactic construct they handle is present, wrap
1946 // the AST node that the inner parser gave them in another node.
1948 // Parse a full expression. The optional arguments are used to
1949 // forbid the `in` operator (in for loops initalization expressions)
1950 // and provide reference for storing '=' operator inside shorthand
1951 // property assignment in contexts where both object expression
1952 // and object pattern might appear (so it's possible to raise
1953 // delayed syntax error at correct position).
1955 pp$3.parseExpression = function(noIn, refDestructuringErrors) {
1956 var startPos = this.start, startLoc = this.startLoc;
1957 var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
1958 if (this.type === types.comma) {
1959 var node = this.startNodeAt(startPos, startLoc);
1960 node.expressions = [expr];
1961 while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); }
1962 return this.finishNode(node, "SequenceExpression")
1967 // Parse an assignment expression. This includes applications of
1968 // operators like `+=`.
1970 pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
1971 if (this.isContextual("yield")) {
1972 if (this.inGenerator) { return this.parseYield(noIn) }
1973 // The tokenizer will assume an expression is allowed after
1974 // `yield`, but this isn't that kind of yield
1975 else { this.exprAllowed = false; }
1978 var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;
1979 if (refDestructuringErrors) {
1980 oldParenAssign = refDestructuringErrors.parenthesizedAssign;
1981 oldTrailingComma = refDestructuringErrors.trailingComma;
1982 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
1984 refDestructuringErrors = new DestructuringErrors;
1985 ownDestructuringErrors = true;
1988 var startPos = this.start, startLoc = this.startLoc;
1989 if (this.type === types.parenL || this.type === types.name)
1990 { this.potentialArrowAt = this.start; }
1991 var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
1992 if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
1993 if (this.type.isAssign) {
1994 var node = this.startNodeAt(startPos, startLoc);
1995 node.operator = this.value;
1996 node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;
1997 if (!ownDestructuringErrors) {
1998 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
2000 if (refDestructuringErrors.shorthandAssign >= node.left.start)
2001 { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly
2002 this.checkLVal(left);
2004 node.right = this.parseMaybeAssign(noIn);
2005 return this.finishNode(node, "AssignmentExpression")
2007 if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
2009 if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
2010 if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
2014 // Parse a ternary conditional (`?:`) operator.
2016 pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
2017 var startPos = this.start, startLoc = this.startLoc;
2018 var expr = this.parseExprOps(noIn, refDestructuringErrors);
2019 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2020 if (this.eat(types.question)) {
2021 var node = this.startNodeAt(startPos, startLoc);
2023 node.consequent = this.parseMaybeAssign();
2024 this.expect(types.colon);
2025 node.alternate = this.parseMaybeAssign(noIn);
2026 return this.finishNode(node, "ConditionalExpression")
2031 // Start the precedence parser.
2033 pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
2034 var startPos = this.start, startLoc = this.startLoc;
2035 var expr = this.parseMaybeUnary(refDestructuringErrors, false);
2036 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2037 return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
2040 // Parse binary operators with the operator precedence parsing
2041 // algorithm. `left` is the left-hand side of the operator.
2042 // `minPrec` provides context that allows the function to stop and
2043 // defer further parser to one of its callers when it encounters an
2044 // operator that has a lower precedence than the set it is parsing.
2046 pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
2047 var prec = this.type.binop;
2048 if (prec != null && (!noIn || this.type !== types._in)) {
2049 if (prec > minPrec) {
2050 var logical = this.type === types.logicalOR || this.type === types.logicalAND;
2051 var coalesce = this.type === types.coalesce;
2053 // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.
2054 // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.
2055 prec = types.logicalAND.binop;
2057 var op = this.value;
2059 var startPos = this.start, startLoc = this.startLoc;
2060 var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
2061 var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
2062 if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) {
2063 this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
2065 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
2071 pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
2072 var node = this.startNodeAt(startPos, startLoc);
2076 return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
2079 // Parse unary operators, both prefix and postfix.
2081 pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
2082 var startPos = this.start, startLoc = this.startLoc, expr;
2083 if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
2084 expr = this.parseAwait();
2086 } else if (this.type.prefix) {
2087 var node = this.startNode(), update = this.type === types.incDec;
2088 node.operator = this.value;
2091 node.argument = this.parseMaybeUnary(null, true);
2092 this.checkExpressionErrors(refDestructuringErrors, true);
2093 if (update) { this.checkLVal(node.argument); }
2094 else if (this.strict && node.operator === "delete" &&
2095 node.argument.type === "Identifier")
2096 { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
2097 else { sawUnary = true; }
2098 expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
2100 expr = this.parseExprSubscripts(refDestructuringErrors);
2101 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2102 while (this.type.postfix && !this.canInsertSemicolon()) {
2103 var node$1 = this.startNodeAt(startPos, startLoc);
2104 node$1.operator = this.value;
2105 node$1.prefix = false;
2106 node$1.argument = expr;
2107 this.checkLVal(expr);
2109 expr = this.finishNode(node$1, "UpdateExpression");
2113 if (!sawUnary && this.eat(types.starstar))
2114 { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
2119 // Parse call, dot, and `[]`-subscript expressions.
2121 pp$3.parseExprSubscripts = function(refDestructuringErrors) {
2122 var startPos = this.start, startLoc = this.startLoc;
2123 var expr = this.parseExprAtom(refDestructuringErrors);
2124 if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
2126 var result = this.parseSubscripts(expr, startPos, startLoc);
2127 if (refDestructuringErrors && result.type === "MemberExpression") {
2128 if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
2129 if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
2134 pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
2135 var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
2136 this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
2137 this.potentialArrowAt === base.start;
2138 var optionalChained = false;
2141 var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained);
2143 if (element.optional) { optionalChained = true; }
2144 if (element === base || element.type === "ArrowFunctionExpression") {
2145 if (optionalChained) {
2146 var chainNode = this.startNodeAt(startPos, startLoc);
2147 chainNode.expression = element;
2148 element = this.finishNode(chainNode, "ChainExpression");
2157 pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) {
2158 var optionalSupported = this.options.ecmaVersion >= 11;
2159 var optional = optionalSupported && this.eat(types.questionDot);
2160 if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
2162 var computed = this.eat(types.bracketL);
2163 if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) {
2164 var node = this.startNodeAt(startPos, startLoc);
2166 node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never");
2167 node.computed = !!computed;
2168 if (computed) { this.expect(types.bracketR); }
2169 if (optionalSupported) {
2170 node.optional = optional;
2172 base = this.finishNode(node, "MemberExpression");
2173 } else if (!noCalls && this.eat(types.parenL)) {
2174 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2177 this.awaitIdentPos = 0;
2178 var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
2179 if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) {
2180 this.checkPatternErrors(refDestructuringErrors, false);
2181 this.checkYieldAwaitInDefaultParams();
2182 if (this.awaitIdentPos > 0)
2183 { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
2184 this.yieldPos = oldYieldPos;
2185 this.awaitPos = oldAwaitPos;
2186 this.awaitIdentPos = oldAwaitIdentPos;
2187 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true)
2189 this.checkExpressionErrors(refDestructuringErrors, true);
2190 this.yieldPos = oldYieldPos || this.yieldPos;
2191 this.awaitPos = oldAwaitPos || this.awaitPos;
2192 this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
2193 var node$1 = this.startNodeAt(startPos, startLoc);
2194 node$1.callee = base;
2195 node$1.arguments = exprList;
2196 if (optionalSupported) {
2197 node$1.optional = optional;
2199 base = this.finishNode(node$1, "CallExpression");
2200 } else if (this.type === types.backQuote) {
2201 if (optional || optionalChained) {
2202 this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
2204 var node$2 = this.startNodeAt(startPos, startLoc);
2206 node$2.quasi = this.parseTemplate({isTagged: true});
2207 base = this.finishNode(node$2, "TaggedTemplateExpression");
2212 // Parse an atomic expression — either a single token that is an
2213 // expression, an expression started by a keyword like `function` or
2214 // `new`, or an expression wrapped in punctuation like `()`, `[]`,
2217 pp$3.parseExprAtom = function(refDestructuringErrors) {
2218 // If a division operator appears in an expression position, the
2219 // tokenizer got confused, and we force it to read a regexp instead.
2220 if (this.type === types.slash) { this.readRegexp(); }
2222 var node, canBeArrow = this.potentialArrowAt === this.start;
2223 switch (this.type) {
2225 if (!this.allowSuper)
2226 { this.raise(this.start, "'super' keyword outside a method"); }
2227 node = this.startNode();
2229 if (this.type === types.parenL && !this.allowDirectSuper)
2230 { this.raise(node.start, "super() call outside constructor of a subclass"); }
2231 // The `super` keyword can appear at below:
2233 // super [ Expression ]
2234 // super . IdentifierName
2236 // super ( Arguments )
2237 if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)
2238 { this.unexpected(); }
2239 return this.finishNode(node, "Super")
2242 node = this.startNode();
2244 return this.finishNode(node, "ThisExpression")
2247 var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
2248 var id = this.parseIdent(false);
2249 if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
2250 { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true) }
2251 if (canBeArrow && !this.canInsertSemicolon()) {
2252 if (this.eat(types.arrow))
2253 { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
2254 if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
2255 id = this.parseIdent(false);
2256 if (this.canInsertSemicolon() || !this.eat(types.arrow))
2257 { this.unexpected(); }
2258 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
2264 var value = this.value;
2265 node = this.parseLiteral(value.value);
2266 node.regex = {pattern: value.pattern, flags: value.flags};
2269 case types.num: case types.string:
2270 return this.parseLiteral(this.value)
2272 case types._null: case types._true: case types._false:
2273 node = this.startNode();
2274 node.value = this.type === types._null ? null : this.type === types._true;
2275 node.raw = this.type.keyword;
2277 return this.finishNode(node, "Literal")
2280 var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
2281 if (refDestructuringErrors) {
2282 if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
2283 { refDestructuringErrors.parenthesizedAssign = start; }
2284 if (refDestructuringErrors.parenthesizedBind < 0)
2285 { refDestructuringErrors.parenthesizedBind = start; }
2289 case types.bracketL:
2290 node = this.startNode();
2292 node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
2293 return this.finishNode(node, "ArrayExpression")
2296 return this.parseObj(false, refDestructuringErrors)
2298 case types._function:
2299 node = this.startNode();
2301 return this.parseFunction(node, 0)
2304 return this.parseClass(this.startNode(), false)
2307 return this.parseNew()
2309 case types.backQuote:
2310 return this.parseTemplate()
2313 if (this.options.ecmaVersion >= 11) {
2314 return this.parseExprImport()
2316 return this.unexpected()
2324 pp$3.parseExprImport = function() {
2325 var node = this.startNode();
2327 // Consume `import` as an identifier for `import.meta`.
2328 // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.
2329 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
2330 var meta = this.parseIdent(true);
2332 switch (this.type) {
2334 return this.parseDynamicImport(node)
2337 return this.parseImportMeta(node)
2343 pp$3.parseDynamicImport = function(node) {
2344 this.next(); // skip `(`
2346 // Parse node.source.
2347 node.source = this.parseMaybeAssign();
2350 if (!this.eat(types.parenR)) {
2351 var errorPos = this.start;
2352 if (this.eat(types.comma) && this.eat(types.parenR)) {
2353 this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
2355 this.unexpected(errorPos);
2359 return this.finishNode(node, "ImportExpression")
2362 pp$3.parseImportMeta = function(node) {
2363 this.next(); // skip `.`
2365 var containsEsc = this.containsEsc;
2366 node.property = this.parseIdent(true);
2368 if (node.property.name !== "meta")
2369 { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
2371 { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
2372 if (this.options.sourceType !== "module")
2373 { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
2375 return this.finishNode(node, "MetaProperty")
2378 pp$3.parseLiteral = function(value) {
2379 var node = this.startNode();
2381 node.raw = this.input.slice(this.start, this.end);
2382 if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); }
2384 return this.finishNode(node, "Literal")
2387 pp$3.parseParenExpression = function() {
2388 this.expect(types.parenL);
2389 var val = this.parseExpression();
2390 this.expect(types.parenR);
2394 pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
2395 var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
2396 if (this.options.ecmaVersion >= 6) {
2399 var innerStartPos = this.start, innerStartLoc = this.startLoc;
2400 var exprList = [], first = true, lastIsComma = false;
2401 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
2404 // Do not save awaitIdentPos to allow checking awaits nested in parameters
2405 while (this.type !== types.parenR) {
2406 first ? first = false : this.expect(types.comma);
2407 if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) {
2410 } else if (this.type === types.ellipsis) {
2411 spreadStart = this.start;
2412 exprList.push(this.parseParenItem(this.parseRestBinding()));
2413 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
2416 exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
2419 var innerEndPos = this.start, innerEndLoc = this.startLoc;
2420 this.expect(types.parenR);
2422 if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
2423 this.checkPatternErrors(refDestructuringErrors, false);
2424 this.checkYieldAwaitInDefaultParams();
2425 this.yieldPos = oldYieldPos;
2426 this.awaitPos = oldAwaitPos;
2427 return this.parseParenArrowList(startPos, startLoc, exprList)
2430 if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
2431 if (spreadStart) { this.unexpected(spreadStart); }
2432 this.checkExpressionErrors(refDestructuringErrors, true);
2433 this.yieldPos = oldYieldPos || this.yieldPos;
2434 this.awaitPos = oldAwaitPos || this.awaitPos;
2436 if (exprList.length > 1) {
2437 val = this.startNodeAt(innerStartPos, innerStartLoc);
2438 val.expressions = exprList;
2439 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
2444 val = this.parseParenExpression();
2447 if (this.options.preserveParens) {
2448 var par = this.startNodeAt(startPos, startLoc);
2449 par.expression = val;
2450 return this.finishNode(par, "ParenthesizedExpression")
2456 pp$3.parseParenItem = function(item) {
2460 pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
2461 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
2464 // New's precedence is slightly tricky. It must allow its argument to
2465 // be a `[]` or dot subscript expression, but not a call — at least,
2466 // not without wrapping it in parentheses. Thus, it uses the noCalls
2467 // argument to parseSubscripts to prevent it from consuming the
2472 pp$3.parseNew = function() {
2473 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
2474 var node = this.startNode();
2475 var meta = this.parseIdent(true);
2476 if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
2478 var containsEsc = this.containsEsc;
2479 node.property = this.parseIdent(true);
2480 if (node.property.name !== "target")
2481 { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
2483 { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
2484 if (!this.inNonArrowFunction())
2485 { this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); }
2486 return this.finishNode(node, "MetaProperty")
2488 var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import;
2489 node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
2490 if (isImport && node.callee.type === "ImportExpression") {
2491 this.raise(startPos, "Cannot use new with import()");
2493 if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }
2494 else { node.arguments = empty$1; }
2495 return this.finishNode(node, "NewExpression")
2498 // Parse template expression.
2500 pp$3.parseTemplateElement = function(ref) {
2501 var isTagged = ref.isTagged;
2503 var elem = this.startNode();
2504 if (this.type === types.invalidTemplate) {
2506 this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
2514 raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
2519 elem.tail = this.type === types.backQuote;
2520 return this.finishNode(elem, "TemplateElement")
2523 pp$3.parseTemplate = function(ref) {
2524 if ( ref === void 0 ) ref = {};
2525 var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
2527 var node = this.startNode();
2529 node.expressions = [];
2530 var curElt = this.parseTemplateElement({isTagged: isTagged});
2531 node.quasis = [curElt];
2532 while (!curElt.tail) {
2533 if (this.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); }
2534 this.expect(types.dollarBraceL);
2535 node.expressions.push(this.parseExpression());
2536 this.expect(types.braceR);
2537 node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
2540 return this.finishNode(node, "TemplateLiteral")
2543 pp$3.isAsyncProp = function(prop) {
2544 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
2545 (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)) &&
2546 !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
2549 // Parse an object literal or binding pattern.
2551 pp$3.parseObj = function(isPattern, refDestructuringErrors) {
2552 var node = this.startNode(), first = true, propHash = {};
2553 node.properties = [];
2555 while (!this.eat(types.braceR)) {
2557 this.expect(types.comma);
2558 if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break }
2559 } else { first = false; }
2561 var prop = this.parseProperty(isPattern, refDestructuringErrors);
2562 if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
2563 node.properties.push(prop);
2565 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
2568 pp$3.parseProperty = function(isPattern, refDestructuringErrors) {
2569 var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
2570 if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {
2572 prop.argument = this.parseIdent(false);
2573 if (this.type === types.comma) {
2574 this.raise(this.start, "Comma is not permitted after the rest element");
2576 return this.finishNode(prop, "RestElement")
2578 // To disallow parenthesized identifier via `this.toAssignable()`.
2579 if (this.type === types.parenL && refDestructuringErrors) {
2580 if (refDestructuringErrors.parenthesizedAssign < 0) {
2581 refDestructuringErrors.parenthesizedAssign = this.start;
2583 if (refDestructuringErrors.parenthesizedBind < 0) {
2584 refDestructuringErrors.parenthesizedBind = this.start;
2588 prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
2589 // To disallow trailing comma via `this.toAssignable()`.
2590 if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
2591 refDestructuringErrors.trailingComma = this.start;
2594 return this.finishNode(prop, "SpreadElement")
2596 if (this.options.ecmaVersion >= 6) {
2597 prop.method = false;
2598 prop.shorthand = false;
2599 if (isPattern || refDestructuringErrors) {
2600 startPos = this.start;
2601 startLoc = this.startLoc;
2604 { isGenerator = this.eat(types.star); }
2606 var containsEsc = this.containsEsc;
2607 this.parsePropertyName(prop);
2608 if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
2610 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
2611 this.parsePropertyName(prop, refDestructuringErrors);
2615 this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
2616 return this.finishNode(prop, "Property")
2619 pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
2620 if ((isGenerator || isAsync) && this.type === types.colon)
2621 { this.unexpected(); }
2623 if (this.eat(types.colon)) {
2624 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
2626 } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
2627 if (isPattern) { this.unexpected(); }
2630 prop.value = this.parseMethod(isGenerator, isAsync);
2631 } else if (!isPattern && !containsEsc &&
2632 this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
2633 (prop.key.name === "get" || prop.key.name === "set") &&
2634 (this.type !== types.comma && this.type !== types.braceR && this.type !== types.eq)) {
2635 if (isGenerator || isAsync) { this.unexpected(); }
2636 prop.kind = prop.key.name;
2637 this.parsePropertyName(prop);
2638 prop.value = this.parseMethod(false);
2639 var paramCount = prop.kind === "get" ? 0 : 1;
2640 if (prop.value.params.length !== paramCount) {
2641 var start = prop.value.start;
2642 if (prop.kind === "get")
2643 { this.raiseRecoverable(start, "getter should have no params"); }
2645 { this.raiseRecoverable(start, "setter should have exactly one param"); }
2647 if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
2648 { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
2650 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
2651 if (isGenerator || isAsync) { this.unexpected(); }
2652 this.checkUnreserved(prop.key);
2653 if (prop.key.name === "await" && !this.awaitIdentPos)
2654 { this.awaitIdentPos = startPos; }
2657 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
2658 } else if (this.type === types.eq && refDestructuringErrors) {
2659 if (refDestructuringErrors.shorthandAssign < 0)
2660 { refDestructuringErrors.shorthandAssign = this.start; }
2661 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
2663 prop.value = prop.key;
2665 prop.shorthand = true;
2666 } else { this.unexpected(); }
2669 pp$3.parsePropertyName = function(prop) {
2670 if (this.options.ecmaVersion >= 6) {
2671 if (this.eat(types.bracketL)) {
2672 prop.computed = true;
2673 prop.key = this.parseMaybeAssign();
2674 this.expect(types.bracketR);
2677 prop.computed = false;
2680 return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
2683 // Initialize empty function node.
2685 pp$3.initFunction = function(node) {
2687 if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
2688 if (this.options.ecmaVersion >= 8) { node.async = false; }
2691 // Parse object or class method.
2693 pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
2694 var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2696 this.initFunction(node);
2697 if (this.options.ecmaVersion >= 6)
2698 { node.generator = isGenerator; }
2699 if (this.options.ecmaVersion >= 8)
2700 { node.async = !!isAsync; }
2704 this.awaitIdentPos = 0;
2705 this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
2707 this.expect(types.parenL);
2708 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
2709 this.checkYieldAwaitInDefaultParams();
2710 this.parseFunctionBody(node, false, true);
2712 this.yieldPos = oldYieldPos;
2713 this.awaitPos = oldAwaitPos;
2714 this.awaitIdentPos = oldAwaitIdentPos;
2715 return this.finishNode(node, "FunctionExpression")
2718 // Parse arrow function expression with given parameters.
2720 pp$3.parseArrowExpression = function(node, params, isAsync) {
2721 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2723 this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
2724 this.initFunction(node);
2725 if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
2729 this.awaitIdentPos = 0;
2731 node.params = this.toAssignableList(params, true);
2732 this.parseFunctionBody(node, true, false);
2734 this.yieldPos = oldYieldPos;
2735 this.awaitPos = oldAwaitPos;
2736 this.awaitIdentPos = oldAwaitIdentPos;
2737 return this.finishNode(node, "ArrowFunctionExpression")
2740 // Parse function body and check parameters.
2742 pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) {
2743 var isExpression = isArrowFunction && this.type !== types.braceL;
2744 var oldStrict = this.strict, useStrict = false;
2747 node.body = this.parseMaybeAssign();
2748 node.expression = true;
2749 this.checkParams(node, false);
2751 var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
2752 if (!oldStrict || nonSimple) {
2753 useStrict = this.strictDirective(this.end);
2754 // If this is a strict mode function, verify that argument names
2755 // are not repeated, and it does not try to bind the words `eval`
2757 if (useStrict && nonSimple)
2758 { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
2760 // Start a new scope with regard to labels and the `inFunction`
2761 // flag (restore them to their old value afterwards).
2762 var oldLabels = this.labels;
2764 if (useStrict) { this.strict = true; }
2766 // Add the params to varDeclaredNames to ensure that an error is thrown
2767 // if a let/const declaration in the function clashes with one of the params.
2768 this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
2769 // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
2770 if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); }
2771 node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
2772 node.expression = false;
2773 this.adaptDirectivePrologue(node.body.body);
2774 this.labels = oldLabels;
2779 pp$3.isSimpleParamList = function(params) {
2780 for (var i = 0, list = params; i < list.length; i += 1)
2782 var param = list[i];
2784 if (param.type !== "Identifier") { return false
2789 // Checks function params for various disallowed patterns such as using "eval"
2790 // or "arguments" and duplicate parameters.
2792 pp$3.checkParams = function(node, allowDuplicates) {
2794 for (var i = 0, list = node.params; i < list.length; i += 1)
2796 var param = list[i];
2798 this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash);
2802 // Parses a comma-separated list of expressions, and returns them as
2803 // an array. `close` is the token type that ends the list, and
2804 // `allowEmpty` can be turned on to allow subsequent commas with
2805 // nothing in between them to be parsed as `null` (which is needed
2806 // for array literals).
2808 pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
2809 var elts = [], first = true;
2810 while (!this.eat(close)) {
2812 this.expect(types.comma);
2813 if (allowTrailingComma && this.afterTrailingComma(close)) { break }
2814 } else { first = false; }
2817 if (allowEmpty && this.type === types.comma)
2819 else if (this.type === types.ellipsis) {
2820 elt = this.parseSpread(refDestructuringErrors);
2821 if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0)
2822 { refDestructuringErrors.trailingComma = this.start; }
2824 elt = this.parseMaybeAssign(false, refDestructuringErrors);
2831 pp$3.checkUnreserved = function(ref) {
2832 var start = ref.start;
2834 var name = ref.name;
2836 if (this.inGenerator && name === "yield")
2837 { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
2838 if (this.inAsync && name === "await")
2839 { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
2840 if (this.keywords.test(name))
2841 { this.raise(start, ("Unexpected keyword '" + name + "'")); }
2842 if (this.options.ecmaVersion < 6 &&
2843 this.input.slice(start, end).indexOf("\\") !== -1) { return }
2844 var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
2845 if (re.test(name)) {
2846 if (!this.inAsync && name === "await")
2847 { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
2848 this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
2852 // Parse the next token as an identifier. If `liberal` is true (used
2853 // when parsing properties), it will also convert keywords into
2856 pp$3.parseIdent = function(liberal, isBinding) {
2857 var node = this.startNode();
2858 if (this.type === types.name) {
2859 node.name = this.value;
2860 } else if (this.type.keyword) {
2861 node.name = this.type.keyword;
2863 // To fix https://github.com/acornjs/acorn/issues/575
2864 // `class` and `function` keywords push new context into this.context.
2865 // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
2866 // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
2867 if ((node.name === "class" || node.name === "function") &&
2868 (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
2874 this.next(!!liberal);
2875 this.finishNode(node, "Identifier");
2877 this.checkUnreserved(node);
2878 if (node.name === "await" && !this.awaitIdentPos)
2879 { this.awaitIdentPos = node.start; }
2884 // Parses yield expression inside generator.
2886 pp$3.parseYield = function(noIn) {
2887 if (!this.yieldPos) { this.yieldPos = this.start; }
2889 var node = this.startNode();
2891 if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {
2892 node.delegate = false;
2893 node.argument = null;
2895 node.delegate = this.eat(types.star);
2896 node.argument = this.parseMaybeAssign(noIn);
2898 return this.finishNode(node, "YieldExpression")
2901 pp$3.parseAwait = function() {
2902 if (!this.awaitPos) { this.awaitPos = this.start; }
2904 var node = this.startNode();
2906 node.argument = this.parseMaybeUnary(null, false);
2907 return this.finishNode(node, "AwaitExpression")
2910 var pp$4 = Parser.prototype;
2912 // This function is used to raise exceptions on parse errors. It
2913 // takes an offset integer (into the current `input`) to indicate
2914 // the location of the error, attaches the position to the end
2915 // of the error message, and then raises a `SyntaxError` with that
2918 pp$4.raise = function(pos, message) {
2919 var loc = getLineInfo(this.input, pos);
2920 message += " (" + loc.line + ":" + loc.column + ")";
2921 var err = new SyntaxError(message);
2922 err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
2926 pp$4.raiseRecoverable = pp$4.raise;
2928 pp$4.curPosition = function() {
2929 if (this.options.locations) {
2930 return new Position(this.curLine, this.pos - this.lineStart)
2934 var pp$5 = Parser.prototype;
2936 var Scope = function Scope(flags) {
2938 // A list of var-declared names in the current lexical scope
2940 // A list of lexically-declared names in the current lexical scope
2942 // A list of lexically-declared FunctionDeclaration names in the current lexical scope
2943 this.functions = [];
2946 // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
2948 pp$5.enterScope = function(flags) {
2949 this.scopeStack.push(new Scope(flags));
2952 pp$5.exitScope = function() {
2953 this.scopeStack.pop();
2957 // > At the top level of a function, or script, function declarations are
2958 // > treated like var declarations rather than like lexical declarations.
2959 pp$5.treatFunctionsAsVarInScope = function(scope) {
2960 return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
2963 pp$5.declareName = function(name, bindingType, pos) {
2964 var redeclared = false;
2965 if (bindingType === BIND_LEXICAL) {
2966 var scope = this.currentScope();
2967 redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
2968 scope.lexical.push(name);
2969 if (this.inModule && (scope.flags & SCOPE_TOP))
2970 { delete this.undefinedExports[name]; }
2971 } else if (bindingType === BIND_SIMPLE_CATCH) {
2972 var scope$1 = this.currentScope();
2973 scope$1.lexical.push(name);
2974 } else if (bindingType === BIND_FUNCTION) {
2975 var scope$2 = this.currentScope();
2976 if (this.treatFunctionsAsVar)
2977 { redeclared = scope$2.lexical.indexOf(name) > -1; }
2979 { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
2980 scope$2.functions.push(name);
2982 for (var i = this.scopeStack.length - 1; i >= 0; --i) {
2983 var scope$3 = this.scopeStack[i];
2984 if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
2985 !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
2989 scope$3.var.push(name);
2990 if (this.inModule && (scope$3.flags & SCOPE_TOP))
2991 { delete this.undefinedExports[name]; }
2992 if (scope$3.flags & SCOPE_VAR) { break }
2995 if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
2998 pp$5.checkLocalExport = function(id) {
2999 // scope.functions must be empty as Module code is always strict.
3000 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
3001 this.scopeStack[0].var.indexOf(id.name) === -1) {
3002 this.undefinedExports[id.name] = id;
3006 pp$5.currentScope = function() {
3007 return this.scopeStack[this.scopeStack.length - 1]
3010 pp$5.currentVarScope = function() {
3011 for (var i = this.scopeStack.length - 1;; i--) {
3012 var scope = this.scopeStack[i];
3013 if (scope.flags & SCOPE_VAR) { return scope }
3017 // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
3018 pp$5.currentThisScope = function() {
3019 for (var i = this.scopeStack.length - 1;; i--) {
3020 var scope = this.scopeStack[i];
3021 if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }
3025 var Node = function Node(parser, pos, loc) {
3029 if (parser.options.locations)
3030 { this.loc = new SourceLocation(parser, loc); }
3031 if (parser.options.directSourceFile)
3032 { this.sourceFile = parser.options.directSourceFile; }
3033 if (parser.options.ranges)
3034 { this.range = [pos, 0]; }
3037 // Start an AST node, attaching a start offset.
3039 var pp$6 = Parser.prototype;
3041 pp$6.startNode = function() {
3042 return new Node(this, this.start, this.startLoc)
3045 pp$6.startNodeAt = function(pos, loc) {
3046 return new Node(this, pos, loc)
3049 // Finish an AST node, adding `type` and `end` properties.
3051 function finishNodeAt(node, type, pos, loc) {
3054 if (this.options.locations)
3055 { node.loc.end = loc; }
3056 if (this.options.ranges)
3057 { node.range[1] = pos; }
3061 pp$6.finishNode = function(node, type) {
3062 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
3065 // Finish node at given position
3067 pp$6.finishNodeAt = function(node, type, pos, loc) {
3068 return finishNodeAt.call(this, node, type, pos, loc)
3071 // The algorithm used to determine whether a regexp can appear at a
3073 var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
3075 this.isExpr = !!isExpr;
3076 this.preserveSpace = !!preserveSpace;
3077 this.override = override;
3078 this.generator = !!generator;
3082 b_stat: new TokContext("{", false),
3083 b_expr: new TokContext("{", true),
3084 b_tmpl: new TokContext("${", false),
3085 p_stat: new TokContext("(", false),
3086 p_expr: new TokContext("(", true),
3087 q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
3088 f_stat: new TokContext("function", false),
3089 f_expr: new TokContext("function", true),
3090 f_expr_gen: new TokContext("function", true, false, null, true),
3091 f_gen: new TokContext("function", false, false, null, true)
3094 var pp$7 = Parser.prototype;
3096 pp$7.initialContext = function() {
3097 return [types$1.b_stat]
3100 pp$7.braceIsBlock = function(prevType) {
3101 var parent = this.curContext();
3102 if (parent === types$1.f_expr || parent === types$1.f_stat)
3104 if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
3105 { return !parent.isExpr }
3107 // The check for `tt.name && exprAllowed` detects whether we are
3108 // after a `yield` or `of` construct. See the `updateContext` for
3110 if (prevType === types._return || prevType === types.name && this.exprAllowed)
3111 { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
3112 if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)
3114 if (prevType === types.braceL)
3115 { return parent === types$1.b_stat }
3116 if (prevType === types._var || prevType === types._const || prevType === types.name)
3118 return !this.exprAllowed
3121 pp$7.inGeneratorContext = function() {
3122 for (var i = this.context.length - 1; i >= 1; i--) {
3123 var context = this.context[i];
3124 if (context.token === "function")
3125 { return context.generator }
3130 pp$7.updateContext = function(prevType) {
3131 var update, type = this.type;
3132 if (type.keyword && prevType === types.dot)
3133 { this.exprAllowed = false; }
3134 else if (update = type.updateContext)
3135 { update.call(this, prevType); }
3137 { this.exprAllowed = type.beforeExpr; }
3140 // Token-specific context update code
3142 types.parenR.updateContext = types.braceR.updateContext = function() {
3143 if (this.context.length === 1) {
3144 this.exprAllowed = true;
3147 var out = this.context.pop();
3148 if (out === types$1.b_stat && this.curContext().token === "function") {
3149 out = this.context.pop();
3151 this.exprAllowed = !out.isExpr;
3154 types.braceL.updateContext = function(prevType) {
3155 this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
3156 this.exprAllowed = true;
3159 types.dollarBraceL.updateContext = function() {
3160 this.context.push(types$1.b_tmpl);
3161 this.exprAllowed = true;
3164 types.parenL.updateContext = function(prevType) {
3165 var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
3166 this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
3167 this.exprAllowed = true;
3170 types.incDec.updateContext = function() {
3171 // tokExprAllowed stays unchanged
3174 types._function.updateContext = types._class.updateContext = function(prevType) {
3175 if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
3176 !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
3177 !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
3178 { this.context.push(types$1.f_expr); }
3180 { this.context.push(types$1.f_stat); }
3181 this.exprAllowed = false;
3184 types.backQuote.updateContext = function() {
3185 if (this.curContext() === types$1.q_tmpl)
3186 { this.context.pop(); }
3188 { this.context.push(types$1.q_tmpl); }
3189 this.exprAllowed = false;
3192 types.star.updateContext = function(prevType) {
3193 if (prevType === types._function) {
3194 var index = this.context.length - 1;
3195 if (this.context[index] === types$1.f_expr)
3196 { this.context[index] = types$1.f_expr_gen; }
3198 { this.context[index] = types$1.f_gen; }
3200 this.exprAllowed = true;
3203 types.name.updateContext = function(prevType) {
3204 var allowed = false;
3205 if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {
3206 if (this.value === "of" && !this.exprAllowed ||
3207 this.value === "yield" && this.inGeneratorContext())
3210 this.exprAllowed = allowed;
3213 // This file contains Unicode properties extracted from the ECMAScript
3214 // specification. The lists are extracted like so:
3215 // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
3217 // #table-binary-unicode-properties
3218 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";
3219 var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
3220 var ecma11BinaryProperties = ecma10BinaryProperties;
3221 var unicodeBinaryProperties = {
3222 9: ecma9BinaryProperties,
3223 10: ecma10BinaryProperties,
3224 11: ecma11BinaryProperties
3227 // #table-unicode-general-category-values
3228 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";
3230 // #table-unicode-script-values
3231 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";
3232 var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
3233 var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
3234 var unicodeScriptValues = {
3235 9: ecma9ScriptValues,
3236 10: ecma10ScriptValues,
3237 11: ecma11ScriptValues
3241 function buildUnicodeData(ecmaVersion) {
3242 var d = data[ecmaVersion] = {
3243 binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
3245 General_Category: wordsRegexp(unicodeGeneralCategoryValues),
3246 Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
3249 d.nonBinary.Script_Extensions = d.nonBinary.Script;
3251 d.nonBinary.gc = d.nonBinary.General_Category;
3252 d.nonBinary.sc = d.nonBinary.Script;
3253 d.nonBinary.scx = d.nonBinary.Script_Extensions;
3255 buildUnicodeData(9);
3256 buildUnicodeData(10);
3257 buildUnicodeData(11);
3259 var pp$8 = Parser.prototype;
3261 var RegExpValidationState = function RegExpValidationState(parser) {
3262 this.parser = parser;
3263 this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
3264 this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion];
3268 this.switchU = false;
3269 this.switchN = false;
3271 this.lastIntValue = 0;
3272 this.lastStringValue = "";
3273 this.lastAssertionIsQuantifiable = false;
3274 this.numCapturingParens = 0;
3275 this.maxBackReference = 0;
3276 this.groupNames = [];
3277 this.backReferenceNames = [];
3280 RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
3281 var unicode = flags.indexOf("u") !== -1;
3282 this.start = start | 0;
3283 this.source = pattern + "";
3285 this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
3286 this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
3289 RegExpValidationState.prototype.raise = function raise (message) {
3290 this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
3293 // If u flag is given, this returns the code point at the index (it combines a surrogate pair).
3294 // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
3295 RegExpValidationState.prototype.at = function at (i, forceU) {
3296 if ( forceU === void 0 ) forceU = false;
3298 var s = this.source;
3303 var c = s.charCodeAt(i);
3304 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
3307 var next = s.charCodeAt(i + 1);
3308 return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
3311 RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
3312 if ( forceU === void 0 ) forceU = false;
3314 var s = this.source;
3319 var c = s.charCodeAt(i), next;
3320 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
3321 (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
3327 RegExpValidationState.prototype.current = function current (forceU) {
3328 if ( forceU === void 0 ) forceU = false;
3330 return this.at(this.pos, forceU)
3333 RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
3334 if ( forceU === void 0 ) forceU = false;
3336 return this.at(this.nextIndex(this.pos, forceU), forceU)
3339 RegExpValidationState.prototype.advance = function advance (forceU) {
3340 if ( forceU === void 0 ) forceU = false;
3342 this.pos = this.nextIndex(this.pos, forceU);
3345 RegExpValidationState.prototype.eat = function eat (ch, forceU) {
3346 if ( forceU === void 0 ) forceU = false;
3348 if (this.current(forceU) === ch) {
3349 this.advance(forceU);
3355 function codePointToString(ch) {
3356 if (ch <= 0xFFFF) { return String.fromCharCode(ch) }
3358 return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
3362 * Validate the flags part of a given RegExpLiteral.
3364 * @param {RegExpValidationState} state The state to validate RegExp.
3367 pp$8.validateRegExpFlags = function(state) {
3368 var validFlags = state.validFlags;
3369 var flags = state.flags;
3371 for (var i = 0; i < flags.length; i++) {
3372 var flag = flags.charAt(i);
3373 if (validFlags.indexOf(flag) === -1) {
3374 this.raise(state.start, "Invalid regular expression flag");
3376 if (flags.indexOf(flag, i + 1) > -1) {
3377 this.raise(state.start, "Duplicate regular expression flag");
3383 * Validate the pattern part of a given RegExpLiteral.
3385 * @param {RegExpValidationState} state The state to validate RegExp.
3388 pp$8.validateRegExpPattern = function(state) {
3389 this.regexp_pattern(state);
3391 // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
3392 // parsing contains a |GroupName|, reparse with the goal symbol
3393 // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
3394 // exception if _P_ did not conform to the grammar, if any elements of _P_
3395 // were not matched by the parse, or if any Early Error conditions exist.
3396 if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
3397 state.switchN = true;
3398 this.regexp_pattern(state);
3402 // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
3403 pp$8.regexp_pattern = function(state) {
3405 state.lastIntValue = 0;
3406 state.lastStringValue = "";
3407 state.lastAssertionIsQuantifiable = false;
3408 state.numCapturingParens = 0;
3409 state.maxBackReference = 0;
3410 state.groupNames.length = 0;
3411 state.backReferenceNames.length = 0;
3413 this.regexp_disjunction(state);
3415 if (state.pos !== state.source.length) {
3416 // Make the same messages as V8.
3417 if (state.eat(0x29 /* ) */)) {
3418 state.raise("Unmatched ')'");
3420 if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {
3421 state.raise("Lone quantifier brackets");
3424 if (state.maxBackReference > state.numCapturingParens) {
3425 state.raise("Invalid escape");
3427 for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
3430 if (state.groupNames.indexOf(name) === -1) {
3431 state.raise("Invalid named capture referenced");
3436 // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
3437 pp$8.regexp_disjunction = function(state) {
3438 this.regexp_alternative(state);
3439 while (state.eat(0x7C /* | */)) {
3440 this.regexp_alternative(state);
3443 // Make the same message as V8.
3444 if (this.regexp_eatQuantifier(state, true)) {
3445 state.raise("Nothing to repeat");
3447 if (state.eat(0x7B /* { */)) {
3448 state.raise("Lone quantifier brackets");
3452 // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
3453 pp$8.regexp_alternative = function(state) {
3454 while (state.pos < state.source.length && this.regexp_eatTerm(state))
3458 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
3459 pp$8.regexp_eatTerm = function(state) {
3460 if (this.regexp_eatAssertion(state)) {
3461 // Handle `QuantifiableAssertion Quantifier` alternative.
3462 // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
3463 // is a QuantifiableAssertion.
3464 if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
3465 // Make the same message as V8.
3466 if (state.switchU) {
3467 state.raise("Invalid quantifier");
3473 if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
3474 this.regexp_eatQuantifier(state);
3481 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
3482 pp$8.regexp_eatAssertion = function(state) {
3483 var start = state.pos;
3484 state.lastAssertionIsQuantifiable = false;
3487 if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
3492 if (state.eat(0x5C /* \ */)) {
3493 if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
3499 // Lookahead / Lookbehind
3500 if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
3501 var lookbehind = false;
3502 if (this.options.ecmaVersion >= 9) {
3503 lookbehind = state.eat(0x3C /* < */);
3505 if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
3506 this.regexp_disjunction(state);
3507 if (!state.eat(0x29 /* ) */)) {
3508 state.raise("Unterminated group");
3510 state.lastAssertionIsQuantifiable = !lookbehind;
3519 // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
3520 pp$8.regexp_eatQuantifier = function(state, noError) {
3521 if ( noError === void 0 ) noError = false;
3523 if (this.regexp_eatQuantifierPrefix(state, noError)) {
3524 state.eat(0x3F /* ? */);
3530 // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
3531 pp$8.regexp_eatQuantifierPrefix = function(state, noError) {
3533 state.eat(0x2A /* * */) ||
3534 state.eat(0x2B /* + */) ||
3535 state.eat(0x3F /* ? */) ||
3536 this.regexp_eatBracedQuantifier(state, noError)
3539 pp$8.regexp_eatBracedQuantifier = function(state, noError) {
3540 var start = state.pos;
3541 if (state.eat(0x7B /* { */)) {
3542 var min = 0, max = -1;
3543 if (this.regexp_eatDecimalDigits(state)) {
3544 min = state.lastIntValue;
3545 if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
3546 max = state.lastIntValue;
3548 if (state.eat(0x7D /* } */)) {
3549 // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
3550 if (max !== -1 && max < min && !noError) {
3551 state.raise("numbers out of order in {} quantifier");
3556 if (state.switchU && !noError) {
3557 state.raise("Incomplete quantifier");
3564 // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
3565 pp$8.regexp_eatAtom = function(state) {
3567 this.regexp_eatPatternCharacters(state) ||
3568 state.eat(0x2E /* . */) ||
3569 this.regexp_eatReverseSolidusAtomEscape(state) ||
3570 this.regexp_eatCharacterClass(state) ||
3571 this.regexp_eatUncapturingGroup(state) ||
3572 this.regexp_eatCapturingGroup(state)
3575 pp$8.regexp_eatReverseSolidusAtomEscape = function(state) {
3576 var start = state.pos;
3577 if (state.eat(0x5C /* \ */)) {
3578 if (this.regexp_eatAtomEscape(state)) {
3585 pp$8.regexp_eatUncapturingGroup = function(state) {
3586 var start = state.pos;
3587 if (state.eat(0x28 /* ( */)) {
3588 if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
3589 this.regexp_disjunction(state);
3590 if (state.eat(0x29 /* ) */)) {
3593 state.raise("Unterminated group");
3599 pp$8.regexp_eatCapturingGroup = function(state) {
3600 if (state.eat(0x28 /* ( */)) {
3601 if (this.options.ecmaVersion >= 9) {
3602 this.regexp_groupSpecifier(state);
3603 } else if (state.current() === 0x3F /* ? */) {
3604 state.raise("Invalid group");
3606 this.regexp_disjunction(state);
3607 if (state.eat(0x29 /* ) */)) {
3608 state.numCapturingParens += 1;
3611 state.raise("Unterminated group");
3616 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
3617 pp$8.regexp_eatExtendedAtom = function(state) {
3619 state.eat(0x2E /* . */) ||
3620 this.regexp_eatReverseSolidusAtomEscape(state) ||
3621 this.regexp_eatCharacterClass(state) ||
3622 this.regexp_eatUncapturingGroup(state) ||
3623 this.regexp_eatCapturingGroup(state) ||
3624 this.regexp_eatInvalidBracedQuantifier(state) ||
3625 this.regexp_eatExtendedPatternCharacter(state)
3629 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
3630 pp$8.regexp_eatInvalidBracedQuantifier = function(state) {
3631 if (this.regexp_eatBracedQuantifier(state, true)) {
3632 state.raise("Nothing to repeat");
3637 // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
3638 pp$8.regexp_eatSyntaxCharacter = function(state) {
3639 var ch = state.current();
3640 if (isSyntaxCharacter(ch)) {
3641 state.lastIntValue = ch;
3647 function isSyntaxCharacter(ch) {
3649 ch === 0x24 /* $ */ ||
3650 ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
3651 ch === 0x2E /* . */ ||
3652 ch === 0x3F /* ? */ ||
3653 ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
3654 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
3658 // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
3660 pp$8.regexp_eatPatternCharacters = function(state) {
3661 var start = state.pos;
3663 while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
3666 return state.pos !== start
3669 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
3670 pp$8.regexp_eatExtendedPatternCharacter = function(state) {
3671 var ch = state.current();
3674 ch !== 0x24 /* $ */ &&
3675 !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
3676 ch !== 0x2E /* . */ &&
3677 ch !== 0x3F /* ? */ &&
3678 ch !== 0x5B /* [ */ &&
3679 ch !== 0x5E /* ^ */ &&
3688 // GroupSpecifier ::
3691 pp$8.regexp_groupSpecifier = function(state) {
3692 if (state.eat(0x3F /* ? */)) {
3693 if (this.regexp_eatGroupName(state)) {
3694 if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
3695 state.raise("Duplicate capture group name");
3697 state.groupNames.push(state.lastStringValue);
3700 state.raise("Invalid group");
3705 // `<` RegExpIdentifierName `>`
3706 // Note: this updates `state.lastStringValue` property with the eaten name.
3707 pp$8.regexp_eatGroupName = function(state) {
3708 state.lastStringValue = "";
3709 if (state.eat(0x3C /* < */)) {
3710 if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
3713 state.raise("Invalid capture group name");
3718 // RegExpIdentifierName ::
3719 // RegExpIdentifierStart
3720 // RegExpIdentifierName RegExpIdentifierPart
3721 // Note: this updates `state.lastStringValue` property with the eaten name.
3722 pp$8.regexp_eatRegExpIdentifierName = function(state) {
3723 state.lastStringValue = "";
3724 if (this.regexp_eatRegExpIdentifierStart(state)) {
3725 state.lastStringValue += codePointToString(state.lastIntValue);
3726 while (this.regexp_eatRegExpIdentifierPart(state)) {
3727 state.lastStringValue += codePointToString(state.lastIntValue);
3734 // RegExpIdentifierStart ::
3738 // `\` RegExpUnicodeEscapeSequence[+U]
3739 pp$8.regexp_eatRegExpIdentifierStart = function(state) {
3740 var start = state.pos;
3741 var forceU = this.options.ecmaVersion >= 11;
3742 var ch = state.current(forceU);
3743 state.advance(forceU);
3745 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
3746 ch = state.lastIntValue;
3748 if (isRegExpIdentifierStart(ch)) {
3749 state.lastIntValue = ch;
3756 function isRegExpIdentifierStart(ch) {
3757 return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
3760 // RegExpIdentifierPart ::
3761 // UnicodeIDContinue
3764 // `\` RegExpUnicodeEscapeSequence[+U]
3767 pp$8.regexp_eatRegExpIdentifierPart = function(state) {
3768 var start = state.pos;
3769 var forceU = this.options.ecmaVersion >= 11;
3770 var ch = state.current(forceU);
3771 state.advance(forceU);
3773 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
3774 ch = state.lastIntValue;
3776 if (isRegExpIdentifierPart(ch)) {
3777 state.lastIntValue = ch;
3784 function isRegExpIdentifierPart(ch) {
3785 return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
3788 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
3789 pp$8.regexp_eatAtomEscape = function(state) {
3791 this.regexp_eatBackReference(state) ||
3792 this.regexp_eatCharacterClassEscape(state) ||
3793 this.regexp_eatCharacterEscape(state) ||
3794 (state.switchN && this.regexp_eatKGroupName(state))
3798 if (state.switchU) {
3799 // Make the same message as V8.
3800 if (state.current() === 0x63 /* c */) {
3801 state.raise("Invalid unicode escape");
3803 state.raise("Invalid escape");
3807 pp$8.regexp_eatBackReference = function(state) {
3808 var start = state.pos;
3809 if (this.regexp_eatDecimalEscape(state)) {
3810 var n = state.lastIntValue;
3811 if (state.switchU) {
3812 // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
3813 if (n > state.maxBackReference) {
3814 state.maxBackReference = n;
3818 if (n <= state.numCapturingParens) {
3825 pp$8.regexp_eatKGroupName = function(state) {
3826 if (state.eat(0x6B /* k */)) {
3827 if (this.regexp_eatGroupName(state)) {
3828 state.backReferenceNames.push(state.lastStringValue);
3831 state.raise("Invalid named reference");
3836 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
3837 pp$8.regexp_eatCharacterEscape = function(state) {
3839 this.regexp_eatControlEscape(state) ||
3840 this.regexp_eatCControlLetter(state) ||
3841 this.regexp_eatZero(state) ||
3842 this.regexp_eatHexEscapeSequence(state) ||
3843 this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
3844 (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
3845 this.regexp_eatIdentityEscape(state)
3848 pp$8.regexp_eatCControlLetter = function(state) {
3849 var start = state.pos;
3850 if (state.eat(0x63 /* c */)) {
3851 if (this.regexp_eatControlLetter(state)) {
3858 pp$8.regexp_eatZero = function(state) {
3859 if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
3860 state.lastIntValue = 0;
3867 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
3868 pp$8.regexp_eatControlEscape = function(state) {
3869 var ch = state.current();
3870 if (ch === 0x74 /* t */) {
3871 state.lastIntValue = 0x09; /* \t */
3875 if (ch === 0x6E /* n */) {
3876 state.lastIntValue = 0x0A; /* \n */
3880 if (ch === 0x76 /* v */) {
3881 state.lastIntValue = 0x0B; /* \v */
3885 if (ch === 0x66 /* f */) {
3886 state.lastIntValue = 0x0C; /* \f */
3890 if (ch === 0x72 /* r */) {
3891 state.lastIntValue = 0x0D; /* \r */
3898 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
3899 pp$8.regexp_eatControlLetter = function(state) {
3900 var ch = state.current();
3901 if (isControlLetter(ch)) {
3902 state.lastIntValue = ch % 0x20;
3908 function isControlLetter(ch) {
3910 (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
3911 (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
3915 // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
3916 pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
3917 if ( forceU === void 0 ) forceU = false;
3919 var start = state.pos;
3920 var switchU = forceU || state.switchU;
3922 if (state.eat(0x75 /* u */)) {
3923 if (this.regexp_eatFixedHexDigits(state, 4)) {
3924 var lead = state.lastIntValue;
3925 if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
3926 var leadSurrogateEnd = state.pos;
3927 if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
3928 var trail = state.lastIntValue;
3929 if (trail >= 0xDC00 && trail <= 0xDFFF) {
3930 state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
3934 state.pos = leadSurrogateEnd;
3935 state.lastIntValue = lead;
3941 state.eat(0x7B /* { */) &&
3942 this.regexp_eatHexDigits(state) &&
3943 state.eat(0x7D /* } */) &&
3944 isValidUnicode(state.lastIntValue)
3949 state.raise("Invalid unicode escape");
3956 function isValidUnicode(ch) {
3957 return ch >= 0 && ch <= 0x10FFFF
3960 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
3961 pp$8.regexp_eatIdentityEscape = function(state) {
3962 if (state.switchU) {
3963 if (this.regexp_eatSyntaxCharacter(state)) {
3966 if (state.eat(0x2F /* / */)) {
3967 state.lastIntValue = 0x2F; /* / */
3973 var ch = state.current();
3974 if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
3975 state.lastIntValue = ch;
3983 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
3984 pp$8.regexp_eatDecimalEscape = function(state) {
3985 state.lastIntValue = 0;
3986 var ch = state.current();
3987 if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
3989 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
3991 } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
3997 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
3998 pp$8.regexp_eatCharacterClassEscape = function(state) {
3999 var ch = state.current();
4001 if (isCharacterClassEscape(ch)) {
4002 state.lastIntValue = -1;
4009 this.options.ecmaVersion >= 9 &&
4010 (ch === 0x50 /* P */ || ch === 0x70 /* p */)
4012 state.lastIntValue = -1;
4015 state.eat(0x7B /* { */) &&
4016 this.regexp_eatUnicodePropertyValueExpression(state) &&
4017 state.eat(0x7D /* } */)
4021 state.raise("Invalid property name");
4026 function isCharacterClassEscape(ch) {
4028 ch === 0x64 /* d */ ||
4029 ch === 0x44 /* D */ ||
4030 ch === 0x73 /* s */ ||
4031 ch === 0x53 /* S */ ||
4032 ch === 0x77 /* w */ ||
4037 // UnicodePropertyValueExpression ::
4038 // UnicodePropertyName `=` UnicodePropertyValue
4039 // LoneUnicodePropertyNameOrValue
4040 pp$8.regexp_eatUnicodePropertyValueExpression = function(state) {
4041 var start = state.pos;
4043 // UnicodePropertyName `=` UnicodePropertyValue
4044 if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
4045 var name = state.lastStringValue;
4046 if (this.regexp_eatUnicodePropertyValue(state)) {
4047 var value = state.lastStringValue;
4048 this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
4054 // LoneUnicodePropertyNameOrValue
4055 if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
4056 var nameOrValue = state.lastStringValue;
4057 this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
4062 pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
4063 if (!has(state.unicodeProperties.nonBinary, name))
4064 { state.raise("Invalid property name"); }
4065 if (!state.unicodeProperties.nonBinary[name].test(value))
4066 { state.raise("Invalid property value"); }
4068 pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
4069 if (!state.unicodeProperties.binary.test(nameOrValue))
4070 { state.raise("Invalid property name"); }
4073 // UnicodePropertyName ::
4074 // UnicodePropertyNameCharacters
4075 pp$8.regexp_eatUnicodePropertyName = function(state) {
4077 state.lastStringValue = "";
4078 while (isUnicodePropertyNameCharacter(ch = state.current())) {
4079 state.lastStringValue += codePointToString(ch);
4082 return state.lastStringValue !== ""
4084 function isUnicodePropertyNameCharacter(ch) {
4085 return isControlLetter(ch) || ch === 0x5F /* _ */
4088 // UnicodePropertyValue ::
4089 // UnicodePropertyValueCharacters
4090 pp$8.regexp_eatUnicodePropertyValue = function(state) {
4092 state.lastStringValue = "";
4093 while (isUnicodePropertyValueCharacter(ch = state.current())) {
4094 state.lastStringValue += codePointToString(ch);
4097 return state.lastStringValue !== ""
4099 function isUnicodePropertyValueCharacter(ch) {
4100 return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
4103 // LoneUnicodePropertyNameOrValue ::
4104 // UnicodePropertyValueCharacters
4105 pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
4106 return this.regexp_eatUnicodePropertyValue(state)
4109 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
4110 pp$8.regexp_eatCharacterClass = function(state) {
4111 if (state.eat(0x5B /* [ */)) {
4112 state.eat(0x5E /* ^ */);
4113 this.regexp_classRanges(state);
4114 if (state.eat(0x5D /* ] */)) {
4117 // Unreachable since it threw "unterminated regular expression" error before.
4118 state.raise("Unterminated character class");
4123 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
4124 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
4125 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
4126 pp$8.regexp_classRanges = function(state) {
4127 while (this.regexp_eatClassAtom(state)) {
4128 var left = state.lastIntValue;
4129 if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
4130 var right = state.lastIntValue;
4131 if (state.switchU && (left === -1 || right === -1)) {
4132 state.raise("Invalid character class");
4134 if (left !== -1 && right !== -1 && left > right) {
4135 state.raise("Range out of order in character class");
4141 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
4142 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
4143 pp$8.regexp_eatClassAtom = function(state) {
4144 var start = state.pos;
4146 if (state.eat(0x5C /* \ */)) {
4147 if (this.regexp_eatClassEscape(state)) {
4150 if (state.switchU) {
4151 // Make the same message as V8.
4152 var ch$1 = state.current();
4153 if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
4154 state.raise("Invalid class escape");
4156 state.raise("Invalid escape");
4161 var ch = state.current();
4162 if (ch !== 0x5D /* ] */) {
4163 state.lastIntValue = ch;
4171 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
4172 pp$8.regexp_eatClassEscape = function(state) {
4173 var start = state.pos;
4175 if (state.eat(0x62 /* b */)) {
4176 state.lastIntValue = 0x08; /* <BS> */
4180 if (state.switchU && state.eat(0x2D /* - */)) {
4181 state.lastIntValue = 0x2D; /* - */
4185 if (!state.switchU && state.eat(0x63 /* c */)) {
4186 if (this.regexp_eatClassControlLetter(state)) {
4193 this.regexp_eatCharacterClassEscape(state) ||
4194 this.regexp_eatCharacterEscape(state)
4198 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
4199 pp$8.regexp_eatClassControlLetter = function(state) {
4200 var ch = state.current();
4201 if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
4202 state.lastIntValue = ch % 0x20;
4209 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
4210 pp$8.regexp_eatHexEscapeSequence = function(state) {
4211 var start = state.pos;
4212 if (state.eat(0x78 /* x */)) {
4213 if (this.regexp_eatFixedHexDigits(state, 2)) {
4216 if (state.switchU) {
4217 state.raise("Invalid escape");
4224 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
4225 pp$8.regexp_eatDecimalDigits = function(state) {
4226 var start = state.pos;
4228 state.lastIntValue = 0;
4229 while (isDecimalDigit(ch = state.current())) {
4230 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
4233 return state.pos !== start
4235 function isDecimalDigit(ch) {
4236 return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
4239 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
4240 pp$8.regexp_eatHexDigits = function(state) {
4241 var start = state.pos;
4243 state.lastIntValue = 0;
4244 while (isHexDigit(ch = state.current())) {
4245 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
4248 return state.pos !== start
4250 function isHexDigit(ch) {
4252 (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
4253 (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
4254 (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
4257 function hexToInt(ch) {
4258 if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
4259 return 10 + (ch - 0x41 /* A */)
4261 if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
4262 return 10 + (ch - 0x61 /* a */)
4264 return ch - 0x30 /* 0 */
4267 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
4268 // Allows only 0-377(octal) i.e. 0-255(decimal).
4269 pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) {
4270 if (this.regexp_eatOctalDigit(state)) {
4271 var n1 = state.lastIntValue;
4272 if (this.regexp_eatOctalDigit(state)) {
4273 var n2 = state.lastIntValue;
4274 if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
4275 state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
4277 state.lastIntValue = n1 * 8 + n2;
4280 state.lastIntValue = n1;
4287 // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
4288 pp$8.regexp_eatOctalDigit = function(state) {
4289 var ch = state.current();
4290 if (isOctalDigit(ch)) {
4291 state.lastIntValue = ch - 0x30; /* 0 */
4295 state.lastIntValue = 0;
4298 function isOctalDigit(ch) {
4299 return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
4302 // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
4303 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
4304 // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
4305 pp$8.regexp_eatFixedHexDigits = function(state, length) {
4306 var start = state.pos;
4307 state.lastIntValue = 0;
4308 for (var i = 0; i < length; ++i) {
4309 var ch = state.current();
4310 if (!isHexDigit(ch)) {
4314 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
4320 // Object type used to represent tokens. Note that normally, tokens
4321 // simply exist as properties on the parser object. This is only
4322 // used for the onToken callback and the external tokenizer.
4324 var Token = function Token(p) {
4326 this.value = p.value;
4327 this.start = p.start;
4329 if (p.options.locations)
4330 { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
4331 if (p.options.ranges)
4332 { this.range = [p.start, p.end]; }
4337 var pp$9 = Parser.prototype;
4339 // Move to the next token
4341 pp$9.next = function(ignoreEscapeSequenceInKeyword) {
4342 if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
4343 { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
4344 if (this.options.onToken)
4345 { this.options.onToken(new Token(this)); }
4347 this.lastTokEnd = this.end;
4348 this.lastTokStart = this.start;
4349 this.lastTokEndLoc = this.endLoc;
4350 this.lastTokStartLoc = this.startLoc;
4354 pp$9.getToken = function() {
4356 return new Token(this)
4359 // If we're in an ES6 environment, make parsers iterable
4360 if (typeof Symbol !== "undefined")
4361 { pp$9[Symbol.iterator] = function() {
4366 var token = this$1.getToken();
4368 done: token.type === types.eof,
4375 // Toggle strict mode. Re-reads the next number or string to please
4376 // pedantic tests (`"use strict"; 010;` should fail).
4378 pp$9.curContext = function() {
4379 return this.context[this.context.length - 1]
4382 // Read a single token, updating the parser object's token-related
4385 pp$9.nextToken = function() {
4386 var curContext = this.curContext();
4387 if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
4389 this.start = this.pos;
4390 if (this.options.locations) { this.startLoc = this.curPosition(); }
4391 if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
4393 if (curContext.override) { return curContext.override(this) }
4394 else { this.readToken(this.fullCharCodeAtPos()); }
4397 pp$9.readToken = function(code) {
4398 // Identifier or keyword. '\uXXXX' sequences are allowed in
4399 // identifiers, so '\' also dispatches to that.
4400 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
4401 { return this.readWord() }
4403 return this.getTokenFromCode(code)
4406 pp$9.fullCharCodeAtPos = function() {
4407 var code = this.input.charCodeAt(this.pos);
4408 if (code <= 0xd7ff || code >= 0xe000) { return code }
4409 var next = this.input.charCodeAt(this.pos + 1);
4410 return (code << 10) + next - 0x35fdc00
4413 pp$9.skipBlockComment = function() {
4414 var startLoc = this.options.onComment && this.curPosition();
4415 var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
4416 if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
4418 if (this.options.locations) {
4419 lineBreakG.lastIndex = start;
4421 while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
4423 this.lineStart = match.index + match[0].length;
4426 if (this.options.onComment)
4427 { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
4428 startLoc, this.curPosition()); }
4431 pp$9.skipLineComment = function(startSkip) {
4432 var start = this.pos;
4433 var startLoc = this.options.onComment && this.curPosition();
4434 var ch = this.input.charCodeAt(this.pos += startSkip);
4435 while (this.pos < this.input.length && !isNewLine(ch)) {
4436 ch = this.input.charCodeAt(++this.pos);
4438 if (this.options.onComment)
4439 { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
4440 startLoc, this.curPosition()); }
4443 // Called at the start of the parse and after every token. Skips
4444 // whitespace and comments, and.
4446 pp$9.skipSpace = function() {
4447 loop: while (this.pos < this.input.length) {
4448 var ch = this.input.charCodeAt(this.pos);
4450 case 32: case 160: // ' '
4454 if (this.input.charCodeAt(this.pos + 1) === 10) {
4457 case 10: case 8232: case 8233:
4459 if (this.options.locations) {
4461 this.lineStart = this.pos;
4465 switch (this.input.charCodeAt(this.pos + 1)) {
4467 this.skipBlockComment();
4470 this.skipLineComment(2);
4477 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
4486 // Called at the end of every token. Sets `end`, `val`, and
4487 // maintains `context` and `exprAllowed`, and skips the space after
4488 // the token, so that the next one's `start` will point at the
4491 pp$9.finishToken = function(type, val) {
4492 this.end = this.pos;
4493 if (this.options.locations) { this.endLoc = this.curPosition(); }
4494 var prevType = this.type;
4498 this.updateContext(prevType);
4501 // ### Token reading
4503 // This is the function that is called to fetch the next token. It
4504 // is somewhat obscure, because it works in character codes rather
4505 // than characters, and because operator parsing has been inlined
4508 // All in the name of speed.
4510 pp$9.readToken_dot = function() {
4511 var next = this.input.charCodeAt(this.pos + 1);
4512 if (next >= 48 && next <= 57) { return this.readNumber(true) }
4513 var next2 = this.input.charCodeAt(this.pos + 2);
4514 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
4516 return this.finishToken(types.ellipsis)
4519 return this.finishToken(types.dot)
4523 pp$9.readToken_slash = function() { // '/'
4524 var next = this.input.charCodeAt(this.pos + 1);
4525 if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
4526 if (next === 61) { return this.finishOp(types.assign, 2) }
4527 return this.finishOp(types.slash, 1)
4530 pp$9.readToken_mult_modulo_exp = function(code) { // '%*'
4531 var next = this.input.charCodeAt(this.pos + 1);
4533 var tokentype = code === 42 ? types.star : types.modulo;
4535 // exponentiation operator ** and **=
4536 if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
4538 tokentype = types.starstar;
4539 next = this.input.charCodeAt(this.pos + 2);
4542 if (next === 61) { return this.finishOp(types.assign, size + 1) }
4543 return this.finishOp(tokentype, size)
4546 pp$9.readToken_pipe_amp = function(code) { // '|&'
4547 var next = this.input.charCodeAt(this.pos + 1);
4548 if (next === code) {
4549 if (this.options.ecmaVersion >= 12) {
4550 var next2 = this.input.charCodeAt(this.pos + 2);
4551 if (next2 === 61) { return this.finishOp(types.assign, 3) }
4553 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 var ecmaVersion = this.options.ecmaVersion;
4612 if (ecmaVersion >= 11) {
4613 var next = this.input.charCodeAt(this.pos + 1);
4615 var next2 = this.input.charCodeAt(this.pos + 2);
4616 if (next2 < 48 || next2 > 57) { return this.finishOp(types.questionDot, 2) }
4619 if (ecmaVersion >= 12) {
4620 var next2$1 = this.input.charCodeAt(this.pos + 2);
4621 if (next2$1 === 61) { return this.finishOp(types.assign, 3) }
4623 return this.finishOp(types.coalesce, 2)
4626 return this.finishOp(types.question, 1)
4629 pp$9.getTokenFromCode = function(code) {
4631 // The interpretation of a dot depends on whether it is followed
4632 // by a digit or another two dots.
4634 return this.readToken_dot()
4636 // Punctuation tokens.
4637 case 40: ++this.pos; return this.finishToken(types.parenL)
4638 case 41: ++this.pos; return this.finishToken(types.parenR)
4639 case 59: ++this.pos; return this.finishToken(types.semi)
4640 case 44: ++this.pos; return this.finishToken(types.comma)
4641 case 91: ++this.pos; return this.finishToken(types.bracketL)
4642 case 93: ++this.pos; return this.finishToken(types.bracketR)
4643 case 123: ++this.pos; return this.finishToken(types.braceL)
4644 case 125: ++this.pos; return this.finishToken(types.braceR)
4645 case 58: ++this.pos; return this.finishToken(types.colon)
4648 if (this.options.ecmaVersion < 6) { break }
4650 return this.finishToken(types.backQuote)
4653 var next = this.input.charCodeAt(this.pos + 1);
4654 if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
4655 if (this.options.ecmaVersion >= 6) {
4656 if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
4657 if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
4660 // Anything else beginning with a digit is an integer, octal
4661 // number, or float.
4662 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
4663 return this.readNumber(false)
4665 // Quotes produce strings.
4666 case 34: case 39: // '"', "'"
4667 return this.readString(code)
4669 // Operators are parsed inline in tiny state machines. '=' (61) is
4670 // often referred to. `finishOp` simply skips the amount of
4671 // characters it is given as second argument, and returns a token
4672 // of the type given by its first argument.
4675 return this.readToken_slash()
4677 case 37: case 42: // '%*'
4678 return this.readToken_mult_modulo_exp(code)
4680 case 124: case 38: // '|&'
4681 return this.readToken_pipe_amp(code)
4684 return this.readToken_caret()
4686 case 43: case 45: // '+-'
4687 return this.readToken_plus_min(code)
4689 case 60: case 62: // '<>'
4690 return this.readToken_lt_gt(code)
4692 case 61: case 33: // '=!'
4693 return this.readToken_eq_excl(code)
4696 return this.readToken_question()
4699 return this.finishOp(types.prefix, 1)
4702 this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
4705 pp$9.finishOp = function(type, size) {
4706 var str = this.input.slice(this.pos, this.pos + size);
4708 return this.finishToken(type, str)
4711 pp$9.readRegexp = function() {
4712 var escaped, inClass, start = this.pos;
4714 if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
4715 var ch = this.input.charAt(this.pos);
4716 if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
4718 if (ch === "[") { inClass = true; }
4719 else if (ch === "]" && inClass) { inClass = false; }
4720 else if (ch === "/" && !inClass) { break }
4721 escaped = ch === "\\";
4722 } else { escaped = false; }
4725 var pattern = this.input.slice(start, this.pos);
4727 var flagsStart = this.pos;
4728 var flags = this.readWord1();
4729 if (this.containsEsc) { this.unexpected(flagsStart); }
4732 var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
4733 state.reset(start, pattern, flags);
4734 this.validateRegExpFlags(state);
4735 this.validateRegExpPattern(state);
4737 // Create Literal#value property value.
4740 value = new RegExp(pattern, flags);
4742 // ESTree requires null if it failed to instantiate RegExp object.
4743 // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
4746 return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value})
4749 // Read an integer in the given radix. Return null if zero digits
4750 // were read, the integer value otherwise. When `len` is given, this
4751 // will return `null` unless the integer has exactly `len` digits.
4753 pp$9.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
4754 // `len` is used for character escape sequences. In that case, disallow separators.
4755 var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined;
4757 // `maybeLegacyOctalNumericLiteral` is true if it doesn't have prefix (0x,0o,0b)
4758 // and isn't fraction part nor exponent part. In that case, if the first digit
4759 // is zero then disallow separators.
4760 var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48;
4762 var start = this.pos, total = 0, lastCode = 0;
4763 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) {
4764 var code = this.input.charCodeAt(this.pos), val = (void 0);
4766 if (allowSeparators && code === 95) {
4767 if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); }
4768 if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); }
4769 if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); }
4774 if (code >= 97) { val = code - 97 + 10; } // a
4775 else if (code >= 65) { val = code - 65 + 10; } // A
4776 else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
4777 else { val = Infinity; }
4778 if (val >= radix) { break }
4780 total = total * radix + val;
4783 if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); }
4784 if (this.pos === start || len != null && this.pos - start !== len) { return null }
4789 function stringToNumber(str, isLegacyOctalNumericLiteral) {
4790 if (isLegacyOctalNumericLiteral) {
4791 return parseInt(str, 8)
4794 // `parseFloat(value)` stops parsing at the first numeric separator then returns a wrong value.
4795 return parseFloat(str.replace(/_/g, ""))
4798 function stringToBigInt(str) {
4799 if (typeof BigInt !== "function") {
4803 // `BigInt(value)` throws syntax error if the string contains numeric separators.
4804 return BigInt(str.replace(/_/g, ""))
4807 pp$9.readRadixNumber = function(radix) {
4808 var start = this.pos;
4809 this.pos += 2; // 0x
4810 var val = this.readInt(radix);
4811 if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
4812 if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
4813 val = stringToBigInt(this.input.slice(start, this.pos));
4815 } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4816 return this.finishToken(types.num, val)
4819 // Read an integer, octal integer, or floating-point number.
4821 pp$9.readNumber = function(startsWithDot) {
4822 var start = this.pos;
4823 if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); }
4824 var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
4825 if (octal && this.strict) { this.raise(start, "Invalid number"); }
4826 var next = this.input.charCodeAt(this.pos);
4827 if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
4828 var val$1 = stringToBigInt(this.input.slice(start, this.pos));
4830 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4831 return this.finishToken(types.num, val$1)
4833 if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
4834 if (next === 46 && !octal) { // '.'
4837 next = this.input.charCodeAt(this.pos);
4839 if ((next === 69 || next === 101) && !octal) { // 'eE'
4840 next = this.input.charCodeAt(++this.pos);
4841 if (next === 43 || next === 45) { ++this.pos; } // '+-'
4842 if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
4844 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4846 var val = stringToNumber(this.input.slice(start, this.pos), octal);
4847 return this.finishToken(types.num, val)
4850 // Read a string value, interpreting backslash-escapes.
4852 pp$9.readCodePoint = function() {
4853 var ch = this.input.charCodeAt(this.pos), code;
4855 if (ch === 123) { // '{'
4856 if (this.options.ecmaVersion < 6) { this.unexpected(); }
4857 var codePos = ++this.pos;
4858 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
4860 if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
4862 code = this.readHexChar(4);
4867 function codePointToString$1(code) {
4869 if (code <= 0xFFFF) { return String.fromCharCode(code) }
4871 return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
4874 pp$9.readString = function(quote) {
4875 var out = "", chunkStart = ++this.pos;
4877 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
4878 var ch = this.input.charCodeAt(this.pos);
4879 if (ch === quote) { break }
4880 if (ch === 92) { // '\'
4881 out += this.input.slice(chunkStart, this.pos);
4882 out += this.readEscapedChar(false);
4883 chunkStart = this.pos;
4885 if (isNewLine(ch, this.options.ecmaVersion >= 10)) { this.raise(this.start, "Unterminated string constant"); }
4889 out += this.input.slice(chunkStart, this.pos++);
4890 return this.finishToken(types.string, out)
4893 // Reads template string tokens.
4895 var INVALID_TEMPLATE_ESCAPE_ERROR = {};
4897 pp$9.tryReadTemplateToken = function() {
4898 this.inTemplateElement = true;
4900 this.readTmplToken();
4902 if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
4903 this.readInvalidTemplateToken();
4909 this.inTemplateElement = false;
4912 pp$9.invalidStringToken = function(position, message) {
4913 if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
4914 throw INVALID_TEMPLATE_ESCAPE_ERROR
4916 this.raise(position, message);
4920 pp$9.readTmplToken = function() {
4921 var out = "", chunkStart = this.pos;
4923 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
4924 var ch = this.input.charCodeAt(this.pos);
4925 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
4926 if (this.pos === this.start && (this.type === types.template || this.type === types.invalidTemplate)) {
4929 return this.finishToken(types.dollarBraceL)
4932 return this.finishToken(types.backQuote)
4935 out += this.input.slice(chunkStart, this.pos);
4936 return this.finishToken(types.template, out)
4938 if (ch === 92) { // '\'
4939 out += this.input.slice(chunkStart, this.pos);
4940 out += this.readEscapedChar(true);
4941 chunkStart = this.pos;
4942 } else if (isNewLine(ch)) {
4943 out += this.input.slice(chunkStart, this.pos);
4947 if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
4952 out += String.fromCharCode(ch);
4955 if (this.options.locations) {
4957 this.lineStart = this.pos;
4959 chunkStart = this.pos;
4966 // Reads a template token to search for the end, without validating any escape sequences
4967 pp$9.readInvalidTemplateToken = function() {
4968 for (; this.pos < this.input.length; this.pos++) {
4969 switch (this.input[this.pos]) {
4975 if (this.input[this.pos + 1] !== "{") {
4981 return this.finishToken(types.invalidTemplate, this.input.slice(this.start, this.pos))
4986 this.raise(this.start, "Unterminated template");
4989 // Used to read escaped characters
4991 pp$9.readEscapedChar = function(inTemplate) {
4992 var ch = this.input.charCodeAt(++this.pos);
4995 case 110: return "\n" // 'n' -> '\n'
4996 case 114: return "\r" // 'r' -> '\r'
4997 case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
4998 case 117: return codePointToString$1(this.readCodePoint()) // 'u'
4999 case 116: return "\t" // 't' -> '\t'
5000 case 98: return "\b" // 'b' -> '\b'
5001 case 118: return "\u000b" // 'v' -> '\u000b'
5002 case 102: return "\f" // 'f' -> '\f'
5003 case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
5005 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
5010 var codePos = this.pos - 1;
5012 this.invalidStringToken(
5014 "Invalid escape sequence in template string"
5020 if (ch >= 48 && ch <= 55) {
5021 var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
5022 var octal = parseInt(octalStr, 8);
5024 octalStr = octalStr.slice(0, -1);
5025 octal = parseInt(octalStr, 8);
5027 this.pos += octalStr.length - 1;
5028 ch = this.input.charCodeAt(this.pos);
5029 if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
5030 this.invalidStringToken(
5031 this.pos - 1 - octalStr.length,
5033 ? "Octal literal in template string"
5034 : "Octal literal in strict mode"
5037 return String.fromCharCode(octal)
5039 if (isNewLine(ch)) {
5040 // Unicode new line characters after \ get removed from output in both
5041 // template literals and strings
5044 return String.fromCharCode(ch)
5048 // Used to read character escape sequences ('\x', '\u', '\U').
5050 pp$9.readHexChar = function(len) {
5051 var codePos = this.pos;
5052 var n = this.readInt(16, len);
5053 if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
5057 // Read an identifier, and return it as a string. Sets `this.containsEsc`
5058 // to whether the word contained a '\u' escape.
5060 // Incrementally adds only escaped chars, adding other chunks as-is
5061 // as a micro-optimization.
5063 pp$9.readWord1 = function() {
5064 this.containsEsc = false;
5065 var word = "", first = true, chunkStart = this.pos;
5066 var astral = this.options.ecmaVersion >= 6;
5067 while (this.pos < this.input.length) {
5068 var ch = this.fullCharCodeAtPos();
5069 if (isIdentifierChar(ch, astral)) {
5070 this.pos += ch <= 0xffff ? 1 : 2;
5071 } else if (ch === 92) { // "\"
5072 this.containsEsc = true;
5073 word += this.input.slice(chunkStart, this.pos);
5074 var escStart = this.pos;
5075 if (this.input.charCodeAt(++this.pos) !== 117) // "u"
5076 { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
5078 var esc = this.readCodePoint();
5079 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
5080 { this.invalidStringToken(escStart, "Invalid Unicode escape"); }
5081 word += codePointToString$1(esc);
5082 chunkStart = this.pos;
5088 return word + this.input.slice(chunkStart, this.pos)
5091 // Read an identifier or keyword token. Will check for reserved
5092 // words when necessary.
5094 pp$9.readWord = function() {
5095 var word = this.readWord1();
5096 var type = types.name;
5097 if (this.keywords.test(word)) {
5098 type = keywords$1[word];
5100 return this.finishToken(type, word)
5103 // Acorn is a tiny, fast JavaScript parser written in JavaScript.
5105 var version = "7.4.1";
5110 defaultOptions: defaultOptions,
5112 SourceLocation: SourceLocation,
5113 getLineInfo: getLineInfo,
5115 TokenType: TokenType,
5117 keywordTypes: keywords$1,
5118 TokContext: TokContext,
5119 tokContexts: types$1,
5120 isIdentifierChar: isIdentifierChar,
5121 isIdentifierStart: isIdentifierStart,
5123 isNewLine: isNewLine,
5124 lineBreak: lineBreak,
5125 lineBreakG: lineBreakG,
5126 nonASCIIwhitespace: nonASCIIwhitespace
5129 // The main exported interface (under `self.acorn` when in the
5130 // browser) is a `parse` function that takes a code string and
5131 // returns an abstract syntax tree as specified by [Mozilla parser
5134 // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
5136 function parse(input, options) {
5137 return Parser.parse(input, options)
5140 // This function tries to parse a single expression at a given
5141 // offset in a string. Useful for parsing mixed-language formats
5142 // that embed JavaScript expressions.
5144 function parseExpressionAt(input, pos, options) {
5145 return Parser.parseExpressionAt(input, pos, options)
5148 // Acorn is organized as a tokenizer and a recursive-descent parser.
5149 // The `tokenizer` export provides an interface to the tokenizer.
5151 function tokenizer(input, options) {
5152 return Parser.tokenizer(input, options)
5155 export { Node, Parser, Position, SourceLocation, TokContext, Token, TokenType, defaultOptions, getLineInfo, isIdentifierChar, isIdentifierStart, isNewLine, keywords$1 as keywordTypes, lineBreak, lineBreakG, nonASCIIwhitespace, parse, parseExpressionAt, types$1 as tokContexts, types as tokTypes, tokenizer, version };