UNPKG

236 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5/* eslint max-len: 0 */
6
7// This is a trick taken from Esprima. It turns out that, on
8// non-Chrome browsers, to check whether a string is in a set, a
9// predicate containing a big ugly `switch` statement is faster than
10// a regular expression, and on Chrome the two are about on par.
11// This function uses `eval` (non-lexical) to produce such a
12// predicate from a space-separated string of words.
13//
14// It starts by sorting the words by length.
15
16function makePredicate(words) {
17 words = words.split(" ");
18 return function (str) {
19 return words.indexOf(str) >= 0;
20 };
21}
22
23// Reserved word lists for various dialects of the language
24
25var reservedWords = {
26 6: makePredicate("enum await"),
27 strict: makePredicate("implements interface let package private protected public static yield"),
28 strictBind: makePredicate("eval arguments")
29};
30
31// And the keywords
32
33var isKeyword = makePredicate("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 let const class extends export import yield super");
34
35// ## Character categories
36
37// Big ugly regular expressions that match characters in the
38// whitespace, identifier, and identifier-start categories. These
39// are only applied when a character is found to actually have a
40// code point above 128.
41// Generated by `bin/generate-identifier-regex.js`.
42
43var 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\u0561-\u0587\u05D0-\u05EA\u05F0-\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\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\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\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\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-\u1877\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\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\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-\uAB65\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";
44var 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\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\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\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\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-\u0C03\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\u0D01-\u0D03\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-\u0EB9\u0EBB\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\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\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\uA900-\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";
45
46var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
47var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
48
49nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
50
51// These are a run-length and offset encoded representation of the
52// >0xffff code points that are a valid part of identifiers. The
53// offset starts at 0x10000, and each pair of numbers represents an
54// offset to the next range, and then a size of the range. They were
55// generated by `bin/generate-identifier-regex.js`.
56// eslint-disable-next-line comma-spacing
57var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 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, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 785, 52, 76, 44, 33, 24, 27, 35, 42, 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, 54, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 86, 25, 391, 63, 32, 0, 449, 56, 264, 8, 2, 36, 18, 0, 50, 29, 881, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 65, 0, 32, 6124, 20, 754, 9486, 1, 3071, 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, 4149, 196, 60, 67, 1213, 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, 10591, 541];
58// eslint-disable-next-line comma-spacing
59var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 10, 2, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 87, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 423, 9, 838, 7, 2, 7, 17, 9, 57, 21, 2, 13, 19882, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 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, 2214, 6, 110, 6, 6, 9, 792487, 239];
60
61// This has a complexity linear to the value of the code. The
62// assumption is that looking up astral identifier characters is
63// rare.
64function isInAstralSet(code, set) {
65 var pos = 0x10000;
66 for (var i = 0; i < set.length; i += 2) {
67 pos += set[i];
68 if (pos > code) return false;
69
70 pos += set[i + 1];
71 if (pos >= code) return true;
72 }
73}
74
75// Test whether a given character code starts an identifier.
76
77function isIdentifierStart(code) {
78 if (code < 65) return code === 36;
79 if (code < 91) return true;
80 if (code < 97) return code === 95;
81 if (code < 123) return true;
82 if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
83 return isInAstralSet(code, astralIdentifierStartCodes);
84}
85
86// Test whether a given character is part of an identifier.
87
88function isIdentifierChar(code) {
89 if (code < 48) return code === 36;
90 if (code < 58) return true;
91 if (code < 65) return false;
92 if (code < 91) return true;
93 if (code < 97) return code === 95;
94 if (code < 123) return true;
95 if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
96 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
97}
98
99// A second optional argument can be given to further configure
100var defaultOptions = {
101 // Source type ("script" or "module") for different semantics
102 sourceType: "script",
103 // Source filename.
104 sourceFilename: undefined,
105 // Line from which to start counting source. Useful for
106 // integration with other tools.
107 startLine: 1,
108 // When enabled, a return at the top level is not considered an
109 // error.
110 allowReturnOutsideFunction: false,
111 // When enabled, import/export statements are not constrained to
112 // appearing at the top of the program.
113 allowImportExportEverywhere: false,
114 // TODO
115 allowSuperOutsideMethod: false,
116 // An array of plugins to enable
117 plugins: [],
118 // TODO
119 strictMode: null
120};
121
122// Interpret and default an options object
123
124function getOptions(opts) {
125 var options = {};
126 for (var key in defaultOptions) {
127 options[key] = opts && key in opts ? opts[key] : defaultOptions[key];
128 }
129 return options;
130}
131
132var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
133 return typeof obj;
134} : function (obj) {
135 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
136};
137
138
139
140
141
142
143
144
145
146
147
148var classCallCheck = function (instance, Constructor) {
149 if (!(instance instanceof Constructor)) {
150 throw new TypeError("Cannot call a class as a function");
151 }
152};
153
154
155
156
157
158
159
160
161
162
163
164var inherits = function (subClass, superClass) {
165 if (typeof superClass !== "function" && superClass !== null) {
166 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
167 }
168
169 subClass.prototype = Object.create(superClass && superClass.prototype, {
170 constructor: {
171 value: subClass,
172 enumerable: false,
173 writable: true,
174 configurable: true
175 }
176 });
177 if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
178};
179
180
181
182
183
184
185
186
187
188
189
190var possibleConstructorReturn = function (self, call) {
191 if (!self) {
192 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
193 }
194
195 return call && (typeof call === "object" || typeof call === "function") ? call : self;
196};
197
198// ## Token types
199
200// The assignment of fine-grained, information-carrying type objects
201// allows the tokenizer to store the information it has about a
202// token in a way that is very cheap for the parser to look up.
203
204// All token type variables start with an underscore, to make them
205// easy to recognize.
206
207// The `beforeExpr` property is used to disambiguate between regular
208// expressions and divisions. It is set on all token types that can
209// be followed by an expression (thus, a slash after them would be a
210// regular expression).
211//
212// `isLoop` marks a keyword as starting a loop, which is important
213// to know when parsing a label, in order to allow or disallow
214// continue jumps to that label.
215
216var beforeExpr = true;
217var startsExpr = true;
218var isLoop = true;
219var isAssign = true;
220var prefix = true;
221var postfix = true;
222
223var TokenType = function TokenType(label) {
224 var conf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
225 classCallCheck(this, TokenType);
226
227 this.label = label;
228 this.keyword = conf.keyword;
229 this.beforeExpr = !!conf.beforeExpr;
230 this.startsExpr = !!conf.startsExpr;
231 this.rightAssociative = !!conf.rightAssociative;
232 this.isLoop = !!conf.isLoop;
233 this.isAssign = !!conf.isAssign;
234 this.prefix = !!conf.prefix;
235 this.postfix = !!conf.postfix;
236 this.binop = conf.binop || null;
237 this.updateContext = null;
238};
239
240var KeywordTokenType = function (_TokenType) {
241 inherits(KeywordTokenType, _TokenType);
242
243 function KeywordTokenType(name) {
244 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
245 classCallCheck(this, KeywordTokenType);
246
247 options.keyword = name;
248
249 return possibleConstructorReturn(this, _TokenType.call(this, name, options));
250 }
251
252 return KeywordTokenType;
253}(TokenType);
254
255var BinopTokenType = function (_TokenType2) {
256 inherits(BinopTokenType, _TokenType2);
257
258 function BinopTokenType(name, prec) {
259 classCallCheck(this, BinopTokenType);
260 return possibleConstructorReturn(this, _TokenType2.call(this, name, { beforeExpr: beforeExpr, binop: prec }));
261 }
262
263 return BinopTokenType;
264}(TokenType);
265
266var types = {
267 num: new TokenType("num", { startsExpr: startsExpr }),
268 regexp: new TokenType("regexp", { startsExpr: startsExpr }),
269 string: new TokenType("string", { startsExpr: startsExpr }),
270 name: new TokenType("name", { startsExpr: startsExpr }),
271 eof: new TokenType("eof"),
272
273 // Punctuation token types.
274 bracketL: new TokenType("[", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
275 bracketR: new TokenType("]"),
276 braceL: new TokenType("{", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
277 braceBarL: new TokenType("{|", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
278 braceR: new TokenType("}"),
279 braceBarR: new TokenType("|}"),
280 parenL: new TokenType("(", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
281 parenR: new TokenType(")"),
282 comma: new TokenType(",", { beforeExpr: beforeExpr }),
283 semi: new TokenType(";", { beforeExpr: beforeExpr }),
284 colon: new TokenType(":", { beforeExpr: beforeExpr }),
285 doubleColon: new TokenType("::", { beforeExpr: beforeExpr }),
286 dot: new TokenType("."),
287 question: new TokenType("?", { beforeExpr: beforeExpr }),
288 arrow: new TokenType("=>", { beforeExpr: beforeExpr }),
289 template: new TokenType("template"),
290 ellipsis: new TokenType("...", { beforeExpr: beforeExpr }),
291 backQuote: new TokenType("`", { startsExpr: startsExpr }),
292 dollarBraceL: new TokenType("${", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
293 at: new TokenType("@"),
294
295 // Operators. These carry several kinds of properties to help the
296 // parser use them properly (the presence of these properties is
297 // what categorizes them as operators).
298 //
299 // `binop`, when present, specifies that this operator is a binary
300 // operator, and will refer to its precedence.
301 //
302 // `prefix` and `postfix` mark the operator as a prefix or postfix
303 // unary operator.
304 //
305 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
306 // binary operators with a very low precedence, that should result
307 // in AssignmentExpression nodes.
308
309 eq: new TokenType("=", { beforeExpr: beforeExpr, isAssign: isAssign }),
310 assign: new TokenType("_=", { beforeExpr: beforeExpr, isAssign: isAssign }),
311 incDec: new TokenType("++/--", { prefix: prefix, postfix: postfix, startsExpr: startsExpr }),
312 prefix: new TokenType("prefix", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }),
313 logicalOR: new BinopTokenType("||", 1),
314 logicalAND: new BinopTokenType("&&", 2),
315 bitwiseOR: new BinopTokenType("|", 3),
316 bitwiseXOR: new BinopTokenType("^", 4),
317 bitwiseAND: new BinopTokenType("&", 5),
318 equality: new BinopTokenType("==/!=", 6),
319 relational: new BinopTokenType("</>", 7),
320 bitShift: new BinopTokenType("<</>>", 8),
321 plusMin: new TokenType("+/-", { beforeExpr: beforeExpr, binop: 9, prefix: prefix, startsExpr: startsExpr }),
322 modulo: new BinopTokenType("%", 10),
323 star: new BinopTokenType("*", 10),
324 slash: new BinopTokenType("/", 10),
325 exponent: new TokenType("**", { beforeExpr: beforeExpr, binop: 11, rightAssociative: true })
326};
327
328var keywords = {
329 "break": new KeywordTokenType("break"),
330 "case": new KeywordTokenType("case", { beforeExpr: beforeExpr }),
331 "catch": new KeywordTokenType("catch"),
332 "continue": new KeywordTokenType("continue"),
333 "debugger": new KeywordTokenType("debugger"),
334 "default": new KeywordTokenType("default", { beforeExpr: beforeExpr }),
335 "do": new KeywordTokenType("do", { isLoop: isLoop, beforeExpr: beforeExpr }),
336 "else": new KeywordTokenType("else", { beforeExpr: beforeExpr }),
337 "finally": new KeywordTokenType("finally"),
338 "for": new KeywordTokenType("for", { isLoop: isLoop }),
339 "function": new KeywordTokenType("function", { startsExpr: startsExpr }),
340 "if": new KeywordTokenType("if"),
341 "return": new KeywordTokenType("return", { beforeExpr: beforeExpr }),
342 "switch": new KeywordTokenType("switch"),
343 "throw": new KeywordTokenType("throw", { beforeExpr: beforeExpr }),
344 "try": new KeywordTokenType("try"),
345 "var": new KeywordTokenType("var"),
346 "let": new KeywordTokenType("let"),
347 "const": new KeywordTokenType("const"),
348 "while": new KeywordTokenType("while", { isLoop: isLoop }),
349 "with": new KeywordTokenType("with"),
350 "new": new KeywordTokenType("new", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
351 "this": new KeywordTokenType("this", { startsExpr: startsExpr }),
352 "super": new KeywordTokenType("super", { startsExpr: startsExpr }),
353 "class": new KeywordTokenType("class"),
354 "extends": new KeywordTokenType("extends", { beforeExpr: beforeExpr }),
355 "export": new KeywordTokenType("export"),
356 "import": new KeywordTokenType("import", { startsExpr: startsExpr }),
357 "yield": new KeywordTokenType("yield", { beforeExpr: beforeExpr, startsExpr: startsExpr }),
358 "null": new KeywordTokenType("null", { startsExpr: startsExpr }),
359 "true": new KeywordTokenType("true", { startsExpr: startsExpr }),
360 "false": new KeywordTokenType("false", { startsExpr: startsExpr }),
361 "in": new KeywordTokenType("in", { beforeExpr: beforeExpr, binop: 7 }),
362 "instanceof": new KeywordTokenType("instanceof", { beforeExpr: beforeExpr, binop: 7 }),
363 "typeof": new KeywordTokenType("typeof", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }),
364 "void": new KeywordTokenType("void", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }),
365 "delete": new KeywordTokenType("delete", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr })
366};
367
368// Map keyword names to token types.
369Object.keys(keywords).forEach(function (name) {
370 types["_" + name] = keywords[name];
371});
372
373// Matches a whole line break (where CRLF is considered a single
374// line break). Used to count lines.
375
376var lineBreak = /\r\n?|\n|\u2028|\u2029/;
377var lineBreakG = new RegExp(lineBreak.source, "g");
378
379function isNewLine(code) {
380 return code === 10 || code === 13 || code === 0x2028 || code === 0x2029;
381}
382
383var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
384
385// The algorithm used to determine whether a regexp can appear at a
386// given point in the program is loosely based on sweet.js' approach.
387// See https://github.com/mozilla/sweet.js/wiki/design
388
389var TokContext = function TokContext(token, isExpr, preserveSpace, override) {
390 classCallCheck(this, TokContext);
391
392 this.token = token;
393 this.isExpr = !!isExpr;
394 this.preserveSpace = !!preserveSpace;
395 this.override = override;
396};
397
398var types$1 = {
399 braceStatement: new TokContext("{", false),
400 braceExpression: new TokContext("{", true),
401 templateQuasi: new TokContext("${", true),
402 parenStatement: new TokContext("(", false),
403 parenExpression: new TokContext("(", true),
404 template: new TokContext("`", true, true, function (p) {
405 return p.readTmplToken();
406 }),
407 functionExpression: new TokContext("function", true)
408};
409
410// Token-specific context update code
411
412types.parenR.updateContext = types.braceR.updateContext = function () {
413 if (this.state.context.length === 1) {
414 this.state.exprAllowed = true;
415 return;
416 }
417
418 var out = this.state.context.pop();
419 if (out === types$1.braceStatement && this.curContext() === types$1.functionExpression) {
420 this.state.context.pop();
421 this.state.exprAllowed = false;
422 } else if (out === types$1.templateQuasi) {
423 this.state.exprAllowed = true;
424 } else {
425 this.state.exprAllowed = !out.isExpr;
426 }
427};
428
429types.name.updateContext = function (prevType) {
430 this.state.exprAllowed = false;
431
432 if (prevType === types._let || prevType === types._const || prevType === types._var) {
433 if (lineBreak.test(this.input.slice(this.state.end))) {
434 this.state.exprAllowed = true;
435 }
436 }
437};
438
439types.braceL.updateContext = function (prevType) {
440 this.state.context.push(this.braceIsBlock(prevType) ? types$1.braceStatement : types$1.braceExpression);
441 this.state.exprAllowed = true;
442};
443
444types.dollarBraceL.updateContext = function () {
445 this.state.context.push(types$1.templateQuasi);
446 this.state.exprAllowed = true;
447};
448
449types.parenL.updateContext = function (prevType) {
450 var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
451 this.state.context.push(statementParens ? types$1.parenStatement : types$1.parenExpression);
452 this.state.exprAllowed = true;
453};
454
455types.incDec.updateContext = function () {
456 // tokExprAllowed stays unchanged
457};
458
459types._function.updateContext = function () {
460 if (this.curContext() !== types$1.braceStatement) {
461 this.state.context.push(types$1.functionExpression);
462 }
463
464 this.state.exprAllowed = false;
465};
466
467types.backQuote.updateContext = function () {
468 if (this.curContext() === types$1.template) {
469 this.state.context.pop();
470 } else {
471 this.state.context.push(types$1.template);
472 }
473 this.state.exprAllowed = false;
474};
475
476// These are used when `options.locations` is on, for the
477// `startLoc` and `endLoc` properties.
478
479var Position = function Position(line, col) {
480 classCallCheck(this, Position);
481
482 this.line = line;
483 this.column = col;
484};
485
486var SourceLocation = function SourceLocation(start, end) {
487 classCallCheck(this, SourceLocation);
488
489 this.start = start;
490 this.end = end;
491};
492
493// The `getLineInfo` function is mostly useful when the
494// `locations` option is off (for performance reasons) and you
495// want to find the line/column position for a given character
496// offset. `input` should be the code string that the offset refers
497// into.
498
499function getLineInfo(input, offset) {
500 for (var line = 1, cur = 0;;) {
501 lineBreakG.lastIndex = cur;
502 var match = lineBreakG.exec(input);
503 if (match && match.index < offset) {
504 ++line;
505 cur = match.index + match[0].length;
506 } else {
507 return new Position(line, offset - cur);
508 }
509 }
510}
511
512var State = function () {
513 function State() {
514 classCallCheck(this, State);
515 }
516
517 State.prototype.init = function init(options, input) {
518 this.strict = options.strictMode === false ? false : options.sourceType === "module";
519
520 this.input = input;
521
522 this.potentialArrowAt = -1;
523
524 this.inMethod = this.inFunction = this.inGenerator = this.inAsync = this.inPropertyName = this.inType = this.inClassProperty = this.noAnonFunctionType = false;
525
526 this.labels = [];
527
528 this.decorators = [];
529
530 this.tokens = [];
531
532 this.comments = [];
533
534 this.trailingComments = [];
535 this.leadingComments = [];
536 this.commentStack = [];
537
538 this.pos = this.lineStart = 0;
539 this.curLine = options.startLine;
540
541 this.type = types.eof;
542 this.value = null;
543 this.start = this.end = this.pos;
544 this.startLoc = this.endLoc = this.curPosition();
545
546 this.lastTokEndLoc = this.lastTokStartLoc = null;
547 this.lastTokStart = this.lastTokEnd = this.pos;
548
549 this.context = [types$1.braceStatement];
550 this.exprAllowed = true;
551
552 this.containsEsc = this.containsOctal = false;
553 this.octalPosition = null;
554
555 this.invalidTemplateEscapePosition = null;
556
557 this.exportedIdentifiers = [];
558
559 return this;
560 };
561
562 // TODO
563
564
565 // TODO
566
567
568 // Used to signify the start of a potential arrow function
569
570
571 // Flags to track whether we are in a function, a generator.
572
573
574 // Labels in scope.
575
576
577 // Leading decorators.
578
579
580 // Token store.
581
582
583 // Comment store.
584
585
586 // Comment attachment store
587
588
589 // The current position of the tokenizer in the input.
590
591
592 // Properties of the current token:
593 // Its type
594
595
596 // For tokens that include more information than their type, the value
597
598
599 // Its start and end offset
600
601
602 // And, if locations are used, the {line, column} object
603 // corresponding to those offsets
604
605
606 // Position information for the previous token
607
608
609 // The context stack is used to superficially track syntactic
610 // context to predict whether a regular expression is allowed in a
611 // given position.
612
613
614 // Used to signal to callers of `readWord1` whether the word
615 // contained any escape sequences. This is needed because words with
616 // escape sequences must not be interpreted as keywords.
617
618
619 // TODO
620
621
622 // Names of exports store. `default` is stored as a name for both
623 // `export default foo;` and `export { foo as default };`.
624
625
626 State.prototype.curPosition = function curPosition() {
627 return new Position(this.curLine, this.pos - this.lineStart);
628 };
629
630 State.prototype.clone = function clone(skipArrays) {
631 var state = new State();
632 for (var key in this) {
633 var val = this[key];
634
635 if ((!skipArrays || key === "context") && Array.isArray(val)) {
636 val = val.slice();
637 }
638
639 state[key] = val;
640 }
641 return state;
642 };
643
644 return State;
645}();
646
647// Object type used to represent tokens. Note that normally, tokens
648// simply exist as properties on the parser object. This is only
649// used for the onToken callback and the external tokenizer.
650
651var Token = function Token(state) {
652 classCallCheck(this, Token);
653
654 this.type = state.type;
655 this.value = state.value;
656 this.start = state.start;
657 this.end = state.end;
658 this.loc = new SourceLocation(state.startLoc, state.endLoc);
659};
660
661// ## Tokenizer
662
663function codePointToString(code) {
664 // UTF-16 Decoding
665 if (code <= 0xFFFF) {
666 return String.fromCharCode(code);
667 } else {
668 return String.fromCharCode((code - 0x10000 >> 10) + 0xD800, (code - 0x10000 & 1023) + 0xDC00);
669 }
670}
671
672var Tokenizer = function () {
673 function Tokenizer(options, input) {
674 classCallCheck(this, Tokenizer);
675
676 this.state = new State();
677 this.state.init(options, input);
678 }
679
680 // Move to the next token
681
682 Tokenizer.prototype.next = function next() {
683 if (!this.isLookahead) {
684 this.state.tokens.push(new Token(this.state));
685 }
686
687 this.state.lastTokEnd = this.state.end;
688 this.state.lastTokStart = this.state.start;
689 this.state.lastTokEndLoc = this.state.endLoc;
690 this.state.lastTokStartLoc = this.state.startLoc;
691 this.nextToken();
692 };
693
694 // TODO
695
696 Tokenizer.prototype.eat = function eat(type) {
697 if (this.match(type)) {
698 this.next();
699 return true;
700 } else {
701 return false;
702 }
703 };
704
705 // TODO
706
707 Tokenizer.prototype.match = function match(type) {
708 return this.state.type === type;
709 };
710
711 // TODO
712
713 Tokenizer.prototype.isKeyword = function isKeyword$$1(word) {
714 return isKeyword(word);
715 };
716
717 // TODO
718
719 Tokenizer.prototype.lookahead = function lookahead() {
720 var old = this.state;
721 this.state = old.clone(true);
722
723 this.isLookahead = true;
724 this.next();
725 this.isLookahead = false;
726
727 var curr = this.state.clone(true);
728 this.state = old;
729 return curr;
730 };
731
732 // Toggle strict mode. Re-reads the next number or string to please
733 // pedantic tests (`"use strict"; 010;` should fail).
734
735 Tokenizer.prototype.setStrict = function setStrict(strict) {
736 this.state.strict = strict;
737 if (!this.match(types.num) && !this.match(types.string)) return;
738 this.state.pos = this.state.start;
739 while (this.state.pos < this.state.lineStart) {
740 this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1;
741 --this.state.curLine;
742 }
743 this.nextToken();
744 };
745
746 Tokenizer.prototype.curContext = function curContext() {
747 return this.state.context[this.state.context.length - 1];
748 };
749
750 // Read a single token, updating the parser object's token-related
751 // properties.
752
753 Tokenizer.prototype.nextToken = function nextToken() {
754 var curContext = this.curContext();
755 if (!curContext || !curContext.preserveSpace) this.skipSpace();
756
757 this.state.containsOctal = false;
758 this.state.octalPosition = null;
759 this.state.start = this.state.pos;
760 this.state.startLoc = this.state.curPosition();
761 if (this.state.pos >= this.input.length) return this.finishToken(types.eof);
762
763 if (curContext.override) {
764 return curContext.override(this);
765 } else {
766 return this.readToken(this.fullCharCodeAtPos());
767 }
768 };
769
770 Tokenizer.prototype.readToken = function readToken(code) {
771 // Identifier or keyword. '\uXXXX' sequences are allowed in
772 // identifiers, so '\' also dispatches to that.
773 if (isIdentifierStart(code) || code === 92 /* '\' */) {
774 return this.readWord();
775 } else {
776 return this.getTokenFromCode(code);
777 }
778 };
779
780 Tokenizer.prototype.fullCharCodeAtPos = function fullCharCodeAtPos() {
781 var code = this.input.charCodeAt(this.state.pos);
782 if (code <= 0xd7ff || code >= 0xe000) return code;
783
784 var next = this.input.charCodeAt(this.state.pos + 1);
785 return (code << 10) + next - 0x35fdc00;
786 };
787
788 Tokenizer.prototype.pushComment = function pushComment(block, text, start, end, startLoc, endLoc) {
789 var comment = {
790 type: block ? "CommentBlock" : "CommentLine",
791 value: text,
792 start: start,
793 end: end,
794 loc: new SourceLocation(startLoc, endLoc)
795 };
796
797 if (!this.isLookahead) {
798 this.state.tokens.push(comment);
799 this.state.comments.push(comment);
800 this.addComment(comment);
801 }
802 };
803
804 Tokenizer.prototype.skipBlockComment = function skipBlockComment() {
805 var startLoc = this.state.curPosition();
806 var start = this.state.pos;
807 var end = this.input.indexOf("*/", this.state.pos += 2);
808 if (end === -1) this.raise(this.state.pos - 2, "Unterminated comment");
809
810 this.state.pos = end + 2;
811 lineBreakG.lastIndex = start;
812 var match = void 0;
813 while ((match = lineBreakG.exec(this.input)) && match.index < this.state.pos) {
814 ++this.state.curLine;
815 this.state.lineStart = match.index + match[0].length;
816 }
817
818 this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition());
819 };
820
821 Tokenizer.prototype.skipLineComment = function skipLineComment(startSkip) {
822 var start = this.state.pos;
823 var startLoc = this.state.curPosition();
824 var ch = this.input.charCodeAt(this.state.pos += startSkip);
825 while (this.state.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
826 ++this.state.pos;
827 ch = this.input.charCodeAt(this.state.pos);
828 }
829
830 this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition());
831 };
832
833 // Called at the start of the parse and after every token. Skips
834 // whitespace and comments, and.
835
836 Tokenizer.prototype.skipSpace = function skipSpace() {
837 loop: while (this.state.pos < this.input.length) {
838 var ch = this.input.charCodeAt(this.state.pos);
839 switch (ch) {
840 case 32:case 160:
841 // ' '
842 ++this.state.pos;
843 break;
844
845 case 13:
846 if (this.input.charCodeAt(this.state.pos + 1) === 10) {
847 ++this.state.pos;
848 }
849
850 case 10:case 8232:case 8233:
851 ++this.state.pos;
852 ++this.state.curLine;
853 this.state.lineStart = this.state.pos;
854 break;
855
856 case 47:
857 // '/'
858 switch (this.input.charCodeAt(this.state.pos + 1)) {
859 case 42:
860 // '*'
861 this.skipBlockComment();
862 break;
863
864 case 47:
865 this.skipLineComment(2);
866 break;
867
868 default:
869 break loop;
870 }
871 break;
872
873 default:
874 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
875 ++this.state.pos;
876 } else {
877 break loop;
878 }
879 }
880 }
881 };
882
883 // Called at the end of every token. Sets `end`, `val`, and
884 // maintains `context` and `exprAllowed`, and skips the space after
885 // the token, so that the next one's `start` will point at the
886 // right position.
887
888 Tokenizer.prototype.finishToken = function finishToken(type, val) {
889 this.state.end = this.state.pos;
890 this.state.endLoc = this.state.curPosition();
891 var prevType = this.state.type;
892 this.state.type = type;
893 this.state.value = val;
894
895 this.updateContext(prevType);
896 };
897
898 // ### Token reading
899
900 // This is the function that is called to fetch the next token. It
901 // is somewhat obscure, because it works in character codes rather
902 // than characters, and because operator parsing has been inlined
903 // into it.
904 //
905 // All in the name of speed.
906 //
907
908
909 Tokenizer.prototype.readToken_dot = function readToken_dot() {
910 var next = this.input.charCodeAt(this.state.pos + 1);
911 if (next >= 48 && next <= 57) {
912 return this.readNumber(true);
913 }
914
915 var next2 = this.input.charCodeAt(this.state.pos + 2);
916 if (next === 46 && next2 === 46) {
917 // 46 = dot '.'
918 this.state.pos += 3;
919 return this.finishToken(types.ellipsis);
920 } else {
921 ++this.state.pos;
922 return this.finishToken(types.dot);
923 }
924 };
925
926 Tokenizer.prototype.readToken_slash = function readToken_slash() {
927 // '/'
928 if (this.state.exprAllowed) {
929 ++this.state.pos;
930 return this.readRegexp();
931 }
932
933 var next = this.input.charCodeAt(this.state.pos + 1);
934 if (next === 61) {
935 return this.finishOp(types.assign, 2);
936 } else {
937 return this.finishOp(types.slash, 1);
938 }
939 };
940
941 Tokenizer.prototype.readToken_mult_modulo = function readToken_mult_modulo(code) {
942 // '%*'
943 var type = code === 42 ? types.star : types.modulo;
944 var width = 1;
945 var next = this.input.charCodeAt(this.state.pos + 1);
946
947 if (next === 42) {
948 // '*'
949 width++;
950 next = this.input.charCodeAt(this.state.pos + 2);
951 type = types.exponent;
952 }
953
954 if (next === 61) {
955 width++;
956 type = types.assign;
957 }
958
959 return this.finishOp(type, width);
960 };
961
962 Tokenizer.prototype.readToken_pipe_amp = function readToken_pipe_amp(code) {
963 // '|&'
964 var next = this.input.charCodeAt(this.state.pos + 1);
965 if (next === code) return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2);
966 if (next === 61) return this.finishOp(types.assign, 2);
967 if (code === 124 && next === 125 && this.hasPlugin("flow")) return this.finishOp(types.braceBarR, 2);
968 return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1);
969 };
970
971 Tokenizer.prototype.readToken_caret = function readToken_caret() {
972 // '^'
973 var next = this.input.charCodeAt(this.state.pos + 1);
974 if (next === 61) {
975 return this.finishOp(types.assign, 2);
976 } else {
977 return this.finishOp(types.bitwiseXOR, 1);
978 }
979 };
980
981 Tokenizer.prototype.readToken_plus_min = function readToken_plus_min(code) {
982 // '+-'
983 var next = this.input.charCodeAt(this.state.pos + 1);
984
985 if (next === code) {
986 if (next === 45 && this.input.charCodeAt(this.state.pos + 2) === 62 && lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.pos))) {
987 // A `-->` line comment
988 this.skipLineComment(3);
989 this.skipSpace();
990 return this.nextToken();
991 }
992 return this.finishOp(types.incDec, 2);
993 }
994
995 if (next === 61) {
996 return this.finishOp(types.assign, 2);
997 } else {
998 return this.finishOp(types.plusMin, 1);
999 }
1000 };
1001
1002 Tokenizer.prototype.readToken_lt_gt = function readToken_lt_gt(code) {
1003 // '<>'
1004 var next = this.input.charCodeAt(this.state.pos + 1);
1005 var size = 1;
1006
1007 if (next === code) {
1008 size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2;
1009 if (this.input.charCodeAt(this.state.pos + size) === 61) return this.finishOp(types.assign, size + 1);
1010 return this.finishOp(types.bitShift, size);
1011 }
1012
1013 if (next === 33 && code === 60 && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) {
1014 if (this.inModule) this.unexpected();
1015 // `<!--`, an XML-style comment that should be interpreted as a line comment
1016 this.skipLineComment(4);
1017 this.skipSpace();
1018 return this.nextToken();
1019 }
1020
1021 if (next === 61) {
1022 // <= | >=
1023 size = 2;
1024 }
1025
1026 return this.finishOp(types.relational, size);
1027 };
1028
1029 Tokenizer.prototype.readToken_eq_excl = function readToken_eq_excl(code) {
1030 // '=!'
1031 var next = this.input.charCodeAt(this.state.pos + 1);
1032 if (next === 61) return this.finishOp(types.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2);
1033 if (code === 61 && next === 62) {
1034 // '=>'
1035 this.state.pos += 2;
1036 return this.finishToken(types.arrow);
1037 }
1038 return this.finishOp(code === 61 ? types.eq : types.prefix, 1);
1039 };
1040
1041 Tokenizer.prototype.getTokenFromCode = function getTokenFromCode(code) {
1042 switch (code) {
1043 // The interpretation of a dot depends on whether it is followed
1044 // by a digit or another two dots.
1045 case 46:
1046 // '.'
1047 return this.readToken_dot();
1048
1049 // Punctuation tokens.
1050 case 40:
1051 ++this.state.pos;return this.finishToken(types.parenL);
1052 case 41:
1053 ++this.state.pos;return this.finishToken(types.parenR);
1054 case 59:
1055 ++this.state.pos;return this.finishToken(types.semi);
1056 case 44:
1057 ++this.state.pos;return this.finishToken(types.comma);
1058 case 91:
1059 ++this.state.pos;return this.finishToken(types.bracketL);
1060 case 93:
1061 ++this.state.pos;return this.finishToken(types.bracketR);
1062
1063 case 123:
1064 if (this.hasPlugin("flow") && this.input.charCodeAt(this.state.pos + 1) === 124) {
1065 return this.finishOp(types.braceBarL, 2);
1066 } else {
1067 ++this.state.pos;
1068 return this.finishToken(types.braceL);
1069 }
1070
1071 case 125:
1072 ++this.state.pos;return this.finishToken(types.braceR);
1073
1074 case 58:
1075 if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) {
1076 return this.finishOp(types.doubleColon, 2);
1077 } else {
1078 ++this.state.pos;
1079 return this.finishToken(types.colon);
1080 }
1081
1082 case 63:
1083 ++this.state.pos;return this.finishToken(types.question);
1084 case 64:
1085 ++this.state.pos;return this.finishToken(types.at);
1086
1087 case 96:
1088 // '`'
1089 ++this.state.pos;
1090 return this.finishToken(types.backQuote);
1091
1092 case 48:
1093 // '0'
1094 var next = this.input.charCodeAt(this.state.pos + 1);
1095 if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
1096 if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
1097 if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
1098 // Anything else beginning with a digit is an integer, octal
1099 // number, or float.
1100 case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
1101 // 1-9
1102 return this.readNumber(false);
1103
1104 // Quotes produce strings.
1105 case 34:case 39:
1106 // '"', "'"
1107 return this.readString(code);
1108
1109 // Operators are parsed inline in tiny state machines. '=' (61) is
1110 // often referred to. `finishOp` simply skips the amount of
1111 // characters it is given as second argument, and returns a token
1112 // of the type given by its first argument.
1113
1114 case 47:
1115 // '/'
1116 return this.readToken_slash();
1117
1118 case 37:case 42:
1119 // '%*'
1120 return this.readToken_mult_modulo(code);
1121
1122 case 124:case 38:
1123 // '|&'
1124 return this.readToken_pipe_amp(code);
1125
1126 case 94:
1127 // '^'
1128 return this.readToken_caret();
1129
1130 case 43:case 45:
1131 // '+-'
1132 return this.readToken_plus_min(code);
1133
1134 case 60:case 62:
1135 // '<>'
1136 return this.readToken_lt_gt(code);
1137
1138 case 61:case 33:
1139 // '=!'
1140 return this.readToken_eq_excl(code);
1141
1142 case 126:
1143 // '~'
1144 return this.finishOp(types.prefix, 1);
1145 }
1146
1147 this.raise(this.state.pos, "Unexpected character '" + codePointToString(code) + "'");
1148 };
1149
1150 Tokenizer.prototype.finishOp = function finishOp(type, size) {
1151 var str = this.input.slice(this.state.pos, this.state.pos + size);
1152 this.state.pos += size;
1153 return this.finishToken(type, str);
1154 };
1155
1156 Tokenizer.prototype.readRegexp = function readRegexp() {
1157 var start = this.state.pos;
1158 var escaped = void 0,
1159 inClass = void 0;
1160 for (;;) {
1161 if (this.state.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
1162 var ch = this.input.charAt(this.state.pos);
1163 if (lineBreak.test(ch)) {
1164 this.raise(start, "Unterminated regular expression");
1165 }
1166 if (escaped) {
1167 escaped = false;
1168 } else {
1169 if (ch === "[") {
1170 inClass = true;
1171 } else if (ch === "]" && inClass) {
1172 inClass = false;
1173 } else if (ch === "/" && !inClass) {
1174 break;
1175 }
1176 escaped = ch === "\\";
1177 }
1178 ++this.state.pos;
1179 }
1180 var content = this.input.slice(start, this.state.pos);
1181 ++this.state.pos;
1182 // Need to use `readWord1` because '\uXXXX' sequences are allowed
1183 // here (don't ask).
1184 var mods = this.readWord1();
1185 if (mods) {
1186 var validFlags = /^[gmsiyu]*$/;
1187 if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
1188 }
1189 return this.finishToken(types.regexp, {
1190 pattern: content,
1191 flags: mods
1192 });
1193 };
1194
1195 // Read an integer in the given radix. Return null if zero digits
1196 // were read, the integer value otherwise. When `len` is given, this
1197 // will return `null` unless the integer has exactly `len` digits.
1198
1199 Tokenizer.prototype.readInt = function readInt(radix, len) {
1200 var start = this.state.pos;
1201 var total = 0;
1202
1203 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
1204 var code = this.input.charCodeAt(this.state.pos);
1205 var val = void 0;
1206 if (code >= 97) {
1207 val = code - 97 + 10; // a
1208 } else if (code >= 65) {
1209 val = code - 65 + 10; // A
1210 } else if (code >= 48 && code <= 57) {
1211 val = code - 48; // 0-9
1212 } else {
1213 val = Infinity;
1214 }
1215 if (val >= radix) break;
1216 ++this.state.pos;
1217 total = total * radix + val;
1218 }
1219 if (this.state.pos === start || len != null && this.state.pos - start !== len) return null;
1220
1221 return total;
1222 };
1223
1224 Tokenizer.prototype.readRadixNumber = function readRadixNumber(radix) {
1225 this.state.pos += 2; // 0x
1226 var val = this.readInt(radix);
1227 if (val == null) this.raise(this.state.start + 2, "Expected number in radix " + radix);
1228 if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number");
1229 return this.finishToken(types.num, val);
1230 };
1231
1232 // Read an integer, octal integer, or floating-point number.
1233
1234 Tokenizer.prototype.readNumber = function readNumber(startsWithDot) {
1235 var start = this.state.pos;
1236 var octal = this.input.charCodeAt(start) === 48; // '0'
1237 var isFloat = false;
1238
1239 if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
1240 if (octal && this.state.pos == start + 1) octal = false; // number === 0
1241
1242 var next = this.input.charCodeAt(this.state.pos);
1243 if (next === 46 && !octal) {
1244 // '.'
1245 ++this.state.pos;
1246 this.readInt(10);
1247 isFloat = true;
1248 next = this.input.charCodeAt(this.state.pos);
1249 }
1250
1251 if ((next === 69 || next === 101) && !octal) {
1252 // 'eE'
1253 next = this.input.charCodeAt(++this.state.pos);
1254 if (next === 43 || next === 45) ++this.state.pos; // '+-'
1255 if (this.readInt(10) === null) this.raise(start, "Invalid number");
1256 isFloat = true;
1257 }
1258
1259 if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number");
1260
1261 var str = this.input.slice(start, this.state.pos);
1262 var val = void 0;
1263 if (isFloat) {
1264 val = parseFloat(str);
1265 } else if (!octal || str.length === 1) {
1266 val = parseInt(str, 10);
1267 } else if (this.state.strict) {
1268 this.raise(start, "Invalid number");
1269 } else if (/[89]/.test(str)) {
1270 val = parseInt(str, 10);
1271 } else {
1272 val = parseInt(str, 8);
1273 }
1274 return this.finishToken(types.num, val);
1275 };
1276
1277 // Read a string value, interpreting backslash-escapes.
1278
1279 Tokenizer.prototype.readCodePoint = function readCodePoint(throwOnInvalid) {
1280 var ch = this.input.charCodeAt(this.state.pos);
1281 var code = void 0;
1282
1283 if (ch === 123) {
1284 // '{'
1285 var codePos = ++this.state.pos;
1286 code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, throwOnInvalid);
1287 ++this.state.pos;
1288 if (code === null) {
1289 --this.state.invalidTemplateEscapePosition; // to point to the '\'' instead of the 'u'
1290 } else if (code > 0x10FFFF) {
1291 if (throwOnInvalid) {
1292 this.raise(codePos, "Code point out of bounds");
1293 } else {
1294 this.state.invalidTemplateEscapePosition = codePos - 2;
1295 return null;
1296 }
1297 }
1298 } else {
1299 code = this.readHexChar(4, throwOnInvalid);
1300 }
1301 return code;
1302 };
1303
1304 Tokenizer.prototype.readString = function readString(quote) {
1305 var out = "",
1306 chunkStart = ++this.state.pos;
1307 for (;;) {
1308 if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated string constant");
1309 var ch = this.input.charCodeAt(this.state.pos);
1310 if (ch === quote) break;
1311 if (ch === 92) {
1312 // '\'
1313 out += this.input.slice(chunkStart, this.state.pos);
1314 out += this.readEscapedChar(false);
1315 chunkStart = this.state.pos;
1316 } else {
1317 if (isNewLine(ch)) this.raise(this.state.start, "Unterminated string constant");
1318 ++this.state.pos;
1319 }
1320 }
1321 out += this.input.slice(chunkStart, this.state.pos++);
1322 return this.finishToken(types.string, out);
1323 };
1324
1325 // Reads template string tokens.
1326
1327 Tokenizer.prototype.readTmplToken = function readTmplToken() {
1328 var out = "",
1329 chunkStart = this.state.pos,
1330 containsInvalid = false;
1331 for (;;) {
1332 if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated template");
1333 var ch = this.input.charCodeAt(this.state.pos);
1334 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) {
1335 // '`', '${'
1336 if (this.state.pos === this.state.start && this.match(types.template)) {
1337 if (ch === 36) {
1338 this.state.pos += 2;
1339 return this.finishToken(types.dollarBraceL);
1340 } else {
1341 ++this.state.pos;
1342 return this.finishToken(types.backQuote);
1343 }
1344 }
1345 out += this.input.slice(chunkStart, this.state.pos);
1346 return this.finishToken(types.template, containsInvalid ? null : out);
1347 }
1348 if (ch === 92) {
1349 // '\'
1350 out += this.input.slice(chunkStart, this.state.pos);
1351 var escaped = this.readEscapedChar(true);
1352 if (escaped === null) {
1353 containsInvalid = true;
1354 } else {
1355 out += escaped;
1356 }
1357 chunkStart = this.state.pos;
1358 } else if (isNewLine(ch)) {
1359 out += this.input.slice(chunkStart, this.state.pos);
1360 ++this.state.pos;
1361 switch (ch) {
1362 case 13:
1363 if (this.input.charCodeAt(this.state.pos) === 10) ++this.state.pos;
1364 case 10:
1365 out += "\n";
1366 break;
1367 default:
1368 out += String.fromCharCode(ch);
1369 break;
1370 }
1371 ++this.state.curLine;
1372 this.state.lineStart = this.state.pos;
1373 chunkStart = this.state.pos;
1374 } else {
1375 ++this.state.pos;
1376 }
1377 }
1378 };
1379
1380 // Used to read escaped characters
1381
1382 Tokenizer.prototype.readEscapedChar = function readEscapedChar(inTemplate) {
1383 var throwOnInvalid = !inTemplate;
1384 var ch = this.input.charCodeAt(++this.state.pos);
1385 ++this.state.pos;
1386 switch (ch) {
1387 case 110:
1388 return "\n"; // 'n' -> '\n'
1389 case 114:
1390 return "\r"; // 'r' -> '\r'
1391 case 120:
1392 {
1393 // 'x'
1394 var code = this.readHexChar(2, throwOnInvalid);
1395 return code === null ? null : String.fromCharCode(code);
1396 }
1397 case 117:
1398 {
1399 // 'u'
1400 var _code = this.readCodePoint(throwOnInvalid);
1401 return _code === null ? null : codePointToString(_code);
1402 }
1403 case 116:
1404 return "\t"; // 't' -> '\t'
1405 case 98:
1406 return "\b"; // 'b' -> '\b'
1407 case 118:
1408 return "\x0B"; // 'v' -> '\u000b'
1409 case 102:
1410 return "\f"; // 'f' -> '\f'
1411 case 13:
1412 if (this.input.charCodeAt(this.state.pos) === 10) ++this.state.pos; // '\r\n'
1413 case 10:
1414 // ' \n'
1415 this.state.lineStart = this.state.pos;
1416 ++this.state.curLine;
1417 return "";
1418 default:
1419 if (ch >= 48 && ch <= 55) {
1420 var codePos = this.state.pos - 1;
1421 var octalStr = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/)[0];
1422 var octal = parseInt(octalStr, 8);
1423 if (octal > 255) {
1424 octalStr = octalStr.slice(0, -1);
1425 octal = parseInt(octalStr, 8);
1426 }
1427 if (octal > 0) {
1428 if (inTemplate) {
1429 this.state.invalidTemplateEscapePosition = codePos;
1430 return null;
1431 } else if (this.state.strict) {
1432 this.raise(codePos, "Octal literal in strict mode");
1433 } else if (!this.state.containsOctal) {
1434 // These properties are only used to throw an error for an octal which occurs
1435 // in a directive which occurs prior to a "use strict" directive.
1436 this.state.containsOctal = true;
1437 this.state.octalPosition = codePos;
1438 }
1439 }
1440 this.state.pos += octalStr.length - 1;
1441 return String.fromCharCode(octal);
1442 }
1443 return String.fromCharCode(ch);
1444 }
1445 };
1446
1447 // Used to read character escape sequences ('\x', '\u').
1448
1449 Tokenizer.prototype.readHexChar = function readHexChar(len, throwOnInvalid) {
1450 var codePos = this.state.pos;
1451 var n = this.readInt(16, len);
1452 if (n === null) {
1453 if (throwOnInvalid) {
1454 this.raise(codePos, "Bad character escape sequence");
1455 } else {
1456 this.state.pos = codePos - 1;
1457 this.state.invalidTemplateEscapePosition = codePos - 1;
1458 }
1459 }
1460 return n;
1461 };
1462
1463 // Read an identifier, and return it as a string. Sets `this.state.containsEsc`
1464 // to whether the word contained a '\u' escape.
1465 //
1466 // Incrementally adds only escaped chars, adding other chunks as-is
1467 // as a micro-optimization.
1468
1469 Tokenizer.prototype.readWord1 = function readWord1() {
1470 this.state.containsEsc = false;
1471 var word = "",
1472 first = true,
1473 chunkStart = this.state.pos;
1474 while (this.state.pos < this.input.length) {
1475 var ch = this.fullCharCodeAtPos();
1476 if (isIdentifierChar(ch)) {
1477 this.state.pos += ch <= 0xffff ? 1 : 2;
1478 } else if (ch === 92) {
1479 // "\"
1480 this.state.containsEsc = true;
1481
1482 word += this.input.slice(chunkStart, this.state.pos);
1483 var escStart = this.state.pos;
1484
1485 if (this.input.charCodeAt(++this.state.pos) !== 117) {
1486 // "u"
1487 this.raise(this.state.pos, "Expecting Unicode escape sequence \\uXXXX");
1488 }
1489
1490 ++this.state.pos;
1491 var esc = this.readCodePoint(true);
1492 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, true)) {
1493 this.raise(escStart, "Invalid Unicode escape");
1494 }
1495
1496 word += codePointToString(esc);
1497 chunkStart = this.state.pos;
1498 } else {
1499 break;
1500 }
1501 first = false;
1502 }
1503 return word + this.input.slice(chunkStart, this.state.pos);
1504 };
1505
1506 // Read an identifier or keyword token. Will check for reserved
1507 // words when necessary.
1508
1509 Tokenizer.prototype.readWord = function readWord() {
1510 var word = this.readWord1();
1511 var type = types.name;
1512 if (!this.state.containsEsc && this.isKeyword(word)) {
1513 type = keywords[word];
1514 }
1515 return this.finishToken(type, word);
1516 };
1517
1518 Tokenizer.prototype.braceIsBlock = function braceIsBlock(prevType) {
1519 if (prevType === types.colon) {
1520 var parent = this.curContext();
1521 if (parent === types$1.braceStatement || parent === types$1.braceExpression) {
1522 return !parent.isExpr;
1523 }
1524 }
1525
1526 if (prevType === types._return) {
1527 return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
1528 }
1529
1530 if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR) {
1531 return true;
1532 }
1533
1534 if (prevType === types.braceL) {
1535 return this.curContext() === types$1.braceStatement;
1536 }
1537
1538 return !this.state.exprAllowed;
1539 };
1540
1541 Tokenizer.prototype.updateContext = function updateContext(prevType) {
1542 var type = this.state.type;
1543 var update = void 0;
1544
1545 if (type.keyword && prevType === types.dot) {
1546 this.state.exprAllowed = false;
1547 } else if (update = type.updateContext) {
1548 update.call(this, prevType);
1549 } else {
1550 this.state.exprAllowed = type.beforeExpr;
1551 }
1552 };
1553
1554 return Tokenizer;
1555}();
1556
1557var plugins = {};
1558var frozenDeprecatedWildcardPluginList = ["jsx", "doExpressions", "objectRestSpread", "decorators", "classProperties", "exportExtensions", "asyncGenerators", "functionBind", "functionSent", "dynamicImport", "flow"];
1559
1560var Parser = function (_Tokenizer) {
1561 inherits(Parser, _Tokenizer);
1562
1563 function Parser(options, input) {
1564 classCallCheck(this, Parser);
1565
1566 options = getOptions(options);
1567
1568 var _this = possibleConstructorReturn(this, _Tokenizer.call(this, options, input));
1569
1570 _this.options = options;
1571 _this.inModule = _this.options.sourceType === "module";
1572 _this.input = input;
1573 _this.plugins = _this.loadPlugins(_this.options.plugins);
1574 _this.filename = options.sourceFilename;
1575
1576 // If enabled, skip leading hashbang line.
1577 if (_this.state.pos === 0 && _this.input[0] === "#" && _this.input[1] === "!") {
1578 _this.skipLineComment(2);
1579 }
1580 return _this;
1581 }
1582
1583 Parser.prototype.isReservedWord = function isReservedWord(word) {
1584 if (word === "await") {
1585 return this.inModule;
1586 } else {
1587 return reservedWords[6](word);
1588 }
1589 };
1590
1591 Parser.prototype.hasPlugin = function hasPlugin(name) {
1592 if (this.plugins["*"] && frozenDeprecatedWildcardPluginList.indexOf(name) > -1) {
1593 return true;
1594 }
1595
1596 return !!this.plugins[name];
1597 };
1598
1599 Parser.prototype.extend = function extend(name, f) {
1600 this[name] = f(this[name]);
1601 };
1602
1603 Parser.prototype.loadAllPlugins = function loadAllPlugins() {
1604 var _this2 = this;
1605
1606 // ensure flow plugin loads last, also ensure estree is not loaded with *
1607 var pluginNames = Object.keys(plugins).filter(function (name) {
1608 return name !== "flow" && name !== "estree";
1609 });
1610 pluginNames.push("flow");
1611
1612 pluginNames.forEach(function (name) {
1613 var plugin = plugins[name];
1614 if (plugin) plugin(_this2);
1615 });
1616 };
1617
1618 Parser.prototype.loadPlugins = function loadPlugins(pluginList) {
1619 // TODO: Deprecate "*" option in next major version of Babylon
1620 if (pluginList.indexOf("*") >= 0) {
1621 this.loadAllPlugins();
1622
1623 return { "*": true };
1624 }
1625
1626 var pluginMap = {};
1627
1628 if (pluginList.indexOf("flow") >= 0) {
1629 // ensure flow plugin loads last
1630 pluginList = pluginList.filter(function (plugin) {
1631 return plugin !== "flow";
1632 });
1633 pluginList.push("flow");
1634 }
1635
1636 if (pluginList.indexOf("estree") >= 0) {
1637 // ensure estree plugin loads first
1638 pluginList = pluginList.filter(function (plugin) {
1639 return plugin !== "estree";
1640 });
1641 pluginList.unshift("estree");
1642 }
1643
1644 for (var _iterator = pluginList, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
1645 var _ref;
1646
1647 if (_isArray) {
1648 if (_i >= _iterator.length) break;
1649 _ref = _iterator[_i++];
1650 } else {
1651 _i = _iterator.next();
1652 if (_i.done) break;
1653 _ref = _i.value;
1654 }
1655
1656 var name = _ref;
1657
1658 if (!pluginMap[name]) {
1659 pluginMap[name] = true;
1660
1661 var plugin = plugins[name];
1662 if (plugin) plugin(this);
1663 }
1664 }
1665
1666 return pluginMap;
1667 };
1668
1669 Parser.prototype.parse = function parse() {
1670 var file = this.startNode();
1671 var program = this.startNode();
1672 this.nextToken();
1673 return this.parseTopLevel(file, program);
1674 };
1675
1676 return Parser;
1677}(Tokenizer);
1678
1679var pp = Parser.prototype;
1680
1681// ## Parser utilities
1682
1683// TODO
1684
1685pp.addExtra = function (node, key, val) {
1686 if (!node) return;
1687
1688 var extra = node.extra = node.extra || {};
1689 extra[key] = val;
1690};
1691
1692// TODO
1693
1694pp.isRelational = function (op) {
1695 return this.match(types.relational) && this.state.value === op;
1696};
1697
1698// TODO
1699
1700pp.expectRelational = function (op) {
1701 if (this.isRelational(op)) {
1702 this.next();
1703 } else {
1704 this.unexpected(null, types.relational);
1705 }
1706};
1707
1708// Tests whether parsed token is a contextual keyword.
1709
1710pp.isContextual = function (name) {
1711 return this.match(types.name) && this.state.value === name;
1712};
1713
1714// Consumes contextual keyword if possible.
1715
1716pp.eatContextual = function (name) {
1717 return this.state.value === name && this.eat(types.name);
1718};
1719
1720// Asserts that following token is given contextual keyword.
1721
1722pp.expectContextual = function (name, message) {
1723 if (!this.eatContextual(name)) this.unexpected(null, message);
1724};
1725
1726// Test whether a semicolon can be inserted at the current position.
1727
1728pp.canInsertSemicolon = function () {
1729 return this.match(types.eof) || this.match(types.braceR) || lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
1730};
1731
1732// TODO
1733
1734pp.isLineTerminator = function () {
1735 return this.eat(types.semi) || this.canInsertSemicolon();
1736};
1737
1738// Consume a semicolon, or, failing that, see if we are allowed to
1739// pretend that there is a semicolon at this position.
1740
1741pp.semicolon = function () {
1742 if (!this.isLineTerminator()) this.unexpected(null, types.semi);
1743};
1744
1745// Expect a token of a given type. If found, consume it, otherwise,
1746// raise an unexpected token error at given pos.
1747
1748pp.expect = function (type, pos) {
1749 return this.eat(type) || this.unexpected(pos, type);
1750};
1751
1752// Raise an unexpected token error. Can take the expected token type
1753// instead of a message string.
1754
1755pp.unexpected = function (pos) {
1756 var messageOrType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "Unexpected token";
1757
1758 if (messageOrType && (typeof messageOrType === "undefined" ? "undefined" : _typeof(messageOrType)) === "object" && messageOrType.label) {
1759 messageOrType = "Unexpected token, expected " + messageOrType.label;
1760 }
1761 this.raise(pos != null ? pos : this.state.start, messageOrType);
1762};
1763
1764/* eslint max-len: 0 */
1765
1766var pp$1 = Parser.prototype;
1767
1768// ### Statement parsing
1769
1770// Parse a program. Initializes the parser, reads any number of
1771// statements, and wraps them in a Program node. Optionally takes a
1772// `program` argument. If present, the statements will be appended
1773// to its body instead of creating a new node.
1774
1775pp$1.parseTopLevel = function (file, program) {
1776 program.sourceType = this.options.sourceType;
1777
1778 this.parseBlockBody(program, true, true, types.eof);
1779
1780 file.program = this.finishNode(program, "Program");
1781 file.comments = this.state.comments;
1782 file.tokens = this.state.tokens;
1783
1784 return this.finishNode(file, "File");
1785};
1786
1787var loopLabel = { kind: "loop" };
1788var switchLabel = { kind: "switch" };
1789
1790// TODO
1791
1792pp$1.stmtToDirective = function (stmt) {
1793 var expr = stmt.expression;
1794
1795 var directiveLiteral = this.startNodeAt(expr.start, expr.loc.start);
1796 var directive = this.startNodeAt(stmt.start, stmt.loc.start);
1797
1798 var raw = this.input.slice(expr.start, expr.end);
1799 var val = directiveLiteral.value = raw.slice(1, -1); // remove quotes
1800
1801 this.addExtra(directiveLiteral, "raw", raw);
1802 this.addExtra(directiveLiteral, "rawValue", val);
1803
1804 directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end);
1805
1806 return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end);
1807};
1808
1809// Parse a single statement.
1810//
1811// If expecting a statement and finding a slash operator, parse a
1812// regular expression literal. This is to handle cases like
1813// `if (foo) /blah/.exec(foo)`, where looking at the previous token
1814// does not help.
1815
1816pp$1.parseStatement = function (declaration, topLevel) {
1817 if (this.match(types.at)) {
1818 this.parseDecorators(true);
1819 }
1820
1821 var starttype = this.state.type;
1822 var node = this.startNode();
1823
1824 // Most types of statements are recognized by the keyword they
1825 // start with. Many are trivial to parse, some require a bit of
1826 // complexity.
1827
1828 switch (starttype) {
1829 case types._break:case types._continue:
1830 return this.parseBreakContinueStatement(node, starttype.keyword);
1831 case types._debugger:
1832 return this.parseDebuggerStatement(node);
1833 case types._do:
1834 return this.parseDoStatement(node);
1835 case types._for:
1836 return this.parseForStatement(node);
1837 case types._function:
1838 if (!declaration) this.unexpected();
1839 return this.parseFunctionStatement(node);
1840
1841 case types._class:
1842 if (!declaration) this.unexpected();
1843 return this.parseClass(node, true);
1844
1845 case types._if:
1846 return this.parseIfStatement(node);
1847 case types._return:
1848 return this.parseReturnStatement(node);
1849 case types._switch:
1850 return this.parseSwitchStatement(node);
1851 case types._throw:
1852 return this.parseThrowStatement(node);
1853 case types._try:
1854 return this.parseTryStatement(node);
1855
1856 case types._let:
1857 case types._const:
1858 if (!declaration) this.unexpected(); // NOTE: falls through to _var
1859
1860 case types._var:
1861 return this.parseVarStatement(node, starttype);
1862
1863 case types._while:
1864 return this.parseWhileStatement(node);
1865 case types._with:
1866 return this.parseWithStatement(node);
1867 case types.braceL:
1868 return this.parseBlock();
1869 case types.semi:
1870 return this.parseEmptyStatement(node);
1871 case types._export:
1872 case types._import:
1873 if (this.hasPlugin("dynamicImport") && this.lookahead().type === types.parenL) break;
1874
1875 if (!this.options.allowImportExportEverywhere) {
1876 if (!topLevel) {
1877 this.raise(this.state.start, "'import' and 'export' may only appear at the top level");
1878 }
1879
1880 if (!this.inModule) {
1881 this.raise(this.state.start, "'import' and 'export' may appear only with 'sourceType: \"module\"'");
1882 }
1883 }
1884 return starttype === types._import ? this.parseImport(node) : this.parseExport(node);
1885
1886 case types.name:
1887 if (this.state.value === "async") {
1888 // peek ahead and see if next token is a function
1889 var state = this.state.clone();
1890 this.next();
1891 if (this.match(types._function) && !this.canInsertSemicolon()) {
1892 this.expect(types._function);
1893 return this.parseFunction(node, true, false, true);
1894 } else {
1895 this.state = state;
1896 }
1897 }
1898 }
1899
1900 // If the statement does not start with a statement keyword or a
1901 // brace, it's an ExpressionStatement or LabeledStatement. We
1902 // simply start parsing an expression, and afterwards, if the
1903 // next token is a colon and the expression was a simple
1904 // Identifier node, we switch to interpreting it as a label.
1905 var maybeName = this.state.value;
1906 var expr = this.parseExpression();
1907
1908 if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) {
1909 return this.parseLabeledStatement(node, maybeName, expr);
1910 } else {
1911 return this.parseExpressionStatement(node, expr);
1912 }
1913};
1914
1915pp$1.takeDecorators = function (node) {
1916 if (this.state.decorators.length) {
1917 node.decorators = this.state.decorators;
1918 this.state.decorators = [];
1919 }
1920};
1921
1922pp$1.parseDecorators = function (allowExport) {
1923 while (this.match(types.at)) {
1924 var decorator = this.parseDecorator();
1925 this.state.decorators.push(decorator);
1926 }
1927
1928 if (allowExport && this.match(types._export)) {
1929 return;
1930 }
1931
1932 if (!this.match(types._class)) {
1933 this.raise(this.state.start, "Leading decorators must be attached to a class declaration");
1934 }
1935};
1936
1937pp$1.parseDecorator = function () {
1938 if (!this.hasPlugin("decorators")) {
1939 this.unexpected();
1940 }
1941 var node = this.startNode();
1942 this.next();
1943 node.expression = this.parseMaybeAssign();
1944 return this.finishNode(node, "Decorator");
1945};
1946
1947pp$1.parseBreakContinueStatement = function (node, keyword) {
1948 var isBreak = keyword === "break";
1949 this.next();
1950
1951 if (this.isLineTerminator()) {
1952 node.label = null;
1953 } else if (!this.match(types.name)) {
1954 this.unexpected();
1955 } else {
1956 node.label = this.parseIdentifier();
1957 this.semicolon();
1958 }
1959
1960 // Verify that there is an actual destination to break or
1961 // continue to.
1962 var i = void 0;
1963 for (i = 0; i < this.state.labels.length; ++i) {
1964 var lab = this.state.labels[i];
1965 if (node.label == null || lab.name === node.label.name) {
1966 if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
1967 if (node.label && isBreak) break;
1968 }
1969 }
1970 if (i === this.state.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
1971 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
1972};
1973
1974pp$1.parseDebuggerStatement = function (node) {
1975 this.next();
1976 this.semicolon();
1977 return this.finishNode(node, "DebuggerStatement");
1978};
1979
1980pp$1.parseDoStatement = function (node) {
1981 this.next();
1982 this.state.labels.push(loopLabel);
1983 node.body = this.parseStatement(false);
1984 this.state.labels.pop();
1985 this.expect(types._while);
1986 node.test = this.parseParenExpression();
1987 this.eat(types.semi);
1988 return this.finishNode(node, "DoWhileStatement");
1989};
1990
1991// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
1992// loop is non-trivial. Basically, we have to parse the init `var`
1993// statement or expression, disallowing the `in` operator (see
1994// the second parameter to `parseExpression`), and then check
1995// whether the next token is `in` or `of`. When there is no init
1996// part (semicolon immediately after the opening parenthesis), it
1997// is a regular `for` loop.
1998
1999pp$1.parseForStatement = function (node) {
2000 this.next();
2001 this.state.labels.push(loopLabel);
2002
2003 var forAwait = false;
2004 if (this.hasPlugin("asyncGenerators") && this.state.inAsync && this.isContextual("await")) {
2005 forAwait = true;
2006 this.next();
2007 }
2008 this.expect(types.parenL);
2009
2010 if (this.match(types.semi)) {
2011 if (forAwait) {
2012 this.unexpected();
2013 }
2014 return this.parseFor(node, null);
2015 }
2016
2017 if (this.match(types._var) || this.match(types._let) || this.match(types._const)) {
2018 var _init = this.startNode();
2019 var varKind = this.state.type;
2020 this.next();
2021 this.parseVar(_init, true, varKind);
2022 this.finishNode(_init, "VariableDeclaration");
2023
2024 if (this.match(types._in) || this.isContextual("of")) {
2025 if (_init.declarations.length === 1 && !_init.declarations[0].init) {
2026 return this.parseForIn(node, _init, forAwait);
2027 }
2028 }
2029 if (forAwait) {
2030 this.unexpected();
2031 }
2032 return this.parseFor(node, _init);
2033 }
2034
2035 var refShorthandDefaultPos = { start: 0 };
2036 var init = this.parseExpression(true, refShorthandDefaultPos);
2037 if (this.match(types._in) || this.isContextual("of")) {
2038 var description = this.isContextual("of") ? "for-of statement" : "for-in statement";
2039 this.toAssignable(init, undefined, description);
2040 this.checkLVal(init, undefined, undefined, description);
2041 return this.parseForIn(node, init, forAwait);
2042 } else if (refShorthandDefaultPos.start) {
2043 this.unexpected(refShorthandDefaultPos.start);
2044 }
2045 if (forAwait) {
2046 this.unexpected();
2047 }
2048 return this.parseFor(node, init);
2049};
2050
2051pp$1.parseFunctionStatement = function (node) {
2052 this.next();
2053 return this.parseFunction(node, true);
2054};
2055
2056pp$1.parseIfStatement = function (node) {
2057 this.next();
2058 node.test = this.parseParenExpression();
2059 node.consequent = this.parseStatement(false);
2060 node.alternate = this.eat(types._else) ? this.parseStatement(false) : null;
2061 return this.finishNode(node, "IfStatement");
2062};
2063
2064pp$1.parseReturnStatement = function (node) {
2065 if (!this.state.inFunction && !this.options.allowReturnOutsideFunction) {
2066 this.raise(this.state.start, "'return' outside of function");
2067 }
2068
2069 this.next();
2070
2071 // In `return` (and `break`/`continue`), the keywords with
2072 // optional arguments, we eagerly look for a semicolon or the
2073 // possibility to insert one.
2074
2075 if (this.isLineTerminator()) {
2076 node.argument = null;
2077 } else {
2078 node.argument = this.parseExpression();
2079 this.semicolon();
2080 }
2081
2082 return this.finishNode(node, "ReturnStatement");
2083};
2084
2085pp$1.parseSwitchStatement = function (node) {
2086 this.next();
2087 node.discriminant = this.parseParenExpression();
2088 node.cases = [];
2089 this.expect(types.braceL);
2090 this.state.labels.push(switchLabel);
2091
2092 // Statements under must be grouped (by label) in SwitchCase
2093 // nodes. `cur` is used to keep the node that we are currently
2094 // adding statements to.
2095
2096 var cur = void 0;
2097 for (var sawDefault; !this.match(types.braceR);) {
2098 if (this.match(types._case) || this.match(types._default)) {
2099 var isCase = this.match(types._case);
2100 if (cur) this.finishNode(cur, "SwitchCase");
2101 node.cases.push(cur = this.startNode());
2102 cur.consequent = [];
2103 this.next();
2104 if (isCase) {
2105 cur.test = this.parseExpression();
2106 } else {
2107 if (sawDefault) this.raise(this.state.lastTokStart, "Multiple default clauses");
2108 sawDefault = true;
2109 cur.test = null;
2110 }
2111 this.expect(types.colon);
2112 } else {
2113 if (cur) {
2114 cur.consequent.push(this.parseStatement(true));
2115 } else {
2116 this.unexpected();
2117 }
2118 }
2119 }
2120 if (cur) this.finishNode(cur, "SwitchCase");
2121 this.next(); // Closing brace
2122 this.state.labels.pop();
2123 return this.finishNode(node, "SwitchStatement");
2124};
2125
2126pp$1.parseThrowStatement = function (node) {
2127 this.next();
2128 if (lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))) this.raise(this.state.lastTokEnd, "Illegal newline after throw");
2129 node.argument = this.parseExpression();
2130 this.semicolon();
2131 return this.finishNode(node, "ThrowStatement");
2132};
2133
2134// Reused empty array added for node fields that are always empty.
2135
2136var empty = [];
2137
2138pp$1.parseTryStatement = function (node) {
2139 this.next();
2140
2141 node.block = this.parseBlock();
2142 node.handler = null;
2143
2144 if (this.match(types._catch)) {
2145 var clause = this.startNode();
2146 this.next();
2147
2148 this.expect(types.parenL);
2149 clause.param = this.parseBindingAtom();
2150 this.checkLVal(clause.param, true, Object.create(null), "catch clause");
2151 this.expect(types.parenR);
2152
2153 clause.body = this.parseBlock();
2154 node.handler = this.finishNode(clause, "CatchClause");
2155 }
2156
2157 node.guardedHandlers = empty;
2158 node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
2159
2160 if (!node.handler && !node.finalizer) {
2161 this.raise(node.start, "Missing catch or finally clause");
2162 }
2163
2164 return this.finishNode(node, "TryStatement");
2165};
2166
2167pp$1.parseVarStatement = function (node, kind) {
2168 this.next();
2169 this.parseVar(node, false, kind);
2170 this.semicolon();
2171 return this.finishNode(node, "VariableDeclaration");
2172};
2173
2174pp$1.parseWhileStatement = function (node) {
2175 this.next();
2176 node.test = this.parseParenExpression();
2177 this.state.labels.push(loopLabel);
2178 node.body = this.parseStatement(false);
2179 this.state.labels.pop();
2180 return this.finishNode(node, "WhileStatement");
2181};
2182
2183pp$1.parseWithStatement = function (node) {
2184 if (this.state.strict) this.raise(this.state.start, "'with' in strict mode");
2185 this.next();
2186 node.object = this.parseParenExpression();
2187 node.body = this.parseStatement(false);
2188 return this.finishNode(node, "WithStatement");
2189};
2190
2191pp$1.parseEmptyStatement = function (node) {
2192 this.next();
2193 return this.finishNode(node, "EmptyStatement");
2194};
2195
2196pp$1.parseLabeledStatement = function (node, maybeName, expr) {
2197 for (var _iterator = this.state.labels, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
2198 var _ref;
2199
2200 if (_isArray) {
2201 if (_i >= _iterator.length) break;
2202 _ref = _iterator[_i++];
2203 } else {
2204 _i = _iterator.next();
2205 if (_i.done) break;
2206 _ref = _i.value;
2207 }
2208
2209 var _label = _ref;
2210
2211 if (_label.name === maybeName) {
2212 this.raise(expr.start, "Label '" + maybeName + "' is already declared");
2213 }
2214 }
2215
2216 var kind = this.state.type.isLoop ? "loop" : this.match(types._switch) ? "switch" : null;
2217 for (var i = this.state.labels.length - 1; i >= 0; i--) {
2218 var label = this.state.labels[i];
2219 if (label.statementStart === node.start) {
2220 label.statementStart = this.state.start;
2221 label.kind = kind;
2222 } else {
2223 break;
2224 }
2225 }
2226
2227 this.state.labels.push({ name: maybeName, kind: kind, statementStart: this.state.start });
2228 node.body = this.parseStatement(true);
2229 this.state.labels.pop();
2230 node.label = expr;
2231 return this.finishNode(node, "LabeledStatement");
2232};
2233
2234pp$1.parseExpressionStatement = function (node, expr) {
2235 node.expression = expr;
2236 this.semicolon();
2237 return this.finishNode(node, "ExpressionStatement");
2238};
2239
2240// Parse a semicolon-enclosed block of statements, handling `"use
2241// strict"` declarations when `allowStrict` is true (used for
2242// function bodies).
2243
2244pp$1.parseBlock = function (allowDirectives) {
2245 var node = this.startNode();
2246 this.expect(types.braceL);
2247 this.parseBlockBody(node, allowDirectives, false, types.braceR);
2248 return this.finishNode(node, "BlockStatement");
2249};
2250
2251pp$1.isValidDirective = function (stmt) {
2252 return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized;
2253};
2254
2255pp$1.parseBlockBody = function (node, allowDirectives, topLevel, end) {
2256 node.body = [];
2257 node.directives = [];
2258
2259 var parsedNonDirective = false;
2260 var oldStrict = void 0;
2261 var octalPosition = void 0;
2262
2263 while (!this.eat(end)) {
2264 if (!parsedNonDirective && this.state.containsOctal && !octalPosition) {
2265 octalPosition = this.state.octalPosition;
2266 }
2267
2268 var stmt = this.parseStatement(true, topLevel);
2269
2270 if (allowDirectives && !parsedNonDirective && this.isValidDirective(stmt)) {
2271 var directive = this.stmtToDirective(stmt);
2272 node.directives.push(directive);
2273
2274 if (oldStrict === undefined && directive.value.value === "use strict") {
2275 oldStrict = this.state.strict;
2276 this.setStrict(true);
2277
2278 if (octalPosition) {
2279 this.raise(octalPosition, "Octal literal in strict mode");
2280 }
2281 }
2282
2283 continue;
2284 }
2285
2286 parsedNonDirective = true;
2287 node.body.push(stmt);
2288 }
2289
2290 if (oldStrict === false) {
2291 this.setStrict(false);
2292 }
2293};
2294
2295// Parse a regular `for` loop. The disambiguation code in
2296// `parseStatement` will already have parsed the init statement or
2297// expression.
2298
2299pp$1.parseFor = function (node, init) {
2300 node.init = init;
2301 this.expect(types.semi);
2302 node.test = this.match(types.semi) ? null : this.parseExpression();
2303 this.expect(types.semi);
2304 node.update = this.match(types.parenR) ? null : this.parseExpression();
2305 this.expect(types.parenR);
2306 node.body = this.parseStatement(false);
2307 this.state.labels.pop();
2308 return this.finishNode(node, "ForStatement");
2309};
2310
2311// Parse a `for`/`in` and `for`/`of` loop, which are almost
2312// same from parser's perspective.
2313
2314pp$1.parseForIn = function (node, init, forAwait) {
2315 var type = void 0;
2316 if (forAwait) {
2317 this.eatContextual("of");
2318 type = "ForAwaitStatement";
2319 } else {
2320 type = this.match(types._in) ? "ForInStatement" : "ForOfStatement";
2321 this.next();
2322 }
2323 node.left = init;
2324 node.right = this.parseExpression();
2325 this.expect(types.parenR);
2326 node.body = this.parseStatement(false);
2327 this.state.labels.pop();
2328 return this.finishNode(node, type);
2329};
2330
2331// Parse a list of variable declarations.
2332
2333pp$1.parseVar = function (node, isFor, kind) {
2334 node.declarations = [];
2335 node.kind = kind.keyword;
2336 for (;;) {
2337 var decl = this.startNode();
2338 this.parseVarHead(decl);
2339 if (this.eat(types.eq)) {
2340 decl.init = this.parseMaybeAssign(isFor);
2341 } else if (kind === types._const && !(this.match(types._in) || this.isContextual("of"))) {
2342 this.unexpected();
2343 } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(types._in) || this.isContextual("of")))) {
2344 this.raise(this.state.lastTokEnd, "Complex binding patterns require an initialization value");
2345 } else {
2346 decl.init = null;
2347 }
2348 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
2349 if (!this.eat(types.comma)) break;
2350 }
2351 return node;
2352};
2353
2354pp$1.parseVarHead = function (decl) {
2355 decl.id = this.parseBindingAtom();
2356 this.checkLVal(decl.id, true, undefined, "variable declaration");
2357};
2358
2359// Parse a function declaration or literal (depending on the
2360// `isStatement` parameter).
2361
2362pp$1.parseFunction = function (node, isStatement, allowExpressionBody, isAsync, optionalId) {
2363 var oldInMethod = this.state.inMethod;
2364 this.state.inMethod = false;
2365
2366 this.initFunction(node, isAsync);
2367
2368 if (this.match(types.star)) {
2369 if (node.async && !this.hasPlugin("asyncGenerators")) {
2370 this.unexpected();
2371 } else {
2372 node.generator = true;
2373 this.next();
2374 }
2375 }
2376
2377 if (isStatement && !optionalId && !this.match(types.name) && !this.match(types._yield)) {
2378 this.unexpected();
2379 }
2380
2381 if (this.match(types.name) || this.match(types._yield)) {
2382 node.id = this.parseBindingIdentifier();
2383 }
2384
2385 this.parseFunctionParams(node);
2386 this.parseFunctionBody(node, allowExpressionBody);
2387
2388 this.state.inMethod = oldInMethod;
2389
2390 return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
2391};
2392
2393pp$1.parseFunctionParams = function (node) {
2394 this.expect(types.parenL);
2395 node.params = this.parseBindingList(types.parenR);
2396};
2397
2398// Parse a class declaration or literal (depending on the
2399// `isStatement` parameter).
2400
2401pp$1.parseClass = function (node, isStatement, optionalId) {
2402 this.next();
2403 this.takeDecorators(node);
2404 this.parseClassId(node, isStatement, optionalId);
2405 this.parseClassSuper(node);
2406 this.parseClassBody(node);
2407 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
2408};
2409
2410pp$1.isClassProperty = function () {
2411 return this.match(types.eq) || this.match(types.semi) || this.match(types.braceR);
2412};
2413
2414pp$1.isClassMethod = function () {
2415 return this.match(types.parenL);
2416};
2417
2418pp$1.isNonstaticConstructor = function (method) {
2419 return !method.computed && !method.static && (method.key.name === "constructor" || // Identifier
2420 method.key.value === "constructor" // Literal
2421 );
2422};
2423
2424pp$1.parseClassBody = function (node) {
2425 // class bodies are implicitly strict
2426 var oldStrict = this.state.strict;
2427 this.state.strict = true;
2428
2429 var hadConstructorCall = false;
2430 var hadConstructor = false;
2431 var decorators = [];
2432 var classBody = this.startNode();
2433
2434 classBody.body = [];
2435
2436 this.expect(types.braceL);
2437
2438 while (!this.eat(types.braceR)) {
2439 if (this.eat(types.semi)) {
2440 if (decorators.length > 0) {
2441 this.raise(this.state.lastTokEnd, "Decorators must not be followed by a semicolon");
2442 }
2443 continue;
2444 }
2445
2446 if (this.match(types.at)) {
2447 decorators.push(this.parseDecorator());
2448 continue;
2449 }
2450
2451 var method = this.startNode();
2452
2453 // steal the decorators if there are any
2454 if (decorators.length) {
2455 method.decorators = decorators;
2456 decorators = [];
2457 }
2458
2459 method.static = false;
2460 if (this.match(types.name) && this.state.value === "static") {
2461 var key = this.parseIdentifier(true); // eats 'static'
2462 if (this.isClassMethod()) {
2463 // a method named 'static'
2464 method.kind = "method";
2465 method.computed = false;
2466 method.key = key;
2467 this.parseClassMethod(classBody, method, false, false);
2468 continue;
2469 } else if (this.isClassProperty()) {
2470 // a property named 'static'
2471 method.computed = false;
2472 method.key = key;
2473 classBody.body.push(this.parseClassProperty(method));
2474 continue;
2475 }
2476 // otherwise something static
2477 method.static = true;
2478 }
2479
2480 if (this.eat(types.star)) {
2481 // a generator
2482 method.kind = "method";
2483 this.parsePropertyName(method);
2484 if (this.isNonstaticConstructor(method)) {
2485 this.raise(method.key.start, "Constructor can't be a generator");
2486 }
2487 if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) {
2488 this.raise(method.key.start, "Classes may not have static property named prototype");
2489 }
2490 this.parseClassMethod(classBody, method, true, false);
2491 } else {
2492 var isSimple = this.match(types.name);
2493 var _key = this.parsePropertyName(method);
2494 if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) {
2495 this.raise(method.key.start, "Classes may not have static property named prototype");
2496 }
2497 if (this.isClassMethod()) {
2498 // a normal method
2499 if (this.isNonstaticConstructor(method)) {
2500 if (hadConstructor) {
2501 this.raise(_key.start, "Duplicate constructor in the same class");
2502 } else if (method.decorators) {
2503 this.raise(method.start, "You can't attach decorators to a class constructor");
2504 }
2505 hadConstructor = true;
2506 method.kind = "constructor";
2507 } else {
2508 method.kind = "method";
2509 }
2510 this.parseClassMethod(classBody, method, false, false);
2511 } else if (this.isClassProperty()) {
2512 // a normal property
2513 if (this.isNonstaticConstructor(method)) {
2514 this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'");
2515 }
2516 classBody.body.push(this.parseClassProperty(method));
2517 } else if (isSimple && _key.name === "async" && !this.isLineTerminator()) {
2518 // an async method
2519 var isGenerator = this.hasPlugin("asyncGenerators") && this.eat(types.star);
2520 method.kind = "method";
2521 this.parsePropertyName(method);
2522 if (this.isNonstaticConstructor(method)) {
2523 this.raise(method.key.start, "Constructor can't be an async function");
2524 }
2525 this.parseClassMethod(classBody, method, isGenerator, true);
2526 } else if (isSimple && (_key.name === "get" || _key.name === "set") && !(this.isLineTerminator() && this.match(types.star))) {
2527 // `get\n*` is an uninitialized property named 'get' followed by a generator.
2528 // a getter or setter
2529 method.kind = _key.name;
2530 this.parsePropertyName(method);
2531 if (this.isNonstaticConstructor(method)) {
2532 this.raise(method.key.start, "Constructor can't have get/set modifier");
2533 }
2534 this.parseClassMethod(classBody, method, false, false);
2535 this.checkGetterSetterParamCount(method);
2536 } else if (this.hasPlugin("classConstructorCall") && isSimple && _key.name === "call" && this.match(types.name) && this.state.value === "constructor") {
2537 // a (deprecated) call constructor
2538 if (hadConstructorCall) {
2539 this.raise(method.start, "Duplicate constructor call in the same class");
2540 } else if (method.decorators) {
2541 this.raise(method.start, "You can't attach decorators to a class constructor");
2542 }
2543 hadConstructorCall = true;
2544 method.kind = "constructorCall";
2545 this.parsePropertyName(method); // consume "constructor" and make it the method's name
2546 this.parseClassMethod(classBody, method, false, false);
2547 } else if (this.isLineTerminator()) {
2548 // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token)
2549 if (this.isNonstaticConstructor(method)) {
2550 this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'");
2551 }
2552 classBody.body.push(this.parseClassProperty(method));
2553 } else {
2554 this.unexpected();
2555 }
2556 }
2557 }
2558
2559 if (decorators.length) {
2560 this.raise(this.state.start, "You have trailing decorators with no method");
2561 }
2562
2563 node.body = this.finishNode(classBody, "ClassBody");
2564
2565 this.state.strict = oldStrict;
2566};
2567
2568pp$1.parseClassProperty = function (node) {
2569 this.state.inClassProperty = true;
2570 if (this.match(types.eq)) {
2571 if (!this.hasPlugin("classProperties")) this.unexpected();
2572 this.next();
2573 node.value = this.parseMaybeAssign();
2574 } else {
2575 node.value = null;
2576 }
2577 this.semicolon();
2578 this.state.inClassProperty = false;
2579 return this.finishNode(node, "ClassProperty");
2580};
2581
2582pp$1.parseClassMethod = function (classBody, method, isGenerator, isAsync) {
2583 this.parseMethod(method, isGenerator, isAsync);
2584 classBody.body.push(this.finishNode(method, "ClassMethod"));
2585};
2586
2587pp$1.parseClassId = function (node, isStatement, optionalId) {
2588 if (this.match(types.name)) {
2589 node.id = this.parseIdentifier();
2590 } else {
2591 if (optionalId || !isStatement) {
2592 node.id = null;
2593 } else {
2594 this.unexpected();
2595 }
2596 }
2597};
2598
2599pp$1.parseClassSuper = function (node) {
2600 node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
2601};
2602
2603// Parses module export declaration.
2604
2605pp$1.parseExport = function (node) {
2606 this.next();
2607 // export * from '...'
2608 if (this.match(types.star)) {
2609 var specifier = this.startNode();
2610 this.next();
2611 if (this.hasPlugin("exportExtensions") && this.eatContextual("as")) {
2612 specifier.exported = this.parseIdentifier();
2613 node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")];
2614 this.parseExportSpecifiersMaybe(node);
2615 this.parseExportFrom(node, true);
2616 } else {
2617 this.parseExportFrom(node, true);
2618 return this.finishNode(node, "ExportAllDeclaration");
2619 }
2620 } else if (this.hasPlugin("exportExtensions") && this.isExportDefaultSpecifier()) {
2621 var _specifier = this.startNode();
2622 _specifier.exported = this.parseIdentifier(true);
2623 node.specifiers = [this.finishNode(_specifier, "ExportDefaultSpecifier")];
2624 if (this.match(types.comma) && this.lookahead().type === types.star) {
2625 this.expect(types.comma);
2626 var _specifier2 = this.startNode();
2627 this.expect(types.star);
2628 this.expectContextual("as");
2629 _specifier2.exported = this.parseIdentifier();
2630 node.specifiers.push(this.finishNode(_specifier2, "ExportNamespaceSpecifier"));
2631 } else {
2632 this.parseExportSpecifiersMaybe(node);
2633 }
2634 this.parseExportFrom(node, true);
2635 } else if (this.eat(types._default)) {
2636 // export default ...
2637 var expr = this.startNode();
2638 var needsSemi = false;
2639 if (this.eat(types._function)) {
2640 expr = this.parseFunction(expr, true, false, false, true);
2641 } else if (this.match(types._class)) {
2642 expr = this.parseClass(expr, true, true);
2643 } else {
2644 needsSemi = true;
2645 expr = this.parseMaybeAssign();
2646 }
2647 node.declaration = expr;
2648 if (needsSemi) this.semicolon();
2649 this.checkExport(node, true, true);
2650 return this.finishNode(node, "ExportDefaultDeclaration");
2651 } else if (this.shouldParseExportDeclaration()) {
2652 node.specifiers = [];
2653 node.source = null;
2654 node.declaration = this.parseExportDeclaration(node);
2655 } else {
2656 // export { x, y as z } [from '...']
2657 node.declaration = null;
2658 node.specifiers = this.parseExportSpecifiers();
2659 this.parseExportFrom(node);
2660 }
2661 this.checkExport(node, true);
2662 return this.finishNode(node, "ExportNamedDeclaration");
2663};
2664
2665pp$1.parseExportDeclaration = function () {
2666 return this.parseStatement(true);
2667};
2668
2669pp$1.isExportDefaultSpecifier = function () {
2670 if (this.match(types.name)) {
2671 return this.state.value !== "async";
2672 }
2673
2674 if (!this.match(types._default)) {
2675 return false;
2676 }
2677
2678 var lookahead = this.lookahead();
2679 return lookahead.type === types.comma || lookahead.type === types.name && lookahead.value === "from";
2680};
2681
2682pp$1.parseExportSpecifiersMaybe = function (node) {
2683 if (this.eat(types.comma)) {
2684 node.specifiers = node.specifiers.concat(this.parseExportSpecifiers());
2685 }
2686};
2687
2688pp$1.parseExportFrom = function (node, expect) {
2689 if (this.eatContextual("from")) {
2690 node.source = this.match(types.string) ? this.parseExprAtom() : this.unexpected();
2691 this.checkExport(node);
2692 } else {
2693 if (expect) {
2694 this.unexpected();
2695 } else {
2696 node.source = null;
2697 }
2698 }
2699
2700 this.semicolon();
2701};
2702
2703pp$1.shouldParseExportDeclaration = function () {
2704 return this.state.type.keyword === "var" || this.state.type.keyword === "const" || this.state.type.keyword === "let" || this.state.type.keyword === "function" || this.state.type.keyword === "class" || this.isContextual("async");
2705};
2706
2707pp$1.checkExport = function (node, checkNames, isDefault) {
2708 if (checkNames) {
2709 // Check for duplicate exports
2710 if (isDefault) {
2711 // Default exports
2712 this.checkDuplicateExports(node, "default");
2713 } else if (node.specifiers && node.specifiers.length) {
2714 // Named exports
2715 for (var _iterator2 = node.specifiers, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
2716 var _ref2;
2717
2718 if (_isArray2) {
2719 if (_i2 >= _iterator2.length) break;
2720 _ref2 = _iterator2[_i2++];
2721 } else {
2722 _i2 = _iterator2.next();
2723 if (_i2.done) break;
2724 _ref2 = _i2.value;
2725 }
2726
2727 var specifier = _ref2;
2728
2729 this.checkDuplicateExports(specifier, specifier.exported.name);
2730 }
2731 } else if (node.declaration) {
2732 // Exported declarations
2733 if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
2734 this.checkDuplicateExports(node, node.declaration.id.name);
2735 } else if (node.declaration.type === "VariableDeclaration") {
2736 for (var _iterator3 = node.declaration.declarations, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
2737 var _ref3;
2738
2739 if (_isArray3) {
2740 if (_i3 >= _iterator3.length) break;
2741 _ref3 = _iterator3[_i3++];
2742 } else {
2743 _i3 = _iterator3.next();
2744 if (_i3.done) break;
2745 _ref3 = _i3.value;
2746 }
2747
2748 var declaration = _ref3;
2749
2750 this.checkDeclaration(declaration.id);
2751 }
2752 }
2753 }
2754 }
2755
2756 if (this.state.decorators.length) {
2757 var isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression");
2758 if (!node.declaration || !isClass) {
2759 this.raise(node.start, "You can only use decorators on an export when exporting a class");
2760 }
2761 this.takeDecorators(node.declaration);
2762 }
2763};
2764
2765pp$1.checkDeclaration = function (node) {
2766 if (node.type === "ObjectPattern") {
2767 for (var _iterator4 = node.properties, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
2768 var _ref4;
2769
2770 if (_isArray4) {
2771 if (_i4 >= _iterator4.length) break;
2772 _ref4 = _iterator4[_i4++];
2773 } else {
2774 _i4 = _iterator4.next();
2775 if (_i4.done) break;
2776 _ref4 = _i4.value;
2777 }
2778
2779 var prop = _ref4;
2780
2781 this.checkDeclaration(prop);
2782 }
2783 } else if (node.type === "ArrayPattern") {
2784 for (var _iterator5 = node.elements, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
2785 var _ref5;
2786
2787 if (_isArray5) {
2788 if (_i5 >= _iterator5.length) break;
2789 _ref5 = _iterator5[_i5++];
2790 } else {
2791 _i5 = _iterator5.next();
2792 if (_i5.done) break;
2793 _ref5 = _i5.value;
2794 }
2795
2796 var elem = _ref5;
2797
2798 if (elem) {
2799 this.checkDeclaration(elem);
2800 }
2801 }
2802 } else if (node.type === "ObjectProperty") {
2803 this.checkDeclaration(node.value);
2804 } else if (node.type === "RestElement" || node.type === "RestProperty") {
2805 this.checkDeclaration(node.argument);
2806 } else if (node.type === "Identifier") {
2807 this.checkDuplicateExports(node, node.name);
2808 }
2809};
2810
2811pp$1.checkDuplicateExports = function (node, name) {
2812 if (this.state.exportedIdentifiers.indexOf(name) > -1) {
2813 this.raiseDuplicateExportError(node, name);
2814 }
2815 this.state.exportedIdentifiers.push(name);
2816};
2817
2818pp$1.raiseDuplicateExportError = function (node, name) {
2819 this.raise(node.start, name === "default" ? "Only one default export allowed per module." : "`" + name + "` has already been exported. Exported identifiers must be unique.");
2820};
2821
2822// Parses a comma-separated list of module exports.
2823
2824pp$1.parseExportSpecifiers = function () {
2825 var nodes = [];
2826 var first = true;
2827 var needsFrom = void 0;
2828
2829 // export { x, y as z } [from '...']
2830 this.expect(types.braceL);
2831
2832 while (!this.eat(types.braceR)) {
2833 if (first) {
2834 first = false;
2835 } else {
2836 this.expect(types.comma);
2837 if (this.eat(types.braceR)) break;
2838 }
2839
2840 var isDefault = this.match(types._default);
2841 if (isDefault && !needsFrom) needsFrom = true;
2842
2843 var node = this.startNode();
2844 node.local = this.parseIdentifier(isDefault);
2845 node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone();
2846 nodes.push(this.finishNode(node, "ExportSpecifier"));
2847 }
2848
2849 // https://github.com/ember-cli/ember-cli/pull/3739
2850 if (needsFrom && !this.isContextual("from")) {
2851 this.unexpected();
2852 }
2853
2854 return nodes;
2855};
2856
2857// Parses import declaration.
2858
2859pp$1.parseImport = function (node) {
2860 this.eat(types._import);
2861
2862 // import '...'
2863 if (this.match(types.string)) {
2864 node.specifiers = [];
2865 node.source = this.parseExprAtom();
2866 } else {
2867 node.specifiers = [];
2868 this.parseImportSpecifiers(node);
2869 this.expectContextual("from");
2870 node.source = this.match(types.string) ? this.parseExprAtom() : this.unexpected();
2871 }
2872 this.semicolon();
2873 return this.finishNode(node, "ImportDeclaration");
2874};
2875
2876// Parses a comma-separated list of module imports.
2877
2878pp$1.parseImportSpecifiers = function (node) {
2879 var first = true;
2880 if (this.match(types.name)) {
2881 // import defaultObj, { x, y as z } from '...'
2882 var startPos = this.state.start;
2883 var startLoc = this.state.startLoc;
2884 node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdentifier(), startPos, startLoc));
2885 if (!this.eat(types.comma)) return;
2886 }
2887
2888 if (this.match(types.star)) {
2889 var specifier = this.startNode();
2890 this.next();
2891 this.expectContextual("as");
2892 specifier.local = this.parseIdentifier();
2893 this.checkLVal(specifier.local, true, undefined, "import namespace specifier");
2894 node.specifiers.push(this.finishNode(specifier, "ImportNamespaceSpecifier"));
2895 return;
2896 }
2897
2898 this.expect(types.braceL);
2899 while (!this.eat(types.braceR)) {
2900 if (first) {
2901 first = false;
2902 } else {
2903 // Detect an attempt to deep destructure
2904 if (this.eat(types.colon)) {
2905 this.unexpected(null, "ES2015 named imports do not destructure. Use another statement for destructuring after the import.");
2906 }
2907
2908 this.expect(types.comma);
2909 if (this.eat(types.braceR)) break;
2910 }
2911
2912 this.parseImportSpecifier(node);
2913 }
2914};
2915
2916pp$1.parseImportSpecifier = function (node) {
2917 var specifier = this.startNode();
2918 specifier.imported = this.parseIdentifier(true);
2919 if (this.eatContextual("as")) {
2920 specifier.local = this.parseIdentifier();
2921 } else {
2922 this.checkReservedWord(specifier.imported.name, specifier.start, true, true);
2923 specifier.local = specifier.imported.__clone();
2924 }
2925 this.checkLVal(specifier.local, true, undefined, "import specifier");
2926 node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
2927};
2928
2929pp$1.parseImportSpecifierDefault = function (id, startPos, startLoc) {
2930 var node = this.startNodeAt(startPos, startLoc);
2931 node.local = id;
2932 this.checkLVal(node.local, true, undefined, "default import specifier");
2933 return this.finishNode(node, "ImportDefaultSpecifier");
2934};
2935
2936var pp$2 = Parser.prototype;
2937
2938// Convert existing expression atom to assignable pattern
2939// if possible.
2940
2941pp$2.toAssignable = function (node, isBinding, contextDescription) {
2942 if (node) {
2943 switch (node.type) {
2944 case "Identifier":
2945 case "ObjectPattern":
2946 case "ArrayPattern":
2947 case "AssignmentPattern":
2948 break;
2949
2950 case "ObjectExpression":
2951 node.type = "ObjectPattern";
2952 for (var _iterator = node.properties, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
2953 var _ref;
2954
2955 if (_isArray) {
2956 if (_i >= _iterator.length) break;
2957 _ref = _iterator[_i++];
2958 } else {
2959 _i = _iterator.next();
2960 if (_i.done) break;
2961 _ref = _i.value;
2962 }
2963
2964 var prop = _ref;
2965
2966 if (prop.type === "ObjectMethod") {
2967 if (prop.kind === "get" || prop.kind === "set") {
2968 this.raise(prop.key.start, "Object pattern can't contain getter or setter");
2969 } else {
2970 this.raise(prop.key.start, "Object pattern can't contain methods");
2971 }
2972 } else {
2973 this.toAssignable(prop, isBinding, "object destructuring pattern");
2974 }
2975 }
2976 break;
2977
2978 case "ObjectProperty":
2979 this.toAssignable(node.value, isBinding, contextDescription);
2980 break;
2981
2982 case "SpreadProperty":
2983 node.type = "RestProperty";
2984 var arg = node.argument;
2985 this.toAssignable(arg, isBinding, contextDescription);
2986 break;
2987
2988 case "ArrayExpression":
2989 node.type = "ArrayPattern";
2990 this.toAssignableList(node.elements, isBinding, contextDescription);
2991 break;
2992
2993 case "AssignmentExpression":
2994 if (node.operator === "=") {
2995 node.type = "AssignmentPattern";
2996 delete node.operator;
2997 } else {
2998 this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
2999 }
3000 break;
3001
3002 case "MemberExpression":
3003 if (!isBinding) break;
3004
3005 default:
3006 {
3007 var message = "Invalid left-hand side" + (contextDescription ? " in " + contextDescription : /* istanbul ignore next */"expression");
3008 this.raise(node.start, message);
3009 }
3010 }
3011 }
3012 return node;
3013};
3014
3015// Convert list of expression atoms to binding list.
3016
3017pp$2.toAssignableList = function (exprList, isBinding, contextDescription) {
3018 var end = exprList.length;
3019 if (end) {
3020 var last = exprList[end - 1];
3021 if (last && last.type === "RestElement") {
3022 --end;
3023 } else if (last && last.type === "SpreadElement") {
3024 last.type = "RestElement";
3025 var arg = last.argument;
3026 this.toAssignable(arg, isBinding, contextDescription);
3027 if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") {
3028 this.unexpected(arg.start);
3029 }
3030 --end;
3031 }
3032 }
3033 for (var i = 0; i < end; i++) {
3034 var elt = exprList[i];
3035 if (elt) this.toAssignable(elt, isBinding, contextDescription);
3036 }
3037 return exprList;
3038};
3039
3040// Convert list of expression atoms to a list of
3041
3042pp$2.toReferencedList = function (exprList) {
3043 return exprList;
3044};
3045
3046// Parses spread element.
3047
3048pp$2.parseSpread = function (refShorthandDefaultPos) {
3049 var node = this.startNode();
3050 this.next();
3051 node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos);
3052 return this.finishNode(node, "SpreadElement");
3053};
3054
3055pp$2.parseRest = function () {
3056 var node = this.startNode();
3057 this.next();
3058 node.argument = this.parseBindingIdentifier();
3059 return this.finishNode(node, "RestElement");
3060};
3061
3062pp$2.shouldAllowYieldIdentifier = function () {
3063 return this.match(types._yield) && !this.state.strict && !this.state.inGenerator;
3064};
3065
3066pp$2.parseBindingIdentifier = function () {
3067 return this.parseIdentifier(this.shouldAllowYieldIdentifier());
3068};
3069
3070// Parses lvalue (assignable) atom.
3071
3072pp$2.parseBindingAtom = function () {
3073 switch (this.state.type) {
3074 case types._yield:
3075 if (this.state.strict || this.state.inGenerator) this.unexpected();
3076 // fall-through
3077 case types.name:
3078 return this.parseIdentifier(true);
3079
3080 case types.bracketL:
3081 var node = this.startNode();
3082 this.next();
3083 node.elements = this.parseBindingList(types.bracketR, true);
3084 return this.finishNode(node, "ArrayPattern");
3085
3086 case types.braceL:
3087 return this.parseObj(true);
3088
3089 default:
3090 this.unexpected();
3091 }
3092};
3093
3094pp$2.parseBindingList = function (close, allowEmpty) {
3095 var elts = [];
3096 var first = true;
3097 while (!this.eat(close)) {
3098 if (first) {
3099 first = false;
3100 } else {
3101 this.expect(types.comma);
3102 }
3103 if (allowEmpty && this.match(types.comma)) {
3104 elts.push(null);
3105 } else if (this.eat(close)) {
3106 break;
3107 } else if (this.match(types.ellipsis)) {
3108 elts.push(this.parseAssignableListItemTypes(this.parseRest()));
3109 this.expect(close);
3110 break;
3111 } else {
3112 var decorators = [];
3113 while (this.match(types.at)) {
3114 decorators.push(this.parseDecorator());
3115 }
3116 var left = this.parseMaybeDefault();
3117 if (decorators.length) {
3118 left.decorators = decorators;
3119 }
3120 this.parseAssignableListItemTypes(left);
3121 elts.push(this.parseMaybeDefault(left.start, left.loc.start, left));
3122 }
3123 }
3124 return elts;
3125};
3126
3127pp$2.parseAssignableListItemTypes = function (param) {
3128 return param;
3129};
3130
3131// Parses assignment pattern around given atom if possible.
3132
3133pp$2.parseMaybeDefault = function (startPos, startLoc, left) {
3134 startLoc = startLoc || this.state.startLoc;
3135 startPos = startPos || this.state.start;
3136 left = left || this.parseBindingAtom();
3137 if (!this.eat(types.eq)) return left;
3138
3139 var node = this.startNodeAt(startPos, startLoc);
3140 node.left = left;
3141 node.right = this.parseMaybeAssign();
3142 return this.finishNode(node, "AssignmentPattern");
3143};
3144
3145// Verify that a node is an lval — something that can be assigned
3146// to.
3147
3148pp$2.checkLVal = function (expr, isBinding, checkClashes, contextDescription) {
3149 switch (expr.type) {
3150 case "Identifier":
3151 this.checkReservedWord(expr.name, expr.start, false, true);
3152
3153 if (checkClashes) {
3154 // we need to prefix this with an underscore for the cases where we have a key of
3155 // `__proto__`. there's a bug in old V8 where the following wouldn't work:
3156 //
3157 // > var obj = Object.create(null);
3158 // undefined
3159 // > obj.__proto__
3160 // null
3161 // > obj.__proto__ = true;
3162 // true
3163 // > obj.__proto__
3164 // null
3165 var key = "_" + expr.name;
3166
3167 if (checkClashes[key]) {
3168 this.raise(expr.start, "Argument name clash in strict mode");
3169 } else {
3170 checkClashes[key] = true;
3171 }
3172 }
3173 break;
3174
3175 case "MemberExpression":
3176 if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
3177 break;
3178
3179 case "ObjectPattern":
3180 for (var _iterator2 = expr.properties, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
3181 var _ref2;
3182
3183 if (_isArray2) {
3184 if (_i2 >= _iterator2.length) break;
3185 _ref2 = _iterator2[_i2++];
3186 } else {
3187 _i2 = _iterator2.next();
3188 if (_i2.done) break;
3189 _ref2 = _i2.value;
3190 }
3191
3192 var prop = _ref2;
3193
3194 if (prop.type === "ObjectProperty") prop = prop.value;
3195 this.checkLVal(prop, isBinding, checkClashes, "object destructuring pattern");
3196 }
3197 break;
3198
3199 case "ArrayPattern":
3200 for (var _iterator3 = expr.elements, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
3201 var _ref3;
3202
3203 if (_isArray3) {
3204 if (_i3 >= _iterator3.length) break;
3205 _ref3 = _iterator3[_i3++];
3206 } else {
3207 _i3 = _iterator3.next();
3208 if (_i3.done) break;
3209 _ref3 = _i3.value;
3210 }
3211
3212 var elem = _ref3;
3213
3214 if (elem) this.checkLVal(elem, isBinding, checkClashes, "array destructuring pattern");
3215 }
3216 break;
3217
3218 case "AssignmentPattern":
3219 this.checkLVal(expr.left, isBinding, checkClashes, "assignment pattern");
3220 break;
3221
3222 case "RestProperty":
3223 this.checkLVal(expr.argument, isBinding, checkClashes, "rest property");
3224 break;
3225
3226 case "RestElement":
3227 this.checkLVal(expr.argument, isBinding, checkClashes, "rest element");
3228 break;
3229
3230 default:
3231 {
3232 var message = (isBinding ? /* istanbul ignore next */"Binding invalid" : "Invalid") + " left-hand side" + (contextDescription ? " in " + contextDescription : /* istanbul ignore next */"expression");
3233 this.raise(expr.start, message);
3234 }
3235 }
3236};
3237
3238/* eslint max-len: 0 */
3239
3240// A recursive descent parser operates by defining functions for all
3241// syntactic elements, and recursively calling those, each function
3242// advancing the input stream and returning an AST node. Precedence
3243// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
3244// instead of `(!x)[1]` is handled by the fact that the parser
3245// function that parses unary prefix operators is called first, and
3246// in turn calls the function that parses `[]` subscripts — that
3247// way, it'll receive the node for `x[1]` already parsed, and wraps
3248// *that* in the unary operator node.
3249//
3250// Acorn uses an [operator precedence parser][opp] to handle binary
3251// operator precedence, because it is much more compact than using
3252// the technique outlined above, which uses different, nesting
3253// functions to specify precedence, for all of the ten binary
3254// precedence levels that JavaScript defines.
3255//
3256// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
3257
3258var pp$3 = Parser.prototype;
3259
3260// Check if property name clashes with already added.
3261// Object/class getters and setters are not allowed to clash —
3262// either with each other or with an init property — and in
3263// strict mode, init properties are also not allowed to be repeated.
3264
3265pp$3.checkPropClash = function (prop, propHash) {
3266 if (prop.computed || prop.kind) return;
3267
3268 var key = prop.key;
3269 // It is either an Identifier or a String/NumericLiteral
3270 var name = key.type === "Identifier" ? key.name : String(key.value);
3271
3272 if (name === "__proto__") {
3273 if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
3274 propHash.proto = true;
3275 }
3276};
3277
3278// Convenience method to parse an Expression only
3279pp$3.getExpression = function () {
3280 this.nextToken();
3281 var expr = this.parseExpression();
3282 if (!this.match(types.eof)) {
3283 this.unexpected();
3284 }
3285 return expr;
3286};
3287
3288// ### Expression parsing
3289
3290// These nest, from the most general expression type at the top to
3291// 'atomic', nondivisible expression types at the bottom. Most of
3292// the functions will simply let the function (s) below them parse,
3293// and, *if* the syntactic construct they handle is present, wrap
3294// the AST node that the inner parser gave them in another node.
3295
3296// Parse a full expression. The optional arguments are used to
3297// forbid the `in` operator (in for loops initialization expressions)
3298// and provide reference for storing '=' operator inside shorthand
3299// property assignment in contexts where both object expression
3300// and object pattern might appear (so it's possible to raise
3301// delayed syntax error at correct position).
3302
3303pp$3.parseExpression = function (noIn, refShorthandDefaultPos) {
3304 var startPos = this.state.start;
3305 var startLoc = this.state.startLoc;
3306 var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
3307 if (this.match(types.comma)) {
3308 var node = this.startNodeAt(startPos, startLoc);
3309 node.expressions = [expr];
3310 while (this.eat(types.comma)) {
3311 node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
3312 }
3313 this.toReferencedList(node.expressions);
3314 return this.finishNode(node, "SequenceExpression");
3315 }
3316 return expr;
3317};
3318
3319// Parse an assignment expression. This includes applications of
3320// operators like `+=`.
3321
3322pp$3.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) {
3323 var startPos = this.state.start;
3324 var startLoc = this.state.startLoc;
3325
3326 if (this.match(types._yield) && this.state.inGenerator) {
3327 var _left = this.parseYield();
3328 if (afterLeftParse) _left = afterLeftParse.call(this, _left, startPos, startLoc);
3329 return _left;
3330 }
3331
3332 var failOnShorthandAssign = void 0;
3333 if (refShorthandDefaultPos) {
3334 failOnShorthandAssign = false;
3335 } else {
3336 refShorthandDefaultPos = { start: 0 };
3337 failOnShorthandAssign = true;
3338 }
3339
3340 if (this.match(types.parenL) || this.match(types.name)) {
3341 this.state.potentialArrowAt = this.state.start;
3342 }
3343
3344 var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos);
3345 if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
3346 if (this.state.type.isAssign) {
3347 var node = this.startNodeAt(startPos, startLoc);
3348 node.operator = this.state.value;
3349 node.left = this.match(types.eq) ? this.toAssignable(left, undefined, "assignment expression") : left;
3350 refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
3351
3352 this.checkLVal(left, undefined, undefined, "assignment expression");
3353
3354 if (left.extra && left.extra.parenthesized) {
3355 var errorMsg = void 0;
3356 if (left.type === "ObjectPattern") {
3357 errorMsg = "`({a}) = 0` use `({a} = 0)`";
3358 } else if (left.type === "ArrayPattern") {
3359 errorMsg = "`([a]) = 0` use `([a] = 0)`";
3360 }
3361 if (errorMsg) {
3362 this.raise(left.start, "You're trying to assign to a parenthesized expression, eg. instead of " + errorMsg);
3363 }
3364 }
3365
3366 this.next();
3367 node.right = this.parseMaybeAssign(noIn);
3368 return this.finishNode(node, "AssignmentExpression");
3369 } else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
3370 this.unexpected(refShorthandDefaultPos.start);
3371 }
3372
3373 return left;
3374};
3375
3376// Parse a ternary conditional (`?:`) operator.
3377
3378pp$3.parseMaybeConditional = function (noIn, refShorthandDefaultPos, refNeedsArrowPos) {
3379 var startPos = this.state.start;
3380 var startLoc = this.state.startLoc;
3381 var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
3382 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
3383
3384 return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos);
3385};
3386
3387pp$3.parseConditional = function (expr, noIn, startPos, startLoc) {
3388 if (this.eat(types.question)) {
3389 var node = this.startNodeAt(startPos, startLoc);
3390 node.test = expr;
3391 node.consequent = this.parseMaybeAssign();
3392 this.expect(types.colon);
3393 node.alternate = this.parseMaybeAssign(noIn);
3394 return this.finishNode(node, "ConditionalExpression");
3395 }
3396 return expr;
3397};
3398
3399// Start the precedence parser.
3400
3401pp$3.parseExprOps = function (noIn, refShorthandDefaultPos) {
3402 var startPos = this.state.start;
3403 var startLoc = this.state.startLoc;
3404 var expr = this.parseMaybeUnary(refShorthandDefaultPos);
3405 if (refShorthandDefaultPos && refShorthandDefaultPos.start) {
3406 return expr;
3407 } else {
3408 return this.parseExprOp(expr, startPos, startLoc, -1, noIn);
3409 }
3410};
3411
3412// Parse binary operators with the operator precedence parsing
3413// algorithm. `left` is the left-hand side of the operator.
3414// `minPrec` provides context that allows the function to stop and
3415// defer further parser to one of its callers when it encounters an
3416// operator that has a lower precedence than the set it is parsing.
3417
3418pp$3.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
3419 var prec = this.state.type.binop;
3420 if (prec != null && (!noIn || !this.match(types._in))) {
3421 if (prec > minPrec) {
3422 var node = this.startNodeAt(leftStartPos, leftStartLoc);
3423 node.left = left;
3424 node.operator = this.state.value;
3425
3426 if (node.operator === "**" && left.type === "UnaryExpression" && left.extra && !left.extra.parenthesizedArgument && !left.extra.parenthesized) {
3427 this.raise(left.argument.start, "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.");
3428 }
3429
3430 var op = this.state.type;
3431 this.next();
3432
3433 var startPos = this.state.start;
3434 var startLoc = this.state.startLoc;
3435 node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn);
3436
3437 this.finishNode(node, op === types.logicalOR || op === types.logicalAND ? "LogicalExpression" : "BinaryExpression");
3438 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
3439 }
3440 }
3441 return left;
3442};
3443
3444// Parse unary operators, both prefix and postfix.
3445
3446pp$3.parseMaybeUnary = function (refShorthandDefaultPos) {
3447 if (this.state.type.prefix) {
3448 var node = this.startNode();
3449 var update = this.match(types.incDec);
3450 node.operator = this.state.value;
3451 node.prefix = true;
3452 this.next();
3453
3454 var argType = this.state.type;
3455 node.argument = this.parseMaybeUnary();
3456
3457 this.addExtra(node, "parenthesizedArgument", argType === types.parenL && (!node.argument.extra || !node.argument.extra.parenthesized));
3458
3459 if (refShorthandDefaultPos && refShorthandDefaultPos.start) {
3460 this.unexpected(refShorthandDefaultPos.start);
3461 }
3462
3463 if (update) {
3464 this.checkLVal(node.argument, undefined, undefined, "prefix operation");
3465 } else if (this.state.strict && node.operator === "delete" && node.argument.type === "Identifier") {
3466 this.raise(node.start, "Deleting local variable in strict mode");
3467 }
3468
3469 return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
3470 }
3471
3472 var startPos = this.state.start;
3473 var startLoc = this.state.startLoc;
3474 var expr = this.parseExprSubscripts(refShorthandDefaultPos);
3475 if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
3476 while (this.state.type.postfix && !this.canInsertSemicolon()) {
3477 var _node = this.startNodeAt(startPos, startLoc);
3478 _node.operator = this.state.value;
3479 _node.prefix = false;
3480 _node.argument = expr;
3481 this.checkLVal(expr, undefined, undefined, "postfix operation");
3482 this.next();
3483 expr = this.finishNode(_node, "UpdateExpression");
3484 }
3485 return expr;
3486};
3487
3488// Parse call, dot, and `[]`-subscript expressions.
3489
3490pp$3.parseExprSubscripts = function (refShorthandDefaultPos) {
3491 var startPos = this.state.start;
3492 var startLoc = this.state.startLoc;
3493 var potentialArrowAt = this.state.potentialArrowAt;
3494 var expr = this.parseExprAtom(refShorthandDefaultPos);
3495
3496 if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) {
3497 return expr;
3498 }
3499
3500 if (refShorthandDefaultPos && refShorthandDefaultPos.start) {
3501 return expr;
3502 }
3503
3504 return this.parseSubscripts(expr, startPos, startLoc);
3505};
3506
3507pp$3.parseSubscripts = function (base, startPos, startLoc, noCalls) {
3508 for (;;) {
3509 if (!noCalls && this.eat(types.doubleColon)) {
3510 var node = this.startNodeAt(startPos, startLoc);
3511 node.object = base;
3512 node.callee = this.parseNoCallExpr();
3513 return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls);
3514 } else if (this.eat(types.dot)) {
3515 var _node2 = this.startNodeAt(startPos, startLoc);
3516 _node2.object = base;
3517 _node2.property = this.parseIdentifier(true);
3518 _node2.computed = false;
3519 base = this.finishNode(_node2, "MemberExpression");
3520 } else if (this.eat(types.bracketL)) {
3521 var _node3 = this.startNodeAt(startPos, startLoc);
3522 _node3.object = base;
3523 _node3.property = this.parseExpression();
3524 _node3.computed = true;
3525 this.expect(types.bracketR);
3526 base = this.finishNode(_node3, "MemberExpression");
3527 } else if (!noCalls && this.match(types.parenL)) {
3528 var possibleAsync = this.state.potentialArrowAt === base.start && base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon();
3529 this.next();
3530
3531 var _node4 = this.startNodeAt(startPos, startLoc);
3532 _node4.callee = base;
3533 _node4.arguments = this.parseCallExpressionArguments(types.parenR, possibleAsync);
3534 if (_node4.callee.type === "Import" && _node4.arguments.length !== 1) {
3535 this.raise(_node4.start, "import() requires exactly one argument");
3536 }
3537 base = this.finishNode(_node4, "CallExpression");
3538
3539 if (possibleAsync && this.shouldParseAsyncArrow()) {
3540 return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), _node4);
3541 } else {
3542 this.toReferencedList(_node4.arguments);
3543 }
3544 } else if (this.match(types.backQuote)) {
3545 var _node5 = this.startNodeAt(startPos, startLoc);
3546 _node5.tag = base;
3547 _node5.quasi = this.parseTemplate(true);
3548 base = this.finishNode(_node5, "TaggedTemplateExpression");
3549 } else {
3550 return base;
3551 }
3552 }
3553};
3554
3555pp$3.parseCallExpressionArguments = function (close, possibleAsyncArrow) {
3556 var elts = [];
3557 var innerParenStart = void 0;
3558 var first = true;
3559
3560 while (!this.eat(close)) {
3561 if (first) {
3562 first = false;
3563 } else {
3564 this.expect(types.comma);
3565 if (this.eat(close)) break;
3566 }
3567
3568 // we need to make sure that if this is an async arrow functions, that we don't allow inner parens inside the params
3569 if (this.match(types.parenL) && !innerParenStart) {
3570 innerParenStart = this.state.start;
3571 }
3572
3573 elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { start: 0 } : undefined, possibleAsyncArrow ? { start: 0 } : undefined));
3574 }
3575
3576 // we found an async arrow function so let's not allow any inner parens
3577 if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) {
3578 this.unexpected();
3579 }
3580
3581 return elts;
3582};
3583
3584pp$3.shouldParseAsyncArrow = function () {
3585 return this.match(types.arrow);
3586};
3587
3588pp$3.parseAsyncArrowFromCallExpression = function (node, call) {
3589 this.expect(types.arrow);
3590 return this.parseArrowExpression(node, call.arguments, true);
3591};
3592
3593// Parse a no-call expression (like argument of `new` or `::` operators).
3594
3595pp$3.parseNoCallExpr = function () {
3596 var startPos = this.state.start;
3597 var startLoc = this.state.startLoc;
3598 return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
3599};
3600
3601// Parse an atomic expression — either a single token that is an
3602// expression, an expression started by a keyword like `function` or
3603// `new`, or an expression wrapped in punctuation like `()`, `[]`,
3604// or `{}`.
3605
3606pp$3.parseExprAtom = function (refShorthandDefaultPos) {
3607 var canBeArrow = this.state.potentialArrowAt === this.state.start;
3608 var node = void 0;
3609
3610 switch (this.state.type) {
3611 case types._super:
3612 if (!this.state.inMethod && !this.state.inClassProperty && !this.options.allowSuperOutsideMethod) {
3613 this.raise(this.state.start, "'super' outside of function or class");
3614 }
3615
3616 node = this.startNode();
3617 this.next();
3618 if (!this.match(types.parenL) && !this.match(types.bracketL) && !this.match(types.dot)) {
3619 this.unexpected();
3620 }
3621 if (this.match(types.parenL) && this.state.inMethod !== "constructor" && !this.options.allowSuperOutsideMethod) {
3622 this.raise(node.start, "super() outside of class constructor");
3623 }
3624 return this.finishNode(node, "Super");
3625
3626 case types._import:
3627 if (!this.hasPlugin("dynamicImport")) this.unexpected();
3628
3629 node = this.startNode();
3630 this.next();
3631 if (!this.match(types.parenL)) {
3632 this.unexpected(null, types.parenL);
3633 }
3634 return this.finishNode(node, "Import");
3635
3636 case types._this:
3637 node = this.startNode();
3638 this.next();
3639 return this.finishNode(node, "ThisExpression");
3640
3641 case types._yield:
3642 if (this.state.inGenerator) this.unexpected();
3643
3644 case types.name:
3645 node = this.startNode();
3646 var allowAwait = this.state.value === "await" && this.state.inAsync;
3647 var allowYield = this.shouldAllowYieldIdentifier();
3648 var id = this.parseIdentifier(allowAwait || allowYield);
3649
3650 if (id.name === "await") {
3651 if (this.state.inAsync || this.inModule) {
3652 return this.parseAwait(node);
3653 }
3654 } else if (id.name === "async" && this.match(types._function) && !this.canInsertSemicolon()) {
3655 this.next();
3656 return this.parseFunction(node, false, false, true);
3657 } else if (canBeArrow && id.name === "async" && this.match(types.name)) {
3658 var params = [this.parseIdentifier()];
3659 this.expect(types.arrow);
3660 // let foo = bar => {};
3661 return this.parseArrowExpression(node, params, true);
3662 }
3663
3664 if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
3665 return this.parseArrowExpression(node, [id]);
3666 }
3667
3668 return id;
3669
3670 case types._do:
3671 if (this.hasPlugin("doExpressions")) {
3672 var _node6 = this.startNode();
3673 this.next();
3674 var oldInFunction = this.state.inFunction;
3675 var oldLabels = this.state.labels;
3676 this.state.labels = [];
3677 this.state.inFunction = false;
3678 _node6.body = this.parseBlock(false, true);
3679 this.state.inFunction = oldInFunction;
3680 this.state.labels = oldLabels;
3681 return this.finishNode(_node6, "DoExpression");
3682 }
3683
3684 case types.regexp:
3685 var value = this.state.value;
3686 node = this.parseLiteral(value.value, "RegExpLiteral");
3687 node.pattern = value.pattern;
3688 node.flags = value.flags;
3689 return node;
3690
3691 case types.num:
3692 return this.parseLiteral(this.state.value, "NumericLiteral");
3693
3694 case types.string:
3695 return this.parseLiteral(this.state.value, "StringLiteral");
3696
3697 case types._null:
3698 node = this.startNode();
3699 this.next();
3700 return this.finishNode(node, "NullLiteral");
3701
3702 case types._true:case types._false:
3703 node = this.startNode();
3704 node.value = this.match(types._true);
3705 this.next();
3706 return this.finishNode(node, "BooleanLiteral");
3707
3708 case types.parenL:
3709 return this.parseParenAndDistinguishExpression(null, null, canBeArrow);
3710
3711 case types.bracketL:
3712 node = this.startNode();
3713 this.next();
3714 node.elements = this.parseExprList(types.bracketR, true, refShorthandDefaultPos);
3715 this.toReferencedList(node.elements);
3716 return this.finishNode(node, "ArrayExpression");
3717
3718 case types.braceL:
3719 return this.parseObj(false, refShorthandDefaultPos);
3720
3721 case types._function:
3722 return this.parseFunctionExpression();
3723
3724 case types.at:
3725 this.parseDecorators();
3726
3727 case types._class:
3728 node = this.startNode();
3729 this.takeDecorators(node);
3730 return this.parseClass(node, false);
3731
3732 case types._new:
3733 return this.parseNew();
3734
3735 case types.backQuote:
3736 return this.parseTemplate(false);
3737
3738 case types.doubleColon:
3739 node = this.startNode();
3740 this.next();
3741 node.object = null;
3742 var callee = node.callee = this.parseNoCallExpr();
3743 if (callee.type === "MemberExpression") {
3744 return this.finishNode(node, "BindExpression");
3745 } else {
3746 this.raise(callee.start, "Binding should be performed on object property.");
3747 }
3748
3749 default:
3750 this.unexpected();
3751 }
3752};
3753
3754pp$3.parseFunctionExpression = function () {
3755 var node = this.startNode();
3756 var meta = this.parseIdentifier(true);
3757 if (this.state.inGenerator && this.eat(types.dot) && this.hasPlugin("functionSent")) {
3758 return this.parseMetaProperty(node, meta, "sent");
3759 } else {
3760 return this.parseFunction(node, false);
3761 }
3762};
3763
3764pp$3.parseMetaProperty = function (node, meta, propertyName) {
3765 node.meta = meta;
3766 node.property = this.parseIdentifier(true);
3767
3768 if (node.property.name !== propertyName) {
3769 this.raise(node.property.start, "The only valid meta property for new is " + meta.name + "." + propertyName);
3770 }
3771
3772 return this.finishNode(node, "MetaProperty");
3773};
3774
3775pp$3.parseLiteral = function (value, type, startPos, startLoc) {
3776 startPos = startPos || this.state.start;
3777 startLoc = startLoc || this.state.startLoc;
3778
3779 var node = this.startNodeAt(startPos, startLoc);
3780 this.addExtra(node, "rawValue", value);
3781 this.addExtra(node, "raw", this.input.slice(startPos, this.state.end));
3782 node.value = value;
3783 this.next();
3784 return this.finishNode(node, type);
3785};
3786
3787pp$3.parseParenExpression = function () {
3788 this.expect(types.parenL);
3789 var val = this.parseExpression();
3790 this.expect(types.parenR);
3791 return val;
3792};
3793
3794pp$3.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow) {
3795 startPos = startPos || this.state.start;
3796 startLoc = startLoc || this.state.startLoc;
3797
3798 var val = void 0;
3799 this.expect(types.parenL);
3800
3801 var innerStartPos = this.state.start;
3802 var innerStartLoc = this.state.startLoc;
3803 var exprList = [];
3804 var refShorthandDefaultPos = { start: 0 };
3805 var refNeedsArrowPos = { start: 0 };
3806 var first = true;
3807 var spreadStart = void 0;
3808 var optionalCommaStart = void 0;
3809
3810 while (!this.match(types.parenR)) {
3811 if (first) {
3812 first = false;
3813 } else {
3814 this.expect(types.comma, refNeedsArrowPos.start || null);
3815 if (this.match(types.parenR)) {
3816 optionalCommaStart = this.state.start;
3817 break;
3818 }
3819 }
3820
3821 if (this.match(types.ellipsis)) {
3822 var spreadNodeStartPos = this.state.start;
3823 var spreadNodeStartLoc = this.state.startLoc;
3824 spreadStart = this.state.start;
3825 exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartPos, spreadNodeStartLoc));
3826 break;
3827 } else {
3828 exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos));
3829 }
3830 }
3831
3832 var innerEndPos = this.state.start;
3833 var innerEndLoc = this.state.startLoc;
3834 this.expect(types.parenR);
3835
3836 var arrowNode = this.startNodeAt(startPos, startLoc);
3837 if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) {
3838 for (var _iterator = exprList, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
3839 var _ref;
3840
3841 if (_isArray) {
3842 if (_i >= _iterator.length) break;
3843 _ref = _iterator[_i++];
3844 } else {
3845 _i = _iterator.next();
3846 if (_i.done) break;
3847 _ref = _i.value;
3848 }
3849
3850 var param = _ref;
3851
3852 if (param.extra && param.extra.parenthesized) this.unexpected(param.extra.parenStart);
3853 }
3854
3855 return this.parseArrowExpression(arrowNode, exprList);
3856 }
3857
3858 if (!exprList.length) {
3859 this.unexpected(this.state.lastTokStart);
3860 }
3861 if (optionalCommaStart) this.unexpected(optionalCommaStart);
3862 if (spreadStart) this.unexpected(spreadStart);
3863 if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
3864 if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start);
3865
3866 if (exprList.length > 1) {
3867 val = this.startNodeAt(innerStartPos, innerStartLoc);
3868 val.expressions = exprList;
3869 this.toReferencedList(val.expressions);
3870 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
3871 } else {
3872 val = exprList[0];
3873 }
3874
3875 this.addExtra(val, "parenthesized", true);
3876 this.addExtra(val, "parenStart", startPos);
3877
3878 return val;
3879};
3880
3881pp$3.shouldParseArrow = function () {
3882 return !this.canInsertSemicolon();
3883};
3884
3885pp$3.parseArrow = function (node) {
3886 if (this.eat(types.arrow)) {
3887 return node;
3888 }
3889};
3890
3891pp$3.parseParenItem = function (node) {
3892 return node;
3893};
3894
3895// New's precedence is slightly tricky. It must allow its argument
3896// to be a `[]` or dot subscript expression, but not a call — at
3897// least, not without wrapping it in parentheses. Thus, it uses the
3898
3899pp$3.parseNew = function () {
3900 var node = this.startNode();
3901 var meta = this.parseIdentifier(true);
3902
3903 if (this.eat(types.dot)) {
3904 var metaProp = this.parseMetaProperty(node, meta, "target");
3905
3906 if (!this.state.inFunction) {
3907 this.raise(metaProp.property.start, "new.target can only be used in functions");
3908 }
3909
3910 return metaProp;
3911 }
3912
3913 node.callee = this.parseNoCallExpr();
3914
3915 if (this.eat(types.parenL)) {
3916 node.arguments = this.parseExprList(types.parenR);
3917 this.toReferencedList(node.arguments);
3918 } else {
3919 node.arguments = [];
3920 }
3921
3922 return this.finishNode(node, "NewExpression");
3923};
3924
3925// Parse template expression.
3926
3927pp$3.parseTemplateElement = function (isTagged) {
3928 var elem = this.startNode();
3929 if (this.state.value === null) {
3930 if (!isTagged || !this.hasPlugin("templateInvalidEscapes")) {
3931 this.raise(this.state.invalidTemplateEscapePosition, "Invalid escape sequence in template");
3932 } else {
3933 this.state.invalidTemplateEscapePosition = null;
3934 }
3935 }
3936 elem.value = {
3937 raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"),
3938 cooked: this.state.value
3939 };
3940 this.next();
3941 elem.tail = this.match(types.backQuote);
3942 return this.finishNode(elem, "TemplateElement");
3943};
3944
3945pp$3.parseTemplate = function (isTagged) {
3946 var node = this.startNode();
3947 this.next();
3948 node.expressions = [];
3949 var curElt = this.parseTemplateElement(isTagged);
3950 node.quasis = [curElt];
3951 while (!curElt.tail) {
3952 this.expect(types.dollarBraceL);
3953 node.expressions.push(this.parseExpression());
3954 this.expect(types.braceR);
3955 node.quasis.push(curElt = this.parseTemplateElement(isTagged));
3956 }
3957 this.next();
3958 return this.finishNode(node, "TemplateLiteral");
3959};
3960
3961// Parse an object literal or binding pattern.
3962
3963pp$3.parseObj = function (isPattern, refShorthandDefaultPos) {
3964 var decorators = [];
3965 var propHash = Object.create(null);
3966 var first = true;
3967 var node = this.startNode();
3968
3969 node.properties = [];
3970 this.next();
3971
3972 var firstRestLocation = null;
3973
3974 while (!this.eat(types.braceR)) {
3975 if (first) {
3976 first = false;
3977 } else {
3978 this.expect(types.comma);
3979 if (this.eat(types.braceR)) break;
3980 }
3981
3982 while (this.match(types.at)) {
3983 decorators.push(this.parseDecorator());
3984 }
3985
3986 var prop = this.startNode(),
3987 isGenerator = false,
3988 isAsync = false,
3989 startPos = void 0,
3990 startLoc = void 0;
3991 if (decorators.length) {
3992 prop.decorators = decorators;
3993 decorators = [];
3994 }
3995
3996 if (this.hasPlugin("objectRestSpread") && this.match(types.ellipsis)) {
3997 prop = this.parseSpread(isPattern ? { start: 0 } : undefined);
3998 prop.type = isPattern ? "RestProperty" : "SpreadProperty";
3999 if (isPattern) this.toAssignable(prop.argument, true, "object pattern");
4000 node.properties.push(prop);
4001 if (isPattern) {
4002 var position = this.state.start;
4003 if (firstRestLocation !== null) {
4004 this.unexpected(firstRestLocation, "Cannot have multiple rest elements when destructuring");
4005 } else if (this.eat(types.braceR)) {
4006 break;
4007 } else if (this.match(types.comma) && this.lookahead().type === types.braceR) {
4008 // TODO: temporary rollback
4009 // this.unexpected(position, "A trailing comma is not permitted after the rest element");
4010 continue;
4011 } else {
4012 firstRestLocation = position;
4013 continue;
4014 }
4015 } else {
4016 continue;
4017 }
4018 }
4019
4020 prop.method = false;
4021 prop.shorthand = false;
4022
4023 if (isPattern || refShorthandDefaultPos) {
4024 startPos = this.state.start;
4025 startLoc = this.state.startLoc;
4026 }
4027
4028 if (!isPattern) {
4029 isGenerator = this.eat(types.star);
4030 }
4031
4032 if (!isPattern && this.isContextual("async")) {
4033 if (isGenerator) this.unexpected();
4034
4035 var asyncId = this.parseIdentifier();
4036 if (this.match(types.colon) || this.match(types.parenL) || this.match(types.braceR) || this.match(types.eq) || this.match(types.comma)) {
4037 prop.key = asyncId;
4038 prop.computed = false;
4039 } else {
4040 isAsync = true;
4041 if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(types.star);
4042 this.parsePropertyName(prop);
4043 }
4044 } else {
4045 this.parsePropertyName(prop);
4046 }
4047
4048 this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos);
4049 this.checkPropClash(prop, propHash);
4050
4051 if (prop.shorthand) {
4052 this.addExtra(prop, "shorthand", true);
4053 }
4054
4055 node.properties.push(prop);
4056 }
4057
4058 if (firstRestLocation !== null) {
4059 this.unexpected(firstRestLocation, "The rest element has to be the last element when destructuring");
4060 }
4061
4062 if (decorators.length) {
4063 this.raise(this.state.start, "You have trailing decorators with no property");
4064 }
4065
4066 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
4067};
4068
4069pp$3.isGetterOrSetterMethod = function (prop, isPattern) {
4070 return !isPattern && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.match(types.string) || // get "string"() {}
4071 this.match(types.num) || // get 1() {}
4072 this.match(types.bracketL) || // get ["string"]() {}
4073 this.match(types.name) || // get foo() {}
4074 this.state.type.keyword // get debugger() {}
4075 );
4076};
4077
4078// get methods aren't allowed to have any parameters
4079// set methods must have exactly 1 parameter
4080pp$3.checkGetterSetterParamCount = function (method) {
4081 var paramCount = method.kind === "get" ? 0 : 1;
4082 if (method.params.length !== paramCount) {
4083 var start = method.start;
4084 if (method.kind === "get") {
4085 this.raise(start, "getter should have no params");
4086 } else {
4087 this.raise(start, "setter should have exactly one param");
4088 }
4089 }
4090};
4091
4092pp$3.parseObjectMethod = function (prop, isGenerator, isAsync, isPattern) {
4093 if (isAsync || isGenerator || this.match(types.parenL)) {
4094 if (isPattern) this.unexpected();
4095 prop.kind = "method";
4096 prop.method = true;
4097 this.parseMethod(prop, isGenerator, isAsync);
4098
4099 return this.finishNode(prop, "ObjectMethod");
4100 }
4101
4102 if (this.isGetterOrSetterMethod(prop, isPattern)) {
4103 if (isGenerator || isAsync) this.unexpected();
4104 prop.kind = prop.key.name;
4105 this.parsePropertyName(prop);
4106 this.parseMethod(prop);
4107 this.checkGetterSetterParamCount(prop);
4108
4109 return this.finishNode(prop, "ObjectMethod");
4110 }
4111};
4112
4113pp$3.parseObjectProperty = function (prop, startPos, startLoc, isPattern, refShorthandDefaultPos) {
4114 if (this.eat(types.colon)) {
4115 prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
4116
4117 return this.finishNode(prop, "ObjectProperty");
4118 }
4119
4120 if (!prop.computed && prop.key.type === "Identifier") {
4121 this.checkReservedWord(prop.key.name, prop.key.start, true, true);
4122
4123 if (isPattern) {
4124 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone());
4125 } else if (this.match(types.eq) && refShorthandDefaultPos) {
4126 if (!refShorthandDefaultPos.start) {
4127 refShorthandDefaultPos.start = this.state.start;
4128 }
4129 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone());
4130 } else {
4131 prop.value = prop.key.__clone();
4132 }
4133 prop.shorthand = true;
4134
4135 return this.finishNode(prop, "ObjectProperty");
4136 }
4137};
4138
4139pp$3.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) {
4140 var node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos);
4141
4142 if (!node) this.unexpected();
4143
4144 return node;
4145};
4146
4147pp$3.parsePropertyName = function (prop) {
4148 if (this.eat(types.bracketL)) {
4149 prop.computed = true;
4150 prop.key = this.parseMaybeAssign();
4151 this.expect(types.bracketR);
4152 } else {
4153 prop.computed = false;
4154 var oldInPropertyName = this.state.inPropertyName;
4155 this.state.inPropertyName = true;
4156 prop.key = this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true);
4157 this.state.inPropertyName = oldInPropertyName;
4158 }
4159 return prop.key;
4160};
4161
4162// Initialize empty function node.
4163
4164pp$3.initFunction = function (node, isAsync) {
4165 node.id = null;
4166 node.generator = false;
4167 node.expression = false;
4168 node.async = !!isAsync;
4169};
4170
4171// Parse object or class method.
4172
4173pp$3.parseMethod = function (node, isGenerator, isAsync) {
4174 var oldInMethod = this.state.inMethod;
4175 this.state.inMethod = node.kind || true;
4176 this.initFunction(node, isAsync);
4177 this.expect(types.parenL);
4178 node.params = this.parseBindingList(types.parenR);
4179 node.generator = !!isGenerator;
4180 this.parseFunctionBody(node);
4181 this.state.inMethod = oldInMethod;
4182 return node;
4183};
4184
4185// Parse arrow function expression with given parameters.
4186
4187pp$3.parseArrowExpression = function (node, params, isAsync) {
4188 this.initFunction(node, isAsync);
4189 node.params = this.toAssignableList(params, true, "arrow function parameters");
4190 this.parseFunctionBody(node, true);
4191 return this.finishNode(node, "ArrowFunctionExpression");
4192};
4193
4194pp$3.isStrictBody = function (node, isExpression) {
4195 if (!isExpression && node.body.directives.length) {
4196 for (var _iterator2 = node.body.directives, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
4197 var _ref2;
4198
4199 if (_isArray2) {
4200 if (_i2 >= _iterator2.length) break;
4201 _ref2 = _iterator2[_i2++];
4202 } else {
4203 _i2 = _iterator2.next();
4204 if (_i2.done) break;
4205 _ref2 = _i2.value;
4206 }
4207
4208 var directive = _ref2;
4209
4210 if (directive.value.value === "use strict") {
4211 return true;
4212 }
4213 }
4214 }
4215
4216 return false;
4217};
4218
4219// Parse function body and check parameters.
4220pp$3.parseFunctionBody = function (node, allowExpression) {
4221 var isExpression = allowExpression && !this.match(types.braceL);
4222
4223 var oldInAsync = this.state.inAsync;
4224 this.state.inAsync = node.async;
4225 if (isExpression) {
4226 node.body = this.parseMaybeAssign();
4227 node.expression = true;
4228 } else {
4229 // Start a new scope with regard to labels and the `inFunction`
4230 // flag (restore them to their old value afterwards).
4231 var oldInFunc = this.state.inFunction;
4232 var oldInGen = this.state.inGenerator;
4233 var oldLabels = this.state.labels;
4234 this.state.inFunction = true;this.state.inGenerator = node.generator;this.state.labels = [];
4235 node.body = this.parseBlock(true);
4236 node.expression = false;
4237 this.state.inFunction = oldInFunc;this.state.inGenerator = oldInGen;this.state.labels = oldLabels;
4238 }
4239 this.state.inAsync = oldInAsync;
4240
4241 // If this is a strict mode function, verify that argument names
4242 // are not repeated, and it does not try to bind the words `eval`
4243 // or `arguments`.
4244 var isStrict = this.isStrictBody(node, isExpression);
4245 // Also check when allowExpression === true for arrow functions
4246 var checkLVal = this.state.strict || allowExpression || isStrict;
4247
4248 if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") {
4249 this.raise(node.id.start, "Binding yield in strict mode");
4250 }
4251
4252 if (checkLVal) {
4253 var nameHash = Object.create(null);
4254 var oldStrict = this.state.strict;
4255 if (isStrict) this.state.strict = true;
4256 if (node.id) {
4257 this.checkLVal(node.id, true, undefined, "function name");
4258 }
4259 for (var _iterator3 = node.params, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
4260 var _ref3;
4261
4262 if (_isArray3) {
4263 if (_i3 >= _iterator3.length) break;
4264 _ref3 = _iterator3[_i3++];
4265 } else {
4266 _i3 = _iterator3.next();
4267 if (_i3.done) break;
4268 _ref3 = _i3.value;
4269 }
4270
4271 var param = _ref3;
4272
4273 if (isStrict && param.type !== "Identifier") {
4274 this.raise(param.start, "Non-simple parameter in strict mode");
4275 }
4276 this.checkLVal(param, true, nameHash, "function parameter list");
4277 }
4278 this.state.strict = oldStrict;
4279 }
4280};
4281
4282// Parses a comma-separated list of expressions, and returns them as
4283// an array. `close` is the token type that ends the list, and
4284// `allowEmpty` can be turned on to allow subsequent commas with
4285// nothing in between them to be parsed as `null` (which is needed
4286// for array literals).
4287
4288pp$3.parseExprList = function (close, allowEmpty, refShorthandDefaultPos) {
4289 var elts = [];
4290 var first = true;
4291
4292 while (!this.eat(close)) {
4293 if (first) {
4294 first = false;
4295 } else {
4296 this.expect(types.comma);
4297 if (this.eat(close)) break;
4298 }
4299
4300 elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos));
4301 }
4302 return elts;
4303};
4304
4305pp$3.parseExprListItem = function (allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) {
4306 var elt = void 0;
4307 if (allowEmpty && this.match(types.comma)) {
4308 elt = null;
4309 } else if (this.match(types.ellipsis)) {
4310 elt = this.parseSpread(refShorthandDefaultPos);
4311 } else {
4312 elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos);
4313 }
4314 return elt;
4315};
4316
4317// Parse the next token as an identifier. If `liberal` is true (used
4318// when parsing properties), it will also convert keywords into
4319// identifiers.
4320
4321pp$3.parseIdentifier = function (liberal) {
4322 var node = this.startNode();
4323 if (!liberal) {
4324 this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false);
4325 }
4326
4327 if (this.match(types.name)) {
4328 node.name = this.state.value;
4329 } else if (this.state.type.keyword) {
4330 node.name = this.state.type.keyword;
4331 } else {
4332 this.unexpected();
4333 }
4334
4335 if (!liberal && node.name === "await" && this.state.inAsync) {
4336 this.raise(node.start, "invalid use of await inside of an async function");
4337 }
4338
4339 node.loc.identifierName = node.name;
4340
4341 this.next();
4342 return this.finishNode(node, "Identifier");
4343};
4344
4345pp$3.checkReservedWord = function (word, startLoc, checkKeywords, isBinding) {
4346 if (this.isReservedWord(word) || checkKeywords && this.isKeyword(word)) {
4347 this.raise(startLoc, word + " is a reserved word");
4348 }
4349
4350 if (this.state.strict && (reservedWords.strict(word) || isBinding && reservedWords.strictBind(word))) {
4351 this.raise(startLoc, word + " is a reserved word in strict mode");
4352 }
4353};
4354
4355// Parses await expression inside async function.
4356
4357pp$3.parseAwait = function (node) {
4358 // istanbul ignore next: this condition is checked at the call site so won't be hit here
4359 if (!this.state.inAsync) {
4360 this.unexpected();
4361 }
4362 if (this.match(types.star)) {
4363 this.raise(node.start, "await* has been removed from the async functions proposal. Use Promise.all() instead.");
4364 }
4365 node.argument = this.parseMaybeUnary();
4366 return this.finishNode(node, "AwaitExpression");
4367};
4368
4369// Parses yield expression inside generator.
4370
4371pp$3.parseYield = function () {
4372 var node = this.startNode();
4373 this.next();
4374 if (this.match(types.semi) || this.canInsertSemicolon() || !this.match(types.star) && !this.state.type.startsExpr) {
4375 node.delegate = false;
4376 node.argument = null;
4377 } else {
4378 node.delegate = this.eat(types.star);
4379 node.argument = this.parseMaybeAssign();
4380 }
4381 return this.finishNode(node, "YieldExpression");
4382};
4383
4384// Start an AST node, attaching a start offset.
4385
4386var pp$4 = Parser.prototype;
4387var commentKeys = ["leadingComments", "trailingComments", "innerComments"];
4388
4389var Node = function () {
4390 function Node(pos, loc, filename) {
4391 classCallCheck(this, Node);
4392
4393 this.type = "";
4394 this.start = pos;
4395 this.end = 0;
4396 this.loc = new SourceLocation(loc);
4397 if (filename) this.loc.filename = filename;
4398 }
4399
4400 Node.prototype.__clone = function __clone() {
4401 var node2 = new Node();
4402 for (var key in this) {
4403 // Do not clone comments that are already attached to the node
4404 if (commentKeys.indexOf(key) < 0) {
4405 node2[key] = this[key];
4406 }
4407 }
4408
4409 return node2;
4410 };
4411
4412 return Node;
4413}();
4414
4415pp$4.startNode = function () {
4416 return new Node(this.state.start, this.state.startLoc, this.filename);
4417};
4418
4419pp$4.startNodeAt = function (pos, loc) {
4420 return new Node(pos, loc, this.filename);
4421};
4422
4423function finishNodeAt(node, type, pos, loc) {
4424 node.type = type;
4425 node.end = pos;
4426 node.loc.end = loc;
4427 this.processComment(node);
4428 return node;
4429}
4430
4431// Finish an AST node, adding `type` and `end` properties.
4432
4433pp$4.finishNode = function (node, type) {
4434 return finishNodeAt.call(this, node, type, this.state.lastTokEnd, this.state.lastTokEndLoc);
4435};
4436
4437// Finish node at given position
4438
4439pp$4.finishNodeAt = function (node, type, pos, loc) {
4440 return finishNodeAt.call(this, node, type, pos, loc);
4441};
4442
4443var pp$5 = Parser.prototype;
4444
4445// This function is used to raise exceptions on parse errors. It
4446// takes an offset integer (into the current `input`) to indicate
4447// the location of the error, attaches the position to the end
4448// of the error message, and then raises a `SyntaxError` with that
4449// message.
4450
4451pp$5.raise = function (pos, message) {
4452 var loc = getLineInfo(this.input, pos);
4453 message += " (" + loc.line + ":" + loc.column + ")";
4454 var err = new SyntaxError(message);
4455 err.pos = pos;
4456 err.loc = loc;
4457 throw err;
4458};
4459
4460/* eslint max-len: 0 */
4461
4462/**
4463 * Based on the comment attachment algorithm used in espree and estraverse.
4464 *
4465 * Redistribution and use in source and binary forms, with or without
4466 * modification, are permitted provided that the following conditions are met:
4467 *
4468 * * Redistributions of source code must retain the above copyright
4469 * notice, this list of conditions and the following disclaimer.
4470 * * Redistributions in binary form must reproduce the above copyright
4471 * notice, this list of conditions and the following disclaimer in the
4472 * documentation and/or other materials provided with the distribution.
4473 *
4474 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
4475 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4476 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4477 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
4478 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4479 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4480 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4481 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4482 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
4483 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4484 */
4485
4486function last(stack) {
4487 return stack[stack.length - 1];
4488}
4489
4490var pp$6 = Parser.prototype;
4491
4492pp$6.addComment = function (comment) {
4493 if (this.filename) comment.loc.filename = this.filename;
4494 this.state.trailingComments.push(comment);
4495 this.state.leadingComments.push(comment);
4496};
4497
4498pp$6.processComment = function (node) {
4499 if (node.type === "Program" && node.body.length > 0) return;
4500
4501 var stack = this.state.commentStack;
4502
4503 var firstChild = void 0,
4504 lastChild = void 0,
4505 trailingComments = void 0,
4506 i = void 0,
4507 j = void 0;
4508
4509 if (this.state.trailingComments.length > 0) {
4510 // If the first comment in trailingComments comes after the
4511 // current node, then we're good - all comments in the array will
4512 // come after the node and so it's safe to add them as official
4513 // trailingComments.
4514 if (this.state.trailingComments[0].start >= node.end) {
4515 trailingComments = this.state.trailingComments;
4516 this.state.trailingComments = [];
4517 } else {
4518 // Otherwise, if the first comment doesn't come after the
4519 // current node, that means we have a mix of leading and trailing
4520 // comments in the array and that leadingComments contains the
4521 // same items as trailingComments. Reset trailingComments to
4522 // zero items and we'll handle this by evaluating leadingComments
4523 // later.
4524 this.state.trailingComments.length = 0;
4525 }
4526 } else {
4527 var lastInStack = last(stack);
4528 if (stack.length > 0 && lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) {
4529 trailingComments = lastInStack.trailingComments;
4530 lastInStack.trailingComments = null;
4531 }
4532 }
4533
4534 // Eating the stack.
4535 if (stack.length > 0 && last(stack).start >= node.start) {
4536 firstChild = stack.pop();
4537 }
4538
4539 while (stack.length > 0 && last(stack).start >= node.start) {
4540 lastChild = stack.pop();
4541 }
4542
4543 if (!lastChild && firstChild) lastChild = firstChild;
4544
4545 // Attach comments that follow a trailing comma on the last
4546 // property in an object literal or a trailing comma in function arguments
4547 // as trailing comments
4548 if (firstChild && this.state.leadingComments.length > 0) {
4549 var lastComment = last(this.state.leadingComments);
4550
4551 if (firstChild.type === "ObjectProperty") {
4552 if (lastComment.start >= node.start) {
4553 if (this.state.commentPreviousNode) {
4554 for (j = 0; j < this.state.leadingComments.length; j++) {
4555 if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) {
4556 this.state.leadingComments.splice(j, 1);
4557 j--;
4558 }
4559 }
4560
4561 if (this.state.leadingComments.length > 0) {
4562 firstChild.trailingComments = this.state.leadingComments;
4563 this.state.leadingComments = [];
4564 }
4565 }
4566 }
4567 } else if (node.type === "CallExpression" && node.arguments && node.arguments.length) {
4568 var lastArg = last(node.arguments);
4569
4570 if (lastArg && lastComment.start >= lastArg.start && lastComment.end <= node.end) {
4571 if (this.state.commentPreviousNode) {
4572 if (this.state.leadingComments.length > 0) {
4573 lastArg.trailingComments = this.state.leadingComments;
4574 this.state.leadingComments = [];
4575 }
4576 }
4577 }
4578 }
4579 }
4580
4581 if (lastChild) {
4582 if (lastChild.leadingComments) {
4583 if (lastChild !== node && last(lastChild.leadingComments).end <= node.start) {
4584 node.leadingComments = lastChild.leadingComments;
4585 lastChild.leadingComments = null;
4586 } else {
4587 // A leading comment for an anonymous class had been stolen by its first ClassMethod,
4588 // so this takes back the leading comment.
4589 // See also: https://github.com/eslint/espree/issues/158
4590 for (i = lastChild.leadingComments.length - 2; i >= 0; --i) {
4591 if (lastChild.leadingComments[i].end <= node.start) {
4592 node.leadingComments = lastChild.leadingComments.splice(0, i + 1);
4593 break;
4594 }
4595 }
4596 }
4597 }
4598 } else if (this.state.leadingComments.length > 0) {
4599 if (last(this.state.leadingComments).end <= node.start) {
4600 if (this.state.commentPreviousNode) {
4601 for (j = 0; j < this.state.leadingComments.length; j++) {
4602 if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) {
4603 this.state.leadingComments.splice(j, 1);
4604 j--;
4605 }
4606 }
4607 }
4608 if (this.state.leadingComments.length > 0) {
4609 node.leadingComments = this.state.leadingComments;
4610 this.state.leadingComments = [];
4611 }
4612 } else {
4613 // https://github.com/eslint/espree/issues/2
4614 //
4615 // In special cases, such as return (without a value) and
4616 // debugger, all comments will end up as leadingComments and
4617 // will otherwise be eliminated. This step runs when the
4618 // commentStack is empty and there are comments left
4619 // in leadingComments.
4620 //
4621 // This loop figures out the stopping point between the actual
4622 // leading and trailing comments by finding the location of the
4623 // first comment that comes after the given node.
4624 for (i = 0; i < this.state.leadingComments.length; i++) {
4625 if (this.state.leadingComments[i].end > node.start) {
4626 break;
4627 }
4628 }
4629
4630 // Split the array based on the location of the first comment
4631 // that comes after the node. Keep in mind that this could
4632 // result in an empty array, and if so, the array must be
4633 // deleted.
4634 node.leadingComments = this.state.leadingComments.slice(0, i);
4635 if (node.leadingComments.length === 0) {
4636 node.leadingComments = null;
4637 }
4638
4639 // Similarly, trailing comments are attached later. The variable
4640 // must be reset to null if there are no trailing comments.
4641 trailingComments = this.state.leadingComments.slice(i);
4642 if (trailingComments.length === 0) {
4643 trailingComments = null;
4644 }
4645 }
4646 }
4647
4648 this.state.commentPreviousNode = node;
4649
4650 if (trailingComments) {
4651 if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) {
4652 node.innerComments = trailingComments;
4653 } else {
4654 node.trailingComments = trailingComments;
4655 }
4656 }
4657
4658 stack.push(node);
4659};
4660
4661var pp$7 = Parser.prototype;
4662
4663pp$7.estreeParseRegExpLiteral = function (_ref) {
4664 var pattern = _ref.pattern,
4665 flags = _ref.flags;
4666
4667 var regex = null;
4668 try {
4669 regex = new RegExp(pattern, flags);
4670 } catch (e) {
4671 // In environments that don't support these flags value will
4672 // be null as the regex can't be represented natively.
4673 }
4674 var node = this.estreeParseLiteral(regex);
4675 node.regex = { pattern: pattern, flags: flags };
4676
4677 return node;
4678};
4679
4680pp$7.estreeParseLiteral = function (value) {
4681 return this.parseLiteral(value, "Literal");
4682};
4683
4684pp$7.directiveToStmt = function (directive) {
4685 var directiveLiteral = directive.value;
4686
4687 var stmt = this.startNodeAt(directive.start, directive.loc.start);
4688 var expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start);
4689
4690 expression.value = directiveLiteral.value;
4691 expression.raw = directiveLiteral.extra.raw;
4692
4693 stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end);
4694 stmt.directive = directiveLiteral.extra.raw.slice(1, -1);
4695
4696 return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end);
4697};
4698
4699function isSimpleProperty(node) {
4700 return node && node.type === "Property" && node.kind === "init" && node.method === false;
4701}
4702
4703var estreePlugin = function (instance) {
4704 instance.extend("checkDeclaration", function (inner) {
4705 return function (node) {
4706 if (isSimpleProperty(node)) {
4707 this.checkDeclaration(node.value);
4708 } else {
4709 inner.call(this, node);
4710 }
4711 };
4712 });
4713
4714 instance.extend("checkGetterSetterParamCount", function () {
4715 return function (prop) {
4716 var paramCount = prop.kind === "get" ? 0 : 1;
4717 if (prop.value.params.length !== paramCount) {
4718 var start = prop.start;
4719 if (prop.kind === "get") {
4720 this.raise(start, "getter should have no params");
4721 } else {
4722 this.raise(start, "setter should have exactly one param");
4723 }
4724 }
4725 };
4726 });
4727
4728 instance.extend("checkLVal", function (inner) {
4729 return function (expr, isBinding, checkClashes) {
4730 var _this = this;
4731
4732 switch (expr.type) {
4733 case "ObjectPattern":
4734 expr.properties.forEach(function (prop) {
4735 _this.checkLVal(prop.type === "Property" ? prop.value : prop, isBinding, checkClashes, "object destructuring pattern");
4736 });
4737 break;
4738 default:
4739 for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
4740 args[_key - 3] = arguments[_key];
4741 }
4742
4743 inner.call.apply(inner, [this, expr, isBinding, checkClashes].concat(args));
4744 }
4745 };
4746 });
4747
4748 instance.extend("checkPropClash", function () {
4749 return function (prop, propHash) {
4750 if (prop.computed || !isSimpleProperty(prop)) return;
4751
4752 var key = prop.key;
4753 // It is either an Identifier or a String/NumericLiteral
4754 var name = key.type === "Identifier" ? key.name : String(key.value);
4755
4756 if (name === "__proto__") {
4757 if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
4758 propHash.proto = true;
4759 }
4760 };
4761 });
4762
4763 instance.extend("isStrictBody", function () {
4764 return function (node, isExpression) {
4765 if (!isExpression && node.body.body.length > 0) {
4766 for (var _iterator = node.body.body, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
4767 var _ref2;
4768
4769 if (_isArray) {
4770 if (_i >= _iterator.length) break;
4771 _ref2 = _iterator[_i++];
4772 } else {
4773 _i = _iterator.next();
4774 if (_i.done) break;
4775 _ref2 = _i.value;
4776 }
4777
4778 var directive = _ref2;
4779
4780 if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") {
4781 if (directive.expression.value === "use strict") return true;
4782 } else {
4783 // Break for the first non literal expression
4784 break;
4785 }
4786 }
4787 }
4788
4789 return false;
4790 };
4791 });
4792
4793 instance.extend("isValidDirective", function () {
4794 return function (stmt) {
4795 return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && (!stmt.expression.extra || !stmt.expression.extra.parenthesized);
4796 };
4797 });
4798
4799 instance.extend("stmtToDirective", function (inner) {
4800 return function (stmt) {
4801 var directive = inner.call(this, stmt);
4802 var value = stmt.expression.value;
4803
4804 // Reset value to the actual value as in estree mode we want
4805 // the stmt to have the real value and not the raw value
4806 directive.value.value = value;
4807
4808 return directive;
4809 };
4810 });
4811
4812 instance.extend("parseBlockBody", function (inner) {
4813 return function (node) {
4814 var _this2 = this;
4815
4816 for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
4817 args[_key2 - 1] = arguments[_key2];
4818 }
4819
4820 inner.call.apply(inner, [this, node].concat(args));
4821
4822 node.directives.reverse().forEach(function (directive) {
4823 node.body.unshift(_this2.directiveToStmt(directive));
4824 });
4825 delete node.directives;
4826 };
4827 });
4828
4829 instance.extend("parseClassMethod", function () {
4830 return function (classBody, method, isGenerator, isAsync) {
4831 this.parseMethod(method, isGenerator, isAsync);
4832 if (method.typeParameters) {
4833 method.value.typeParameters = method.typeParameters;
4834 delete method.typeParameters;
4835 }
4836 classBody.body.push(this.finishNode(method, "MethodDefinition"));
4837 };
4838 });
4839
4840 instance.extend("parseExprAtom", function (inner) {
4841 return function () {
4842 switch (this.state.type) {
4843 case types.regexp:
4844 return this.estreeParseRegExpLiteral(this.state.value);
4845
4846 case types.num:
4847 case types.string:
4848 return this.estreeParseLiteral(this.state.value);
4849
4850 case types._null:
4851 return this.estreeParseLiteral(null);
4852
4853 case types._true:
4854 return this.estreeParseLiteral(true);
4855
4856 case types._false:
4857 return this.estreeParseLiteral(false);
4858
4859 default:
4860 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
4861 args[_key3] = arguments[_key3];
4862 }
4863
4864 return inner.call.apply(inner, [this].concat(args));
4865 }
4866 };
4867 });
4868
4869 instance.extend("parseLiteral", function (inner) {
4870 return function () {
4871 for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
4872 args[_key4] = arguments[_key4];
4873 }
4874
4875 var node = inner.call.apply(inner, [this].concat(args));
4876 node.raw = node.extra.raw;
4877 delete node.extra;
4878
4879 return node;
4880 };
4881 });
4882
4883 instance.extend("parseMethod", function (inner) {
4884 return function (node) {
4885 var funcNode = this.startNode();
4886 funcNode.kind = node.kind; // provide kind, so inner method correctly sets state
4887
4888 for (var _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
4889 args[_key5 - 1] = arguments[_key5];
4890 }
4891
4892 funcNode = inner.call.apply(inner, [this, funcNode].concat(args));
4893 delete funcNode.kind;
4894 node.value = this.finishNode(funcNode, "FunctionExpression");
4895
4896 return node;
4897 };
4898 });
4899
4900 instance.extend("parseObjectMethod", function (inner) {
4901 return function () {
4902 for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
4903 args[_key6] = arguments[_key6];
4904 }
4905
4906 var node = inner.call.apply(inner, [this].concat(args));
4907
4908 if (node) {
4909 if (node.kind === "method") node.kind = "init";
4910 node.type = "Property";
4911 }
4912
4913 return node;
4914 };
4915 });
4916
4917 instance.extend("parseObjectProperty", function (inner) {
4918 return function () {
4919 for (var _len7 = arguments.length, args = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
4920 args[_key7] = arguments[_key7];
4921 }
4922
4923 var node = inner.call.apply(inner, [this].concat(args));
4924
4925 if (node) {
4926 node.kind = "init";
4927 node.type = "Property";
4928 }
4929
4930 return node;
4931 };
4932 });
4933
4934 instance.extend("toAssignable", function (inner) {
4935 return function (node, isBinding) {
4936 for (var _len8 = arguments.length, args = Array(_len8 > 2 ? _len8 - 2 : 0), _key8 = 2; _key8 < _len8; _key8++) {
4937 args[_key8 - 2] = arguments[_key8];
4938 }
4939
4940 if (isSimpleProperty(node)) {
4941 this.toAssignable.apply(this, [node.value, isBinding].concat(args));
4942
4943 return node;
4944 } else if (node.type === "ObjectExpression") {
4945 node.type = "ObjectPattern";
4946 for (var _iterator2 = node.properties, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
4947 var _ref3;
4948
4949 if (_isArray2) {
4950 if (_i2 >= _iterator2.length) break;
4951 _ref3 = _iterator2[_i2++];
4952 } else {
4953 _i2 = _iterator2.next();
4954 if (_i2.done) break;
4955 _ref3 = _i2.value;
4956 }
4957
4958 var prop = _ref3;
4959
4960 if (prop.kind === "get" || prop.kind === "set") {
4961 this.raise(prop.key.start, "Object pattern can't contain getter or setter");
4962 } else if (prop.method) {
4963 this.raise(prop.key.start, "Object pattern can't contain methods");
4964 } else {
4965 this.toAssignable(prop, isBinding, "object destructuring pattern");
4966 }
4967 }
4968
4969 return node;
4970 }
4971
4972 return inner.call.apply(inner, [this, node, isBinding].concat(args));
4973 };
4974 });
4975};
4976
4977/* eslint max-len: 0 */
4978
4979var primitiveTypes = ["any", "mixed", "empty", "bool", "boolean", "number", "string", "void", "null"];
4980
4981var pp$8 = Parser.prototype;
4982
4983pp$8.flowParseTypeInitialiser = function (tok) {
4984 var oldInType = this.state.inType;
4985 this.state.inType = true;
4986 this.expect(tok || types.colon);
4987
4988 var type = this.flowParseType();
4989 this.state.inType = oldInType;
4990 return type;
4991};
4992
4993pp$8.flowParsePredicate = function () {
4994 var node = this.startNode();
4995 var moduloLoc = this.state.startLoc;
4996 var moduloPos = this.state.start;
4997 this.expect(types.modulo);
4998 var checksLoc = this.state.startLoc;
4999 this.expectContextual("checks");
5000 // Force '%' and 'checks' to be adjacent
5001 if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) {
5002 this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here.");
5003 }
5004 if (this.eat(types.parenL)) {
5005 node.expression = this.parseExpression();
5006 this.expect(types.parenR);
5007 return this.finishNode(node, "DeclaredPredicate");
5008 } else {
5009 return this.finishNode(node, "InferredPredicate");
5010 }
5011};
5012
5013pp$8.flowParseTypeAndPredicateInitialiser = function () {
5014 var oldInType = this.state.inType;
5015 this.state.inType = true;
5016 this.expect(types.colon);
5017 var type = null;
5018 var predicate = null;
5019 if (this.match(types.modulo)) {
5020 this.state.inType = oldInType;
5021 predicate = this.flowParsePredicate();
5022 } else {
5023 type = this.flowParseType();
5024 this.state.inType = oldInType;
5025 if (this.match(types.modulo)) {
5026 predicate = this.flowParsePredicate();
5027 }
5028 }
5029 return [type, predicate];
5030};
5031
5032pp$8.flowParseDeclareClass = function (node) {
5033 this.next();
5034 this.flowParseInterfaceish(node, true);
5035 return this.finishNode(node, "DeclareClass");
5036};
5037
5038pp$8.flowParseDeclareFunction = function (node) {
5039 this.next();
5040
5041 var id = node.id = this.parseIdentifier();
5042
5043 var typeNode = this.startNode();
5044 var typeContainer = this.startNode();
5045
5046 if (this.isRelational("<")) {
5047 typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
5048 } else {
5049 typeNode.typeParameters = null;
5050 }
5051
5052 this.expect(types.parenL);
5053 var tmp = this.flowParseFunctionTypeParams();
5054 typeNode.params = tmp.params;
5055 typeNode.rest = tmp.rest;
5056 this.expect(types.parenR);
5057 var predicate = null;
5058
5059 var _flowParseTypeAndPred = this.flowParseTypeAndPredicateInitialiser();
5060
5061 typeNode.returnType = _flowParseTypeAndPred[0];
5062 predicate = _flowParseTypeAndPred[1];
5063
5064 typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
5065 typeContainer.predicate = predicate;
5066 id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
5067
5068 this.finishNode(id, id.type);
5069
5070 this.semicolon();
5071
5072 return this.finishNode(node, "DeclareFunction");
5073};
5074
5075pp$8.flowParseDeclare = function (node) {
5076 if (this.match(types._class)) {
5077 return this.flowParseDeclareClass(node);
5078 } else if (this.match(types._function)) {
5079 return this.flowParseDeclareFunction(node);
5080 } else if (this.match(types._var)) {
5081 return this.flowParseDeclareVariable(node);
5082 } else if (this.isContextual("module")) {
5083 if (this.lookahead().type === types.dot) {
5084 return this.flowParseDeclareModuleExports(node);
5085 } else {
5086 return this.flowParseDeclareModule(node);
5087 }
5088 } else if (this.isContextual("type")) {
5089 return this.flowParseDeclareTypeAlias(node);
5090 } else if (this.isContextual("opaque")) {
5091 return this.flowParseDeclareOpaqueType(node);
5092 } else if (this.isContextual("interface")) {
5093 return this.flowParseDeclareInterface(node);
5094 } else if (this.match(types._export)) {
5095 return this.flowParseDeclareExportDeclaration(node);
5096 } else {
5097 this.unexpected();
5098 }
5099};
5100
5101pp$8.flowParseDeclareExportDeclaration = function (node) {
5102 this.expect(types._export);
5103 if (this.isContextual("opaque") // declare export opaque ...
5104 ) {
5105 node.declaration = this.flowParseDeclare(this.startNode());
5106 node.default = false;
5107
5108 return this.finishNode(node, "DeclareExportDeclaration");
5109 }
5110
5111 throw this.unexpected();
5112};
5113
5114pp$8.flowParseDeclareVariable = function (node) {
5115 this.next();
5116 node.id = this.flowParseTypeAnnotatableIdentifier();
5117 this.semicolon();
5118 return this.finishNode(node, "DeclareVariable");
5119};
5120
5121pp$8.flowParseDeclareModule = function (node) {
5122 this.next();
5123
5124 if (this.match(types.string)) {
5125 node.id = this.parseExprAtom();
5126 } else {
5127 node.id = this.parseIdentifier();
5128 }
5129
5130 var bodyNode = node.body = this.startNode();
5131 var body = bodyNode.body = [];
5132 this.expect(types.braceL);
5133 while (!this.match(types.braceR)) {
5134 var _bodyNode = this.startNode();
5135
5136 if (this.match(types._import)) {
5137 var lookahead = this.lookahead();
5138 if (lookahead.value !== "type" && lookahead.value !== "typeof") {
5139 this.unexpected(null, "Imports within a `declare module` body must always be `import type` or `import typeof`");
5140 }
5141
5142 this.parseImport(_bodyNode);
5143 } else {
5144 this.expectContextual("declare", "Only declares and type imports are allowed inside declare module");
5145
5146 _bodyNode = this.flowParseDeclare(_bodyNode, true);
5147 }
5148
5149 body.push(_bodyNode);
5150 }
5151 this.expect(types.braceR);
5152
5153 this.finishNode(bodyNode, "BlockStatement");
5154 return this.finishNode(node, "DeclareModule");
5155};
5156
5157pp$8.flowParseDeclareModuleExports = function (node) {
5158 this.expectContextual("module");
5159 this.expect(types.dot);
5160 this.expectContextual("exports");
5161 node.typeAnnotation = this.flowParseTypeAnnotation();
5162 this.semicolon();
5163
5164 return this.finishNode(node, "DeclareModuleExports");
5165};
5166
5167pp$8.flowParseDeclareTypeAlias = function (node) {
5168 this.next();
5169 this.flowParseTypeAlias(node);
5170 return this.finishNode(node, "DeclareTypeAlias");
5171};
5172
5173pp$8.flowParseDeclareOpaqueType = function (node) {
5174 this.next();
5175 this.flowParseOpaqueType(node, true);
5176 return this.finishNode(node, "DeclareOpaqueType");
5177};
5178
5179pp$8.flowParseDeclareInterface = function (node) {
5180 this.next();
5181 this.flowParseInterfaceish(node);
5182 return this.finishNode(node, "DeclareInterface");
5183};
5184
5185// Interfaces
5186
5187pp$8.flowParseInterfaceish = function (node) {
5188 node.id = this.parseIdentifier();
5189
5190 if (this.isRelational("<")) {
5191 node.typeParameters = this.flowParseTypeParameterDeclaration();
5192 } else {
5193 node.typeParameters = null;
5194 }
5195
5196 node.extends = [];
5197 node.mixins = [];
5198
5199 if (this.eat(types._extends)) {
5200 do {
5201 node.extends.push(this.flowParseInterfaceExtends());
5202 } while (this.eat(types.comma));
5203 }
5204
5205 if (this.isContextual("mixins")) {
5206 this.next();
5207 do {
5208 node.mixins.push(this.flowParseInterfaceExtends());
5209 } while (this.eat(types.comma));
5210 }
5211
5212 node.body = this.flowParseObjectType(true, false, false);
5213};
5214
5215pp$8.flowParseInterfaceExtends = function () {
5216 var node = this.startNode();
5217
5218 node.id = this.flowParseQualifiedTypeIdentifier();
5219 if (this.isRelational("<")) {
5220 node.typeParameters = this.flowParseTypeParameterInstantiation();
5221 } else {
5222 node.typeParameters = null;
5223 }
5224
5225 return this.finishNode(node, "InterfaceExtends");
5226};
5227
5228pp$8.flowParseInterface = function (node) {
5229 this.flowParseInterfaceish(node, false);
5230 return this.finishNode(node, "InterfaceDeclaration");
5231};
5232
5233pp$8.flowParseRestrictedIdentifier = function (liberal) {
5234 if (primitiveTypes.indexOf(this.state.value) > -1) {
5235 this.raise(this.state.start, "Cannot overwrite primitive type " + this.state.value);
5236 }
5237
5238 return this.parseIdentifier(liberal);
5239};
5240
5241// Type aliases
5242
5243pp$8.flowParseTypeAlias = function (node) {
5244 node.id = this.flowParseRestrictedIdentifier();
5245
5246 if (this.isRelational("<")) {
5247 node.typeParameters = this.flowParseTypeParameterDeclaration();
5248 } else {
5249 node.typeParameters = null;
5250 }
5251
5252 node.right = this.flowParseTypeInitialiser(types.eq);
5253 this.semicolon();
5254
5255 return this.finishNode(node, "TypeAlias");
5256};
5257
5258// Opaque type aliases
5259
5260pp$8.flowParseOpaqueType = function (node, declare) {
5261 this.expectContextual("type");
5262 node.id = this.flowParseRestrictedIdentifier();
5263
5264 if (this.isRelational("<")) {
5265 node.typeParameters = this.flowParseTypeParameterDeclaration();
5266 } else {
5267 node.typeParameters = null;
5268 }
5269
5270 // Parse the supertype
5271 node.supertype = null;
5272 if (this.match(types.colon)) {
5273 node.supertype = this.flowParseTypeInitialiser(types.colon);
5274 }
5275
5276 node.impltype = null;
5277 if (!declare) {
5278 node.impltype = this.flowParseTypeInitialiser(types.eq);
5279 }
5280 this.semicolon();
5281
5282 return this.finishNode(node, "OpaqueType");
5283};
5284
5285// Type annotations
5286
5287pp$8.flowParseTypeParameter = function () {
5288 var node = this.startNode();
5289
5290 var variance = this.flowParseVariance();
5291
5292 var ident = this.flowParseTypeAnnotatableIdentifier();
5293 node.name = ident.name;
5294 node.variance = variance;
5295 node.bound = ident.typeAnnotation;
5296
5297 if (this.match(types.eq)) {
5298 this.eat(types.eq);
5299 node.default = this.flowParseType();
5300 }
5301
5302 return this.finishNode(node, "TypeParameter");
5303};
5304
5305pp$8.flowParseTypeParameterDeclaration = function () {
5306 var oldInType = this.state.inType;
5307 var node = this.startNode();
5308 node.params = [];
5309
5310 this.state.inType = true;
5311
5312 // istanbul ignore else: this condition is already checked at all call sites
5313 if (this.isRelational("<") || this.match(types.jsxTagStart)) {
5314 this.next();
5315 } else {
5316 this.unexpected();
5317 }
5318
5319 do {
5320 node.params.push(this.flowParseTypeParameter());
5321 if (!this.isRelational(">")) {
5322 this.expect(types.comma);
5323 }
5324 } while (!this.isRelational(">"));
5325 this.expectRelational(">");
5326
5327 this.state.inType = oldInType;
5328
5329 return this.finishNode(node, "TypeParameterDeclaration");
5330};
5331
5332pp$8.flowParseTypeParameterInstantiation = function () {
5333 var node = this.startNode();
5334 var oldInType = this.state.inType;
5335 node.params = [];
5336
5337 this.state.inType = true;
5338
5339 this.expectRelational("<");
5340 while (!this.isRelational(">")) {
5341 node.params.push(this.flowParseType());
5342 if (!this.isRelational(">")) {
5343 this.expect(types.comma);
5344 }
5345 }
5346 this.expectRelational(">");
5347
5348 this.state.inType = oldInType;
5349
5350 return this.finishNode(node, "TypeParameterInstantiation");
5351};
5352
5353pp$8.flowParseObjectPropertyKey = function () {
5354 return this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true);
5355};
5356
5357pp$8.flowParseObjectTypeIndexer = function (node, isStatic, variance) {
5358 node.static = isStatic;
5359
5360 this.expect(types.bracketL);
5361 if (this.lookahead().type === types.colon) {
5362 node.id = this.flowParseObjectPropertyKey();
5363 node.key = this.flowParseTypeInitialiser();
5364 } else {
5365 node.id = null;
5366 node.key = this.flowParseType();
5367 }
5368 this.expect(types.bracketR);
5369 node.value = this.flowParseTypeInitialiser();
5370 node.variance = variance;
5371
5372 this.flowObjectTypeSemicolon();
5373 return this.finishNode(node, "ObjectTypeIndexer");
5374};
5375
5376pp$8.flowParseObjectTypeMethodish = function (node) {
5377 node.params = [];
5378 node.rest = null;
5379 node.typeParameters = null;
5380
5381 if (this.isRelational("<")) {
5382 node.typeParameters = this.flowParseTypeParameterDeclaration();
5383 }
5384
5385 this.expect(types.parenL);
5386 while (!this.match(types.parenR) && !this.match(types.ellipsis)) {
5387 node.params.push(this.flowParseFunctionTypeParam());
5388 if (!this.match(types.parenR)) {
5389 this.expect(types.comma);
5390 }
5391 }
5392
5393 if (this.eat(types.ellipsis)) {
5394 node.rest = this.flowParseFunctionTypeParam();
5395 }
5396 this.expect(types.parenR);
5397 node.returnType = this.flowParseTypeInitialiser();
5398
5399 return this.finishNode(node, "FunctionTypeAnnotation");
5400};
5401
5402pp$8.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) {
5403 var node = this.startNodeAt(startPos, startLoc);
5404 node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(startPos, startLoc));
5405 node.static = isStatic;
5406 node.key = key;
5407 node.optional = false;
5408 this.flowObjectTypeSemicolon();
5409 return this.finishNode(node, "ObjectTypeProperty");
5410};
5411
5412pp$8.flowParseObjectTypeCallProperty = function (node, isStatic) {
5413 var valueNode = this.startNode();
5414 node.static = isStatic;
5415 node.value = this.flowParseObjectTypeMethodish(valueNode);
5416 this.flowObjectTypeSemicolon();
5417 return this.finishNode(node, "ObjectTypeCallProperty");
5418};
5419
5420pp$8.flowParseObjectType = function (allowStatic, allowExact, allowSpread) {
5421 var oldInType = this.state.inType;
5422 this.state.inType = true;
5423
5424 var nodeStart = this.startNode();
5425 var node = void 0;
5426 var propertyKey = void 0;
5427 var isStatic = false;
5428
5429 nodeStart.callProperties = [];
5430 nodeStart.properties = [];
5431 nodeStart.indexers = [];
5432
5433 var endDelim = void 0;
5434 var exact = void 0;
5435 if (allowExact && this.match(types.braceBarL)) {
5436 this.expect(types.braceBarL);
5437 endDelim = types.braceBarR;
5438 exact = true;
5439 } else {
5440 this.expect(types.braceL);
5441 endDelim = types.braceR;
5442 exact = false;
5443 }
5444
5445 nodeStart.exact = exact;
5446
5447 while (!this.match(endDelim)) {
5448 var optional = false;
5449 var startPos = this.state.start;
5450 var startLoc = this.state.startLoc;
5451 node = this.startNode();
5452 if (allowStatic && this.isContextual("static") && this.lookahead().type !== types.colon) {
5453 this.next();
5454 isStatic = true;
5455 }
5456
5457 var variancePos = this.state.start;
5458 var variance = this.flowParseVariance();
5459
5460 if (this.match(types.bracketL)) {
5461 nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance));
5462 } else if (this.match(types.parenL) || this.isRelational("<")) {
5463 if (variance) {
5464 this.unexpected(variancePos);
5465 }
5466 nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic));
5467 } else {
5468 if (this.match(types.ellipsis)) {
5469 if (!allowSpread) {
5470 this.unexpected(null, "Spread operator cannot appear in class or interface definitions");
5471 }
5472 if (variance) {
5473 this.unexpected(variance.start, "Spread properties cannot have variance");
5474 }
5475 this.expect(types.ellipsis);
5476 node.argument = this.flowParseType();
5477 this.flowObjectTypeSemicolon();
5478 nodeStart.properties.push(this.finishNode(node, "ObjectTypeSpreadProperty"));
5479 } else {
5480 propertyKey = this.flowParseObjectPropertyKey();
5481 if (this.isRelational("<") || this.match(types.parenL)) {
5482 // This is a method property
5483 if (variance) {
5484 this.unexpected(variance.start);
5485 }
5486 nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey));
5487 } else {
5488 if (this.eat(types.question)) {
5489 optional = true;
5490 }
5491 node.key = propertyKey;
5492 node.value = this.flowParseTypeInitialiser();
5493 node.optional = optional;
5494 node.static = isStatic;
5495 node.variance = variance;
5496 this.flowObjectTypeSemicolon();
5497 nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty"));
5498 }
5499 }
5500 }
5501
5502 isStatic = false;
5503 }
5504
5505 this.expect(endDelim);
5506
5507 var out = this.finishNode(nodeStart, "ObjectTypeAnnotation");
5508
5509 this.state.inType = oldInType;
5510
5511 return out;
5512};
5513
5514pp$8.flowObjectTypeSemicolon = function () {
5515 if (!this.eat(types.semi) && !this.eat(types.comma) && !this.match(types.braceR) && !this.match(types.braceBarR)) {
5516 this.unexpected();
5517 }
5518};
5519
5520pp$8.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) {
5521 startPos = startPos || this.state.start;
5522 startLoc = startLoc || this.state.startLoc;
5523 var node = id || this.parseIdentifier();
5524
5525 while (this.eat(types.dot)) {
5526 var node2 = this.startNodeAt(startPos, startLoc);
5527 node2.qualification = node;
5528 node2.id = this.parseIdentifier();
5529 node = this.finishNode(node2, "QualifiedTypeIdentifier");
5530 }
5531
5532 return node;
5533};
5534
5535pp$8.flowParseGenericType = function (startPos, startLoc, id) {
5536 var node = this.startNodeAt(startPos, startLoc);
5537
5538 node.typeParameters = null;
5539 node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id);
5540
5541 if (this.isRelational("<")) {
5542 node.typeParameters = this.flowParseTypeParameterInstantiation();
5543 }
5544
5545 return this.finishNode(node, "GenericTypeAnnotation");
5546};
5547
5548pp$8.flowParseTypeofType = function () {
5549 var node = this.startNode();
5550 this.expect(types._typeof);
5551 node.argument = this.flowParsePrimaryType();
5552 return this.finishNode(node, "TypeofTypeAnnotation");
5553};
5554
5555pp$8.flowParseTupleType = function () {
5556 var node = this.startNode();
5557 node.types = [];
5558 this.expect(types.bracketL);
5559 // We allow trailing commas
5560 while (this.state.pos < this.input.length && !this.match(types.bracketR)) {
5561 node.types.push(this.flowParseType());
5562 if (this.match(types.bracketR)) break;
5563 this.expect(types.comma);
5564 }
5565 this.expect(types.bracketR);
5566 return this.finishNode(node, "TupleTypeAnnotation");
5567};
5568
5569pp$8.flowParseFunctionTypeParam = function () {
5570 var name = null;
5571 var optional = false;
5572 var typeAnnotation = null;
5573 var node = this.startNode();
5574 var lh = this.lookahead();
5575 if (lh.type === types.colon || lh.type === types.question) {
5576 name = this.parseIdentifier();
5577 if (this.eat(types.question)) {
5578 optional = true;
5579 }
5580 typeAnnotation = this.flowParseTypeInitialiser();
5581 } else {
5582 typeAnnotation = this.flowParseType();
5583 }
5584 node.name = name;
5585 node.optional = optional;
5586 node.typeAnnotation = typeAnnotation;
5587 return this.finishNode(node, "FunctionTypeParam");
5588};
5589
5590pp$8.reinterpretTypeAsFunctionTypeParam = function (type) {
5591 var node = this.startNodeAt(type.start, type.loc.start);
5592 node.name = null;
5593 node.optional = false;
5594 node.typeAnnotation = type;
5595 return this.finishNode(node, "FunctionTypeParam");
5596};
5597
5598pp$8.flowParseFunctionTypeParams = function () {
5599 var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5600
5601 var ret = { params: params, rest: null };
5602 while (!this.match(types.parenR) && !this.match(types.ellipsis)) {
5603 ret.params.push(this.flowParseFunctionTypeParam());
5604 if (!this.match(types.parenR)) {
5605 this.expect(types.comma);
5606 }
5607 }
5608 if (this.eat(types.ellipsis)) {
5609 ret.rest = this.flowParseFunctionTypeParam();
5610 }
5611 return ret;
5612};
5613
5614pp$8.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) {
5615 switch (id.name) {
5616 case "any":
5617 return this.finishNode(node, "AnyTypeAnnotation");
5618
5619 case "void":
5620 return this.finishNode(node, "VoidTypeAnnotation");
5621
5622 case "bool":
5623 case "boolean":
5624 return this.finishNode(node, "BooleanTypeAnnotation");
5625
5626 case "mixed":
5627 return this.finishNode(node, "MixedTypeAnnotation");
5628
5629 case "empty":
5630 return this.finishNode(node, "EmptyTypeAnnotation");
5631
5632 case "number":
5633 return this.finishNode(node, "NumberTypeAnnotation");
5634
5635 case "string":
5636 return this.finishNode(node, "StringTypeAnnotation");
5637
5638 default:
5639 return this.flowParseGenericType(startPos, startLoc, id);
5640 }
5641};
5642
5643// The parsing of types roughly parallels the parsing of expressions, and
5644// primary types are kind of like primary expressions...they're the
5645// primitives with which other types are constructed.
5646pp$8.flowParsePrimaryType = function () {
5647 var startPos = this.state.start;
5648 var startLoc = this.state.startLoc;
5649 var node = this.startNode();
5650 var tmp = void 0;
5651 var type = void 0;
5652 var isGroupedType = false;
5653 var oldNoAnonFunctionType = this.state.noAnonFunctionType;
5654
5655 switch (this.state.type) {
5656 case types.name:
5657 return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier());
5658
5659 case types.braceL:
5660 return this.flowParseObjectType(false, false, true);
5661
5662 case types.braceBarL:
5663 return this.flowParseObjectType(false, true, true);
5664
5665 case types.bracketL:
5666 return this.flowParseTupleType();
5667
5668 case types.relational:
5669 if (this.state.value === "<") {
5670 node.typeParameters = this.flowParseTypeParameterDeclaration();
5671 this.expect(types.parenL);
5672 tmp = this.flowParseFunctionTypeParams();
5673 node.params = tmp.params;
5674 node.rest = tmp.rest;
5675 this.expect(types.parenR);
5676
5677 this.expect(types.arrow);
5678
5679 node.returnType = this.flowParseType();
5680
5681 return this.finishNode(node, "FunctionTypeAnnotation");
5682 }
5683 break;
5684
5685 case types.parenL:
5686 this.next();
5687
5688 // Check to see if this is actually a grouped type
5689 if (!this.match(types.parenR) && !this.match(types.ellipsis)) {
5690 if (this.match(types.name)) {
5691 var token = this.lookahead().type;
5692 isGroupedType = token !== types.question && token !== types.colon;
5693 } else {
5694 isGroupedType = true;
5695 }
5696 }
5697
5698 if (isGroupedType) {
5699 this.state.noAnonFunctionType = false;
5700 type = this.flowParseType();
5701 this.state.noAnonFunctionType = oldNoAnonFunctionType;
5702
5703 // A `,` or a `) =>` means this is an anonymous function type
5704 if (this.state.noAnonFunctionType || !(this.match(types.comma) || this.match(types.parenR) && this.lookahead().type === types.arrow)) {
5705 this.expect(types.parenR);
5706 return type;
5707 } else {
5708 // Eat a comma if there is one
5709 this.eat(types.comma);
5710 }
5711 }
5712
5713 if (type) {
5714 tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]);
5715 } else {
5716 tmp = this.flowParseFunctionTypeParams();
5717 }
5718
5719 node.params = tmp.params;
5720 node.rest = tmp.rest;
5721
5722 this.expect(types.parenR);
5723
5724 this.expect(types.arrow);
5725
5726 node.returnType = this.flowParseType();
5727
5728 node.typeParameters = null;
5729
5730 return this.finishNode(node, "FunctionTypeAnnotation");
5731
5732 case types.string:
5733 return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation");
5734
5735 case types._true:case types._false:
5736 node.value = this.match(types._true);
5737 this.next();
5738 return this.finishNode(node, "BooleanLiteralTypeAnnotation");
5739
5740 case types.plusMin:
5741 if (this.state.value === "-") {
5742 this.next();
5743 if (!this.match(types.num)) this.unexpected(null, "Unexpected token, expected number");
5744
5745 return this.parseLiteral(-this.state.value, "NumericLiteralTypeAnnotation", node.start, node.loc.start);
5746 }
5747
5748 this.unexpected();
5749 case types.num:
5750 return this.parseLiteral(this.state.value, "NumericLiteralTypeAnnotation");
5751
5752 case types._null:
5753 node.value = this.match(types._null);
5754 this.next();
5755 return this.finishNode(node, "NullLiteralTypeAnnotation");
5756
5757 case types._this:
5758 node.value = this.match(types._this);
5759 this.next();
5760 return this.finishNode(node, "ThisTypeAnnotation");
5761
5762 case types.star:
5763 this.next();
5764 return this.finishNode(node, "ExistentialTypeParam");
5765
5766 default:
5767 if (this.state.type.keyword === "typeof") {
5768 return this.flowParseTypeofType();
5769 }
5770 }
5771
5772 this.unexpected();
5773};
5774
5775pp$8.flowParsePostfixType = function () {
5776 var startPos = this.state.start,
5777 startLoc = this.state.startLoc;
5778 var type = this.flowParsePrimaryType();
5779 while (!this.canInsertSemicolon() && this.match(types.bracketL)) {
5780 var node = this.startNodeAt(startPos, startLoc);
5781 node.elementType = type;
5782 this.expect(types.bracketL);
5783 this.expect(types.bracketR);
5784 type = this.finishNode(node, "ArrayTypeAnnotation");
5785 }
5786 return type;
5787};
5788
5789pp$8.flowParsePrefixType = function () {
5790 var node = this.startNode();
5791 if (this.eat(types.question)) {
5792 node.typeAnnotation = this.flowParsePrefixType();
5793 return this.finishNode(node, "NullableTypeAnnotation");
5794 } else {
5795 return this.flowParsePostfixType();
5796 }
5797};
5798
5799pp$8.flowParseAnonFunctionWithoutParens = function () {
5800 var param = this.flowParsePrefixType();
5801 if (!this.state.noAnonFunctionType && this.eat(types.arrow)) {
5802 var node = this.startNodeAt(param.start, param.loc.start);
5803 node.params = [this.reinterpretTypeAsFunctionTypeParam(param)];
5804 node.rest = null;
5805 node.returnType = this.flowParseType();
5806 node.typeParameters = null;
5807 return this.finishNode(node, "FunctionTypeAnnotation");
5808 }
5809 return param;
5810};
5811
5812pp$8.flowParseIntersectionType = function () {
5813 var node = this.startNode();
5814 this.eat(types.bitwiseAND);
5815 var type = this.flowParseAnonFunctionWithoutParens();
5816 node.types = [type];
5817 while (this.eat(types.bitwiseAND)) {
5818 node.types.push(this.flowParseAnonFunctionWithoutParens());
5819 }
5820 return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
5821};
5822
5823pp$8.flowParseUnionType = function () {
5824 var node = this.startNode();
5825 this.eat(types.bitwiseOR);
5826 var type = this.flowParseIntersectionType();
5827 node.types = [type];
5828 while (this.eat(types.bitwiseOR)) {
5829 node.types.push(this.flowParseIntersectionType());
5830 }
5831 return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
5832};
5833
5834pp$8.flowParseType = function () {
5835 var oldInType = this.state.inType;
5836 this.state.inType = true;
5837 var type = this.flowParseUnionType();
5838 this.state.inType = oldInType;
5839 return type;
5840};
5841
5842pp$8.flowParseTypeAnnotation = function () {
5843 var node = this.startNode();
5844 node.typeAnnotation = this.flowParseTypeInitialiser();
5845 return this.finishNode(node, "TypeAnnotation");
5846};
5847
5848pp$8.flowParseTypeAndPredicateAnnotation = function () {
5849 var node = this.startNode();
5850
5851 var _flowParseTypeAndPred2 = this.flowParseTypeAndPredicateInitialiser();
5852
5853 node.typeAnnotation = _flowParseTypeAndPred2[0];
5854 node.predicate = _flowParseTypeAndPred2[1];
5855
5856 return this.finishNode(node, "TypeAnnotation");
5857};
5858
5859pp$8.flowParseTypeAnnotatableIdentifier = function () {
5860 var ident = this.flowParseRestrictedIdentifier();
5861 if (this.match(types.colon)) {
5862 ident.typeAnnotation = this.flowParseTypeAnnotation();
5863 this.finishNode(ident, ident.type);
5864 }
5865 return ident;
5866};
5867
5868pp$8.typeCastToParameter = function (node) {
5869 node.expression.typeAnnotation = node.typeAnnotation;
5870
5871 return this.finishNodeAt(node.expression, node.expression.type, node.typeAnnotation.end, node.typeAnnotation.loc.end);
5872};
5873
5874pp$8.flowParseVariance = function () {
5875 var variance = null;
5876 if (this.match(types.plusMin)) {
5877 if (this.state.value === "+") {
5878 variance = "plus";
5879 } else if (this.state.value === "-") {
5880 variance = "minus";
5881 }
5882 this.next();
5883 }
5884 return variance;
5885};
5886
5887var flowPlugin = function (instance) {
5888 // plain function return types: function name(): string {}
5889 instance.extend("parseFunctionBody", function (inner) {
5890 return function (node, allowExpression) {
5891 if (this.match(types.colon) && !allowExpression) {
5892 // if allowExpression is true then we're parsing an arrow function and if
5893 // there's a return type then it's been handled elsewhere
5894 node.returnType = this.flowParseTypeAndPredicateAnnotation();
5895 }
5896
5897 return inner.call(this, node, allowExpression);
5898 };
5899 });
5900
5901 // interfaces
5902 instance.extend("parseStatement", function (inner) {
5903 return function (declaration, topLevel) {
5904 // strict mode handling of `interface` since it's a reserved word
5905 if (this.state.strict && this.match(types.name) && this.state.value === "interface") {
5906 var node = this.startNode();
5907 this.next();
5908 return this.flowParseInterface(node);
5909 } else {
5910 return inner.call(this, declaration, topLevel);
5911 }
5912 };
5913 });
5914
5915 // declares, interfaces and type aliases
5916 instance.extend("parseExpressionStatement", function (inner) {
5917 return function (node, expr) {
5918 if (expr.type === "Identifier") {
5919 if (expr.name === "declare") {
5920 if (this.match(types._class) || this.match(types.name) || this.match(types._function) || this.match(types._var) || this.match(types._export)) {
5921 return this.flowParseDeclare(node);
5922 }
5923 } else if (this.match(types.name)) {
5924 if (expr.name === "interface") {
5925 return this.flowParseInterface(node);
5926 } else if (expr.name === "type") {
5927 return this.flowParseTypeAlias(node);
5928 } else if (expr.name === "opaque") {
5929 return this.flowParseOpaqueType(node, false);
5930 }
5931 }
5932 }
5933
5934 return inner.call(this, node, expr);
5935 };
5936 });
5937
5938 // export type
5939 instance.extend("shouldParseExportDeclaration", function (inner) {
5940 return function () {
5941 return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || inner.call(this);
5942 };
5943 });
5944
5945 instance.extend("isExportDefaultSpecifier", function (inner) {
5946 return function () {
5947 if (this.match(types.name) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque")) {
5948 return false;
5949 }
5950
5951 return inner.call(this);
5952 };
5953 });
5954
5955 instance.extend("parseConditional", function (inner) {
5956 return function (expr, noIn, startPos, startLoc, refNeedsArrowPos) {
5957 // only do the expensive clone if there is a question mark
5958 // and if we come from inside parens
5959 if (refNeedsArrowPos && this.match(types.question)) {
5960 var state = this.state.clone();
5961 try {
5962 return inner.call(this, expr, noIn, startPos, startLoc);
5963 } catch (err) {
5964 if (err instanceof SyntaxError) {
5965 this.state = state;
5966 refNeedsArrowPos.start = err.pos || this.state.start;
5967 return expr;
5968 } else {
5969 // istanbul ignore next: no such error is expected
5970 throw err;
5971 }
5972 }
5973 }
5974
5975 return inner.call(this, expr, noIn, startPos, startLoc);
5976 };
5977 });
5978
5979 instance.extend("parseParenItem", function (inner) {
5980 return function (node, startPos, startLoc) {
5981 node = inner.call(this, node, startPos, startLoc);
5982 if (this.eat(types.question)) {
5983 node.optional = true;
5984 }
5985
5986 if (this.match(types.colon)) {
5987 var typeCastNode = this.startNodeAt(startPos, startLoc);
5988 typeCastNode.expression = node;
5989 typeCastNode.typeAnnotation = this.flowParseTypeAnnotation();
5990
5991 return this.finishNode(typeCastNode, "TypeCastExpression");
5992 }
5993
5994 return node;
5995 };
5996 });
5997
5998 instance.extend("parseExport", function (inner) {
5999 return function (node) {
6000 node = inner.call(this, node);
6001 if (node.type === "ExportNamedDeclaration") {
6002 node.exportKind = node.exportKind || "value";
6003 }
6004 return node;
6005 };
6006 });
6007
6008 instance.extend("parseExportDeclaration", function (inner) {
6009 return function (node) {
6010 if (this.isContextual("type")) {
6011 node.exportKind = "type";
6012
6013 var declarationNode = this.startNode();
6014 this.next();
6015
6016 if (this.match(types.braceL)) {
6017 // export type { foo, bar };
6018 node.specifiers = this.parseExportSpecifiers();
6019 this.parseExportFrom(node);
6020 return null;
6021 } else {
6022 // export type Foo = Bar;
6023 return this.flowParseTypeAlias(declarationNode);
6024 }
6025 } else if (this.isContextual("opaque")) {
6026 node.exportKind = "type";
6027
6028 var _declarationNode = this.startNode();
6029 this.next();
6030 // export opaque type Foo = Bar;
6031 return this.flowParseOpaqueType(_declarationNode, false);
6032 } else if (this.isContextual("interface")) {
6033 node.exportKind = "type";
6034 var _declarationNode2 = this.startNode();
6035 this.next();
6036 return this.flowParseInterface(_declarationNode2);
6037 } else {
6038 return inner.call(this, node);
6039 }
6040 };
6041 });
6042
6043 instance.extend("parseClassId", function (inner) {
6044 return function (node) {
6045 inner.apply(this, arguments);
6046 if (this.isRelational("<")) {
6047 node.typeParameters = this.flowParseTypeParameterDeclaration();
6048 }
6049 };
6050 });
6051
6052 // don't consider `void` to be a keyword as then it'll use the void token type
6053 // and set startExpr
6054 instance.extend("isKeyword", function (inner) {
6055 return function (name) {
6056 if (this.state.inType && name === "void") {
6057 return false;
6058 } else {
6059 return inner.call(this, name);
6060 }
6061 };
6062 });
6063
6064 // ensure that inside flow types, we bypass the jsx parser plugin
6065 instance.extend("readToken", function (inner) {
6066 return function (code) {
6067 if (this.state.inType && (code === 62 || code === 60)) {
6068 return this.finishOp(types.relational, 1);
6069 } else {
6070 return inner.call(this, code);
6071 }
6072 };
6073 });
6074
6075 // don't lex any token as a jsx one inside a flow type
6076 instance.extend("jsx_readToken", function (inner) {
6077 return function () {
6078 if (!this.state.inType) return inner.call(this);
6079 };
6080 });
6081
6082 instance.extend("toAssignable", function (inner) {
6083 return function (node, isBinding, contextDescription) {
6084 if (node.type === "TypeCastExpression") {
6085 return inner.call(this, this.typeCastToParameter(node), isBinding, contextDescription);
6086 } else {
6087 return inner.call(this, node, isBinding, contextDescription);
6088 }
6089 };
6090 });
6091
6092 // turn type casts that we found in function parameter head into type annotated params
6093 instance.extend("toAssignableList", function (inner) {
6094 return function (exprList, isBinding, contextDescription) {
6095 for (var i = 0; i < exprList.length; i++) {
6096 var expr = exprList[i];
6097 if (expr && expr.type === "TypeCastExpression") {
6098 exprList[i] = this.typeCastToParameter(expr);
6099 }
6100 }
6101 return inner.call(this, exprList, isBinding, contextDescription);
6102 };
6103 });
6104
6105 // this is a list of nodes, from something like a call expression, we need to filter the
6106 // type casts that we've found that are illegal in this context
6107 instance.extend("toReferencedList", function () {
6108 return function (exprList) {
6109 for (var i = 0; i < exprList.length; i++) {
6110 var expr = exprList[i];
6111 if (expr && expr._exprListItem && expr.type === "TypeCastExpression") {
6112 this.raise(expr.start, "Unexpected type cast");
6113 }
6114 }
6115
6116 return exprList;
6117 };
6118 });
6119
6120 // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents
6121 // the position where this function is called
6122 instance.extend("parseExprListItem", function (inner) {
6123 return function () {
6124 var container = this.startNode();
6125
6126 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
6127 args[_key] = arguments[_key];
6128 }
6129
6130 var node = inner.call.apply(inner, [this].concat(args));
6131 if (this.match(types.colon)) {
6132 container._exprListItem = true;
6133 container.expression = node;
6134 container.typeAnnotation = this.flowParseTypeAnnotation();
6135 return this.finishNode(container, "TypeCastExpression");
6136 } else {
6137 return node;
6138 }
6139 };
6140 });
6141
6142 instance.extend("checkLVal", function (inner) {
6143 return function (node) {
6144 if (node.type !== "TypeCastExpression") {
6145 return inner.apply(this, arguments);
6146 }
6147 };
6148 });
6149
6150 // parse class property type annotations
6151 instance.extend("parseClassProperty", function (inner) {
6152 return function (node) {
6153 delete node.variancePos;
6154 if (this.match(types.colon)) {
6155 node.typeAnnotation = this.flowParseTypeAnnotation();
6156 }
6157 return inner.call(this, node);
6158 };
6159 });
6160
6161 // determine whether or not we're currently in the position where a class method would appear
6162 instance.extend("isClassMethod", function (inner) {
6163 return function () {
6164 return this.isRelational("<") || inner.call(this);
6165 };
6166 });
6167
6168 // determine whether or not we're currently in the position where a class property would appear
6169 instance.extend("isClassProperty", function (inner) {
6170 return function () {
6171 return this.match(types.colon) || inner.call(this);
6172 };
6173 });
6174
6175 instance.extend("isNonstaticConstructor", function (inner) {
6176 return function (method) {
6177 return !this.match(types.colon) && inner.call(this, method);
6178 };
6179 });
6180
6181 // parse type parameters for class methods
6182 instance.extend("parseClassMethod", function (inner) {
6183 return function (classBody, method) {
6184 if (method.variance) {
6185 this.unexpected(method.variancePos);
6186 }
6187 delete method.variance;
6188 delete method.variancePos;
6189 if (this.isRelational("<")) {
6190 method.typeParameters = this.flowParseTypeParameterDeclaration();
6191 }
6192
6193 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
6194 args[_key2 - 2] = arguments[_key2];
6195 }
6196
6197 inner.call.apply(inner, [this, classBody, method].concat(args));
6198 };
6199 });
6200
6201 // parse a the super class type parameters and implements
6202 instance.extend("parseClassSuper", function (inner) {
6203 return function (node, isStatement) {
6204 inner.call(this, node, isStatement);
6205 if (node.superClass && this.isRelational("<")) {
6206 node.superTypeParameters = this.flowParseTypeParameterInstantiation();
6207 }
6208 if (this.isContextual("implements")) {
6209 this.next();
6210 var implemented = node.implements = [];
6211 do {
6212 var _node = this.startNode();
6213 _node.id = this.parseIdentifier();
6214 if (this.isRelational("<")) {
6215 _node.typeParameters = this.flowParseTypeParameterInstantiation();
6216 } else {
6217 _node.typeParameters = null;
6218 }
6219 implemented.push(this.finishNode(_node, "ClassImplements"));
6220 } while (this.eat(types.comma));
6221 }
6222 };
6223 });
6224
6225 instance.extend("parsePropertyName", function (inner) {
6226 return function (node) {
6227 var variancePos = this.state.start;
6228 var variance = this.flowParseVariance();
6229 var key = inner.call(this, node);
6230 node.variance = variance;
6231 node.variancePos = variancePos;
6232 return key;
6233 };
6234 });
6235
6236 // parse type parameters for object method shorthand
6237 instance.extend("parseObjPropValue", function (inner) {
6238 return function (prop) {
6239 if (prop.variance) {
6240 this.unexpected(prop.variancePos);
6241 }
6242 delete prop.variance;
6243 delete prop.variancePos;
6244
6245 var typeParameters = void 0;
6246
6247 // method shorthand
6248 if (this.isRelational("<")) {
6249 typeParameters = this.flowParseTypeParameterDeclaration();
6250 if (!this.match(types.parenL)) this.unexpected();
6251 }
6252
6253 inner.apply(this, arguments);
6254
6255 // add typeParameters if we found them
6256 if (typeParameters) {
6257 (prop.value || prop).typeParameters = typeParameters;
6258 }
6259 };
6260 });
6261
6262 instance.extend("parseAssignableListItemTypes", function () {
6263 return function (param) {
6264 if (this.eat(types.question)) {
6265 param.optional = true;
6266 }
6267 if (this.match(types.colon)) {
6268 param.typeAnnotation = this.flowParseTypeAnnotation();
6269 }
6270 this.finishNode(param, param.type);
6271 return param;
6272 };
6273 });
6274
6275 instance.extend("parseMaybeDefault", function (inner) {
6276 return function () {
6277 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
6278 args[_key3] = arguments[_key3];
6279 }
6280
6281 var node = inner.apply(this, args);
6282
6283 if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) {
6284 this.raise(node.typeAnnotation.start, "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`");
6285 }
6286
6287 return node;
6288 };
6289 });
6290
6291 // parse typeof and type imports
6292 instance.extend("parseImportSpecifiers", function (inner) {
6293 return function (node) {
6294 node.importKind = "value";
6295
6296 var kind = null;
6297 if (this.match(types._typeof)) {
6298 kind = "typeof";
6299 } else if (this.isContextual("type")) {
6300 kind = "type";
6301 }
6302 if (kind) {
6303 var lh = this.lookahead();
6304 if (lh.type === types.name && lh.value !== "from" || lh.type === types.braceL || lh.type === types.star) {
6305 this.next();
6306 node.importKind = kind;
6307 }
6308 }
6309
6310 inner.call(this, node);
6311 };
6312 });
6313
6314 // parse import-type/typeof shorthand
6315 instance.extend("parseImportSpecifier", function () {
6316 return function (node) {
6317 var specifier = this.startNode();
6318 var firstIdentLoc = this.state.start;
6319 var firstIdent = this.parseIdentifier(true);
6320
6321 var specifierTypeKind = null;
6322 if (firstIdent.name === "type") {
6323 specifierTypeKind = "type";
6324 } else if (firstIdent.name === "typeof") {
6325 specifierTypeKind = "typeof";
6326 }
6327
6328 var isBinding = false;
6329 if (this.isContextual("as")) {
6330 var as_ident = this.parseIdentifier(true);
6331 if (specifierTypeKind !== null && !this.match(types.name) && !this.state.type.keyword) {
6332 // `import {type as ,` or `import {type as }`
6333 specifier.imported = as_ident;
6334 specifier.importKind = specifierTypeKind;
6335 specifier.local = as_ident.__clone();
6336 } else {
6337 // `import {type as foo`
6338 specifier.imported = firstIdent;
6339 specifier.importKind = null;
6340 specifier.local = this.parseIdentifier();
6341 }
6342 } else if (specifierTypeKind !== null && (this.match(types.name) || this.state.type.keyword)) {
6343 // `import {type foo`
6344 specifier.imported = this.parseIdentifier(true);
6345 specifier.importKind = specifierTypeKind;
6346 if (this.eatContextual("as")) {
6347 specifier.local = this.parseIdentifier();
6348 } else {
6349 isBinding = true;
6350 specifier.local = specifier.imported.__clone();
6351 }
6352 } else {
6353 isBinding = true;
6354 specifier.imported = firstIdent;
6355 specifier.importKind = null;
6356 specifier.local = specifier.imported.__clone();
6357 }
6358
6359 if ((node.importKind === "type" || node.importKind === "typeof") && (specifier.importKind === "type" || specifier.importKind === "typeof")) {
6360 this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`");
6361 }
6362
6363 if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true);
6364
6365 this.checkLVal(specifier.local, true, undefined, "import specifier");
6366 node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
6367 };
6368 });
6369
6370 // parse function type parameters - function foo<T>() {}
6371 instance.extend("parseFunctionParams", function (inner) {
6372 return function (node) {
6373 if (this.isRelational("<")) {
6374 node.typeParameters = this.flowParseTypeParameterDeclaration();
6375 }
6376 inner.call(this, node);
6377 };
6378 });
6379
6380 // parse flow type annotations on variable declarator heads - let foo: string = bar
6381 instance.extend("parseVarHead", function (inner) {
6382 return function (decl) {
6383 inner.call(this, decl);
6384 if (this.match(types.colon)) {
6385 decl.id.typeAnnotation = this.flowParseTypeAnnotation();
6386 this.finishNode(decl.id, decl.id.type);
6387 }
6388 };
6389 });
6390
6391 // parse the return type of an async arrow function - let foo = (async (): number => {});
6392 instance.extend("parseAsyncArrowFromCallExpression", function (inner) {
6393 return function (node, call) {
6394 if (this.match(types.colon)) {
6395 var oldNoAnonFunctionType = this.state.noAnonFunctionType;
6396 this.state.noAnonFunctionType = true;
6397 node.returnType = this.flowParseTypeAnnotation();
6398 this.state.noAnonFunctionType = oldNoAnonFunctionType;
6399 }
6400
6401 return inner.call(this, node, call);
6402 };
6403 });
6404
6405 // todo description
6406 instance.extend("shouldParseAsyncArrow", function (inner) {
6407 return function () {
6408 return this.match(types.colon) || inner.call(this);
6409 };
6410 });
6411
6412 // We need to support type parameter declarations for arrow functions. This
6413 // is tricky. There are three situations we need to handle
6414 //
6415 // 1. This is either JSX or an arrow function. We'll try JSX first. If that
6416 // fails, we'll try an arrow function. If that fails, we'll throw the JSX
6417 // error.
6418 // 2. This is an arrow function. We'll parse the type parameter declaration,
6419 // parse the rest, make sure the rest is an arrow function, and go from
6420 // there
6421 // 3. This is neither. Just call the inner function
6422 instance.extend("parseMaybeAssign", function (inner) {
6423 return function () {
6424 var jsxError = null;
6425
6426 for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
6427 args[_key4] = arguments[_key4];
6428 }
6429
6430 if (types.jsxTagStart && this.match(types.jsxTagStart)) {
6431 var state = this.state.clone();
6432 try {
6433 return inner.apply(this, args);
6434 } catch (err) {
6435 if (err instanceof SyntaxError) {
6436 this.state = state;
6437
6438 // Remove `tc.j_expr` and `tc.j_oTag` from context added
6439 // by parsing `jsxTagStart` to stop the JSX plugin from
6440 // messing with the tokens
6441 this.state.context.length -= 2;
6442
6443 jsxError = err;
6444 } else {
6445 // istanbul ignore next: no such error is expected
6446 throw err;
6447 }
6448 }
6449 }
6450
6451 if (jsxError != null || this.isRelational("<")) {
6452 var arrowExpression = void 0;
6453 var typeParameters = void 0;
6454 try {
6455 typeParameters = this.flowParseTypeParameterDeclaration();
6456
6457 arrowExpression = inner.apply(this, args);
6458 arrowExpression.typeParameters = typeParameters;
6459 arrowExpression.start = typeParameters.start;
6460 arrowExpression.loc.start = typeParameters.loc.start;
6461 } catch (err) {
6462 throw jsxError || err;
6463 }
6464
6465 if (arrowExpression.type === "ArrowFunctionExpression") {
6466 return arrowExpression;
6467 } else if (jsxError != null) {
6468 throw jsxError;
6469 } else {
6470 this.raise(typeParameters.start, "Expected an arrow function after this type parameter declaration");
6471 }
6472 }
6473
6474 return inner.apply(this, args);
6475 };
6476 });
6477
6478 // handle return types for arrow functions
6479 instance.extend("parseArrow", function (inner) {
6480 return function (node) {
6481 if (this.match(types.colon)) {
6482 var state = this.state.clone();
6483 try {
6484 var oldNoAnonFunctionType = this.state.noAnonFunctionType;
6485 this.state.noAnonFunctionType = true;
6486 var returnType = this.flowParseTypeAndPredicateAnnotation();
6487 this.state.noAnonFunctionType = oldNoAnonFunctionType;
6488
6489 if (this.canInsertSemicolon()) this.unexpected();
6490 if (!this.match(types.arrow)) this.unexpected();
6491 // assign after it is clear it is an arrow
6492 node.returnType = returnType;
6493 } catch (err) {
6494 if (err instanceof SyntaxError) {
6495 this.state = state;
6496 } else {
6497 // istanbul ignore next: no such error is expected
6498 throw err;
6499 }
6500 }
6501 }
6502
6503 return inner.call(this, node);
6504 };
6505 });
6506
6507 instance.extend("shouldParseArrow", function (inner) {
6508 return function () {
6509 return this.match(types.colon) || inner.call(this);
6510 };
6511 });
6512};
6513
6514// Adapted from String.fromcodepoint to export the function without modifying String
6515/*! https://mths.be/fromcodepoint v0.2.1 by @mathias */
6516
6517// The MIT License (MIT)
6518// Copyright (c) Mathias Bynens
6519//
6520// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6521// associated documentation files (the "Software"), to deal in the Software without restriction,
6522// including without limitation the rights to use, copy, modify, merge, publish, distribute,
6523// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
6524// furnished to do so, subject to the following conditions:
6525//
6526// The above copyright notice and this permission notice shall be included in all copies or
6527// substantial portions of the Software.
6528//
6529// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
6530// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
6531// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
6532// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6533// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6534
6535var fromCodePoint = String.fromCodePoint;
6536
6537if (!fromCodePoint) {
6538 var stringFromCharCode = String.fromCharCode;
6539 var floor = Math.floor;
6540 fromCodePoint = function fromCodePoint() {
6541 var MAX_SIZE = 0x4000;
6542 var codeUnits = [];
6543 var highSurrogate = void 0;
6544 var lowSurrogate = void 0;
6545 var index = -1;
6546 var length = arguments.length;
6547 if (!length) {
6548 return "";
6549 }
6550 var result = "";
6551 while (++index < length) {
6552 var codePoint = Number(arguments[index]);
6553 if (!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
6554 codePoint < 0 || // not a valid Unicode code point
6555 codePoint > 0x10FFFF || // not a valid Unicode code point
6556 floor(codePoint) != codePoint // not an integer
6557 ) {
6558 throw RangeError("Invalid code point: " + codePoint);
6559 }
6560 if (codePoint <= 0xFFFF) {
6561 // BMP code point
6562 codeUnits.push(codePoint);
6563 } else {
6564 // Astral code point; split in surrogate halves
6565 // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
6566 codePoint -= 0x10000;
6567 highSurrogate = (codePoint >> 10) + 0xD800;
6568 lowSurrogate = codePoint % 0x400 + 0xDC00;
6569 codeUnits.push(highSurrogate, lowSurrogate);
6570 }
6571 if (index + 1 == length || codeUnits.length > MAX_SIZE) {
6572 result += stringFromCharCode.apply(null, codeUnits);
6573 codeUnits.length = 0;
6574 }
6575 }
6576 return result;
6577 };
6578}
6579
6580var fromCodePoint$1 = fromCodePoint;
6581
6582var XHTMLEntities = {
6583 quot: "\"",
6584 amp: "&",
6585 apos: "'",
6586 lt: "<",
6587 gt: ">",
6588 nbsp: "\xA0",
6589 iexcl: "\xA1",
6590 cent: "\xA2",
6591 pound: "\xA3",
6592 curren: "\xA4",
6593 yen: "\xA5",
6594 brvbar: "\xA6",
6595 sect: "\xA7",
6596 uml: "\xA8",
6597 copy: "\xA9",
6598 ordf: "\xAA",
6599 laquo: "\xAB",
6600 not: "\xAC",
6601 shy: "\xAD",
6602 reg: "\xAE",
6603 macr: "\xAF",
6604 deg: "\xB0",
6605 plusmn: "\xB1",
6606 sup2: "\xB2",
6607 sup3: "\xB3",
6608 acute: "\xB4",
6609 micro: "\xB5",
6610 para: "\xB6",
6611 middot: "\xB7",
6612 cedil: "\xB8",
6613 sup1: "\xB9",
6614 ordm: "\xBA",
6615 raquo: "\xBB",
6616 frac14: "\xBC",
6617 frac12: "\xBD",
6618 frac34: "\xBE",
6619 iquest: "\xBF",
6620 Agrave: "\xC0",
6621 Aacute: "\xC1",
6622 Acirc: "\xC2",
6623 Atilde: "\xC3",
6624 Auml: "\xC4",
6625 Aring: "\xC5",
6626 AElig: "\xC6",
6627 Ccedil: "\xC7",
6628 Egrave: "\xC8",
6629 Eacute: "\xC9",
6630 Ecirc: "\xCA",
6631 Euml: "\xCB",
6632 Igrave: "\xCC",
6633 Iacute: "\xCD",
6634 Icirc: "\xCE",
6635 Iuml: "\xCF",
6636 ETH: "\xD0",
6637 Ntilde: "\xD1",
6638 Ograve: "\xD2",
6639 Oacute: "\xD3",
6640 Ocirc: "\xD4",
6641 Otilde: "\xD5",
6642 Ouml: "\xD6",
6643 times: "\xD7",
6644 Oslash: "\xD8",
6645 Ugrave: "\xD9",
6646 Uacute: "\xDA",
6647 Ucirc: "\xDB",
6648 Uuml: "\xDC",
6649 Yacute: "\xDD",
6650 THORN: "\xDE",
6651 szlig: "\xDF",
6652 agrave: "\xE0",
6653 aacute: "\xE1",
6654 acirc: "\xE2",
6655 atilde: "\xE3",
6656 auml: "\xE4",
6657 aring: "\xE5",
6658 aelig: "\xE6",
6659 ccedil: "\xE7",
6660 egrave: "\xE8",
6661 eacute: "\xE9",
6662 ecirc: "\xEA",
6663 euml: "\xEB",
6664 igrave: "\xEC",
6665 iacute: "\xED",
6666 icirc: "\xEE",
6667 iuml: "\xEF",
6668 eth: "\xF0",
6669 ntilde: "\xF1",
6670 ograve: "\xF2",
6671 oacute: "\xF3",
6672 ocirc: "\xF4",
6673 otilde: "\xF5",
6674 ouml: "\xF6",
6675 divide: "\xF7",
6676 oslash: "\xF8",
6677 ugrave: "\xF9",
6678 uacute: "\xFA",
6679 ucirc: "\xFB",
6680 uuml: "\xFC",
6681 yacute: "\xFD",
6682 thorn: "\xFE",
6683 yuml: "\xFF",
6684 OElig: "\u0152",
6685 oelig: "\u0153",
6686 Scaron: "\u0160",
6687 scaron: "\u0161",
6688 Yuml: "\u0178",
6689 fnof: "\u0192",
6690 circ: "\u02C6",
6691 tilde: "\u02DC",
6692 Alpha: "\u0391",
6693 Beta: "\u0392",
6694 Gamma: "\u0393",
6695 Delta: "\u0394",
6696 Epsilon: "\u0395",
6697 Zeta: "\u0396",
6698 Eta: "\u0397",
6699 Theta: "\u0398",
6700 Iota: "\u0399",
6701 Kappa: "\u039A",
6702 Lambda: "\u039B",
6703 Mu: "\u039C",
6704 Nu: "\u039D",
6705 Xi: "\u039E",
6706 Omicron: "\u039F",
6707 Pi: "\u03A0",
6708 Rho: "\u03A1",
6709 Sigma: "\u03A3",
6710 Tau: "\u03A4",
6711 Upsilon: "\u03A5",
6712 Phi: "\u03A6",
6713 Chi: "\u03A7",
6714 Psi: "\u03A8",
6715 Omega: "\u03A9",
6716 alpha: "\u03B1",
6717 beta: "\u03B2",
6718 gamma: "\u03B3",
6719 delta: "\u03B4",
6720 epsilon: "\u03B5",
6721 zeta: "\u03B6",
6722 eta: "\u03B7",
6723 theta: "\u03B8",
6724 iota: "\u03B9",
6725 kappa: "\u03BA",
6726 lambda: "\u03BB",
6727 mu: "\u03BC",
6728 nu: "\u03BD",
6729 xi: "\u03BE",
6730 omicron: "\u03BF",
6731 pi: "\u03C0",
6732 rho: "\u03C1",
6733 sigmaf: "\u03C2",
6734 sigma: "\u03C3",
6735 tau: "\u03C4",
6736 upsilon: "\u03C5",
6737 phi: "\u03C6",
6738 chi: "\u03C7",
6739 psi: "\u03C8",
6740 omega: "\u03C9",
6741 thetasym: "\u03D1",
6742 upsih: "\u03D2",
6743 piv: "\u03D6",
6744 ensp: "\u2002",
6745 emsp: "\u2003",
6746 thinsp: "\u2009",
6747 zwnj: "\u200C",
6748 zwj: "\u200D",
6749 lrm: "\u200E",
6750 rlm: "\u200F",
6751 ndash: "\u2013",
6752 mdash: "\u2014",
6753 lsquo: "\u2018",
6754 rsquo: "\u2019",
6755 sbquo: "\u201A",
6756 ldquo: "\u201C",
6757 rdquo: "\u201D",
6758 bdquo: "\u201E",
6759 dagger: "\u2020",
6760 Dagger: "\u2021",
6761 bull: "\u2022",
6762 hellip: "\u2026",
6763 permil: "\u2030",
6764 prime: "\u2032",
6765 Prime: "\u2033",
6766 lsaquo: "\u2039",
6767 rsaquo: "\u203A",
6768 oline: "\u203E",
6769 frasl: "\u2044",
6770 euro: "\u20AC",
6771 image: "\u2111",
6772 weierp: "\u2118",
6773 real: "\u211C",
6774 trade: "\u2122",
6775 alefsym: "\u2135",
6776 larr: "\u2190",
6777 uarr: "\u2191",
6778 rarr: "\u2192",
6779 darr: "\u2193",
6780 harr: "\u2194",
6781 crarr: "\u21B5",
6782 lArr: "\u21D0",
6783 uArr: "\u21D1",
6784 rArr: "\u21D2",
6785 dArr: "\u21D3",
6786 hArr: "\u21D4",
6787 forall: "\u2200",
6788 part: "\u2202",
6789 exist: "\u2203",
6790 empty: "\u2205",
6791 nabla: "\u2207",
6792 isin: "\u2208",
6793 notin: "\u2209",
6794 ni: "\u220B",
6795 prod: "\u220F",
6796 sum: "\u2211",
6797 minus: "\u2212",
6798 lowast: "\u2217",
6799 radic: "\u221A",
6800 prop: "\u221D",
6801 infin: "\u221E",
6802 ang: "\u2220",
6803 and: "\u2227",
6804 or: "\u2228",
6805 cap: "\u2229",
6806 cup: "\u222A",
6807 "int": "\u222B",
6808 there4: "\u2234",
6809 sim: "\u223C",
6810 cong: "\u2245",
6811 asymp: "\u2248",
6812 ne: "\u2260",
6813 equiv: "\u2261",
6814 le: "\u2264",
6815 ge: "\u2265",
6816 sub: "\u2282",
6817 sup: "\u2283",
6818 nsub: "\u2284",
6819 sube: "\u2286",
6820 supe: "\u2287",
6821 oplus: "\u2295",
6822 otimes: "\u2297",
6823 perp: "\u22A5",
6824 sdot: "\u22C5",
6825 lceil: "\u2308",
6826 rceil: "\u2309",
6827 lfloor: "\u230A",
6828 rfloor: "\u230B",
6829 lang: "\u2329",
6830 rang: "\u232A",
6831 loz: "\u25CA",
6832 spades: "\u2660",
6833 clubs: "\u2663",
6834 hearts: "\u2665",
6835 diams: "\u2666"
6836};
6837
6838var HEX_NUMBER = /^[\da-fA-F]+$/;
6839var DECIMAL_NUMBER = /^\d+$/;
6840
6841types$1.j_oTag = new TokContext("<tag", false);
6842types$1.j_cTag = new TokContext("</tag", false);
6843types$1.j_expr = new TokContext("<tag>...</tag>", true, true);
6844
6845types.jsxName = new TokenType("jsxName");
6846types.jsxText = new TokenType("jsxText", { beforeExpr: true });
6847types.jsxTagStart = new TokenType("jsxTagStart", { startsExpr: true });
6848types.jsxTagEnd = new TokenType("jsxTagEnd");
6849
6850types.jsxTagStart.updateContext = function () {
6851 this.state.context.push(types$1.j_expr); // treat as beginning of JSX expression
6852 this.state.context.push(types$1.j_oTag); // start opening tag context
6853 this.state.exprAllowed = false;
6854};
6855
6856types.jsxTagEnd.updateContext = function (prevType) {
6857 var out = this.state.context.pop();
6858 if (out === types$1.j_oTag && prevType === types.slash || out === types$1.j_cTag) {
6859 this.state.context.pop();
6860 this.state.exprAllowed = this.curContext() === types$1.j_expr;
6861 } else {
6862 this.state.exprAllowed = true;
6863 }
6864};
6865
6866var pp$9 = Parser.prototype;
6867
6868// Reads inline JSX contents token.
6869
6870pp$9.jsxReadToken = function () {
6871 var out = "";
6872 var chunkStart = this.state.pos;
6873 for (;;) {
6874 if (this.state.pos >= this.input.length) {
6875 this.raise(this.state.start, "Unterminated JSX contents");
6876 }
6877
6878 var ch = this.input.charCodeAt(this.state.pos);
6879
6880 switch (ch) {
6881 case 60: // "<"
6882 case 123:
6883 // "{"
6884 if (this.state.pos === this.state.start) {
6885 if (ch === 60 && this.state.exprAllowed) {
6886 ++this.state.pos;
6887 return this.finishToken(types.jsxTagStart);
6888 }
6889 return this.getTokenFromCode(ch);
6890 }
6891 out += this.input.slice(chunkStart, this.state.pos);
6892 return this.finishToken(types.jsxText, out);
6893
6894 case 38:
6895 // "&"
6896 out += this.input.slice(chunkStart, this.state.pos);
6897 out += this.jsxReadEntity();
6898 chunkStart = this.state.pos;
6899 break;
6900
6901 default:
6902 if (isNewLine(ch)) {
6903 out += this.input.slice(chunkStart, this.state.pos);
6904 out += this.jsxReadNewLine(true);
6905 chunkStart = this.state.pos;
6906 } else {
6907 ++this.state.pos;
6908 }
6909 }
6910 }
6911};
6912
6913pp$9.jsxReadNewLine = function (normalizeCRLF) {
6914 var ch = this.input.charCodeAt(this.state.pos);
6915 var out = void 0;
6916 ++this.state.pos;
6917 if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) {
6918 ++this.state.pos;
6919 out = normalizeCRLF ? "\n" : "\r\n";
6920 } else {
6921 out = String.fromCharCode(ch);
6922 }
6923 ++this.state.curLine;
6924 this.state.lineStart = this.state.pos;
6925
6926 return out;
6927};
6928
6929pp$9.jsxReadString = function (quote) {
6930 var out = "";
6931 var chunkStart = ++this.state.pos;
6932 for (;;) {
6933 if (this.state.pos >= this.input.length) {
6934 this.raise(this.state.start, "Unterminated string constant");
6935 }
6936
6937 var ch = this.input.charCodeAt(this.state.pos);
6938 if (ch === quote) break;
6939 if (ch === 38) {
6940 // "&"
6941 out += this.input.slice(chunkStart, this.state.pos);
6942 out += this.jsxReadEntity();
6943 chunkStart = this.state.pos;
6944 } else if (isNewLine(ch)) {
6945 out += this.input.slice(chunkStart, this.state.pos);
6946 out += this.jsxReadNewLine(false);
6947 chunkStart = this.state.pos;
6948 } else {
6949 ++this.state.pos;
6950 }
6951 }
6952 out += this.input.slice(chunkStart, this.state.pos++);
6953 return this.finishToken(types.string, out);
6954};
6955
6956pp$9.jsxReadEntity = function () {
6957 var str = "";
6958 var count = 0;
6959 var entity = void 0;
6960 var ch = this.input[this.state.pos];
6961
6962 var startPos = ++this.state.pos;
6963 while (this.state.pos < this.input.length && count++ < 10) {
6964 ch = this.input[this.state.pos++];
6965 if (ch === ";") {
6966 if (str[0] === "#") {
6967 if (str[1] === "x") {
6968 str = str.substr(2);
6969 if (HEX_NUMBER.test(str)) entity = fromCodePoint$1(parseInt(str, 16));
6970 } else {
6971 str = str.substr(1);
6972 if (DECIMAL_NUMBER.test(str)) entity = fromCodePoint$1(parseInt(str, 10));
6973 }
6974 } else {
6975 entity = XHTMLEntities[str];
6976 }
6977 break;
6978 }
6979 str += ch;
6980 }
6981 if (!entity) {
6982 this.state.pos = startPos;
6983 return "&";
6984 }
6985 return entity;
6986};
6987
6988// Read a JSX identifier (valid tag or attribute name).
6989//
6990// Optimized version since JSX identifiers can"t contain
6991// escape characters and so can be read as single slice.
6992// Also assumes that first character was already checked
6993// by isIdentifierStart in readToken.
6994
6995pp$9.jsxReadWord = function () {
6996 var ch = void 0;
6997 var start = this.state.pos;
6998 do {
6999 ch = this.input.charCodeAt(++this.state.pos);
7000 } while (isIdentifierChar(ch) || ch === 45); // "-"
7001 return this.finishToken(types.jsxName, this.input.slice(start, this.state.pos));
7002};
7003
7004// Transforms JSX element name to string.
7005
7006function getQualifiedJSXName(object) {
7007 if (object.type === "JSXIdentifier") {
7008 return object.name;
7009 }
7010
7011 if (object.type === "JSXNamespacedName") {
7012 return object.namespace.name + ":" + object.name.name;
7013 }
7014
7015 if (object.type === "JSXMemberExpression") {
7016 return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property);
7017 }
7018}
7019
7020// Parse next token as JSX identifier
7021
7022pp$9.jsxParseIdentifier = function () {
7023 var node = this.startNode();
7024 if (this.match(types.jsxName)) {
7025 node.name = this.state.value;
7026 } else if (this.state.type.keyword) {
7027 node.name = this.state.type.keyword;
7028 } else {
7029 this.unexpected();
7030 }
7031 this.next();
7032 return this.finishNode(node, "JSXIdentifier");
7033};
7034
7035// Parse namespaced identifier.
7036
7037pp$9.jsxParseNamespacedName = function () {
7038 var startPos = this.state.start;
7039 var startLoc = this.state.startLoc;
7040 var name = this.jsxParseIdentifier();
7041 if (!this.eat(types.colon)) return name;
7042
7043 var node = this.startNodeAt(startPos, startLoc);
7044 node.namespace = name;
7045 node.name = this.jsxParseIdentifier();
7046 return this.finishNode(node, "JSXNamespacedName");
7047};
7048
7049// Parses element name in any form - namespaced, member
7050// or single identifier.
7051
7052pp$9.jsxParseElementName = function () {
7053 var startPos = this.state.start;
7054 var startLoc = this.state.startLoc;
7055 var node = this.jsxParseNamespacedName();
7056 while (this.eat(types.dot)) {
7057 var newNode = this.startNodeAt(startPos, startLoc);
7058 newNode.object = node;
7059 newNode.property = this.jsxParseIdentifier();
7060 node = this.finishNode(newNode, "JSXMemberExpression");
7061 }
7062 return node;
7063};
7064
7065// Parses any type of JSX attribute value.
7066
7067pp$9.jsxParseAttributeValue = function () {
7068 var node = void 0;
7069 switch (this.state.type) {
7070 case types.braceL:
7071 node = this.jsxParseExpressionContainer();
7072 if (node.expression.type === "JSXEmptyExpression") {
7073 this.raise(node.start, "JSX attributes must only be assigned a non-empty expression");
7074 } else {
7075 return node;
7076 }
7077
7078 case types.jsxTagStart:
7079 case types.string:
7080 node = this.parseExprAtom();
7081 node.extra = null;
7082 return node;
7083
7084 default:
7085 this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text");
7086 }
7087};
7088
7089// JSXEmptyExpression is unique type since it doesn't actually parse anything,
7090// and so it should start at the end of last read token (left brace) and finish
7091// at the beginning of the next one (right brace).
7092
7093pp$9.jsxParseEmptyExpression = function () {
7094 var node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc);
7095 return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc);
7096};
7097
7098// Parse JSX spread child
7099
7100pp$9.jsxParseSpreadChild = function () {
7101 var node = this.startNode();
7102 this.expect(types.braceL);
7103 this.expect(types.ellipsis);
7104 node.expression = this.parseExpression();
7105 this.expect(types.braceR);
7106
7107 return this.finishNode(node, "JSXSpreadChild");
7108};
7109
7110// Parses JSX expression enclosed into curly brackets.
7111
7112
7113pp$9.jsxParseExpressionContainer = function () {
7114 var node = this.startNode();
7115 this.next();
7116 if (this.match(types.braceR)) {
7117 node.expression = this.jsxParseEmptyExpression();
7118 } else {
7119 node.expression = this.parseExpression();
7120 }
7121 this.expect(types.braceR);
7122 return this.finishNode(node, "JSXExpressionContainer");
7123};
7124
7125// Parses following JSX attribute name-value pair.
7126
7127pp$9.jsxParseAttribute = function () {
7128 var node = this.startNode();
7129 if (this.eat(types.braceL)) {
7130 this.expect(types.ellipsis);
7131 node.argument = this.parseMaybeAssign();
7132 this.expect(types.braceR);
7133 return this.finishNode(node, "JSXSpreadAttribute");
7134 }
7135 node.name = this.jsxParseNamespacedName();
7136 node.value = this.eat(types.eq) ? this.jsxParseAttributeValue() : null;
7137 return this.finishNode(node, "JSXAttribute");
7138};
7139
7140// Parses JSX opening tag starting after "<".
7141
7142pp$9.jsxParseOpeningElementAt = function (startPos, startLoc) {
7143 var node = this.startNodeAt(startPos, startLoc);
7144 node.attributes = [];
7145 node.name = this.jsxParseElementName();
7146 while (!this.match(types.slash) && !this.match(types.jsxTagEnd)) {
7147 node.attributes.push(this.jsxParseAttribute());
7148 }
7149 node.selfClosing = this.eat(types.slash);
7150 this.expect(types.jsxTagEnd);
7151 return this.finishNode(node, "JSXOpeningElement");
7152};
7153
7154// Parses JSX closing tag starting after "</".
7155
7156pp$9.jsxParseClosingElementAt = function (startPos, startLoc) {
7157 var node = this.startNodeAt(startPos, startLoc);
7158 node.name = this.jsxParseElementName();
7159 this.expect(types.jsxTagEnd);
7160 return this.finishNode(node, "JSXClosingElement");
7161};
7162
7163// Parses entire JSX element, including it"s opening tag
7164// (starting after "<"), attributes, contents and closing tag.
7165
7166pp$9.jsxParseElementAt = function (startPos, startLoc) {
7167 var node = this.startNodeAt(startPos, startLoc);
7168 var children = [];
7169 var openingElement = this.jsxParseOpeningElementAt(startPos, startLoc);
7170 var closingElement = null;
7171
7172 if (!openingElement.selfClosing) {
7173 contents: for (;;) {
7174 switch (this.state.type) {
7175 case types.jsxTagStart:
7176 startPos = this.state.start;startLoc = this.state.startLoc;
7177 this.next();
7178 if (this.eat(types.slash)) {
7179 closingElement = this.jsxParseClosingElementAt(startPos, startLoc);
7180 break contents;
7181 }
7182 children.push(this.jsxParseElementAt(startPos, startLoc));
7183 break;
7184
7185 case types.jsxText:
7186 children.push(this.parseExprAtom());
7187 break;
7188
7189 case types.braceL:
7190 if (this.lookahead().type === types.ellipsis) {
7191 children.push(this.jsxParseSpreadChild());
7192 } else {
7193 children.push(this.jsxParseExpressionContainer());
7194 }
7195
7196 break;
7197
7198 // istanbul ignore next - should never happen
7199 default:
7200 this.unexpected();
7201 }
7202 }
7203
7204 if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
7205 this.raise(closingElement.start, "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">");
7206 }
7207 }
7208
7209 node.openingElement = openingElement;
7210 node.closingElement = closingElement;
7211 node.children = children;
7212 if (this.match(types.relational) && this.state.value === "<") {
7213 this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
7214 }
7215 return this.finishNode(node, "JSXElement");
7216};
7217
7218// Parses entire JSX element from current position.
7219
7220pp$9.jsxParseElement = function () {
7221 var startPos = this.state.start;
7222 var startLoc = this.state.startLoc;
7223 this.next();
7224 return this.jsxParseElementAt(startPos, startLoc);
7225};
7226
7227var jsxPlugin = function (instance) {
7228 instance.extend("parseExprAtom", function (inner) {
7229 return function (refShortHandDefaultPos) {
7230 if (this.match(types.jsxText)) {
7231 var node = this.parseLiteral(this.state.value, "JSXText");
7232 // https://github.com/babel/babel/issues/2078
7233 node.extra = null;
7234 return node;
7235 } else if (this.match(types.jsxTagStart)) {
7236 return this.jsxParseElement();
7237 } else {
7238 return inner.call(this, refShortHandDefaultPos);
7239 }
7240 };
7241 });
7242
7243 instance.extend("readToken", function (inner) {
7244 return function (code) {
7245 if (this.state.inPropertyName) return inner.call(this, code);
7246
7247 var context = this.curContext();
7248
7249 if (context === types$1.j_expr) {
7250 return this.jsxReadToken();
7251 }
7252
7253 if (context === types$1.j_oTag || context === types$1.j_cTag) {
7254 if (isIdentifierStart(code)) {
7255 return this.jsxReadWord();
7256 }
7257
7258 if (code === 62) {
7259 ++this.state.pos;
7260 return this.finishToken(types.jsxTagEnd);
7261 }
7262
7263 if ((code === 34 || code === 39) && context === types$1.j_oTag) {
7264 return this.jsxReadString(code);
7265 }
7266 }
7267
7268 if (code === 60 && this.state.exprAllowed) {
7269 ++this.state.pos;
7270 return this.finishToken(types.jsxTagStart);
7271 }
7272
7273 return inner.call(this, code);
7274 };
7275 });
7276
7277 instance.extend("updateContext", function (inner) {
7278 return function (prevType) {
7279 if (this.match(types.braceL)) {
7280 var curContext = this.curContext();
7281 if (curContext === types$1.j_oTag) {
7282 this.state.context.push(types$1.braceExpression);
7283 } else if (curContext === types$1.j_expr) {
7284 this.state.context.push(types$1.templateQuasi);
7285 } else {
7286 inner.call(this, prevType);
7287 }
7288 this.state.exprAllowed = true;
7289 } else if (this.match(types.slash) && prevType === types.jsxTagStart) {
7290 this.state.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
7291 this.state.context.push(types$1.j_cTag); // reconsider as closing tag context
7292 this.state.exprAllowed = false;
7293 } else {
7294 return inner.call(this, prevType);
7295 }
7296 };
7297 });
7298};
7299
7300plugins.estree = estreePlugin;
7301plugins.flow = flowPlugin;
7302plugins.jsx = jsxPlugin;
7303
7304function parse(input, options) {
7305 return new Parser(options, input).parse();
7306}
7307
7308function parseExpression(input, options) {
7309 var parser = new Parser(options, input);
7310 if (parser.options.strictMode) {
7311 parser.state.strict = true;
7312 }
7313 return parser.getExpression();
7314}
7315
7316exports.parse = parse;
7317exports.parseExpression = parseExpression;
7318exports.tokTypes = types;
7319
\No newline at end of file