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