1// Reserved word lists for various dialects of the language 2 3var reservedWords = { 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", 6 6: "enum", 7 strict: "implements interface let package private protected public static yield", 8 strictBind: "eval arguments" 9}; 10 11// And the keywords 12 13var 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"; 14 15var keywords = { 16 5: ecma5AndLessKeywords, 17 "5module": ecma5AndLessKeywords + " export import", 18 6: ecma5AndLessKeywords + " const class extends export import super" 19}; 20 21var keywordRelationalOperator = /^in(stanceof)?$/; 22 23// ## Character categories 24 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`. 30var 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-\u08bd\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\u0d05-\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-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7c6\ua7f7-\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-\uab67\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"; 31var 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\u0b56\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\u0d82\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\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\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"; 32 33var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); 34var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); 35 36nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; 37 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 43 44// eslint-disable-next-line comma-spacing 45var 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,477,28,11,0,9,21,155,22,13,52,76,44,33,24,27,35,30,0,12,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,0,33,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,0,161,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,270,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,754,9486,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,42710,42,4148,12,221,3,5761,15,7472,3104,541]; 46 47// eslint-disable-next-line comma-spacing 48var 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,525,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,4,9,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,232,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,19723,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,792487,239]; 49 50// This has a complexity linear to the value of the code. The 51// assumption is that looking up astral identifier characters is 52// rare. 53function isInAstralSet(code, set) { 54 var pos = 0x10000; 55 for (var i = 0; i < set.length; i += 2) { 56 pos += set[i]; 57 if (pos > code) { return false } 58 pos += set[i + 1]; 59 if (pos >= code) { return true } 60 } 61} 62 63// Test whether a given character code starts an identifier. 64 65function 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) 73} 74 75// Test whether a given character is part of an identifier. 76 77function 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) 87} 88 89// ## Token types 90 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. 94 95// All token type variables start with an underscore, to make them 96// easy to recognize. 97 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). 102// 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). 107// 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. 111 112var TokenType = function TokenType(label, conf) { 113 if ( conf === void 0 ) conf = {}; 114 115 this.label = label; 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; 125}; 126 127function binop(name, prec) { 128 return new TokenType(name, {beforeExpr: true, binop: prec}) 129} 130var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; 131 132// Map keyword names to token types. 133 134var keywords$1 = {}; 135 136// Succinct definitions of keyword token types 137function kw(name, options) { 138 if ( options === void 0 ) options = {}; 139 140 options.keyword = name; 141 return keywords$1[name] = new TokenType(name, options) 142} 143 144var types = { 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"), 150 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 arrow: new TokenType("=>", beforeExpr), 164 template: new TokenType("template"), 165 invalidTemplate: new TokenType("invalidTemplate"), 166 ellipsis: new TokenType("...", beforeExpr), 167 backQuote: new TokenType("`", startsExpr), 168 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), 169 170 // Operators. These carry several kinds of properties to help the 171 // parser use them properly (the presence of these properties is 172 // what categorizes them as operators). 173 // 174 // `binop`, when present, specifies that this operator is a binary 175 // operator, and will refer to its precedence. 176 // 177 // `prefix` and `postfix` mark the operator as a prefix or postfix 178 // unary operator. 179 // 180 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as 181 // binary operators with a very low precedence, that should result 182 // in AssignmentExpression nodes. 183 184 eq: new TokenType("=", {beforeExpr: true, isAssign: true}), 185 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), 186 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), 187 prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), 188 logicalOR: binop("||", 1), 189 logicalAND: binop("&&", 2), 190 bitwiseOR: binop("|", 3), 191 bitwiseXOR: binop("^", 4), 192 bitwiseAND: binop("&", 5), 193 equality: binop("==/!=/===/!==", 6), 194 relational: binop("</>/<=/>=", 7), 195 bitShift: binop("<</>>/>>>", 8), 196 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), 197 modulo: binop("%", 10), 198 star: binop("*", 10), 199 slash: binop("/", 10), 200 starstar: new TokenType("**", {beforeExpr: true}), 201 202 // Keyword token types. 203 _break: kw("break"), 204 _case: kw("case", beforeExpr), 205 _catch: kw("catch"), 206 _continue: kw("continue"), 207 _debugger: kw("debugger"), 208 _default: kw("default", beforeExpr), 209 _do: kw("do", {isLoop: true, beforeExpr: true}), 210 _else: kw("else", beforeExpr), 211 _finally: kw("finally"), 212 _for: kw("for", {isLoop: true}), 213 _function: kw("function", startsExpr), 214 _if: kw("if"), 215 _return: kw("return", beforeExpr), 216 _switch: kw("switch"), 217 _throw: kw("throw", beforeExpr), 218 _try: kw("try"), 219 _var: kw("var"), 220 _const: kw("const"), 221 _while: kw("while", {isLoop: true}), 222 _with: kw("with"), 223 _new: kw("new", {beforeExpr: true, startsExpr: true}), 224 _this: kw("this", startsExpr), 225 _super: kw("super", startsExpr), 226 _class: kw("class", startsExpr), 227 _extends: kw("extends", beforeExpr), 228 _export: kw("export"), 229 _import: kw("import", startsExpr), 230 _null: kw("null", startsExpr), 231 _true: kw("true", startsExpr), 232 _false: kw("false", startsExpr), 233 _in: kw("in", {beforeExpr: true, binop: 7}), 234 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), 235 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), 236 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), 237 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) 238}; 239 240// Matches a whole line break (where CRLF is considered a single 241// line break). Used to count lines. 242 243var lineBreak = /\r\n?|\n|\u2028|\u2029/; 244var lineBreakG = new RegExp(lineBreak.source, "g"); 245 246function isNewLine(code, ecma2019String) { 247 return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029)) 248} 249 250var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; 251 252var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; 253 254var ref = Object.prototype; 255var hasOwnProperty = ref.hasOwnProperty; 256var toString = ref.toString; 257 258// Checks if an object has a property. 259 260function has(obj, propName) { 261 return hasOwnProperty.call(obj, propName) 262} 263 264var isArray = Array.isArray || (function (obj) { return ( 265 toString.call(obj) === "[object Array]" 266); }); 267 268function wordsRegexp(words) { 269 return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") 270} 271 272// These are used when `options.locations` is on, for the 273// `startLoc` and `endLoc` properties. 274 275var Position = function Position(line, col) { 276 this.line = line; 277 this.column = col; 278}; 279 280Position.prototype.offset = function offset (n) { 281 return new Position(this.line, this.column + n) 282}; 283 284var SourceLocation = function SourceLocation(p, start, end) { 285 this.start = start; 286 this.end = end; 287 if (p.sourceFile !== null) { this.source = p.sourceFile; } 288}; 289 290// The `getLineInfo` function is mostly useful when the 291// `locations` option is off (for performance reasons) and you 292// want to find the line/column position for a given character 293// offset. `input` should be the code string that the offset refers 294// into. 295 296function getLineInfo(input, offset) { 297 for (var line = 1, cur = 0;;) { 298 lineBreakG.lastIndex = cur; 299 var match = lineBreakG.exec(input); 300 if (match && match.index < offset) { 301 ++line; 302 cur = match.index + match[0].length; 303 } else { 304 return new Position(line, offset - cur) 305 } 306 } 307} 308 309// A second optional argument can be given to further configure 310// the parser process. These options are recognized: 311 312var defaultOptions = { 313 // `ecmaVersion` indicates the ECMAScript version to parse. Must be 314 // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10 315 // (2019). This influences support for strict mode, the set of 316 // reserved words, and support for new syntax features. The default 317 // is 10. 318 ecmaVersion: 10, 319 // `sourceType` indicates the mode the code should be parsed in. 320 // Can be either `"script"` or `"module"`. This influences global 321 // strict mode and parsing of `import` and `export` declarations. 322 sourceType: "script", 323 // `onInsertedSemicolon` can be a callback that will be called 324 // when a semicolon is automatically inserted. It will be passed 325 // the position of the comma as an offset, and if `locations` is 326 // enabled, it is given the location as a `{line, column}` object 327 // as second argument. 328 onInsertedSemicolon: null, 329 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for 330 // trailing commas. 331 onTrailingComma: null, 332 // By default, reserved words are only enforced if ecmaVersion >= 5. 333 // Set `allowReserved` to a boolean value to explicitly turn this on 334 // an off. When this option has the value "never", reserved words 335 // and keywords can also not be used as property names. 336 allowReserved: null, 337 // When enabled, a return at the top level is not considered an 338 // error. 339 allowReturnOutsideFunction: false, 340 // When enabled, import/export statements are not constrained to 341 // appearing at the top of the program. 342 allowImportExportEverywhere: false, 343 // When enabled, await identifiers are allowed to appear at the top-level scope, 344 // but they are still not allowed in non-async functions. 345 allowAwaitOutsideFunction: false, 346 // When enabled, hashbang directive in the beginning of file 347 // is allowed and treated as a line comment. 348 allowHashBang: false, 349 // When `locations` is on, `loc` properties holding objects with 350 // `start` and `end` properties in `{line, column}` form (with 351 // line being 1-based and column 0-based) will be attached to the 352 // nodes. 353 locations: false, 354 // A function can be passed as `onToken` option, which will 355 // cause Acorn to call that function with object in the same 356 // format as tokens returned from `tokenizer().getToken()`. Note 357 // that you are not allowed to call the parser from the 358 // callback—that will corrupt its internal state. 359 onToken: null, 360 // A function can be passed as `onComment` option, which will 361 // cause Acorn to call that function with `(block, text, start, 362 // end)` parameters whenever a comment is skipped. `block` is a 363 // boolean indicating whether this is a block (`/* */`) comment, 364 // `text` is the content of the comment, and `start` and `end` are 365 // character offsets that denote the start and end of the comment. 366 // When the `locations` option is on, two more parameters are 367 // passed, the full `{line, column}` locations of the start and 368 // end of the comments. Note that you are not allowed to call the 369 // parser from the callback—that will corrupt its internal state. 370 onComment: null, 371 // Nodes have their start and end characters offsets recorded in 372 // `start` and `end` properties (directly on the node, rather than 373 // the `loc` object, which holds line/column data. To also add a 374 // [semi-standardized][range] `range` property holding a `[start, 375 // end]` array with the same numbers, set the `ranges` option to 376 // `true`. 377 // 378 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 379 ranges: false, 380 // It is possible to parse multiple files into a single AST by 381 // passing the tree produced by parsing the first file as 382 // `program` option in subsequent parses. This will add the 383 // toplevel forms of the parsed file to the `Program` (top) node 384 // of an existing parse tree. 385 program: null, 386 // When `locations` is on, you can pass this to record the source 387 // file in every node's `loc` object. 388 sourceFile: null, 389 // This value, if given, is stored in every node, whether 390 // `locations` is on or off. 391 directSourceFile: null, 392 // When enabled, parenthesized expressions are represented by 393 // (non-standard) ParenthesizedExpression nodes 394 preserveParens: false 395}; 396 397// Interpret and default an options object 398 399function getOptions(opts) { 400 var options = {}; 401 402 for (var opt in defaultOptions) 403 { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } 404 405 if (options.ecmaVersion >= 2015) 406 { options.ecmaVersion -= 2009; } 407 408 if (options.allowReserved == null) 409 { options.allowReserved = options.ecmaVersion < 5; } 410 411 if (isArray(options.onToken)) { 412 var tokens = options.onToken; 413 options.onToken = function (token) { return tokens.push(token); }; 414 } 415 if (isArray(options.onComment)) 416 { options.onComment = pushComment(options, options.onComment); } 417 418 return options 419} 420 421function pushComment(options, array) { 422 return function(block, text, start, end, startLoc, endLoc) { 423 var comment = { 424 type: block ? "Block" : "Line", 425 value: text, 426 start: start, 427 end: end 428 }; 429 if (options.locations) 430 { comment.loc = new SourceLocation(this, startLoc, endLoc); } 431 if (options.ranges) 432 { comment.range = [start, end]; } 433 array.push(comment); 434 } 435} 436 437// Each scope gets a bitset that may contain these flags 438var 439 SCOPE_TOP = 1, 440 SCOPE_FUNCTION = 2, 441 SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION, 442 SCOPE_ASYNC = 4, 443 SCOPE_GENERATOR = 8, 444 SCOPE_ARROW = 16, 445 SCOPE_SIMPLE_CATCH = 32, 446 SCOPE_SUPER = 64, 447 SCOPE_DIRECT_SUPER = 128; 448 449function functionFlags(async, generator) { 450 return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) 451} 452 453// Used in checkLVal and declareName to determine the type of a binding 454var 455 BIND_NONE = 0, // Not a binding 456 BIND_VAR = 1, // Var-style binding 457 BIND_LEXICAL = 2, // Let- or const-style binding 458 BIND_FUNCTION = 3, // Function declaration 459 BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding 460 BIND_OUTSIDE = 5; // Special case for function names as bound inside the function 461 462var Parser = function Parser(options, input, startPos) { 463 this.options = options = getOptions(options); 464 this.sourceFile = options.sourceFile; 465 this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); 466 var reserved = ""; 467 if (options.allowReserved !== true) { 468 for (var v = options.ecmaVersion;; v--) 469 { if (reserved = reservedWords[v]) { break } } 470 if (options.sourceType === "module") { reserved += " await"; } 471 } 472 this.reservedWords = wordsRegexp(reserved); 473 var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; 474 this.reservedWordsStrict = wordsRegexp(reservedStrict); 475 this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); 476 this.input = String(input); 477 478 // Used to signal to callers of `readWord1` whether the word 479 // contained any escape sequences. This is needed because words with 480 // escape sequences must not be interpreted as keywords. 481 this.containsEsc = false; 482 483 // Set up token state 484 485 // The current position of the tokenizer in the input. 486 if (startPos) { 487 this.pos = startPos; 488 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; 489 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; 490 } else { 491 this.pos = this.lineStart = 0; 492 this.curLine = 1; 493 } 494 495 // Properties of the current token: 496 // Its type 497 this.type = types.eof; 498 // For tokens that include more information than their type, the value 499 this.value = null; 500 // Its start and end offset 501 this.start = this.end = this.pos; 502 // And, if locations are used, the {line, column} object 503 // corresponding to those offsets 504 this.startLoc = this.endLoc = this.curPosition(); 505 506 // Position information for the previous token 507 this.lastTokEndLoc = this.lastTokStartLoc = null; 508 this.lastTokStart = this.lastTokEnd = this.pos; 509 510 // The context stack is used to superficially track syntactic 511 // context to predict whether a regular expression is allowed in a 512 // given position. 513 this.context = this.initialContext(); 514 this.exprAllowed = true; 515 516 // Figure out if it's a module code. 517 this.inModule = options.sourceType === "module"; 518 this.strict = this.inModule || this.strictDirective(this.pos); 519 520 // Used to signify the start of a potential arrow function 521 this.potentialArrowAt = -1; 522 523 // Positions to delayed-check that yield/await does not exist in default parameters. 524 this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; 525 // Labels in scope. 526 this.labels = []; 527 // Thus-far undefined exports. 528 this.undefinedExports = {}; 529 530 // If enabled, skip leading hashbang line. 531 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") 532 { this.skipLineComment(2); } 533 534 // Scope tracking for duplicate variable names (see scope.js) 535 this.scopeStack = []; 536 this.enterScope(SCOPE_TOP); 537 538 // For RegExp validation 539 this.regexpState = null; 540}; 541 542var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } }; 543 544Parser.prototype.parse = function parse () { 545 var node = this.options.program || this.startNode(); 546 this.nextToken(); 547 return this.parseTopLevel(node) 548}; 549 550prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; 551prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; 552prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; 553prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 }; 554prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; 555prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; 556 557// Switch to a getter for 7.0.0. 558Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 }; 559 560Parser.extend = function extend () { 561 var plugins = [], len = arguments.length; 562 while ( len-- ) plugins[ len ] = arguments[ len ]; 563 564 var cls = this; 565 for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } 566 return cls 567}; 568 569Parser.parse = function parse (input, options) { 570 return new this(options, input).parse() 571}; 572 573Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { 574 var parser = new this(options, input, pos); 575 parser.nextToken(); 576 return parser.parseExpression() 577}; 578 579Parser.tokenizer = function tokenizer (input, options) { 580 return new this(options, input) 581}; 582 583Object.defineProperties( Parser.prototype, prototypeAccessors ); 584 585var pp = Parser.prototype; 586 587// ## Parser utilities 588 589var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)")/; 590pp.strictDirective = function(start) { 591 for (;;) { 592 // Try to find string literal. 593 skipWhiteSpace.lastIndex = start; 594 start += skipWhiteSpace.exec(this.input)[0].length; 595 var match = literal.exec(this.input.slice(start)); 596 if (!match) { return false } 597 if ((match[1] || match[2]) === "use strict") { return true } 598 start += match[0].length; 599 600 // Skip semicolon, if any. 601 skipWhiteSpace.lastIndex = start; 602 start += skipWhiteSpace.exec(this.input)[0].length; 603 if (this.input[start] === ";") 604 { start++; } 605 } 606}; 607 608// Predicate that tests whether the next token is of the given 609// type, and if yes, consumes it as a side effect. 610 611pp.eat = function(type) { 612 if (this.type === type) { 613 this.next(); 614 return true 615 } else { 616 return false 617 } 618}; 619 620// Tests whether parsed token is a contextual keyword. 621 622pp.isContextual = function(name) { 623 return this.type === types.name && this.value === name && !this.containsEsc 624}; 625 626// Consumes contextual keyword if possible. 627 628pp.eatContextual = function(name) { 629 if (!this.isContextual(name)) { return false } 630 this.next(); 631 return true 632}; 633 634// Asserts that following token is given contextual keyword. 635 636pp.expectContextual = function(name) { 637 if (!this.eatContextual(name)) { this.unexpected(); } 638}; 639 640// Test whether a semicolon can be inserted at the current position. 641 642pp.canInsertSemicolon = function() { 643 return this.type === types.eof || 644 this.type === types.braceR || 645 lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) 646}; 647 648pp.insertSemicolon = function() { 649 if (this.canInsertSemicolon()) { 650 if (this.options.onInsertedSemicolon) 651 { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } 652 return true 653 } 654}; 655 656// Consume a semicolon, or, failing that, see if we are allowed to 657// pretend that there is a semicolon at this position. 658 659pp.semicolon = function() { 660 if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } 661}; 662 663pp.afterTrailingComma = function(tokType, notNext) { 664 if (this.type === tokType) { 665 if (this.options.onTrailingComma) 666 { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } 667 if (!notNext) 668 { this.next(); } 669 return true 670 } 671}; 672 673// Expect a token of a given type. If found, consume it, otherwise, 674// raise an unexpected token error. 675 676pp.expect = function(type) { 677 this.eat(type) || this.unexpected(); 678}; 679 680// Raise an unexpected token error. 681 682pp.unexpected = function(pos) { 683 this.raise(pos != null ? pos : this.start, "Unexpected token"); 684}; 685 686function DestructuringErrors() { 687 this.shorthandAssign = 688 this.trailingComma = 689 this.parenthesizedAssign = 690 this.parenthesizedBind = 691 this.doubleProto = 692 -1; 693} 694 695pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { 696 if (!refDestructuringErrors) { return } 697 if (refDestructuringErrors.trailingComma > -1) 698 { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } 699 var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; 700 if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } 701}; 702 703pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { 704 if (!refDestructuringErrors) { return false } 705 var shorthandAssign = refDestructuringErrors.shorthandAssign; 706 var doubleProto = refDestructuringErrors.doubleProto; 707 if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } 708 if (shorthandAssign >= 0) 709 { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } 710 if (doubleProto >= 0) 711 { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } 712}; 713 714pp.checkYieldAwaitInDefaultParams = function() { 715 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) 716 { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } 717 if (this.awaitPos) 718 { this.raise(this.awaitPos, "Await expression cannot be a default value"); } 719}; 720 721pp.isSimpleAssignTarget = function(expr) { 722 if (expr.type === "ParenthesizedExpression") 723 { return this.isSimpleAssignTarget(expr.expression) } 724 return expr.type === "Identifier" || expr.type === "MemberExpression" 725}; 726 727var pp$1 = Parser.prototype; 728 729// ### Statement parsing 730 731// Parse a program. Initializes the parser, reads any number of 732// statements, and wraps them in a Program node. Optionally takes a 733// `program` argument. If present, the statements will be appended 734// to its body instead of creating a new node. 735 736pp$1.parseTopLevel = function(node) { 737 var exports = {}; 738 if (!node.body) { node.body = []; } 739 while (this.type !== types.eof) { 740 var stmt = this.parseStatement(null, true, exports); 741 node.body.push(stmt); 742 } 743 if (this.inModule) 744 { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) 745 { 746 var name = list[i]; 747 748 this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); 749 } } 750 this.adaptDirectivePrologue(node.body); 751 this.next(); 752 node.sourceType = this.options.sourceType; 753 return this.finishNode(node, "Program") 754}; 755 756var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; 757 758pp$1.isLet = function(context) { 759 if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } 760 skipWhiteSpace.lastIndex = this.pos; 761 var skip = skipWhiteSpace.exec(this.input); 762 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); 763 // For ambiguous cases, determine if a LexicalDeclaration (or only a 764 // Statement) is allowed here. If context is not empty then only a Statement 765 // is allowed. However, `let [` is an explicit negative lookahead for 766 // ExpressionStatement, so special-case it first. 767 if (nextCh === 91) { return true } // '[' 768 if (context) { return false } 769 770 if (nextCh === 123) { return true } // '{' 771 if (isIdentifierStart(nextCh, true)) { 772 var pos = next + 1; 773 while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } 774 var ident = this.input.slice(next, pos); 775 if (!keywordRelationalOperator.test(ident)) { return true } 776 } 777 return false 778}; 779 780// check 'async [no LineTerminator here] function' 781// - 'async /*foo*/ function' is OK. 782// - 'async /*\n*/ function' is invalid. 783pp$1.isAsyncFunction = function() { 784 if (this.options.ecmaVersion < 8 || !this.isContextual("async")) 785 { return false } 786 787 skipWhiteSpace.lastIndex = this.pos; 788 var skip = skipWhiteSpace.exec(this.input); 789 var next = this.pos + skip[0].length; 790 return !lineBreak.test(this.input.slice(this.pos, next)) && 791 this.input.slice(next, next + 8) === "function" && 792 (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) 793}; 794 795// Parse a single statement. 796// 797// If expecting a statement and finding a slash operator, parse a 798// regular expression literal. This is to handle cases like 799// `if (foo) /blah/.exec(foo)`, where looking at the previous token 800// does not help. 801 802pp$1.parseStatement = function(context, topLevel, exports) { 803 var starttype = this.type, node = this.startNode(), kind; 804 805 if (this.isLet(context)) { 806 starttype = types._var; 807 kind = "let"; 808 } 809 810 // Most types of statements are recognized by the keyword they 811 // start with. Many are trivial to parse, some require a bit of 812 // complexity. 813 814 switch (starttype) { 815 case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) 816 case types._debugger: return this.parseDebuggerStatement(node) 817 case types._do: return this.parseDoStatement(node) 818 case types._for: return this.parseForStatement(node) 819 case types._function: 820 // Function as sole body of either an if statement or a labeled statement 821 // works, but not when it is part of a labeled statement that is the sole 822 // body of an if statement. 823 if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } 824 return this.parseFunctionStatement(node, false, !context) 825 case types._class: 826 if (context) { this.unexpected(); } 827 return this.parseClass(node, true) 828 case types._if: return this.parseIfStatement(node) 829 case types._return: return this.parseReturnStatement(node) 830 case types._switch: return this.parseSwitchStatement(node) 831 case types._throw: return this.parseThrowStatement(node) 832 case types._try: return this.parseTryStatement(node) 833 case types._const: case types._var: 834 kind = kind || this.value; 835 if (context && kind !== "var") { this.unexpected(); } 836 return this.parseVarStatement(node, kind) 837 case types._while: return this.parseWhileStatement(node) 838 case types._with: return this.parseWithStatement(node) 839 case types.braceL: return this.parseBlock(true, node) 840 case types.semi: return this.parseEmptyStatement(node) 841 case types._export: 842 case types._import: 843 if (this.options.ecmaVersion > 10 && starttype === types._import) { 844 skipWhiteSpace.lastIndex = this.pos; 845 var skip = skipWhiteSpace.exec(this.input); 846 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); 847 if (nextCh === 40) // '(' 848 { return this.parseExpressionStatement(node, this.parseExpression()) } 849 } 850 851 if (!this.options.allowImportExportEverywhere) { 852 if (!topLevel) 853 { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } 854 if (!this.inModule) 855 { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } 856 } 857 return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) 858 859 // If the statement does not start with a statement keyword or a 860 // brace, it's an ExpressionStatement or LabeledStatement. We 861 // simply start parsing an expression, and afterwards, if the 862 // next token is a colon and the expression was a simple 863 // Identifier node, we switch to interpreting it as a label. 864 default: 865 if (this.isAsyncFunction()) { 866 if (context) { this.unexpected(); } 867 this.next(); 868 return this.parseFunctionStatement(node, true, !context) 869 } 870 871 var maybeName = this.value, expr = this.parseExpression(); 872 if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) 873 { return this.parseLabeledStatement(node, maybeName, expr, context) } 874 else { return this.parseExpressionStatement(node, expr) } 875 } 876}; 877 878pp$1.parseBreakContinueStatement = function(node, keyword) { 879 var isBreak = keyword === "break"; 880 this.next(); 881 if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } 882 else if (this.type !== types.name) { this.unexpected(); } 883 else { 884 node.label = this.parseIdent(); 885 this.semicolon(); 886 } 887 888 // Verify that there is an actual destination to break or 889 // continue to. 890 var i = 0; 891 for (; i < this.labels.length; ++i) { 892 var lab = this.labels[i]; 893 if (node.label == null || lab.name === node.label.name) { 894 if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } 895 if (node.label && isBreak) { break } 896 } 897 } 898 if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } 899 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") 900}; 901 902pp$1.parseDebuggerStatement = function(node) { 903 this.next(); 904 this.semicolon(); 905 return this.finishNode(node, "DebuggerStatement") 906}; 907 908pp$1.parseDoStatement = function(node) { 909 this.next(); 910 this.labels.push(loopLabel); 911 node.body = this.parseStatement("do"); 912 this.labels.pop(); 913 this.expect(types._while); 914 node.test = this.parseParenExpression(); 915 if (this.options.ecmaVersion >= 6) 916 { this.eat(types.semi); } 917 else 918 { this.semicolon(); } 919 return this.finishNode(node, "DoWhileStatement") 920}; 921 922// Disambiguating between a `for` and a `for`/`in` or `for`/`of` 923// loop is non-trivial. Basically, we have to parse the init `var` 924// statement or expression, disallowing the `in` operator (see 925// the second parameter to `parseExpression`), and then check 926// whether the next token is `in` or `of`. When there is no init 927// part (semicolon immediately after the opening parenthesis), it 928// is a regular `for` loop. 929 930pp$1.parseForStatement = function(node) { 931 this.next(); 932 var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; 933 this.labels.push(loopLabel); 934 this.enterScope(0); 935 this.expect(types.parenL); 936 if (this.type === types.semi) { 937 if (awaitAt > -1) { this.unexpected(awaitAt); } 938 return this.parseFor(node, null) 939 } 940 var isLet = this.isLet(); 941 if (this.type === types._var || this.type === types._const || isLet) { 942 var init$1 = this.startNode(), kind = isLet ? "let" : this.value; 943 this.next(); 944 this.parseVar(init$1, true, kind); 945 this.finishNode(init$1, "VariableDeclaration"); 946 if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { 947 if (this.options.ecmaVersion >= 9) { 948 if (this.type === types._in) { 949 if (awaitAt > -1) { this.unexpected(awaitAt); } 950 } else { node.await = awaitAt > -1; } 951 } 952 return this.parseForIn(node, init$1) 953 } 954 if (awaitAt > -1) { this.unexpected(awaitAt); } 955 return this.parseFor(node, init$1) 956 } 957 var refDestructuringErrors = new DestructuringErrors; 958 var init = this.parseExpression(true, refDestructuringErrors); 959 if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { 960 if (this.options.ecmaVersion >= 9) { 961 if (this.type === types._in) { 962 if (awaitAt > -1) { this.unexpected(awaitAt); } 963 } else { node.await = awaitAt > -1; } 964 } 965 this.toAssignable(init, false, refDestructuringErrors); 966 this.checkLVal(init); 967 return this.parseForIn(node, init) 968 } else { 969 this.checkExpressionErrors(refDestructuringErrors, true); 970 } 971 if (awaitAt > -1) { this.unexpected(awaitAt); } 972 return this.parseFor(node, init) 973}; 974 975pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) { 976 this.next(); 977 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) 978}; 979 980pp$1.parseIfStatement = function(node) { 981 this.next(); 982 node.test = this.parseParenExpression(); 983 // allow function declarations in branches, but only in non-strict mode 984 node.consequent = this.parseStatement("if"); 985 node.alternate = this.eat(types._else) ? this.parseStatement("if") : null; 986 return this.finishNode(node, "IfStatement") 987}; 988 989pp$1.parseReturnStatement = function(node) { 990 if (!this.inFunction && !this.options.allowReturnOutsideFunction) 991 { this.raise(this.start, "'return' outside of function"); } 992 this.next(); 993 994 // In `return` (and `break`/`continue`), the keywords with 995 // optional arguments, we eagerly look for a semicolon or the 996 // possibility to insert one. 997 998 if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } 999 else { node.argument = this.parseExpression(); this.semicolon(); } 1000 return this.finishNode(node, "ReturnStatement") 1001}; 1002 1003pp$1.parseSwitchStatement = function(node) { 1004 this.next(); 1005 node.discriminant = this.parseParenExpression(); 1006 node.cases = []; 1007 this.expect(types.braceL); 1008 this.labels.push(switchLabel); 1009 this.enterScope(0); 1010 1011 // Statements under must be grouped (by label) in SwitchCase 1012 // nodes. `cur` is used to keep the node that we are currently 1013 // adding statements to. 1014 1015 var cur; 1016 for (var sawDefault = false; this.type !== types.braceR;) { 1017 if (this.type === types._case || this.type === types._default) { 1018 var isCase = this.type === types._case; 1019 if (cur) { this.finishNode(cur, "SwitchCase"); } 1020 node.cases.push(cur = this.startNode()); 1021 cur.consequent = []; 1022 this.next(); 1023 if (isCase) { 1024 cur.test = this.parseExpression(); 1025 } else { 1026 if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } 1027 sawDefault = true; 1028 cur.test = null; 1029 } 1030 this.expect(types.colon); 1031 } else { 1032 if (!cur) { this.unexpected(); } 1033 cur.consequent.push(this.parseStatement(null)); 1034 } 1035 } 1036 this.exitScope(); 1037 if (cur) { this.finishNode(cur, "SwitchCase"); } 1038 this.next(); // Closing brace 1039 this.labels.pop(); 1040 return this.finishNode(node, "SwitchStatement") 1041}; 1042 1043pp$1.parseThrowStatement = function(node) { 1044 this.next(); 1045 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) 1046 { this.raise(this.lastTokEnd, "Illegal newline after throw"); } 1047 node.argument = this.parseExpression(); 1048 this.semicolon(); 1049 return this.finishNode(node, "ThrowStatement") 1050}; 1051 1052// Reused empty array added for node fields that are always empty. 1053 1054var empty = []; 1055 1056pp$1.parseTryStatement = function(node) { 1057 this.next(); 1058 node.block = this.parseBlock(); 1059 node.handler = null; 1060 if (this.type === types._catch) { 1061 var clause = this.startNode(); 1062 this.next(); 1063 if (this.eat(types.parenL)) { 1064 clause.param = this.parseBindingAtom(); 1065 var simple = clause.param.type === "Identifier"; 1066 this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); 1067 this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); 1068 this.expect(types.parenR); 1069 } else { 1070 if (this.options.ecmaVersion < 10) { this.unexpected(); } 1071 clause.param = null; 1072 this.enterScope(0); 1073 } 1074 clause.body = this.parseBlock(false); 1075 this.exitScope(); 1076 node.handler = this.finishNode(clause, "CatchClause"); 1077 } 1078 node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; 1079 if (!node.handler && !node.finalizer) 1080 { this.raise(node.start, "Missing catch or finally clause"); } 1081 return this.finishNode(node, "TryStatement") 1082}; 1083 1084pp$1.parseVarStatement = function(node, kind) { 1085 this.next(); 1086 this.parseVar(node, false, kind); 1087 this.semicolon(); 1088 return this.finishNode(node, "VariableDeclaration") 1089}; 1090 1091pp$1.parseWhileStatement = function(node) { 1092 this.next(); 1093 node.test = this.parseParenExpression(); 1094 this.labels.push(loopLabel); 1095 node.body = this.parseStatement("while"); 1096 this.labels.pop(); 1097 return this.finishNode(node, "WhileStatement") 1098}; 1099 1100pp$1.parseWithStatement = function(node) { 1101 if (this.strict) { this.raise(this.start, "'with' in strict mode"); } 1102 this.next(); 1103 node.object = this.parseParenExpression(); 1104 node.body = this.parseStatement("with"); 1105 return this.finishNode(node, "WithStatement") 1106}; 1107 1108pp$1.parseEmptyStatement = function(node) { 1109 this.next(); 1110 return this.finishNode(node, "EmptyStatement") 1111}; 1112 1113pp$1.parseLabeledStatement = function(node, maybeName, expr, context) { 1114 for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) 1115 { 1116 var label = list[i$1]; 1117 1118 if (label.name === maybeName) 1119 { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); 1120 } } 1121 var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; 1122 for (var i = this.labels.length - 1; i >= 0; i--) { 1123 var label$1 = this.labels[i]; 1124 if (label$1.statementStart === node.start) { 1125 // Update information about previous labels on this node 1126 label$1.statementStart = this.start; 1127 label$1.kind = kind; 1128 } else { break } 1129 } 1130 this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); 1131 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); 1132 this.labels.pop(); 1133 node.label = expr; 1134 return this.finishNode(node, "LabeledStatement") 1135}; 1136 1137pp$1.parseExpressionStatement = function(node, expr) { 1138 node.expression = expr; 1139 this.semicolon(); 1140 return this.finishNode(node, "ExpressionStatement") 1141}; 1142 1143// Parse a semicolon-enclosed block of statements, handling `"use 1144// strict"` declarations when `allowStrict` is true (used for 1145// function bodies). 1146 1147pp$1.parseBlock = function(createNewLexicalScope, node) { 1148 if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; 1149 if ( node === void 0 ) node = this.startNode(); 1150 1151 node.body = []; 1152 this.expect(types.braceL); 1153 if (createNewLexicalScope) { this.enterScope(0); } 1154 while (!this.eat(types.braceR)) { 1155 var stmt = this.parseStatement(null); 1156 node.body.push(stmt); 1157 } 1158 if (createNewLexicalScope) { this.exitScope(); } 1159 return this.finishNode(node, "BlockStatement") 1160}; 1161 1162// Parse a regular `for` loop. The disambiguation code in 1163// `parseStatement` will already have parsed the init statement or 1164// expression. 1165 1166pp$1.parseFor = function(node, init) { 1167 node.init = init; 1168 this.expect(types.semi); 1169 node.test = this.type === types.semi ? null : this.parseExpression(); 1170 this.expect(types.semi); 1171 node.update = this.type === types.parenR ? null : this.parseExpression(); 1172 this.expect(types.parenR); 1173 node.body = this.parseStatement("for"); 1174 this.exitScope(); 1175 this.labels.pop(); 1176 return this.finishNode(node, "ForStatement") 1177}; 1178 1179// Parse a `for`/`in` and `for`/`of` loop, which are almost 1180// same from parser's perspective. 1181 1182pp$1.parseForIn = function(node, init) { 1183 var isForIn = this.type === types._in; 1184 this.next(); 1185 1186 if ( 1187 init.type === "VariableDeclaration" && 1188 init.declarations[0].init != null && 1189 ( 1190 !isForIn || 1191 this.options.ecmaVersion < 8 || 1192 this.strict || 1193 init.kind !== "var" || 1194 init.declarations[0].id.type !== "Identifier" 1195 ) 1196 ) { 1197 this.raise( 1198 init.start, 1199 ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") 1200 ); 1201 } else if (init.type === "AssignmentPattern") { 1202 this.raise(init.start, "Invalid left-hand side in for-loop"); 1203 } 1204 node.left = init; 1205 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); 1206 this.expect(types.parenR); 1207 node.body = this.parseStatement("for"); 1208 this.exitScope(); 1209 this.labels.pop(); 1210 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") 1211}; 1212 1213// Parse a list of variable declarations. 1214 1215pp$1.parseVar = function(node, isFor, kind) { 1216 node.declarations = []; 1217 node.kind = kind; 1218 for (;;) { 1219 var decl = this.startNode(); 1220 this.parseVarId(decl, kind); 1221 if (this.eat(types.eq)) { 1222 decl.init = this.parseMaybeAssign(isFor); 1223 } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { 1224 this.unexpected(); 1225 } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) { 1226 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); 1227 } else { 1228 decl.init = null; 1229 } 1230 node.declarations.push(this.finishNode(decl, "VariableDeclarator")); 1231 if (!this.eat(types.comma)) { break } 1232 } 1233 return node 1234}; 1235 1236pp$1.parseVarId = function(decl, kind) { 1237 decl.id = this.parseBindingAtom(); 1238 this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); 1239}; 1240 1241var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; 1242 1243// Parse a function declaration or literal (depending on the 1244// `statement & FUNC_STATEMENT`). 1245 1246// Remove `allowExpressionBody` for 7.0.0, as it is only called with false 1247pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) { 1248 this.initFunction(node); 1249 if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { 1250 if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT)) 1251 { this.unexpected(); } 1252 node.generator = this.eat(types.star); 1253 } 1254 if (this.options.ecmaVersion >= 8) 1255 { node.async = !!isAsync; } 1256 1257 if (statement & FUNC_STATEMENT) { 1258 node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent(); 1259 if (node.id && !(statement & FUNC_HANGING_STATEMENT)) 1260 // If it is a regular function declaration in sloppy mode, then it is 1261 // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding 1262 // mode depends on properties of the current scope (see 1263 // treatFunctionsAsVar). 1264 { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } 1265 } 1266 1267 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; 1268 this.yieldPos = 0; 1269 this.awaitPos = 0; 1270 this.awaitIdentPos = 0; 1271 this.enterScope(functionFlags(node.async, node.generator)); 1272 1273 if (!(statement & FUNC_STATEMENT)) 1274 { node.id = this.type === types.name ? this.parseIdent() : null; } 1275 1276 this.parseFunctionParams(node); 1277 this.parseFunctionBody(node, allowExpressionBody, false); 1278 1279 this.yieldPos = oldYieldPos; 1280 this.awaitPos = oldAwaitPos; 1281 this.awaitIdentPos = oldAwaitIdentPos; 1282 return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") 1283}; 1284 1285pp$1.parseFunctionParams = function(node) { 1286 this.expect(types.parenL); 1287 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); 1288 this.checkYieldAwaitInDefaultParams(); 1289}; 1290 1291// Parse a class declaration or literal (depending on the 1292// `isStatement` parameter). 1293 1294pp$1.parseClass = function(node, isStatement) { 1295 this.next(); 1296 1297 // ecma-262 14.6 Class Definitions 1298 // A class definition is always strict mode code. 1299 var oldStrict = this.strict; 1300 this.strict = true; 1301 1302 this.parseClassId(node, isStatement); 1303 this.parseClassSuper(node); 1304 var classBody = this.startNode(); 1305 var hadConstructor = false; 1306 classBody.body = []; 1307 this.expect(types.braceL); 1308 while (!this.eat(types.braceR)) { 1309 var element = this.parseClassElement(node.superClass !== null); 1310 if (element) { 1311 classBody.body.push(element); 1312 if (element.type === "MethodDefinition" && element.kind === "constructor") { 1313 if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } 1314 hadConstructor = true; 1315 } 1316 } 1317 } 1318 node.body = this.finishNode(classBody, "ClassBody"); 1319 this.strict = oldStrict; 1320 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") 1321}; 1322 1323pp$1.parseClassElement = function(constructorAllowsSuper) { 1324 var this$1 = this; 1325 1326 if (this.eat(types.semi)) { return null } 1327 1328 var method = this.startNode(); 1329 var tryContextual = function (k, noLineBreak) { 1330 if ( noLineBreak === void 0 ) noLineBreak = false; 1331 1332 var start = this$1.start, startLoc = this$1.startLoc; 1333 if (!this$1.eatContextual(k)) { return false } 1334 if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } 1335 if (method.key) { this$1.unexpected(); } 1336 method.computed = false; 1337 method.key = this$1.startNodeAt(start, startLoc); 1338 method.key.name = k; 1339 this$1.finishNode(method.key, "Identifier"); 1340 return false 1341 }; 1342 1343 method.kind = "method"; 1344 method.static = tryContextual("static"); 1345 var isGenerator = this.eat(types.star); 1346 var isAsync = false; 1347 if (!isGenerator) { 1348 if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { 1349 isAsync = true; 1350 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); 1351 } else if (tryContextual("get")) { 1352 method.kind = "get"; 1353 } else if (tryContextual("set")) { 1354 method.kind = "set"; 1355 } 1356 } 1357 if (!method.key) { this.parsePropertyName(method); } 1358 var key = method.key; 1359 var allowsDirectSuper = false; 1360 if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || 1361 key.type === "Literal" && key.value === "constructor")) { 1362 if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } 1363 if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } 1364 if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } 1365 method.kind = "constructor"; 1366 allowsDirectSuper = constructorAllowsSuper; 1367 } else if (method.static && key.type === "Identifier" && key.name === "prototype") { 1368 this.raise(key.start, "Classes may not have a static property named prototype"); 1369 } 1370 this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper); 1371 if (method.kind === "get" && method.value.params.length !== 0) 1372 { this.raiseRecoverable(method.value.start, "getter should have no params"); } 1373 if (method.kind === "set" && method.value.params.length !== 1) 1374 { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } 1375 if (method.kind === "set" && method.value.params[0].type === "RestElement") 1376 { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } 1377 return method 1378}; 1379 1380pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { 1381 method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); 1382 return this.finishNode(method, "MethodDefinition") 1383}; 1384 1385pp$1.parseClassId = function(node, isStatement) { 1386 if (this.type === types.name) { 1387 node.id = this.parseIdent(); 1388 if (isStatement) 1389 { this.checkLVal(node.id, BIND_LEXICAL, false); } 1390 } else { 1391 if (isStatement === true) 1392 { this.unexpected(); } 1393 node.id = null; 1394 } 1395}; 1396 1397pp$1.parseClassSuper = function(node) { 1398 node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; 1399}; 1400 1401// Parses module export declaration. 1402 1403pp$1.parseExport = function(node, exports) { 1404 this.next(); 1405 // export * from '...' 1406 if (this.eat(types.star)) { 1407 this.expectContextual("from"); 1408 if (this.type !== types.string) { this.unexpected(); } 1409 node.source = this.parseExprAtom(); 1410 this.semicolon(); 1411 return this.finishNode(node, "ExportAllDeclaration") 1412 } 1413 if (this.eat(types._default)) { // export default ... 1414 this.checkExport(exports, "default", this.lastTokStart); 1415 var isAsync; 1416 if (this.type === types._function || (isAsync = this.isAsyncFunction())) { 1417 var fNode = this.startNode(); 1418 this.next(); 1419 if (isAsync) { this.next(); } 1420 node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); 1421 } else if (this.type === types._class) { 1422 var cNode = this.startNode(); 1423 node.declaration = this.parseClass(cNode, "nullableID"); 1424 } else { 1425 node.declaration = this.parseMaybeAssign(); 1426 this.semicolon(); 1427 } 1428 return this.finishNode(node, "ExportDefaultDeclaration") 1429 } 1430 // export var|const|let|function|class ... 1431 if (this.shouldParseExportStatement()) { 1432 node.declaration = this.parseStatement(null); 1433 if (node.declaration.type === "VariableDeclaration") 1434 { this.checkVariableExport(exports, node.declaration.declarations); } 1435 else 1436 { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } 1437 node.specifiers = []; 1438 node.source = null; 1439 } else { // export { x, y as z } [from '...'] 1440 node.declaration = null; 1441 node.specifiers = this.parseExportSpecifiers(exports); 1442 if (this.eatContextual("from")) { 1443 if (this.type !== types.string) { this.unexpected(); } 1444 node.source = this.parseExprAtom(); 1445 } else { 1446 for (var i = 0, list = node.specifiers; i < list.length; i += 1) { 1447 // check for keywords used as local names 1448 var spec = list[i]; 1449 1450 this.checkUnreserved(spec.local); 1451 // check if export is defined 1452 this.checkLocalExport(spec.local); 1453 } 1454 1455 node.source = null; 1456 } 1457 this.semicolon(); 1458 } 1459 return this.finishNode(node, "ExportNamedDeclaration") 1460}; 1461 1462pp$1.checkExport = function(exports, name, pos) { 1463 if (!exports) { return } 1464 if (has(exports, name)) 1465 { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } 1466 exports[name] = true; 1467}; 1468 1469pp$1.checkPatternExport = function(exports, pat) { 1470 var type = pat.type; 1471 if (type === "Identifier") 1472 { this.checkExport(exports, pat.name, pat.start); } 1473 else if (type === "ObjectPattern") 1474 { for (var i = 0, list = pat.properties; i < list.length; i += 1) 1475 { 1476 var prop = list[i]; 1477 1478 this.checkPatternExport(exports, prop); 1479 } } 1480 else if (type === "ArrayPattern") 1481 { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { 1482 var elt = list$1[i$1]; 1483 1484 if (elt) { this.checkPatternExport(exports, elt); } 1485 } } 1486 else if (type === "Property") 1487 { this.checkPatternExport(exports, pat.value); } 1488 else if (type === "AssignmentPattern") 1489 { this.checkPatternExport(exports, pat.left); } 1490 else if (type === "RestElement") 1491 { this.checkPatternExport(exports, pat.argument); } 1492 else if (type === "ParenthesizedExpression") 1493 { this.checkPatternExport(exports, pat.expression); } 1494}; 1495 1496pp$1.checkVariableExport = function(exports, decls) { 1497 if (!exports) { return } 1498 for (var i = 0, list = decls; i < list.length; i += 1) 1499 { 1500 var decl = list[i]; 1501 1502 this.checkPatternExport(exports, decl.id); 1503 } 1504}; 1505 1506pp$1.shouldParseExportStatement = function() { 1507 return this.type.keyword === "var" || 1508 this.type.keyword === "const" || 1509 this.type.keyword === "class" || 1510 this.type.keyword === "function" || 1511 this.isLet() || 1512 this.isAsyncFunction() 1513}; 1514 1515// Parses a comma-separated list of module exports. 1516 1517pp$1.parseExportSpecifiers = function(exports) { 1518 var nodes = [], first = true; 1519 // export { x, y as z } [from '...'] 1520 this.expect(types.braceL); 1521 while (!this.eat(types.braceR)) { 1522 if (!first) { 1523 this.expect(types.comma); 1524 if (this.afterTrailingComma(types.braceR)) { break } 1525 } else { first = false; } 1526 1527 var node = this.startNode(); 1528 node.local = this.parseIdent(true); 1529 node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local; 1530 this.checkExport(exports, node.exported.name, node.exported.start); 1531 nodes.push(this.finishNode(node, "ExportSpecifier")); 1532 } 1533 return nodes 1534}; 1535 1536// Parses import declaration. 1537 1538pp$1.parseImport = function(node) { 1539 this.next(); 1540 // import '...' 1541 if (this.type === types.string) { 1542 node.specifiers = empty; 1543 node.source = this.parseExprAtom(); 1544 } else { 1545 node.specifiers = this.parseImportSpecifiers(); 1546 this.expectContextual("from"); 1547 node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); 1548 } 1549 this.semicolon(); 1550 return this.finishNode(node, "ImportDeclaration") 1551}; 1552 1553// Parses a comma-separated list of module imports. 1554 1555pp$1.parseImportSpecifiers = function() { 1556 var nodes = [], first = true; 1557 if (this.type === types.name) { 1558 // import defaultObj, { x, y as z } from '...' 1559 var node = this.startNode(); 1560 node.local = this.parseIdent(); 1561 this.checkLVal(node.local, BIND_LEXICAL); 1562 nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); 1563 if (!this.eat(types.comma)) { return nodes } 1564 } 1565 if (this.type === types.star) { 1566 var node$1 = this.startNode(); 1567 this.next(); 1568 this.expectContextual("as"); 1569 node$1.local = this.parseIdent(); 1570 this.checkLVal(node$1.local, BIND_LEXICAL); 1571 nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); 1572 return nodes 1573 } 1574 this.expect(types.braceL); 1575 while (!this.eat(types.braceR)) { 1576 if (!first) { 1577 this.expect(types.comma); 1578 if (this.afterTrailingComma(types.braceR)) { break } 1579 } else { first = false; } 1580 1581 var node$2 = this.startNode(); 1582 node$2.imported = this.parseIdent(true); 1583 if (this.eatContextual("as")) { 1584 node$2.local = this.parseIdent(); 1585 } else { 1586 this.checkUnreserved(node$2.imported); 1587 node$2.local = node$2.imported; 1588 } 1589 this.checkLVal(node$2.local, BIND_LEXICAL); 1590 nodes.push(this.finishNode(node$2, "ImportSpecifier")); 1591 } 1592 return nodes 1593}; 1594 1595// Set `ExpressionStatement#directive` property for directive prologues. 1596pp$1.adaptDirectivePrologue = function(statements) { 1597 for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { 1598 statements[i].directive = statements[i].expression.raw.slice(1, -1); 1599 } 1600}; 1601pp$1.isDirectiveCandidate = function(statement) { 1602 return ( 1603 statement.type === "ExpressionStatement" && 1604 statement.expression.type === "Literal" && 1605 typeof statement.expression.value === "string" && 1606 // Reject parenthesized strings. 1607 (this.input[statement.start] === "\"" || this.input[statement.start] === "'") 1608 ) 1609}; 1610 1611var pp$2 = Parser.prototype; 1612 1613// Convert existing expression atom to assignable pattern 1614// if possible. 1615 1616pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { 1617 if (this.options.ecmaVersion >= 6 && node) { 1618 switch (node.type) { 1619 case "Identifier": 1620 if (this.inAsync && node.name === "await") 1621 { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } 1622 break 1623 1624 case "ObjectPattern": 1625 case "ArrayPattern": 1626 case "RestElement": 1627 break 1628 1629 case "ObjectExpression": 1630 node.type = "ObjectPattern"; 1631 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } 1632 for (var i = 0, list = node.properties; i < list.length; i += 1) { 1633 var prop = list[i]; 1634 1635 this.toAssignable(prop, isBinding); 1636 // Early error: 1637 // AssignmentRestProperty[Yield, Await] : 1638 // `...` DestructuringAssignmentTarget[Yield, Await] 1639 // 1640 // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. 1641 if ( 1642 prop.type === "RestElement" && 1643 (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") 1644 ) { 1645 this.raise(prop.argument.start, "Unexpected token"); 1646 } 1647 } 1648 break 1649 1650 case "Property": 1651 // AssignmentProperty has type === "Property" 1652 if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } 1653 this.toAssignable(node.value, isBinding); 1654 break 1655 1656 case "ArrayExpression": 1657 node.type = "ArrayPattern"; 1658 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } 1659 this.toAssignableList(node.elements, isBinding); 1660 break 1661 1662 case "SpreadElement": 1663 node.type = "RestElement"; 1664 this.toAssignable(node.argument, isBinding); 1665 if (node.argument.type === "AssignmentPattern") 1666 { this.raise(node.argument.start, "Rest elements cannot have a default value"); } 1667 break 1668 1669 case "AssignmentExpression": 1670 if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } 1671 node.type = "AssignmentPattern"; 1672 delete node.operator; 1673 this.toAssignable(node.left, isBinding); 1674 // falls through to AssignmentPattern 1675 1676 case "AssignmentPattern": 1677 break 1678 1679 case "ParenthesizedExpression": 1680 this.toAssignable(node.expression, isBinding, refDestructuringErrors); 1681 break 1682 1683 case "MemberExpression": 1684 if (!isBinding) { break } 1685 1686 default: 1687 this.raise(node.start, "Assigning to rvalue"); 1688 } 1689 } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } 1690 return node 1691}; 1692 1693// Convert list of expression atoms to binding list. 1694 1695pp$2.toAssignableList = function(exprList, isBinding) { 1696 var end = exprList.length; 1697 for (var i = 0; i < end; i++) { 1698 var elt = exprList[i]; 1699 if (elt) { this.toAssignable(elt, isBinding); } 1700 } 1701 if (end) { 1702 var last = exprList[end - 1]; 1703 if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") 1704 { this.unexpected(last.argument.start); } 1705 } 1706 return exprList 1707}; 1708 1709// Parses spread element. 1710 1711pp$2.parseSpread = function(refDestructuringErrors) { 1712 var node = this.startNode(); 1713 this.next(); 1714 node.argument = this.parseMaybeAssign(false, refDestructuringErrors); 1715 return this.finishNode(node, "SpreadElement") 1716}; 1717 1718pp$2.parseRestBinding = function() { 1719 var node = this.startNode(); 1720 this.next(); 1721 1722 // RestElement inside of a function parameter must be an identifier 1723 if (this.options.ecmaVersion === 6 && this.type !== types.name) 1724 { this.unexpected(); } 1725 1726 node.argument = this.parseBindingAtom(); 1727 1728 return this.finishNode(node, "RestElement") 1729}; 1730 1731// Parses lvalue (assignable) atom. 1732 1733pp$2.parseBindingAtom = function() { 1734 if (this.options.ecmaVersion >= 6) { 1735 switch (this.type) { 1736 case types.bracketL: 1737 var node = this.startNode(); 1738 this.next(); 1739 node.elements = this.parseBindingList(types.bracketR, true, true); 1740 return this.finishNode(node, "ArrayPattern") 1741 1742 case types.braceL: 1743 return this.parseObj(true) 1744 } 1745 } 1746 return this.parseIdent() 1747}; 1748 1749pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { 1750 var elts = [], first = true; 1751 while (!this.eat(close)) { 1752 if (first) { first = false; } 1753 else { this.expect(types.comma); } 1754 if (allowEmpty && this.type === types.comma) { 1755 elts.push(null); 1756 } else if (allowTrailingComma && this.afterTrailingComma(close)) { 1757 break 1758 } else if (this.type === types.ellipsis) { 1759 var rest = this.parseRestBinding(); 1760 this.parseBindingListItem(rest); 1761 elts.push(rest); 1762 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } 1763 this.expect(close); 1764 break 1765 } else { 1766 var elem = this.parseMaybeDefault(this.start, this.startLoc); 1767 this.parseBindingListItem(elem); 1768 elts.push(elem); 1769 } 1770 } 1771 return elts 1772}; 1773 1774pp$2.parseBindingListItem = function(param) { 1775 return param 1776}; 1777 1778// Parses assignment pattern around given atom if possible. 1779 1780pp$2.parseMaybeDefault = function(startPos, startLoc, left) { 1781 left = left || this.parseBindingAtom(); 1782 if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } 1783 var node = this.startNodeAt(startPos, startLoc); 1784 node.left = left; 1785 node.right = this.parseMaybeAssign(); 1786 return this.finishNode(node, "AssignmentPattern") 1787}; 1788 1789// Verify that a node is an lval — something that can be assigned 1790// to. 1791// bindingType can be either: 1792// 'var' indicating that the lval creates a 'var' binding 1793// 'let' indicating that the lval creates a lexical ('let' or 'const') binding 1794// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references 1795 1796pp$2.checkLVal = function(expr, bindingType, checkClashes) { 1797 if ( bindingType === void 0 ) bindingType = BIND_NONE; 1798 1799 switch (expr.type) { 1800 case "Identifier": 1801 if (bindingType === BIND_LEXICAL && expr.name === "let") 1802 { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } 1803 if (this.strict && this.reservedWordsStrictBind.test(expr.name)) 1804 { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } 1805 if (checkClashes) { 1806 if (has(checkClashes, expr.name)) 1807 { this.raiseRecoverable(expr.start, "Argument name clash"); } 1808 checkClashes[expr.name] = true; 1809 } 1810 if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } 1811 break 1812 1813 case "MemberExpression": 1814 if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } 1815 break 1816 1817 case "ObjectPattern": 1818 for (var i = 0, list = expr.properties; i < list.length; i += 1) 1819 { 1820 var prop = list[i]; 1821 1822 this.checkLVal(prop, bindingType, checkClashes); 1823 } 1824 break 1825 1826 case "Property": 1827 // AssignmentProperty has type === "Property" 1828 this.checkLVal(expr.value, bindingType, checkClashes); 1829 break 1830 1831 case "ArrayPattern": 1832 for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { 1833 var elem = list$1[i$1]; 1834 1835 if (elem) { this.checkLVal(elem, bindingType, checkClashes); } 1836 } 1837 break 1838 1839 case "AssignmentPattern": 1840 this.checkLVal(expr.left, bindingType, checkClashes); 1841 break 1842 1843 case "RestElement": 1844 this.checkLVal(expr.argument, bindingType, checkClashes); 1845 break 1846 1847 case "ParenthesizedExpression": 1848 this.checkLVal(expr.expression, bindingType, checkClashes); 1849 break 1850 1851 default: 1852 this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); 1853 } 1854}; 1855 1856// A recursive descent parser operates by defining functions for all 1857 1858var pp$3 = Parser.prototype; 1859 1860// Check if property name clashes with already added. 1861// Object/class getters and setters are not allowed to clash — 1862// either with each other or with an init property — and in 1863// strict mode, init properties are also not allowed to be repeated. 1864 1865pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { 1866 if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") 1867 { return } 1868 if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) 1869 { return } 1870 var key = prop.key; 1871 var name; 1872 switch (key.type) { 1873 case "Identifier": name = key.name; break 1874 case "Literal": name = String(key.value); break 1875 default: return 1876 } 1877 var kind = prop.kind; 1878 if (this.options.ecmaVersion >= 6) { 1879 if (name === "__proto__" && kind === "init") { 1880 if (propHash.proto) { 1881 if (refDestructuringErrors) { 1882 if (refDestructuringErrors.doubleProto < 0) 1883 { refDestructuringErrors.doubleProto = key.start; } 1884 // Backwards-compat kludge. Can be removed in version 6.0 1885 } else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } 1886 } 1887 propHash.proto = true; 1888 } 1889 return 1890 } 1891 name = "$" + name; 1892 var other = propHash[name]; 1893 if (other) { 1894 var redefinition; 1895 if (kind === "init") { 1896 redefinition = this.strict && other.init || other.get || other.set; 1897 } else { 1898 redefinition = other.init || other[kind]; 1899 } 1900 if (redefinition) 1901 { this.raiseRecoverable(key.start, "Redefinition of property"); } 1902 } else { 1903 other = propHash[name] = { 1904 init: false, 1905 get: false, 1906 set: false 1907 }; 1908 } 1909 other[kind] = true; 1910}; 1911 1912// ### Expression parsing 1913 1914// These nest, from the most general expression type at the top to 1915// 'atomic', nondivisible expression types at the bottom. Most of 1916// the functions will simply let the function(s) below them parse, 1917// and, *if* the syntactic construct they handle is present, wrap 1918// the AST node that the inner parser gave them in another node. 1919 1920// Parse a full expression. The optional arguments are used to 1921// forbid the `in` operator (in for loops initalization expressions) 1922// and provide reference for storing '=' operator inside shorthand 1923// property assignment in contexts where both object expression 1924// and object pattern might appear (so it's possible to raise 1925// delayed syntax error at correct position). 1926 1927pp$3.parseExpression = function(noIn, refDestructuringErrors) { 1928 var startPos = this.start, startLoc = this.startLoc; 1929 var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); 1930 if (this.type === types.comma) { 1931 var node = this.startNodeAt(startPos, startLoc); 1932 node.expressions = [expr]; 1933 while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); } 1934 return this.finishNode(node, "SequenceExpression") 1935 } 1936 return expr 1937}; 1938 1939// Parse an assignment expression. This includes applications of 1940// operators like `+=`. 1941 1942pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { 1943 if (this.isContextual("yield")) { 1944 if (this.inGenerator) { return this.parseYield(noIn) } 1945 // The tokenizer will assume an expression is allowed after 1946 // `yield`, but this isn't that kind of yield 1947 else { this.exprAllowed = false; } 1948 } 1949 1950 var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; 1951 if (refDestructuringErrors) { 1952 oldParenAssign = refDestructuringErrors.parenthesizedAssign; 1953 oldTrailingComma = refDestructuringErrors.trailingComma; 1954 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; 1955 } else { 1956 refDestructuringErrors = new DestructuringErrors; 1957 ownDestructuringErrors = true; 1958 } 1959 1960 var startPos = this.start, startLoc = this.startLoc; 1961 if (this.type === types.parenL || this.type === types.name) 1962 { this.potentialArrowAt = this.start; } 1963 var left = this.parseMaybeConditional(noIn, refDestructuringErrors); 1964 if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } 1965 if (this.type.isAssign) { 1966 var node = this.startNodeAt(startPos, startLoc); 1967 node.operator = this.value; 1968 node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; 1969 if (!ownDestructuringErrors) { 1970 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; 1971 } 1972 if (refDestructuringErrors.shorthandAssign >= node.left.start) 1973 { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly 1974 this.checkLVal(left); 1975 this.next(); 1976 node.right = this.parseMaybeAssign(noIn); 1977 return this.finishNode(node, "AssignmentExpression") 1978 } else { 1979 if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } 1980 } 1981 if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } 1982 if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } 1983 return left 1984}; 1985 1986// Parse a ternary conditional (`?:`) operator. 1987 1988pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { 1989 var startPos = this.start, startLoc = this.startLoc; 1990 var expr = this.parseExprOps(noIn, refDestructuringErrors); 1991 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } 1992 if (this.eat(types.question)) { 1993 var node = this.startNodeAt(startPos, startLoc); 1994 node.test = expr; 1995 node.consequent = this.parseMaybeAssign(); 1996 this.expect(types.colon); 1997 node.alternate = this.parseMaybeAssign(noIn); 1998 return this.finishNode(node, "ConditionalExpression") 1999 } 2000 return expr 2001}; 2002 2003// Start the precedence parser. 2004 2005pp$3.parseExprOps = function(noIn, refDestructuringErrors) { 2006 var startPos = this.start, startLoc = this.startLoc; 2007 var expr = this.parseMaybeUnary(refDestructuringErrors, false); 2008 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } 2009 return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) 2010}; 2011 2012// Parse binary operators with the operator precedence parsing 2013// algorithm. `left` is the left-hand side of the operator. 2014// `minPrec` provides context that allows the function to stop and 2015// defer further parser to one of its callers when it encounters an 2016// operator that has a lower precedence than the set it is parsing. 2017 2018pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { 2019 var prec = this.type.binop; 2020 if (prec != null && (!noIn || this.type !== types._in)) { 2021 if (prec > minPrec) { 2022 var logical = this.type === types.logicalOR || this.type === types.logicalAND; 2023 var op = this.value; 2024 this.next(); 2025 var startPos = this.start, startLoc = this.startLoc; 2026 var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); 2027 var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); 2028 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) 2029 } 2030 } 2031 return left 2032}; 2033 2034pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { 2035 var node = this.startNodeAt(startPos, startLoc); 2036 node.left = left; 2037 node.operator = op; 2038 node.right = right; 2039 return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") 2040}; 2041 2042// Parse unary operators, both prefix and postfix. 2043 2044pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { 2045 var startPos = this.start, startLoc = this.startLoc, expr; 2046 if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { 2047 expr = this.parseAwait(); 2048 sawUnary = true; 2049 } else if (this.type.prefix) { 2050 var node = this.startNode(), update = this.type === types.incDec; 2051 node.operator = this.value; 2052 node.prefix = true; 2053 this.next(); 2054 node.argument = this.parseMaybeUnary(null, true); 2055 this.checkExpressionErrors(refDestructuringErrors, true); 2056 if (update) { this.checkLVal(node.argument); } 2057 else if (this.strict && node.operator === "delete" && 2058 node.argument.type === "Identifier") 2059 { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } 2060 else { sawUnary = true; } 2061 expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); 2062 } else { 2063 expr = this.parseExprSubscripts(refDestructuringErrors); 2064 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } 2065 while (this.type.postfix && !this.canInsertSemicolon()) { 2066 var node$1 = this.startNodeAt(startPos, startLoc); 2067 node$1.operator = this.value; 2068 node$1.prefix = false; 2069 node$1.argument = expr; 2070 this.checkLVal(expr); 2071 this.next(); 2072 expr = this.finishNode(node$1, "UpdateExpression"); 2073 } 2074 } 2075 2076 if (!sawUnary && this.eat(types.starstar)) 2077 { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } 2078 else 2079 { return expr } 2080}; 2081 2082// Parse call, dot, and `[]`-subscript expressions. 2083 2084pp$3.parseExprSubscripts = function(refDestructuringErrors) { 2085 var startPos = this.start, startLoc = this.startLoc; 2086 var expr = this.parseExprAtom(refDestructuringErrors); 2087 if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") 2088 { return expr } 2089 var result = this.parseSubscripts(expr, startPos, startLoc); 2090 if (refDestructuringErrors && result.type === "MemberExpression") { 2091 if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } 2092 if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } 2093 } 2094 return result 2095}; 2096 2097pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { 2098 var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && 2099 this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; 2100 while (true) { 2101 var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow); 2102 if (element === base || element.type === "ArrowFunctionExpression") { return element } 2103 base = element; 2104 } 2105}; 2106 2107pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow) { 2108 var computed = this.eat(types.bracketL); 2109 if (computed || this.eat(types.dot)) { 2110 var node = this.startNodeAt(startPos, startLoc); 2111 node.object = base; 2112 node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never"); 2113 node.computed = !!computed; 2114 if (computed) { this.expect(types.bracketR); } 2115 base = this.finishNode(node, "MemberExpression"); 2116 } else if (!noCalls && this.eat(types.parenL)) { 2117 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; 2118 this.yieldPos = 0; 2119 this.awaitPos = 0; 2120 this.awaitIdentPos = 0; 2121 var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); 2122 if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { 2123 this.checkPatternErrors(refDestructuringErrors, false); 2124 this.checkYieldAwaitInDefaultParams(); 2125 if (this.awaitIdentPos > 0) 2126 { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } 2127 this.yieldPos = oldYieldPos; 2128 this.awaitPos = oldAwaitPos; 2129 this.awaitIdentPos = oldAwaitIdentPos; 2130 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true) 2131 } 2132 this.checkExpressionErrors(refDestructuringErrors, true); 2133 this.yieldPos = oldYieldPos || this.yieldPos; 2134 this.awaitPos = oldAwaitPos || this.awaitPos; 2135 this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; 2136 var node$1 = this.startNodeAt(startPos, startLoc); 2137 node$1.callee = base; 2138 node$1.arguments = exprList; 2139 base = this.finishNode(node$1, "CallExpression"); 2140 } else if (this.type === types.backQuote) { 2141 var node$2 = this.startNodeAt(startPos, startLoc); 2142 node$2.tag = base; 2143 node$2.quasi = this.parseTemplate({isTagged: true}); 2144 base = this.finishNode(node$2, "TaggedTemplateExpression"); 2145 } 2146 return base 2147}; 2148 2149// Parse an atomic expression — either a single token that is an 2150// expression, an expression started by a keyword like `function` or 2151// `new`, or an expression wrapped in punctuation like `()`, `[]`, 2152// or `{}`. 2153 2154pp$3.parseExprAtom = function(refDestructuringErrors) { 2155 // If a division operator appears in an expression position, the 2156 // tokenizer got confused, and we force it to read a regexp instead. 2157 if (this.type === types.slash) { this.readRegexp(); } 2158 2159 var node, canBeArrow = this.potentialArrowAt === this.start; 2160 switch (this.type) { 2161 case types._super: 2162 if (!this.allowSuper) 2163 { this.raise(this.start, "'super' keyword outside a method"); } 2164 node = this.startNode(); 2165 this.next(); 2166 if (this.type === types.parenL && !this.allowDirectSuper) 2167 { this.raise(node.start, "super() call outside constructor of a subclass"); } 2168 // The `super` keyword can appear at below: 2169 // SuperProperty: 2170 // super [ Expression ] 2171 // super . IdentifierName 2172 // SuperCall: 2173 // super ( Arguments ) 2174 if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) 2175 { this.unexpected(); } 2176 return this.finishNode(node, "Super") 2177 2178 case types._this: 2179 node = this.startNode(); 2180 this.next(); 2181 return this.finishNode(node, "ThisExpression") 2182 2183 case types.name: 2184 var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; 2185 var id = this.parseIdent(false); 2186 if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) 2187 { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true) } 2188 if (canBeArrow && !this.canInsertSemicolon()) { 2189 if (this.eat(types.arrow)) 2190 { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } 2191 if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { 2192 id = this.parseIdent(false); 2193 if (this.canInsertSemicolon() || !this.eat(types.arrow)) 2194 { this.unexpected(); } 2195 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) 2196 } 2197 } 2198 return id 2199 2200 case types.regexp: 2201 var value = this.value; 2202 node = this.parseLiteral(value.value); 2203 node.regex = {pattern: value.pattern, flags: value.flags}; 2204 return node 2205 2206 case types.num: case types.string: 2207 return this.parseLiteral(this.value) 2208 2209 case types._null: case types._true: case types._false: 2210 node = this.startNode(); 2211 node.value = this.type === types._null ? null : this.type === types._true; 2212 node.raw = this.type.keyword; 2213 this.next(); 2214 return this.finishNode(node, "Literal") 2215 2216 case types.parenL: 2217 var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); 2218 if (refDestructuringErrors) { 2219 if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) 2220 { refDestructuringErrors.parenthesizedAssign = start; } 2221 if (refDestructuringErrors.parenthesizedBind < 0) 2222 { refDestructuringErrors.parenthesizedBind = start; } 2223 } 2224 return expr 2225 2226 case types.bracketL: 2227 node = this.startNode(); 2228 this.next(); 2229 node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); 2230 return this.finishNode(node, "ArrayExpression") 2231 2232 case types.braceL: 2233 return this.parseObj(false, refDestructuringErrors) 2234 2235 case types._function: 2236 node = this.startNode(); 2237 this.next(); 2238 return this.parseFunction(node, 0) 2239 2240 case types._class: 2241 return this.parseClass(this.startNode(), false) 2242 2243 case types._new: 2244 return this.parseNew() 2245 2246 case types.backQuote: 2247 return this.parseTemplate() 2248 2249 case types._import: 2250 if (this.options.ecmaVersion >= 11) { 2251 return this.parseExprImport() 2252 } else { 2253 return this.unexpected() 2254 } 2255 2256 default: 2257 this.unexpected(); 2258 } 2259}; 2260 2261pp$3.parseExprImport = function() { 2262 var node = this.startNode(); 2263 this.next(); // skip `import` 2264 switch (this.type) { 2265 case types.parenL: 2266 return this.parseDynamicImport(node) 2267 default: 2268 this.unexpected(); 2269 } 2270}; 2271 2272pp$3.parseDynamicImport = function(node) { 2273 this.next(); // skip `(` 2274 2275 // Parse node.source. 2276 node.source = this.parseMaybeAssign(); 2277 2278 // Verify ending. 2279 if (!this.eat(types.parenR)) { 2280 var errorPos = this.start; 2281 if (this.eat(types.comma) && this.eat(types.parenR)) { 2282 this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); 2283 } else { 2284 this.unexpected(errorPos); 2285 } 2286 } 2287 2288 return this.finishNode(node, "ImportExpression") 2289}; 2290 2291pp$3.parseLiteral = function(value) { 2292 var node = this.startNode(); 2293 node.value = value; 2294 node.raw = this.input.slice(this.start, this.end); 2295 if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1); } 2296 this.next(); 2297 return this.finishNode(node, "Literal") 2298}; 2299 2300pp$3.parseParenExpression = function() { 2301 this.expect(types.parenL); 2302 var val = this.parseExpression(); 2303 this.expect(types.parenR); 2304 return val 2305}; 2306 2307pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { 2308 var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; 2309 if (this.options.ecmaVersion >= 6) { 2310 this.next(); 2311 2312 var innerStartPos = this.start, innerStartLoc = this.startLoc; 2313 var exprList = [], first = true, lastIsComma = false; 2314 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; 2315 this.yieldPos = 0; 2316 this.awaitPos = 0; 2317 // Do not save awaitIdentPos to allow checking awaits nested in parameters 2318 while (this.type !== types.parenR) { 2319 first ? first = false : this.expect(types.comma); 2320 if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) { 2321 lastIsComma = true; 2322 break 2323 } else if (this.type === types.ellipsis) { 2324 spreadStart = this.start; 2325 exprList.push(this.parseParenItem(this.parseRestBinding())); 2326 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } 2327 break 2328 } else { 2329 exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); 2330 } 2331 } 2332 var innerEndPos = this.start, innerEndLoc = this.startLoc; 2333 this.expect(types.parenR); 2334 2335 if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { 2336 this.checkPatternErrors(refDestructuringErrors, false); 2337 this.checkYieldAwaitInDefaultParams(); 2338 this.yieldPos = oldYieldPos; 2339 this.awaitPos = oldAwaitPos; 2340 return this.parseParenArrowList(startPos, startLoc, exprList) 2341 } 2342 2343 if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } 2344 if (spreadStart) { this.unexpected(spreadStart); } 2345 this.checkExpressionErrors(refDestructuringErrors, true); 2346 this.yieldPos = oldYieldPos || this.yieldPos; 2347 this.awaitPos = oldAwaitPos || this.awaitPos; 2348 2349 if (exprList.length > 1) { 2350 val = this.startNodeAt(innerStartPos, innerStartLoc); 2351 val.expressions = exprList; 2352 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); 2353 } else { 2354 val = exprList[0]; 2355 } 2356 } else { 2357 val = this.parseParenExpression(); 2358 } 2359 2360 if (this.options.preserveParens) { 2361 var par = this.startNodeAt(startPos, startLoc); 2362 par.expression = val; 2363 return this.finishNode(par, "ParenthesizedExpression") 2364 } else { 2365 return val 2366 } 2367}; 2368 2369pp$3.parseParenItem = function(item) { 2370 return item 2371}; 2372 2373pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { 2374 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) 2375}; 2376 2377// New's precedence is slightly tricky. It must allow its argument to 2378// be a `[]` or dot subscript expression, but not a call — at least, 2379// not without wrapping it in parentheses. Thus, it uses the noCalls 2380// argument to parseSubscripts to prevent it from consuming the 2381// argument list. 2382 2383var empty$1 = []; 2384 2385pp$3.parseNew = function() { 2386 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } 2387 var node = this.startNode(); 2388 var meta = this.parseIdent(true); 2389 if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { 2390 node.meta = meta; 2391 var containsEsc = this.containsEsc; 2392 node.property = this.parseIdent(true); 2393 if (node.property.name !== "target" || containsEsc) 2394 { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } 2395 if (!this.inNonArrowFunction()) 2396 { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } 2397 return this.finishNode(node, "MetaProperty") 2398 } 2399 var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import; 2400 node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); 2401 if (isImport && node.callee.type === "ImportExpression") { 2402 this.raise(startPos, "Cannot use new with import()"); 2403 } 2404 if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } 2405 else { node.arguments = empty$1; } 2406 return this.finishNode(node, "NewExpression") 2407}; 2408 2409// Parse template expression. 2410 2411pp$3.parseTemplateElement = function(ref) { 2412 var isTagged = ref.isTagged; 2413 2414 var elem = this.startNode(); 2415 if (this.type === types.invalidTemplate) { 2416 if (!isTagged) { 2417 this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); 2418 } 2419 elem.value = { 2420 raw: this.value, 2421 cooked: null 2422 }; 2423 } else { 2424 elem.value = { 2425 raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), 2426 cooked: this.value 2427 }; 2428 } 2429 this.next(); 2430 elem.tail = this.type === types.backQuote; 2431 return this.finishNode(elem, "TemplateElement") 2432}; 2433 2434pp$3.parseTemplate = function(ref) { 2435 if ( ref === void 0 ) ref = {}; 2436 var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; 2437 2438 var node = this.startNode(); 2439 this.next(); 2440 node.expressions = []; 2441 var curElt = this.parseTemplateElement({isTagged: isTagged}); 2442 node.quasis = [curElt]; 2443 while (!curElt.tail) { 2444 if (this.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); } 2445 this.expect(types.dollarBraceL); 2446 node.expressions.push(this.parseExpression()); 2447 this.expect(types.braceR); 2448 node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); 2449 } 2450 this.next(); 2451 return this.finishNode(node, "TemplateLiteral") 2452}; 2453 2454pp$3.isAsyncProp = function(prop) { 2455 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && 2456 (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)) && 2457 !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) 2458}; 2459 2460// Parse an object literal or binding pattern. 2461 2462pp$3.parseObj = function(isPattern, refDestructuringErrors) { 2463 var node = this.startNode(), first = true, propHash = {}; 2464 node.properties = []; 2465 this.next(); 2466 while (!this.eat(types.braceR)) { 2467 if (!first) { 2468 this.expect(types.comma); 2469 if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break } 2470 } else { first = false; } 2471 2472 var prop = this.parseProperty(isPattern, refDestructuringErrors); 2473 if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } 2474 node.properties.push(prop); 2475 } 2476 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") 2477}; 2478 2479pp$3.parseProperty = function(isPattern, refDestructuringErrors) { 2480 var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; 2481 if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { 2482 if (isPattern) { 2483 prop.argument = this.parseIdent(false); 2484 if (this.type === types.comma) { 2485 this.raise(this.start, "Comma is not permitted after the rest element"); 2486 } 2487 return this.finishNode(prop, "RestElement") 2488 } 2489 // To disallow parenthesized identifier via `this.toAssignable()`. 2490 if (this.type === types.parenL && refDestructuringErrors) { 2491 if (refDestructuringErrors.parenthesizedAssign < 0) { 2492 refDestructuringErrors.parenthesizedAssign = this.start; 2493 } 2494 if (refDestructuringErrors.parenthesizedBind < 0) { 2495 refDestructuringErrors.parenthesizedBind = this.start; 2496 } 2497 } 2498 // Parse argument. 2499 prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); 2500 // To disallow trailing comma via `this.toAssignable()`. 2501 if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { 2502 refDestructuringErrors.trailingComma = this.start; 2503 } 2504 // Finish 2505 return this.finishNode(prop, "SpreadElement") 2506 } 2507 if (this.options.ecmaVersion >= 6) { 2508 prop.method = false; 2509 prop.shorthand = false; 2510 if (isPattern || refDestructuringErrors) { 2511 startPos = this.start; 2512 startLoc = this.startLoc; 2513 } 2514 if (!isPattern) 2515 { isGenerator = this.eat(types.star); } 2516 } 2517 var containsEsc = this.containsEsc; 2518 this.parsePropertyName(prop); 2519 if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { 2520 isAsync = true; 2521 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); 2522 this.parsePropertyName(prop, refDestructuringErrors); 2523 } else { 2524 isAsync = false; 2525 } 2526 this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); 2527 return this.finishNode(prop, "Property") 2528}; 2529 2530pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { 2531 if ((isGenerator || isAsync) && this.type === types.colon) 2532 { this.unexpected(); } 2533 2534 if (this.eat(types.colon)) { 2535 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); 2536 prop.kind = "init"; 2537 } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { 2538 if (isPattern) { this.unexpected(); } 2539 prop.kind = "init"; 2540 prop.method = true; 2541 prop.value = this.parseMethod(isGenerator, isAsync); 2542 } else if (!isPattern && !containsEsc && 2543 this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && 2544 (prop.key.name === "get" || prop.key.name === "set") && 2545 (this.type !== types.comma && this.type !== types.braceR)) { 2546 if (isGenerator || isAsync) { this.unexpected(); } 2547 prop.kind = prop.key.name; 2548 this.parsePropertyName(prop); 2549 prop.value = this.parseMethod(false); 2550 var paramCount = prop.kind === "get" ? 0 : 1; 2551 if (prop.value.params.length !== paramCount) { 2552 var start = prop.value.start; 2553 if (prop.kind === "get") 2554 { this.raiseRecoverable(start, "getter should have no params"); } 2555 else 2556 { this.raiseRecoverable(start, "setter should have exactly one param"); } 2557 } else { 2558 if (prop.kind === "set" && prop.value.params[0].type === "RestElement") 2559 { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } 2560 } 2561 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { 2562 if (isGenerator || isAsync) { this.unexpected(); } 2563 this.checkUnreserved(prop.key); 2564 if (prop.key.name === "await" && !this.awaitIdentPos) 2565 { this.awaitIdentPos = startPos; } 2566 prop.kind = "init"; 2567 if (isPattern) { 2568 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); 2569 } else if (this.type === types.eq && refDestructuringErrors) { 2570 if (refDestructuringErrors.shorthandAssign < 0) 2571 { refDestructuringErrors.shorthandAssign = this.start; } 2572 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); 2573 } else { 2574 prop.value = prop.key; 2575 } 2576 prop.shorthand = true; 2577 } else { this.unexpected(); } 2578}; 2579 2580pp$3.parsePropertyName = function(prop) { 2581 if (this.options.ecmaVersion >= 6) { 2582 if (this.eat(types.bracketL)) { 2583 prop.computed = true; 2584 prop.key = this.parseMaybeAssign(); 2585 this.expect(types.bracketR); 2586 return prop.key 2587 } else { 2588 prop.computed = false; 2589 } 2590 } 2591 return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") 2592}; 2593 2594// Initialize empty function node. 2595 2596pp$3.initFunction = function(node) { 2597 node.id = null; 2598 if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } 2599 if (this.options.ecmaVersion >= 8) { node.async = false; } 2600}; 2601 2602// Parse object or class method. 2603 2604pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { 2605 var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; 2606 2607 this.initFunction(node); 2608 if (this.options.ecmaVersion >= 6) 2609 { node.generator = isGenerator; } 2610 if (this.options.ecmaVersion >= 8) 2611 { node.async = !!isAsync; } 2612 2613 this.yieldPos = 0; 2614 this.awaitPos = 0; 2615 this.awaitIdentPos = 0; 2616 this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); 2617 2618 this.expect(types.parenL); 2619 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); 2620 this.checkYieldAwaitInDefaultParams(); 2621 this.parseFunctionBody(node, false, true); 2622 2623 this.yieldPos = oldYieldPos; 2624 this.awaitPos = oldAwaitPos; 2625 this.awaitIdentPos = oldAwaitIdentPos; 2626 return this.finishNode(node, "FunctionExpression") 2627}; 2628 2629// Parse arrow function expression with given parameters. 2630 2631pp$3.parseArrowExpression = function(node, params, isAsync) { 2632 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; 2633 2634 this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); 2635 this.initFunction(node); 2636 if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } 2637 2638 this.yieldPos = 0; 2639 this.awaitPos = 0; 2640 this.awaitIdentPos = 0; 2641 2642 node.params = this.toAssignableList(params, true); 2643 this.parseFunctionBody(node, true, false); 2644 2645 this.yieldPos = oldYieldPos; 2646 this.awaitPos = oldAwaitPos; 2647 this.awaitIdentPos = oldAwaitIdentPos; 2648 return this.finishNode(node, "ArrowFunctionExpression") 2649}; 2650 2651// Parse function body and check parameters. 2652 2653pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) { 2654 var isExpression = isArrowFunction && this.type !== types.braceL; 2655 var oldStrict = this.strict, useStrict = false; 2656 2657 if (isExpression) { 2658 node.body = this.parseMaybeAssign(); 2659 node.expression = true; 2660 this.checkParams(node, false); 2661 } else { 2662 var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); 2663 if (!oldStrict || nonSimple) { 2664 useStrict = this.strictDirective(this.end); 2665 // If this is a strict mode function, verify that argument names 2666 // are not repeated, and it does not try to bind the words `eval` 2667 // or `arguments`. 2668 if (useStrict && nonSimple) 2669 { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } 2670 } 2671 // Start a new scope with regard to labels and the `inFunction` 2672 // flag (restore them to their old value afterwards). 2673 var oldLabels = this.labels; 2674 this.labels = []; 2675 if (useStrict) { this.strict = true; } 2676 2677 // Add the params to varDeclaredNames to ensure that an error is thrown 2678 // if a let/const declaration in the function clashes with one of the params. 2679 this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); 2680 node.body = this.parseBlock(false); 2681 node.expression = false; 2682 this.adaptDirectivePrologue(node.body.body); 2683 this.labels = oldLabels; 2684 } 2685 this.exitScope(); 2686 2687 // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' 2688 if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); } 2689 this.strict = oldStrict; 2690}; 2691 2692pp$3.isSimpleParamList = function(params) { 2693 for (var i = 0, list = params; i < list.length; i += 1) 2694 { 2695 var param = list[i]; 2696 2697 if (param.type !== "Identifier") { return false 2698 } } 2699 return true 2700}; 2701 2702// Checks function params for various disallowed patterns such as using "eval" 2703// or "arguments" and duplicate parameters. 2704 2705pp$3.checkParams = function(node, allowDuplicates) { 2706 var nameHash = {}; 2707 for (var i = 0, list = node.params; i < list.length; i += 1) 2708 { 2709 var param = list[i]; 2710 2711 this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash); 2712 } 2713}; 2714 2715// Parses a comma-separated list of expressions, and returns them as 2716// an array. `close` is the token type that ends the list, and 2717// `allowEmpty` can be turned on to allow subsequent commas with 2718// nothing in between them to be parsed as `null` (which is needed 2719// for array literals). 2720 2721pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { 2722 var elts = [], first = true; 2723 while (!this.eat(close)) { 2724 if (!first) { 2725 this.expect(types.comma); 2726 if (allowTrailingComma && this.afterTrailingComma(close)) { break } 2727 } else { first = false; } 2728 2729 var elt = (void 0); 2730 if (allowEmpty && this.type === types.comma) 2731 { elt = null; } 2732 else if (this.type === types.ellipsis) { 2733 elt = this.parseSpread(refDestructuringErrors); 2734 if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0) 2735 { refDestructuringErrors.trailingComma = this.start; } 2736 } else { 2737 elt = this.parseMaybeAssign(false, refDestructuringErrors); 2738 } 2739 elts.push(elt); 2740 } 2741 return elts 2742}; 2743 2744pp$3.checkUnreserved = function(ref) { 2745 var start = ref.start; 2746 var end = ref.end; 2747 var name = ref.name; 2748 2749 if (this.inGenerator && name === "yield") 2750 { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } 2751 if (this.inAsync && name === "await") 2752 { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } 2753 if (this.keywords.test(name)) 2754 { this.raise(start, ("Unexpected keyword '" + name + "'")); } 2755 if (this.options.ecmaVersion < 6 && 2756 this.input.slice(start, end).indexOf("\\") !== -1) { return } 2757 var re = this.strict ? this.reservedWordsStrict : this.reservedWords; 2758 if (re.test(name)) { 2759 if (!this.inAsync && name === "await") 2760 { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } 2761 this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); 2762 } 2763}; 2764 2765// Parse the next token as an identifier. If `liberal` is true (used 2766// when parsing properties), it will also convert keywords into 2767// identifiers. 2768 2769pp$3.parseIdent = function(liberal, isBinding) { 2770 var node = this.startNode(); 2771 if (this.type === types.name) { 2772 node.name = this.value; 2773 } else if (this.type.keyword) { 2774 node.name = this.type.keyword; 2775 2776 // To fix https://github.com/acornjs/acorn/issues/575 2777 // `class` and `function` keywords push new context into this.context. 2778 // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. 2779 // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword 2780 if ((node.name === "class" || node.name === "function") && 2781 (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { 2782 this.context.pop(); 2783 } 2784 } else { 2785 this.unexpected(); 2786 } 2787 this.next(!!liberal); 2788 this.finishNode(node, "Identifier"); 2789 if (!liberal) { 2790 this.checkUnreserved(node); 2791 if (node.name === "await" && !this.awaitIdentPos) 2792 { this.awaitIdentPos = node.start; } 2793 } 2794 return node 2795}; 2796 2797// Parses yield expression inside generator. 2798 2799pp$3.parseYield = function(noIn) { 2800 if (!this.yieldPos) { this.yieldPos = this.start; } 2801 2802 var node = this.startNode(); 2803 this.next(); 2804 if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) { 2805 node.delegate = false; 2806 node.argument = null; 2807 } else { 2808 node.delegate = this.eat(types.star); 2809 node.argument = this.parseMaybeAssign(noIn); 2810 } 2811 return this.finishNode(node, "YieldExpression") 2812}; 2813 2814pp$3.parseAwait = function() { 2815 if (!this.awaitPos) { this.awaitPos = this.start; } 2816 2817 var node = this.startNode(); 2818 this.next(); 2819 node.argument = this.parseMaybeUnary(null, false); 2820 return this.finishNode(node, "AwaitExpression") 2821}; 2822 2823var pp$4 = Parser.prototype; 2824 2825// This function is used to raise exceptions on parse errors. It 2826// takes an offset integer (into the current `input`) to indicate 2827// the location of the error, attaches the position to the end 2828// of the error message, and then raises a `SyntaxError` with that 2829// message. 2830 2831pp$4.raise = function(pos, message) { 2832 var loc = getLineInfo(this.input, pos); 2833 message += " (" + loc.line + ":" + loc.column + ")"; 2834 var err = new SyntaxError(message); 2835 err.pos = pos; err.loc = loc; err.raisedAt = this.pos; 2836 throw err 2837}; 2838 2839pp$4.raiseRecoverable = pp$4.raise; 2840 2841pp$4.curPosition = function() { 2842 if (this.options.locations) { 2843 return new Position(this.curLine, this.pos - this.lineStart) 2844 } 2845}; 2846 2847var pp$5 = Parser.prototype; 2848 2849var Scope = function Scope(flags) { 2850 this.flags = flags; 2851 // A list of var-declared names in the current lexical scope 2852 this.var = []; 2853 // A list of lexically-declared names in the current lexical scope 2854 this.lexical = []; 2855 // A list of lexically-declared FunctionDeclaration names in the current lexical scope 2856 this.functions = []; 2857}; 2858 2859// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. 2860 2861pp$5.enterScope = function(flags) { 2862 this.scopeStack.push(new Scope(flags)); 2863}; 2864 2865pp$5.exitScope = function() { 2866 this.scopeStack.pop(); 2867}; 2868 2869// The spec says: 2870// > At the top level of a function, or script, function declarations are 2871// > treated like var declarations rather than like lexical declarations. 2872pp$5.treatFunctionsAsVarInScope = function(scope) { 2873 return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) 2874}; 2875 2876pp$5.declareName = function(name, bindingType, pos) { 2877 var redeclared = false; 2878 if (bindingType === BIND_LEXICAL) { 2879 var scope = this.currentScope(); 2880 redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; 2881 scope.lexical.push(name); 2882 if (this.inModule && (scope.flags & SCOPE_TOP)) 2883 { delete this.undefinedExports[name]; } 2884 } else if (bindingType === BIND_SIMPLE_CATCH) { 2885 var scope$1 = this.currentScope(); 2886 scope$1.lexical.push(name); 2887 } else if (bindingType === BIND_FUNCTION) { 2888 var scope$2 = this.currentScope(); 2889 if (this.treatFunctionsAsVar) 2890 { redeclared = scope$2.lexical.indexOf(name) > -1; } 2891 else 2892 { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } 2893 scope$2.functions.push(name); 2894 } else { 2895 for (var i = this.scopeStack.length - 1; i >= 0; --i) { 2896 var scope$3 = this.scopeStack[i]; 2897 if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || 2898 !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { 2899 redeclared = true; 2900 break 2901 } 2902 scope$3.var.push(name); 2903 if (this.inModule && (scope$3.flags & SCOPE_TOP)) 2904 { delete this.undefinedExports[name]; } 2905 if (scope$3.flags & SCOPE_VAR) { break } 2906 } 2907 } 2908 if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } 2909}; 2910 2911pp$5.checkLocalExport = function(id) { 2912 // scope.functions must be empty as Module code is always strict. 2913 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && 2914 this.scopeStack[0].var.indexOf(id.name) === -1) { 2915 this.undefinedExports[id.name] = id; 2916 } 2917}; 2918 2919pp$5.currentScope = function() { 2920 return this.scopeStack[this.scopeStack.length - 1] 2921}; 2922 2923pp$5.currentVarScope = function() { 2924 for (var i = this.scopeStack.length - 1;; i--) { 2925 var scope = this.scopeStack[i]; 2926 if (scope.flags & SCOPE_VAR) { return scope } 2927 } 2928}; 2929 2930// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. 2931pp$5.currentThisScope = function() { 2932 for (var i = this.scopeStack.length - 1;; i--) { 2933 var scope = this.scopeStack[i]; 2934 if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope } 2935 } 2936}; 2937 2938var Node = function Node(parser, pos, loc) { 2939 this.type = ""; 2940 this.start = pos; 2941 this.end = 0; 2942 if (parser.options.locations) 2943 { this.loc = new SourceLocation(parser, loc); } 2944 if (parser.options.directSourceFile) 2945 { this.sourceFile = parser.options.directSourceFile; } 2946 if (parser.options.ranges) 2947 { this.range = [pos, 0]; } 2948}; 2949 2950// Start an AST node, attaching a start offset. 2951 2952var pp$6 = Parser.prototype; 2953 2954pp$6.startNode = function() { 2955 return new Node(this, this.start, this.startLoc) 2956}; 2957 2958pp$6.startNodeAt = function(pos, loc) { 2959 return new Node(this, pos, loc) 2960}; 2961 2962// Finish an AST node, adding `type` and `end` properties. 2963 2964function finishNodeAt(node, type, pos, loc) { 2965 node.type = type; 2966 node.end = pos; 2967 if (this.options.locations) 2968 { node.loc.end = loc; } 2969 if (this.options.ranges) 2970 { node.range[1] = pos; } 2971 return node 2972} 2973 2974pp$6.finishNode = function(node, type) { 2975 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) 2976}; 2977 2978// Finish node at given position 2979 2980pp$6.finishNodeAt = function(node, type, pos, loc) { 2981 return finishNodeAt.call(this, node, type, pos, loc) 2982}; 2983 2984// The algorithm used to determine whether a regexp can appear at a 2985 2986var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { 2987 this.token = token; 2988 this.isExpr = !!isExpr; 2989 this.preserveSpace = !!preserveSpace; 2990 this.override = override; 2991 this.generator = !!generator; 2992}; 2993 2994var types$1 = { 2995 b_stat: new TokContext("{", false), 2996 b_expr: new TokContext("{", true), 2997 b_tmpl: new TokContext("${", false), 2998 p_stat: new TokContext("(", false), 2999 p_expr: new TokContext("(", true), 3000 q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), 3001 f_stat: new TokContext("function", false), 3002 f_expr: new TokContext("function", true), 3003 f_expr_gen: new TokContext("function", true, false, null, true), 3004 f_gen: new TokContext("function", false, false, null, true) 3005}; 3006 3007var pp$7 = Parser.prototype; 3008 3009pp$7.initialContext = function() { 3010 return [types$1.b_stat] 3011}; 3012 3013pp$7.braceIsBlock = function(prevType) { 3014 var parent = this.curContext(); 3015 if (parent === types$1.f_expr || parent === types$1.f_stat) 3016 { return true } 3017 if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) 3018 { return !parent.isExpr } 3019 3020 // The check for `tt.name && exprAllowed` detects whether we are 3021 // after a `yield` or `of` construct. See the `updateContext` for 3022 // `tt.name`. 3023 if (prevType === types._return || prevType === types.name && this.exprAllowed) 3024 { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } 3025 if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) 3026 { return true } 3027 if (prevType === types.braceL) 3028 { return parent === types$1.b_stat } 3029 if (prevType === types._var || prevType === types._const || prevType === types.name) 3030 { return false } 3031 return !this.exprAllowed 3032}; 3033 3034pp$7.inGeneratorContext = function() { 3035 for (var i = this.context.length - 1; i >= 1; i--) { 3036 var context = this.context[i]; 3037 if (context.token === "function") 3038 { return context.generator } 3039 } 3040 return false 3041}; 3042 3043pp$7.updateContext = function(prevType) { 3044 var update, type = this.type; 3045 if (type.keyword && prevType === types.dot) 3046 { this.exprAllowed = false; } 3047 else if (update = type.updateContext) 3048 { update.call(this, prevType); } 3049 else 3050 { this.exprAllowed = type.beforeExpr; } 3051}; 3052 3053// Token-specific context update code 3054 3055types.parenR.updateContext = types.braceR.updateContext = function() { 3056 if (this.context.length === 1) { 3057 this.exprAllowed = true; 3058 return 3059 } 3060 var out = this.context.pop(); 3061 if (out === types$1.b_stat && this.curContext().token === "function") { 3062 out = this.context.pop(); 3063 } 3064 this.exprAllowed = !out.isExpr; 3065}; 3066 3067types.braceL.updateContext = function(prevType) { 3068 this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); 3069 this.exprAllowed = true; 3070}; 3071 3072types.dollarBraceL.updateContext = function() { 3073 this.context.push(types$1.b_tmpl); 3074 this.exprAllowed = true; 3075}; 3076 3077types.parenL.updateContext = function(prevType) { 3078 var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; 3079 this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); 3080 this.exprAllowed = true; 3081}; 3082 3083types.incDec.updateContext = function() { 3084 // tokExprAllowed stays unchanged 3085}; 3086 3087types._function.updateContext = types._class.updateContext = function(prevType) { 3088 if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && 3089 !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && 3090 !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) 3091 { this.context.push(types$1.f_expr); } 3092 else 3093 { this.context.push(types$1.f_stat); } 3094 this.exprAllowed = false; 3095}; 3096 3097types.backQuote.updateContext = function() { 3098 if (this.curContext() === types$1.q_tmpl) 3099 { this.context.pop(); } 3100 else 3101 { this.context.push(types$1.q_tmpl); } 3102 this.exprAllowed = false; 3103}; 3104 3105types.star.updateContext = function(prevType) { 3106 if (prevType === types._function) { 3107 var index = this.context.length - 1; 3108 if (this.context[index] === types$1.f_expr) 3109 { this.context[index] = types$1.f_expr_gen; } 3110 else 3111 { this.context[index] = types$1.f_gen; } 3112 } 3113 this.exprAllowed = true; 3114}; 3115 3116types.name.updateContext = function(prevType) { 3117 var allowed = false; 3118 if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { 3119 if (this.value === "of" && !this.exprAllowed || 3120 this.value === "yield" && this.inGeneratorContext()) 3121 { allowed = true; } 3122 } 3123 this.exprAllowed = allowed; 3124}; 3125 3126// This file contains Unicode properties extracted from the ECMAScript 3127// specification. The lists are extracted like so: 3128// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) 3129 3130// #table-binary-unicode-properties 3131var 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"; 3132var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; 3133var ecma11BinaryProperties = ecma10BinaryProperties; 3134var unicodeBinaryProperties = { 3135 9: ecma9BinaryProperties, 3136 10: ecma10BinaryProperties, 3137 11: ecma11BinaryProperties 3138}; 3139 3140// #table-unicode-general-category-values 3141var 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"; 3142 3143// #table-unicode-script-values 3144var 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"; 3145var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; 3146var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; 3147var unicodeScriptValues = { 3148 9: ecma9ScriptValues, 3149 10: ecma10ScriptValues, 3150 11: ecma11ScriptValues 3151}; 3152 3153var data = {}; 3154function buildUnicodeData(ecmaVersion) { 3155 var d = data[ecmaVersion] = { 3156 binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), 3157 nonBinary: { 3158 General_Category: wordsRegexp(unicodeGeneralCategoryValues), 3159 Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) 3160 } 3161 }; 3162 d.nonBinary.Script_Extensions = d.nonBinary.Script; 3163 3164 d.nonBinary.gc = d.nonBinary.General_Category; 3165 d.nonBinary.sc = d.nonBinary.Script; 3166 d.nonBinary.scx = d.nonBinary.Script_Extensions; 3167} 3168buildUnicodeData(9); 3169buildUnicodeData(10); 3170buildUnicodeData(11); 3171 3172var pp$8 = Parser.prototype; 3173 3174var RegExpValidationState = function RegExpValidationState(parser) { 3175 this.parser = parser; 3176 this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); 3177 this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion]; 3178 this.source = ""; 3179 this.flags = ""; 3180 this.start = 0; 3181 this.switchU = false; 3182 this.switchN = false; 3183 this.pos = 0; 3184 this.lastIntValue = 0; 3185 this.lastStringValue = ""; 3186 this.lastAssertionIsQuantifiable = false; 3187 this.numCapturingParens = 0; 3188 this.maxBackReference = 0; 3189 this.groupNames = []; 3190 this.backReferenceNames = []; 3191}; 3192 3193RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { 3194 var unicode = flags.indexOf("u") !== -1; 3195 this.start = start | 0; 3196 this.source = pattern + ""; 3197 this.flags = flags; 3198 this.switchU = unicode && this.parser.options.ecmaVersion >= 6; 3199 this.switchN = unicode && this.parser.options.ecmaVersion >= 9; 3200}; 3201 3202RegExpValidationState.prototype.raise = function raise (message) { 3203 this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); 3204}; 3205 3206// If u flag is given, this returns the code point at the index (it combines a surrogate pair). 3207// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). 3208RegExpValidationState.prototype.at = function at (i) { 3209 var s = this.source; 3210 var l = s.length; 3211 if (i >= l) { 3212 return -1 3213 } 3214 var c = s.charCodeAt(i); 3215 if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { 3216 return c 3217 } 3218 var next = s.charCodeAt(i + 1); 3219 return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c 3220}; 3221 3222RegExpValidationState.prototype.nextIndex = function nextIndex (i) { 3223 var s = this.source; 3224 var l = s.length; 3225 if (i >= l) { 3226 return l 3227 } 3228 var c = s.charCodeAt(i), next; 3229 if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || 3230 (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { 3231 return i + 1 3232 } 3233 return i + 2 3234}; 3235 3236RegExpValidationState.prototype.current = function current () { 3237 return this.at(this.pos) 3238}; 3239 3240RegExpValidationState.prototype.lookahead = function lookahead () { 3241 return this.at(this.nextIndex(this.pos)) 3242}; 3243 3244RegExpValidationState.prototype.advance = function advance () { 3245 this.pos = this.nextIndex(this.pos); 3246}; 3247 3248RegExpValidationState.prototype.eat = function eat (ch) { 3249 if (this.current() === ch) { 3250 this.advance(); 3251 return true 3252 } 3253 return false 3254}; 3255 3256function codePointToString(ch) { 3257 if (ch <= 0xFFFF) { return String.fromCharCode(ch) } 3258 ch -= 0x10000; 3259 return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) 3260} 3261 3262/** 3263 * Validate the flags part of a given RegExpLiteral. 3264 * 3265 * @param {RegExpValidationState} state The state to validate RegExp. 3266 * @returns {void} 3267 */ 3268pp$8.validateRegExpFlags = function(state) { 3269 var validFlags = state.validFlags; 3270 var flags = state.flags; 3271 3272 for (var i = 0; i < flags.length; i++) { 3273 var flag = flags.charAt(i); 3274 if (validFlags.indexOf(flag) === -1) { 3275 this.raise(state.start, "Invalid regular expression flag"); 3276 } 3277 if (flags.indexOf(flag, i + 1) > -1) { 3278 this.raise(state.start, "Duplicate regular expression flag"); 3279 } 3280 } 3281}; 3282 3283/** 3284 * Validate the pattern part of a given RegExpLiteral. 3285 * 3286 * @param {RegExpValidationState} state The state to validate RegExp. 3287 * @returns {void} 3288 */ 3289pp$8.validateRegExpPattern = function(state) { 3290 this.regexp_pattern(state); 3291 3292 // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of 3293 // parsing contains a |GroupName|, reparse with the goal symbol 3294 // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* 3295 // exception if _P_ did not conform to the grammar, if any elements of _P_ 3296 // were not matched by the parse, or if any Early Error conditions exist. 3297 if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { 3298 state.switchN = true; 3299 this.regexp_pattern(state); 3300 } 3301}; 3302 3303// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern 3304pp$8.regexp_pattern = function(state) { 3305 state.pos = 0; 3306 state.lastIntValue = 0; 3307 state.lastStringValue = ""; 3308 state.lastAssertionIsQuantifiable = false; 3309 state.numCapturingParens = 0; 3310 state.maxBackReference = 0; 3311 state.groupNames.length = 0; 3312 state.backReferenceNames.length = 0; 3313 3314 this.regexp_disjunction(state); 3315 3316 if (state.pos !== state.source.length) { 3317 // Make the same messages as V8. 3318 if (state.eat(0x29 /* ) */)) { 3319 state.raise("Unmatched ')'"); 3320 } 3321 if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { 3322 state.raise("Lone quantifier brackets"); 3323 } 3324 } 3325 if (state.maxBackReference > state.numCapturingParens) { 3326 state.raise("Invalid escape"); 3327 } 3328 for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { 3329 var name = list[i]; 3330 3331 if (state.groupNames.indexOf(name) === -1) { 3332 state.raise("Invalid named capture referenced"); 3333 } 3334 } 3335}; 3336 3337// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction 3338pp$8.regexp_disjunction = function(state) { 3339 this.regexp_alternative(state); 3340 while (state.eat(0x7C /* | */)) { 3341 this.regexp_alternative(state); 3342 } 3343 3344 // Make the same message as V8. 3345 if (this.regexp_eatQuantifier(state, true)) { 3346 state.raise("Nothing to repeat"); 3347 } 3348 if (state.eat(0x7B /* { */)) { 3349 state.raise("Lone quantifier brackets"); 3350 } 3351}; 3352 3353// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative 3354pp$8.regexp_alternative = function(state) { 3355 while (state.pos < state.source.length && this.regexp_eatTerm(state)) 3356 { } 3357}; 3358 3359// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term 3360pp$8.regexp_eatTerm = function(state) { 3361 if (this.regexp_eatAssertion(state)) { 3362 // Handle `QuantifiableAssertion Quantifier` alternative. 3363 // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion 3364 // is a QuantifiableAssertion. 3365 if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { 3366 // Make the same message as V8. 3367 if (state.switchU) { 3368 state.raise("Invalid quantifier"); 3369 } 3370 } 3371 return true 3372 } 3373 3374 if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { 3375 this.regexp_eatQuantifier(state); 3376 return true 3377 } 3378 3379 return false 3380}; 3381 3382// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion 3383pp$8.regexp_eatAssertion = function(state) { 3384 var start = state.pos; 3385 state.lastAssertionIsQuantifiable = false; 3386 3387 // ^, $ 3388 if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { 3389 return true 3390 } 3391 3392 // \b \B 3393 if (state.eat(0x5C /* \ */)) { 3394 if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { 3395 return true 3396 } 3397 state.pos = start; 3398 } 3399 3400 // Lookahead / Lookbehind 3401 if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { 3402 var lookbehind = false; 3403 if (this.options.ecmaVersion >= 9) { 3404 lookbehind = state.eat(0x3C /* < */); 3405 } 3406 if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { 3407 this.regexp_disjunction(state); 3408 if (!state.eat(0x29 /* ) */)) { 3409 state.raise("Unterminated group"); 3410 } 3411 state.lastAssertionIsQuantifiable = !lookbehind; 3412 return true 3413 } 3414 } 3415 3416 state.pos = start; 3417 return false 3418}; 3419 3420// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier 3421pp$8.regexp_eatQuantifier = function(state, noError) { 3422 if ( noError === void 0 ) noError = false; 3423 3424 if (this.regexp_eatQuantifierPrefix(state, noError)) { 3425 state.eat(0x3F /* ? */); 3426 return true 3427 } 3428 return false 3429}; 3430 3431// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix 3432pp$8.regexp_eatQuantifierPrefix = function(state, noError) { 3433 return ( 3434 state.eat(0x2A /* * */) || 3435 state.eat(0x2B /* + */) || 3436 state.eat(0x3F /* ? */) || 3437 this.regexp_eatBracedQuantifier(state, noError) 3438 ) 3439}; 3440pp$8.regexp_eatBracedQuantifier = function(state, noError) { 3441 var start = state.pos; 3442 if (state.eat(0x7B /* { */)) { 3443 var min = 0, max = -1; 3444 if (this.regexp_eatDecimalDigits(state)) { 3445 min = state.lastIntValue; 3446 if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { 3447 max = state.lastIntValue; 3448 } 3449 if (state.eat(0x7D /* } */)) { 3450 // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term 3451 if (max !== -1 && max < min && !noError) { 3452 state.raise("numbers out of order in {} quantifier"); 3453 } 3454 return true 3455 } 3456 } 3457 if (state.switchU && !noError) { 3458 state.raise("Incomplete quantifier"); 3459 } 3460 state.pos = start; 3461 } 3462 return false 3463}; 3464 3465// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom 3466pp$8.regexp_eatAtom = function(state) { 3467 return ( 3468 this.regexp_eatPatternCharacters(state) || 3469 state.eat(0x2E /* . */) || 3470 this.regexp_eatReverseSolidusAtomEscape(state) || 3471 this.regexp_eatCharacterClass(state) || 3472 this.regexp_eatUncapturingGroup(state) || 3473 this.regexp_eatCapturingGroup(state) 3474 ) 3475}; 3476pp$8.regexp_eatReverseSolidusAtomEscape = function(state) { 3477 var start = state.pos; 3478 if (state.eat(0x5C /* \ */)) { 3479 if (this.regexp_eatAtomEscape(state)) { 3480 return true 3481 } 3482 state.pos = start; 3483 } 3484 return false 3485}; 3486pp$8.regexp_eatUncapturingGroup = function(state) { 3487 var start = state.pos; 3488 if (state.eat(0x28 /* ( */)) { 3489 if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { 3490 this.regexp_disjunction(state); 3491 if (state.eat(0x29 /* ) */)) { 3492 return true 3493 } 3494 state.raise("Unterminated group"); 3495 } 3496 state.pos = start; 3497 } 3498 return false 3499}; 3500pp$8.regexp_eatCapturingGroup = function(state) { 3501 if (state.eat(0x28 /* ( */)) { 3502 if (this.options.ecmaVersion >= 9) { 3503 this.regexp_groupSpecifier(state); 3504 } else if (state.current() === 0x3F /* ? */) { 3505 state.raise("Invalid group"); 3506 } 3507 this.regexp_disjunction(state); 3508 if (state.eat(0x29 /* ) */)) { 3509 state.numCapturingParens += 1; 3510 return true 3511 } 3512 state.raise("Unterminated group"); 3513 } 3514 return false 3515}; 3516 3517// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom 3518pp$8.regexp_eatExtendedAtom = function(state) { 3519 return ( 3520 state.eat(0x2E /* . */) || 3521 this.regexp_eatReverseSolidusAtomEscape(state) || 3522 this.regexp_eatCharacterClass(state) || 3523 this.regexp_eatUncapturingGroup(state) || 3524 this.regexp_eatCapturingGroup(state) || 3525 this.regexp_eatInvalidBracedQuantifier(state) || 3526 this.regexp_eatExtendedPatternCharacter(state) 3527 ) 3528}; 3529 3530// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier 3531pp$8.regexp_eatInvalidBracedQuantifier = function(state) { 3532 if (this.regexp_eatBracedQuantifier(state, true)) { 3533 state.raise("Nothing to repeat"); 3534 } 3535 return false 3536}; 3537 3538// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter 3539pp$8.regexp_eatSyntaxCharacter = function(state) { 3540 var ch = state.current(); 3541 if (isSyntaxCharacter(ch)) { 3542 state.lastIntValue = ch; 3543 state.advance(); 3544 return true 3545 } 3546 return false 3547}; 3548function isSyntaxCharacter(ch) { 3549 return ( 3550 ch === 0x24 /* $ */ || 3551 ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || 3552 ch === 0x2E /* . */ || 3553 ch === 0x3F /* ? */ || 3554 ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || 3555 ch >= 0x7B /* { */ && ch <= 0x7D /* } */ 3556 ) 3557} 3558 3559// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter 3560// But eat eager. 3561pp$8.regexp_eatPatternCharacters = function(state) { 3562 var start = state.pos; 3563 var ch = 0; 3564 while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { 3565 state.advance(); 3566 } 3567 return state.pos !== start 3568}; 3569 3570// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter 3571pp$8.regexp_eatExtendedPatternCharacter = function(state) { 3572 var ch = state.current(); 3573 if ( 3574 ch !== -1 && 3575 ch !== 0x24 /* $ */ && 3576 !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && 3577 ch !== 0x2E /* . */ && 3578 ch !== 0x3F /* ? */ && 3579 ch !== 0x5B /* [ */ && 3580 ch !== 0x5E /* ^ */ && 3581 ch !== 0x7C /* | */ 3582 ) { 3583 state.advance(); 3584 return true 3585 } 3586 return false 3587}; 3588 3589// GroupSpecifier[U] :: 3590// [empty] 3591// `?` GroupName[?U] 3592pp$8.regexp_groupSpecifier = function(state) { 3593 if (state.eat(0x3F /* ? */)) { 3594 if (this.regexp_eatGroupName(state)) { 3595 if (state.groupNames.indexOf(state.lastStringValue) !== -1) { 3596 state.raise("Duplicate capture group name"); 3597 } 3598 state.groupNames.push(state.lastStringValue); 3599 return 3600 } 3601 state.raise("Invalid group"); 3602 } 3603}; 3604 3605// GroupName[U] :: 3606// `<` RegExpIdentifierName[?U] `>` 3607// Note: this updates `state.lastStringValue` property with the eaten name. 3608pp$8.regexp_eatGroupName = function(state) { 3609 state.lastStringValue = ""; 3610 if (state.eat(0x3C /* < */)) { 3611 if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { 3612 return true 3613 } 3614 state.raise("Invalid capture group name"); 3615 } 3616 return false 3617}; 3618 3619// RegExpIdentifierName[U] :: 3620// RegExpIdentifierStart[?U] 3621// RegExpIdentifierName[?U] RegExpIdentifierPart[?U] 3622// Note: this updates `state.lastStringValue` property with the eaten name. 3623pp$8.regexp_eatRegExpIdentifierName = function(state) { 3624 state.lastStringValue = ""; 3625 if (this.regexp_eatRegExpIdentifierStart(state)) { 3626 state.lastStringValue += codePointToString(state.lastIntValue); 3627 while (this.regexp_eatRegExpIdentifierPart(state)) { 3628 state.lastStringValue += codePointToString(state.lastIntValue); 3629 } 3630 return true 3631 } 3632 return false 3633}; 3634 3635// RegExpIdentifierStart[U] :: 3636// UnicodeIDStart 3637// `$` 3638// `_` 3639// `\` RegExpUnicodeEscapeSequence[?U] 3640pp$8.regexp_eatRegExpIdentifierStart = function(state) { 3641 var start = state.pos; 3642 var ch = state.current(); 3643 state.advance(); 3644 3645 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { 3646 ch = state.lastIntValue; 3647 } 3648 if (isRegExpIdentifierStart(ch)) { 3649 state.lastIntValue = ch; 3650 return true 3651 } 3652 3653 state.pos = start; 3654 return false 3655}; 3656function isRegExpIdentifierStart(ch) { 3657 return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ 3658} 3659 3660// RegExpIdentifierPart[U] :: 3661// UnicodeIDContinue 3662// `$` 3663// `_` 3664// `\` RegExpUnicodeEscapeSequence[?U] 3665// <ZWNJ> 3666// <ZWJ> 3667pp$8.regexp_eatRegExpIdentifierPart = function(state) { 3668 var start = state.pos; 3669 var ch = state.current(); 3670 state.advance(); 3671 3672 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { 3673 ch = state.lastIntValue; 3674 } 3675 if (isRegExpIdentifierPart(ch)) { 3676 state.lastIntValue = ch; 3677 return true 3678 } 3679 3680 state.pos = start; 3681 return false 3682}; 3683function isRegExpIdentifierPart(ch) { 3684 return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */ 3685} 3686 3687// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape 3688pp$8.regexp_eatAtomEscape = function(state) { 3689 if ( 3690 this.regexp_eatBackReference(state) || 3691 this.regexp_eatCharacterClassEscape(state) || 3692 this.regexp_eatCharacterEscape(state) || 3693 (state.switchN && this.regexp_eatKGroupName(state)) 3694 ) { 3695 return true 3696 } 3697 if (state.switchU) { 3698 // Make the same message as V8. 3699 if (state.current() === 0x63 /* c */) { 3700 state.raise("Invalid unicode escape"); 3701 } 3702 state.raise("Invalid escape"); 3703 } 3704 return false 3705}; 3706pp$8.regexp_eatBackReference = function(state) { 3707 var start = state.pos; 3708 if (this.regexp_eatDecimalEscape(state)) { 3709 var n = state.lastIntValue; 3710 if (state.switchU) { 3711 // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape 3712 if (n > state.maxBackReference) { 3713 state.maxBackReference = n; 3714 } 3715 return true 3716 } 3717 if (n <= state.numCapturingParens) { 3718 return true 3719 } 3720 state.pos = start; 3721 } 3722 return false 3723}; 3724pp$8.regexp_eatKGroupName = function(state) { 3725 if (state.eat(0x6B /* k */)) { 3726 if (this.regexp_eatGroupName(state)) { 3727 state.backReferenceNames.push(state.lastStringValue); 3728 return true 3729 } 3730 state.raise("Invalid named reference"); 3731 } 3732 return false 3733}; 3734 3735// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape 3736pp$8.regexp_eatCharacterEscape = function(state) { 3737 return ( 3738 this.regexp_eatControlEscape(state) || 3739 this.regexp_eatCControlLetter(state) || 3740 this.regexp_eatZero(state) || 3741 this.regexp_eatHexEscapeSequence(state) || 3742 this.regexp_eatRegExpUnicodeEscapeSequence(state) || 3743 (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || 3744 this.regexp_eatIdentityEscape(state) 3745 ) 3746}; 3747pp$8.regexp_eatCControlLetter = function(state) { 3748 var start = state.pos; 3749 if (state.eat(0x63 /* c */)) { 3750 if (this.regexp_eatControlLetter(state)) { 3751 return true 3752 } 3753 state.pos = start; 3754 } 3755 return false 3756}; 3757pp$8.regexp_eatZero = function(state) { 3758 if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { 3759 state.lastIntValue = 0; 3760 state.advance(); 3761 return true 3762 } 3763 return false 3764}; 3765 3766// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape 3767pp$8.regexp_eatControlEscape = function(state) { 3768 var ch = state.current(); 3769 if (ch === 0x74 /* t */) { 3770 state.lastIntValue = 0x09; /* \t */ 3771 state.advance(); 3772 return true 3773 } 3774 if (ch === 0x6E /* n */) { 3775 state.lastIntValue = 0x0A; /* \n */ 3776 state.advance(); 3777 return true 3778 } 3779 if (ch === 0x76 /* v */) { 3780 state.lastIntValue = 0x0B; /* \v */ 3781 state.advance(); 3782 return true 3783 } 3784 if (ch === 0x66 /* f */) { 3785 state.lastIntValue = 0x0C; /* \f */ 3786 state.advance(); 3787 return true 3788 } 3789 if (ch === 0x72 /* r */) { 3790 state.lastIntValue = 0x0D; /* \r */ 3791 state.advance(); 3792 return true 3793 } 3794 return false 3795}; 3796 3797// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter 3798pp$8.regexp_eatControlLetter = function(state) { 3799 var ch = state.current(); 3800 if (isControlLetter(ch)) { 3801 state.lastIntValue = ch % 0x20; 3802 state.advance(); 3803 return true 3804 } 3805 return false 3806}; 3807function isControlLetter(ch) { 3808 return ( 3809 (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || 3810 (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) 3811 ) 3812} 3813 3814// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence 3815pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state) { 3816 var start = state.pos; 3817 3818 if (state.eat(0x75 /* u */)) { 3819 if (this.regexp_eatFixedHexDigits(state, 4)) { 3820 var lead = state.lastIntValue; 3821 if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) { 3822 var leadSurrogateEnd = state.pos; 3823 if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { 3824 var trail = state.lastIntValue; 3825 if (trail >= 0xDC00 && trail <= 0xDFFF) { 3826 state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; 3827 return true 3828 } 3829 } 3830 state.pos = leadSurrogateEnd; 3831 state.lastIntValue = lead; 3832 } 3833 return true 3834 } 3835 if ( 3836 state.switchU && 3837 state.eat(0x7B /* { */) && 3838 this.regexp_eatHexDigits(state) && 3839 state.eat(0x7D /* } */) && 3840 isValidUnicode(state.lastIntValue) 3841 ) { 3842 return true 3843 } 3844 if (state.switchU) { 3845 state.raise("Invalid unicode escape"); 3846 } 3847 state.pos = start; 3848 } 3849 3850 return false 3851}; 3852function isValidUnicode(ch) { 3853 return ch >= 0 && ch <= 0x10FFFF 3854} 3855 3856// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape 3857pp$8.regexp_eatIdentityEscape = function(state) { 3858 if (state.switchU) { 3859 if (this.regexp_eatSyntaxCharacter(state)) { 3860 return true 3861 } 3862 if (state.eat(0x2F /* / */)) { 3863 state.lastIntValue = 0x2F; /* / */ 3864 return true 3865 } 3866 return false 3867 } 3868 3869 var ch = state.current(); 3870 if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { 3871 state.lastIntValue = ch; 3872 state.advance(); 3873 return true 3874 } 3875 3876 return false 3877}; 3878 3879// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape 3880pp$8.regexp_eatDecimalEscape = function(state) { 3881 state.lastIntValue = 0; 3882 var ch = state.current(); 3883 if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { 3884 do { 3885 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); 3886 state.advance(); 3887 } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) 3888 return true 3889 } 3890 return false 3891}; 3892 3893// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape 3894pp$8.regexp_eatCharacterClassEscape = function(state) { 3895 var ch = state.current(); 3896 3897 if (isCharacterClassEscape(ch)) { 3898 state.lastIntValue = -1; 3899 state.advance(); 3900 return true 3901 } 3902 3903 if ( 3904 state.switchU && 3905 this.options.ecmaVersion >= 9 && 3906 (ch === 0x50 /* P */ || ch === 0x70 /* p */) 3907 ) { 3908 state.lastIntValue = -1; 3909 state.advance(); 3910 if ( 3911 state.eat(0x7B /* { */) && 3912 this.regexp_eatUnicodePropertyValueExpression(state) && 3913 state.eat(0x7D /* } */) 3914 ) { 3915 return true 3916 } 3917 state.raise("Invalid property name"); 3918 } 3919 3920 return false 3921}; 3922function isCharacterClassEscape(ch) { 3923 return ( 3924 ch === 0x64 /* d */ || 3925 ch === 0x44 /* D */ || 3926 ch === 0x73 /* s */ || 3927 ch === 0x53 /* S */ || 3928 ch === 0x77 /* w */ || 3929 ch === 0x57 /* W */ 3930 ) 3931} 3932 3933// UnicodePropertyValueExpression :: 3934// UnicodePropertyName `=` UnicodePropertyValue 3935// LoneUnicodePropertyNameOrValue 3936pp$8.regexp_eatUnicodePropertyValueExpression = function(state) { 3937 var start = state.pos; 3938 3939 // UnicodePropertyName `=` UnicodePropertyValue 3940 if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { 3941 var name = state.lastStringValue; 3942 if (this.regexp_eatUnicodePropertyValue(state)) { 3943 var value = state.lastStringValue; 3944 this.regexp_validateUnicodePropertyNameAndValue(state, name, value); 3945 return true 3946 } 3947 } 3948 state.pos = start; 3949 3950 // LoneUnicodePropertyNameOrValue 3951 if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { 3952 var nameOrValue = state.lastStringValue; 3953 this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); 3954 return true 3955 } 3956 return false 3957}; 3958pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { 3959 if (!has(state.unicodeProperties.nonBinary, name)) 3960 { state.raise("Invalid property name"); } 3961 if (!state.unicodeProperties.nonBinary[name].test(value)) 3962 { state.raise("Invalid property value"); } 3963}; 3964pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { 3965 if (!state.unicodeProperties.binary.test(nameOrValue)) 3966 { state.raise("Invalid property name"); } 3967}; 3968 3969// UnicodePropertyName :: 3970// UnicodePropertyNameCharacters 3971pp$8.regexp_eatUnicodePropertyName = function(state) { 3972 var ch = 0; 3973 state.lastStringValue = ""; 3974 while (isUnicodePropertyNameCharacter(ch = state.current())) { 3975 state.lastStringValue += codePointToString(ch); 3976 state.advance(); 3977 } 3978 return state.lastStringValue !== "" 3979}; 3980function isUnicodePropertyNameCharacter(ch) { 3981 return isControlLetter(ch) || ch === 0x5F /* _ */ 3982} 3983 3984// UnicodePropertyValue :: 3985// UnicodePropertyValueCharacters 3986pp$8.regexp_eatUnicodePropertyValue = function(state) { 3987 var ch = 0; 3988 state.lastStringValue = ""; 3989 while (isUnicodePropertyValueCharacter(ch = state.current())) { 3990 state.lastStringValue += codePointToString(ch); 3991 state.advance(); 3992 } 3993 return state.lastStringValue !== "" 3994}; 3995function isUnicodePropertyValueCharacter(ch) { 3996 return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) 3997} 3998 3999// LoneUnicodePropertyNameOrValue :: 4000// UnicodePropertyValueCharacters 4001pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { 4002 return this.regexp_eatUnicodePropertyValue(state) 4003}; 4004 4005// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass 4006pp$8.regexp_eatCharacterClass = function(state) { 4007 if (state.eat(0x5B /* [ */)) { 4008 state.eat(0x5E /* ^ */); 4009 this.regexp_classRanges(state); 4010 if (state.eat(0x5D /* ] */)) { 4011 return true 4012 } 4013 // Unreachable since it threw "unterminated regular expression" error before. 4014 state.raise("Unterminated character class"); 4015 } 4016 return false 4017}; 4018 4019// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges 4020// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges 4021// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash 4022pp$8.regexp_classRanges = function(state) { 4023 while (this.regexp_eatClassAtom(state)) { 4024 var left = state.lastIntValue; 4025 if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) { 4026 var right = state.lastIntValue; 4027 if (state.switchU && (left === -1 || right === -1)) { 4028 state.raise("Invalid character class"); 4029 } 4030 if (left !== -1 && right !== -1 && left > right) { 4031 state.raise("Range out of order in character class"); 4032 } 4033 } 4034 } 4035}; 4036 4037// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom 4038// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash 4039pp$8.regexp_eatClassAtom = function(state) { 4040 var start = state.pos; 4041 4042 if (state.eat(0x5C /* \ */)) { 4043 if (this.regexp_eatClassEscape(state)) { 4044 return true 4045 } 4046 if (state.switchU) { 4047 // Make the same message as V8. 4048 var ch$1 = state.current(); 4049 if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { 4050 state.raise("Invalid class escape"); 4051 } 4052 state.raise("Invalid escape"); 4053 } 4054 state.pos = start; 4055 } 4056 4057 var ch = state.current(); 4058 if (ch !== 0x5D /* ] */) { 4059 state.lastIntValue = ch; 4060 state.advance(); 4061 return true 4062 } 4063 4064 return false 4065}; 4066 4067// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape 4068pp$8.regexp_eatClassEscape = function(state) { 4069 var start = state.pos; 4070 4071 if (state.eat(0x62 /* b */)) { 4072 state.lastIntValue = 0x08; /* <BS> */ 4073 return true 4074 } 4075 4076 if (state.switchU && state.eat(0x2D /* - */)) { 4077 state.lastIntValue = 0x2D; /* - */ 4078 return true 4079 } 4080 4081 if (!state.switchU && state.eat(0x63 /* c */)) { 4082 if (this.regexp_eatClassControlLetter(state)) { 4083 return true 4084 } 4085 state.pos = start; 4086 } 4087 4088 return ( 4089 this.regexp_eatCharacterClassEscape(state) || 4090 this.regexp_eatCharacterEscape(state) 4091 ) 4092}; 4093 4094// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter 4095pp$8.regexp_eatClassControlLetter = function(state) { 4096 var ch = state.current(); 4097 if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { 4098 state.lastIntValue = ch % 0x20; 4099 state.advance(); 4100 return true 4101 } 4102 return false 4103}; 4104 4105// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence 4106pp$8.regexp_eatHexEscapeSequence = function(state) { 4107 var start = state.pos; 4108 if (state.eat(0x78 /* x */)) { 4109 if (this.regexp_eatFixedHexDigits(state, 2)) { 4110 return true 4111 } 4112 if (state.switchU) { 4113 state.raise("Invalid escape"); 4114 } 4115 state.pos = start; 4116 } 4117 return false 4118}; 4119 4120// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits 4121pp$8.regexp_eatDecimalDigits = function(state) { 4122 var start = state.pos; 4123 var ch = 0; 4124 state.lastIntValue = 0; 4125 while (isDecimalDigit(ch = state.current())) { 4126 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); 4127 state.advance(); 4128 } 4129 return state.pos !== start 4130}; 4131function isDecimalDigit(ch) { 4132 return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ 4133} 4134 4135// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits 4136pp$8.regexp_eatHexDigits = function(state) { 4137 var start = state.pos; 4138 var ch = 0; 4139 state.lastIntValue = 0; 4140 while (isHexDigit(ch = state.current())) { 4141 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); 4142 state.advance(); 4143 } 4144 return state.pos !== start 4145}; 4146function isHexDigit(ch) { 4147 return ( 4148 (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || 4149 (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || 4150 (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) 4151 ) 4152} 4153function hexToInt(ch) { 4154 if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { 4155 return 10 + (ch - 0x41 /* A */) 4156 } 4157 if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { 4158 return 10 + (ch - 0x61 /* a */) 4159 } 4160 return ch - 0x30 /* 0 */ 4161} 4162 4163// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence 4164// Allows only 0-377(octal) i.e. 0-255(decimal). 4165pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) { 4166 if (this.regexp_eatOctalDigit(state)) { 4167 var n1 = state.lastIntValue; 4168 if (this.regexp_eatOctalDigit(state)) { 4169 var n2 = state.lastIntValue; 4170 if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { 4171 state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; 4172 } else { 4173 state.lastIntValue = n1 * 8 + n2; 4174 } 4175 } else { 4176 state.lastIntValue = n1; 4177 } 4178 return true 4179 } 4180 return false 4181}; 4182 4183// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit 4184pp$8.regexp_eatOctalDigit = function(state) { 4185 var ch = state.current(); 4186 if (isOctalDigit(ch)) { 4187 state.lastIntValue = ch - 0x30; /* 0 */ 4188 state.advance(); 4189 return true 4190 } 4191 state.lastIntValue = 0; 4192 return false 4193}; 4194function isOctalDigit(ch) { 4195 return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ 4196} 4197 4198// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits 4199// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit 4200// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence 4201pp$8.regexp_eatFixedHexDigits = function(state, length) { 4202 var start = state.pos; 4203 state.lastIntValue = 0; 4204 for (var i = 0; i < length; ++i) { 4205 var ch = state.current(); 4206 if (!isHexDigit(ch)) { 4207 state.pos = start; 4208 return false 4209 } 4210 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); 4211 state.advance(); 4212 } 4213 return true 4214}; 4215 4216// Object type used to represent tokens. Note that normally, tokens 4217// simply exist as properties on the parser object. This is only 4218// used for the onToken callback and the external tokenizer. 4219 4220var Token = function Token(p) { 4221 this.type = p.type; 4222 this.value = p.value; 4223 this.start = p.start; 4224 this.end = p.end; 4225 if (p.options.locations) 4226 { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } 4227 if (p.options.ranges) 4228 { this.range = [p.start, p.end]; } 4229}; 4230 4231// ## Tokenizer 4232 4233var pp$9 = Parser.prototype; 4234 4235// Move to the next token 4236 4237pp$9.next = function(ignoreEscapeSequenceInKeyword) { 4238 if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) 4239 { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } 4240 if (this.options.onToken) 4241 { this.options.onToken(new Token(this)); } 4242 4243 this.lastTokEnd = this.end; 4244 this.lastTokStart = this.start; 4245 this.lastTokEndLoc = this.endLoc; 4246 this.lastTokStartLoc = this.startLoc; 4247 this.nextToken(); 4248}; 4249 4250pp$9.getToken = function() { 4251 this.next(); 4252 return new Token(this) 4253}; 4254 4255// If we're in an ES6 environment, make parsers iterable 4256if (typeof Symbol !== "undefined") 4257 { pp$9[Symbol.iterator] = function() { 4258 var this$1 = this; 4259 4260 return { 4261 next: function () { 4262 var token = this$1.getToken(); 4263 return { 4264 done: token.type === types.eof, 4265 value: token 4266 } 4267 } 4268 } 4269 }; } 4270 4271// Toggle strict mode. Re-reads the next number or string to please 4272// pedantic tests (`"use strict"; 010;` should fail). 4273 4274pp$9.curContext = function() { 4275 return this.context[this.context.length - 1] 4276}; 4277 4278// Read a single token, updating the parser object's token-related 4279// properties. 4280 4281pp$9.nextToken = function() { 4282 var curContext = this.curContext(); 4283 if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } 4284 4285 this.start = this.pos; 4286 if (this.options.locations) { this.startLoc = this.curPosition(); } 4287 if (this.pos >= this.input.length) { return this.finishToken(types.eof) } 4288 4289 if (curContext.override) { return curContext.override(this) } 4290 else { this.readToken(this.fullCharCodeAtPos()); } 4291}; 4292 4293pp$9.readToken = function(code) { 4294 // Identifier or keyword. '\uXXXX' sequences are allowed in 4295 // identifiers, so '\' also dispatches to that. 4296 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) 4297 { return this.readWord() } 4298 4299 return this.getTokenFromCode(code) 4300}; 4301 4302pp$9.fullCharCodeAtPos = function() { 4303 var code = this.input.charCodeAt(this.pos); 4304 if (code <= 0xd7ff || code >= 0xe000) { return code } 4305 var next = this.input.charCodeAt(this.pos + 1); 4306 return (code << 10) + next - 0x35fdc00 4307}; 4308 4309pp$9.skipBlockComment = function() { 4310 var startLoc = this.options.onComment && this.curPosition(); 4311 var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); 4312 if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } 4313 this.pos = end + 2; 4314 if (this.options.locations) { 4315 lineBreakG.lastIndex = start; 4316 var match; 4317 while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { 4318 ++this.curLine; 4319 this.lineStart = match.index + match[0].length; 4320 } 4321 } 4322 if (this.options.onComment) 4323 { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, 4324 startLoc, this.curPosition()); } 4325}; 4326 4327pp$9.skipLineComment = function(startSkip) { 4328 var start = this.pos; 4329 var startLoc = this.options.onComment && this.curPosition(); 4330 var ch = this.input.charCodeAt(this.pos += startSkip); 4331 while (this.pos < this.input.length && !isNewLine(ch)) { 4332 ch = this.input.charCodeAt(++this.pos); 4333 } 4334 if (this.options.onComment) 4335 { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, 4336 startLoc, this.curPosition()); } 4337}; 4338 4339// Called at the start of the parse and after every token. Skips 4340// whitespace and comments, and. 4341 4342pp$9.skipSpace = function() { 4343 loop: while (this.pos < this.input.length) { 4344 var ch = this.input.charCodeAt(this.pos); 4345 switch (ch) { 4346 case 32: case 160: // ' ' 4347 ++this.pos; 4348 break 4349 case 13: 4350 if (this.input.charCodeAt(this.pos + 1) === 10) { 4351 ++this.pos; 4352 } 4353 case 10: case 8232: case 8233: 4354 ++this.pos; 4355 if (this.options.locations) { 4356 ++this.curLine; 4357 this.lineStart = this.pos; 4358 } 4359 break 4360 case 47: // '/' 4361 switch (this.input.charCodeAt(this.pos + 1)) { 4362 case 42: // '*' 4363 this.skipBlockComment(); 4364 break 4365 case 47: 4366 this.skipLineComment(2); 4367 break 4368 default: 4369 break loop 4370 } 4371 break 4372 default: 4373 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { 4374 ++this.pos; 4375 } else { 4376 break loop 4377 } 4378 } 4379 } 4380}; 4381 4382// Called at the end of every token. Sets `end`, `val`, and 4383// maintains `context` and `exprAllowed`, and skips the space after 4384// the token, so that the next one's `start` will point at the 4385// right position. 4386 4387pp$9.finishToken = function(type, val) { 4388 this.end = this.pos; 4389 if (this.options.locations) { this.endLoc = this.curPosition(); } 4390 var prevType = this.type; 4391 this.type = type; 4392 this.value = val; 4393 4394 this.updateContext(prevType); 4395}; 4396 4397// ### Token reading 4398 4399// This is the function that is called to fetch the next token. It 4400// is somewhat obscure, because it works in character codes rather 4401// than characters, and because operator parsing has been inlined 4402// into it. 4403// 4404// All in the name of speed. 4405// 4406pp$9.readToken_dot = function() { 4407 var next = this.input.charCodeAt(this.pos + 1); 4408 if (next >= 48 && next <= 57) { return this.readNumber(true) } 4409 var next2 = this.input.charCodeAt(this.pos + 2); 4410 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' 4411 this.pos += 3; 4412 return this.finishToken(types.ellipsis) 4413 } else { 4414 ++this.pos; 4415 return this.finishToken(types.dot) 4416 } 4417}; 4418 4419pp$9.readToken_slash = function() { // '/' 4420 var next = this.input.charCodeAt(this.pos + 1); 4421 if (this.exprAllowed) { ++this.pos; return this.readRegexp() } 4422 if (next === 61) { return this.finishOp(types.assign, 2) } 4423 return this.finishOp(types.slash, 1) 4424}; 4425 4426pp$9.readToken_mult_modulo_exp = function(code) { // '%*' 4427 var next = this.input.charCodeAt(this.pos + 1); 4428 var size = 1; 4429 var tokentype = code === 42 ? types.star : types.modulo; 4430 4431 // exponentiation operator ** and **= 4432 if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { 4433 ++size; 4434 tokentype = types.starstar; 4435 next = this.input.charCodeAt(this.pos + 2); 4436 } 4437 4438 if (next === 61) { return this.finishOp(types.assign, size + 1) } 4439 return this.finishOp(tokentype, size) 4440}; 4441 4442pp$9.readToken_pipe_amp = function(code) { // '|&' 4443 var next = this.input.charCodeAt(this.pos + 1); 4444 if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) } 4445 if (next === 61) { return this.finishOp(types.assign, 2) } 4446 return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) 4447}; 4448 4449pp$9.readToken_caret = function() { // '^' 4450 var next = this.input.charCodeAt(this.pos + 1); 4451 if (next === 61) { return this.finishOp(types.assign, 2) } 4452 return this.finishOp(types.bitwiseXOR, 1) 4453}; 4454 4455pp$9.readToken_plus_min = function(code) { // '+-' 4456 var next = this.input.charCodeAt(this.pos + 1); 4457 if (next === code) { 4458 if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && 4459 (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { 4460 // A `-->` line comment 4461 this.skipLineComment(3); 4462 this.skipSpace(); 4463 return this.nextToken() 4464 } 4465 return this.finishOp(types.incDec, 2) 4466 } 4467 if (next === 61) { return this.finishOp(types.assign, 2) } 4468 return this.finishOp(types.plusMin, 1) 4469}; 4470 4471pp$9.readToken_lt_gt = function(code) { // '<>' 4472 var next = this.input.charCodeAt(this.pos + 1); 4473 var size = 1; 4474 if (next === code) { 4475 size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; 4476 if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } 4477 return this.finishOp(types.bitShift, size) 4478 } 4479 if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && 4480 this.input.charCodeAt(this.pos + 3) === 45) { 4481 // `<!--`, an XML-style comment that should be interpreted as a line comment 4482 this.skipLineComment(4); 4483 this.skipSpace(); 4484 return this.nextToken() 4485 } 4486 if (next === 61) { size = 2; } 4487 return this.finishOp(types.relational, size) 4488}; 4489 4490pp$9.readToken_eq_excl = function(code) { // '=!' 4491 var next = this.input.charCodeAt(this.pos + 1); 4492 if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) } 4493 if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>' 4494 this.pos += 2; 4495 return this.finishToken(types.arrow) 4496 } 4497 return this.finishOp(code === 61 ? types.eq : types.prefix, 1) 4498}; 4499 4500pp$9.getTokenFromCode = function(code) { 4501 switch (code) { 4502 // The interpretation of a dot depends on whether it is followed 4503 // by a digit or another two dots. 4504 case 46: // '.' 4505 return this.readToken_dot() 4506 4507 // Punctuation tokens. 4508 case 40: ++this.pos; return this.finishToken(types.parenL) 4509 case 41: ++this.pos; return this.finishToken(types.parenR) 4510 case 59: ++this.pos; return this.finishToken(types.semi) 4511 case 44: ++this.pos; return this.finishToken(types.comma) 4512 case 91: ++this.pos; return this.finishToken(types.bracketL) 4513 case 93: ++this.pos; return this.finishToken(types.bracketR) 4514 case 123: ++this.pos; return this.finishToken(types.braceL) 4515 case 125: ++this.pos; return this.finishToken(types.braceR) 4516 case 58: ++this.pos; return this.finishToken(types.colon) 4517 case 63: ++this.pos; return this.finishToken(types.question) 4518 4519 case 96: // '`' 4520 if (this.options.ecmaVersion < 6) { break } 4521 ++this.pos; 4522 return this.finishToken(types.backQuote) 4523 4524 case 48: // '0' 4525 var next = this.input.charCodeAt(this.pos + 1); 4526 if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number 4527 if (this.options.ecmaVersion >= 6) { 4528 if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number 4529 if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number 4530 } 4531 4532 // Anything else beginning with a digit is an integer, octal 4533 // number, or float. 4534 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 4535 return this.readNumber(false) 4536 4537 // Quotes produce strings. 4538 case 34: case 39: // '"', "'" 4539 return this.readString(code) 4540 4541 // Operators are parsed inline in tiny state machines. '=' (61) is 4542 // often referred to. `finishOp` simply skips the amount of 4543 // characters it is given as second argument, and returns a token 4544 // of the type given by its first argument. 4545 4546 case 47: // '/' 4547 return this.readToken_slash() 4548 4549 case 37: case 42: // '%*' 4550 return this.readToken_mult_modulo_exp(code) 4551 4552 case 124: case 38: // '|&' 4553 return this.readToken_pipe_amp(code) 4554 4555 case 94: // '^' 4556 return this.readToken_caret() 4557 4558 case 43: case 45: // '+-' 4559 return this.readToken_plus_min(code) 4560 4561 case 60: case 62: // '<>' 4562 return this.readToken_lt_gt(code) 4563 4564 case 61: case 33: // '=!' 4565 return this.readToken_eq_excl(code) 4566 4567 case 126: // '~' 4568 return this.finishOp(types.prefix, 1) 4569 } 4570 4571 this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'"); 4572}; 4573 4574pp$9.finishOp = function(type, size) { 4575 var str = this.input.slice(this.pos, this.pos + size); 4576 this.pos += size; 4577 return this.finishToken(type, str) 4578}; 4579 4580pp$9.readRegexp = function() { 4581 var escaped, inClass, start = this.pos; 4582 for (;;) { 4583 if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); } 4584 var ch = this.input.charAt(this.pos); 4585 if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); } 4586 if (!escaped) { 4587 if (ch === "[") { inClass = true; } 4588 else if (ch === "]" && inClass) { inClass = false; } 4589 else if (ch === "/" && !inClass) { break } 4590 escaped = ch === "\\"; 4591 } else { escaped = false; } 4592 ++this.pos; 4593 } 4594 var pattern = this.input.slice(start, this.pos); 4595 ++this.pos; 4596 var flagsStart = this.pos; 4597 var flags = this.readWord1(); 4598 if (this.containsEsc) { this.unexpected(flagsStart); } 4599 4600 // Validate pattern 4601 var state = this.regexpState || (this.regexpState = new RegExpValidationState(this)); 4602 state.reset(start, pattern, flags); 4603 this.validateRegExpFlags(state); 4604 this.validateRegExpPattern(state); 4605 4606 // Create Literal#value property value. 4607 var value = null; 4608 try { 4609 value = new RegExp(pattern, flags); 4610 } catch (e) { 4611 // ESTree requires null if it failed to instantiate RegExp object. 4612 // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral 4613 } 4614 4615 return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value}) 4616}; 4617 4618// Read an integer in the given radix. Return null if zero digits 4619// were read, the integer value otherwise. When `len` is given, this 4620// will return `null` unless the integer has exactly `len` digits. 4621 4622pp$9.readInt = function(radix, len) { 4623 var start = this.pos, total = 0; 4624 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { 4625 var code = this.input.charCodeAt(this.pos), val = (void 0); 4626 if (code >= 97) { val = code - 97 + 10; } // a 4627 else if (code >= 65) { val = code - 65 + 10; } // A 4628 else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9 4629 else { val = Infinity; } 4630 if (val >= radix) { break } 4631 ++this.pos; 4632 total = total * radix + val; 4633 } 4634 if (this.pos === start || len != null && this.pos - start !== len) { return null } 4635 4636 return total 4637}; 4638 4639pp$9.readRadixNumber = function(radix) { 4640 var start = this.pos; 4641 this.pos += 2; // 0x 4642 var val = this.readInt(radix); 4643 if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); } 4644 if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) { 4645 val = typeof BigInt !== "undefined" ? BigInt(this.input.slice(start, this.pos)) : null; 4646 ++this.pos; 4647 } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } 4648 return this.finishToken(types.num, val) 4649}; 4650 4651// Read an integer, octal integer, or floating-point number. 4652 4653pp$9.readNumber = function(startsWithDot) { 4654 var start = this.pos; 4655 if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); } 4656 var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48; 4657 if (octal && this.strict) { this.raise(start, "Invalid number"); } 4658 var next = this.input.charCodeAt(this.pos); 4659 if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) { 4660 var str$1 = this.input.slice(start, this.pos); 4661 var val$1 = typeof BigInt !== "undefined" ? BigInt(str$1) : null; 4662 ++this.pos; 4663 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } 4664 return this.finishToken(types.num, val$1) 4665 } 4666 if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; } 4667 if (next === 46 && !octal) { // '.' 4668 ++this.pos; 4669 this.readInt(10); 4670 next = this.input.charCodeAt(this.pos); 4671 } 4672 if ((next === 69 || next === 101) && !octal) { // 'eE' 4673 next = this.input.charCodeAt(++this.pos); 4674 if (next === 43 || next === 45) { ++this.pos; } // '+-' 4675 if (this.readInt(10) === null) { this.raise(start, "Invalid number"); } 4676 } 4677 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } 4678 4679 var str = this.input.slice(start, this.pos); 4680 var val = octal ? parseInt(str, 8) : parseFloat(str); 4681 return this.finishToken(types.num, val) 4682}; 4683 4684// Read a string value, interpreting backslash-escapes. 4685 4686pp$9.readCodePoint = function() { 4687 var ch = this.input.charCodeAt(this.pos), code; 4688 4689 if (ch === 123) { // '{' 4690 if (this.options.ecmaVersion < 6) { this.unexpected(); } 4691 var codePos = ++this.pos; 4692 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos); 4693 ++this.pos; 4694 if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); } 4695 } else { 4696 code = this.readHexChar(4); 4697 } 4698 return code 4699}; 4700 4701function codePointToString$1(code) { 4702 // UTF-16 Decoding 4703 if (code <= 0xFFFF) { return String.fromCharCode(code) } 4704 code -= 0x10000; 4705 return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) 4706} 4707 4708pp$9.readString = function(quote) { 4709 var out = "", chunkStart = ++this.pos; 4710 for (;;) { 4711 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); } 4712 var ch = this.input.charCodeAt(this.pos); 4713 if (ch === quote) { break } 4714 if (ch === 92) { // '\' 4715 out += this.input.slice(chunkStart, this.pos); 4716 out += this.readEscapedChar(false); 4717 chunkStart = this.pos; 4718 } else { 4719 if (isNewLine(ch, this.options.ecmaVersion >= 10)) { this.raise(this.start, "Unterminated string constant"); } 4720 ++this.pos; 4721 } 4722 } 4723 out += this.input.slice(chunkStart, this.pos++); 4724 return this.finishToken(types.string, out) 4725}; 4726 4727// Reads template string tokens. 4728 4729var INVALID_TEMPLATE_ESCAPE_ERROR = {}; 4730 4731pp$9.tryReadTemplateToken = function() { 4732 this.inTemplateElement = true; 4733 try { 4734 this.readTmplToken(); 4735 } catch (err) { 4736 if (err === INVALID_TEMPLATE_ESCAPE_ERROR) { 4737 this.readInvalidTemplateToken(); 4738 } else { 4739 throw err 4740 } 4741 } 4742 4743 this.inTemplateElement = false; 4744}; 4745 4746pp$9.invalidStringToken = function(position, message) { 4747 if (this.inTemplateElement && this.options.ecmaVersion >= 9) { 4748 throw INVALID_TEMPLATE_ESCAPE_ERROR 4749 } else { 4750 this.raise(position, message); 4751 } 4752}; 4753 4754pp$9.readTmplToken = function() { 4755 var out = "", chunkStart = this.pos; 4756 for (;;) { 4757 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); } 4758 var ch = this.input.charCodeAt(this.pos); 4759 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${' 4760 if (this.pos === this.start && (this.type === types.template || this.type === types.invalidTemplate)) { 4761 if (ch === 36) { 4762 this.pos += 2; 4763 return this.finishToken(types.dollarBraceL) 4764 } else { 4765 ++this.pos; 4766 return this.finishToken(types.backQuote) 4767 } 4768 } 4769 out += this.input.slice(chunkStart, this.pos); 4770 return this.finishToken(types.template, out) 4771 } 4772 if (ch === 92) { // '\' 4773 out += this.input.slice(chunkStart, this.pos); 4774 out += this.readEscapedChar(true); 4775 chunkStart = this.pos; 4776 } else if (isNewLine(ch)) { 4777 out += this.input.slice(chunkStart, this.pos); 4778 ++this.pos; 4779 switch (ch) { 4780 case 13: 4781 if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } 4782 case 10: 4783 out += "\n"; 4784 break 4785 default: 4786 out += String.fromCharCode(ch); 4787 break 4788 } 4789 if (this.options.locations) { 4790 ++this.curLine; 4791 this.lineStart = this.pos; 4792 } 4793 chunkStart = this.pos; 4794 } else { 4795 ++this.pos; 4796 } 4797 } 4798}; 4799 4800// Reads a template token to search for the end, without validating any escape sequences 4801pp$9.readInvalidTemplateToken = function() { 4802 for (; this.pos < this.input.length; this.pos++) { 4803 switch (this.input[this.pos]) { 4804 case "\\": 4805 ++this.pos; 4806 break 4807 4808 case "$": 4809 if (this.input[this.pos + 1] !== "{") { 4810 break 4811 } 4812 // falls through 4813 4814 case "`": 4815 return this.finishToken(types.invalidTemplate, this.input.slice(this.start, this.pos)) 4816 4817 // no default 4818 } 4819 } 4820 this.raise(this.start, "Unterminated template"); 4821}; 4822 4823// Used to read escaped characters 4824 4825pp$9.readEscapedChar = function(inTemplate) { 4826 var ch = this.input.charCodeAt(++this.pos); 4827 ++this.pos; 4828 switch (ch) { 4829 case 110: return "\n" // 'n' -> '\n' 4830 case 114: return "\r" // 'r' -> '\r' 4831 case 120: return String.fromCharCode(this.readHexChar(2)) // 'x' 4832 case 117: return codePointToString$1(this.readCodePoint()) // 'u' 4833 case 116: return "\t" // 't' -> '\t' 4834 case 98: return "\b" // 'b' -> '\b' 4835 case 118: return "\u000b" // 'v' -> '\u000b' 4836 case 102: return "\f" // 'f' -> '\f' 4837 case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n' 4838 case 10: // ' \n' 4839 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; } 4840 return "" 4841 case 56: 4842 case 57: 4843 if (inTemplate) { 4844 var codePos = this.pos - 1; 4845 4846 this.invalidStringToken( 4847 codePos, 4848 "Invalid escape sequence in template string" 4849 ); 4850 4851 return null 4852 } 4853 default: 4854 if (ch >= 48 && ch <= 55) { 4855 var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]; 4856 var octal = parseInt(octalStr, 8); 4857 if (octal > 255) { 4858 octalStr = octalStr.slice(0, -1); 4859 octal = parseInt(octalStr, 8); 4860 } 4861 this.pos += octalStr.length - 1; 4862 ch = this.input.charCodeAt(this.pos); 4863 if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) { 4864 this.invalidStringToken( 4865 this.pos - 1 - octalStr.length, 4866 inTemplate 4867 ? "Octal literal in template string" 4868 : "Octal literal in strict mode" 4869 ); 4870 } 4871 return String.fromCharCode(octal) 4872 } 4873 if (isNewLine(ch)) { 4874 // Unicode new line characters after \ get removed from output in both 4875 // template literals and strings 4876 return "" 4877 } 4878 return String.fromCharCode(ch) 4879 } 4880}; 4881 4882// Used to read character escape sequences ('\x', '\u', '\U'). 4883 4884pp$9.readHexChar = function(len) { 4885 var codePos = this.pos; 4886 var n = this.readInt(16, len); 4887 if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); } 4888 return n 4889}; 4890 4891// Read an identifier, and return it as a string. Sets `this.containsEsc` 4892// to whether the word contained a '\u' escape. 4893// 4894// Incrementally adds only escaped chars, adding other chunks as-is 4895// as a micro-optimization. 4896 4897pp$9.readWord1 = function() { 4898 this.containsEsc = false; 4899 var word = "", first = true, chunkStart = this.pos; 4900 var astral = this.options.ecmaVersion >= 6; 4901 while (this.pos < this.input.length) { 4902 var ch = this.fullCharCodeAtPos(); 4903 if (isIdentifierChar(ch, astral)) { 4904 this.pos += ch <= 0xffff ? 1 : 2; 4905 } else if (ch === 92) { // "\" 4906 this.containsEsc = true; 4907 word += this.input.slice(chunkStart, this.pos); 4908 var escStart = this.pos; 4909 if (this.input.charCodeAt(++this.pos) !== 117) // "u" 4910 { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); } 4911 ++this.pos; 4912 var esc = this.readCodePoint(); 4913 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) 4914 { this.invalidStringToken(escStart, "Invalid Unicode escape"); } 4915 word += codePointToString$1(esc); 4916 chunkStart = this.pos; 4917 } else { 4918 break 4919 } 4920 first = false; 4921 } 4922 return word + this.input.slice(chunkStart, this.pos) 4923}; 4924 4925// Read an identifier or keyword token. Will check for reserved 4926// words when necessary. 4927 4928pp$9.readWord = function() { 4929 var word = this.readWord1(); 4930 var type = types.name; 4931 if (this.keywords.test(word)) { 4932 type = keywords$1[word]; 4933 } 4934 return this.finishToken(type, word) 4935}; 4936 4937// Acorn is a tiny, fast JavaScript parser written in JavaScript. 4938 4939var version = "7.1.0"; 4940 4941Parser.acorn = { 4942 Parser: Parser, 4943 version: version, 4944 defaultOptions: defaultOptions, 4945 Position: Position, 4946 SourceLocation: SourceLocation, 4947 getLineInfo: getLineInfo, 4948 Node: Node, 4949 TokenType: TokenType, 4950 tokTypes: types, 4951 keywordTypes: keywords$1, 4952 TokContext: TokContext, 4953 tokContexts: types$1, 4954 isIdentifierChar: isIdentifierChar, 4955 isIdentifierStart: isIdentifierStart, 4956 Token: Token, 4957 isNewLine: isNewLine, 4958 lineBreak: lineBreak, 4959 lineBreakG: lineBreakG, 4960 nonASCIIwhitespace: nonASCIIwhitespace 4961}; 4962 4963// The main exported interface (under `self.acorn` when in the 4964// browser) is a `parse` function that takes a code string and 4965// returns an abstract syntax tree as specified by [Mozilla parser 4966// API][api]. 4967// 4968// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API 4969 4970function parse(input, options) { 4971 return Parser.parse(input, options) 4972} 4973 4974// This function tries to parse a single expression at a given 4975// offset in a string. Useful for parsing mixed-language formats 4976// that embed JavaScript expressions. 4977 4978function parseExpressionAt(input, pos, options) { 4979 return Parser.parseExpressionAt(input, pos, options) 4980} 4981 4982// Acorn is organized as a tokenizer and a recursive-descent parser. 4983// The `tokenizer` export provides an interface to the tokenizer. 4984 4985function tokenizer(input, options) { 4986 return Parser.tokenizer(input, options) 4987} 4988 4989export { 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 }; 4990