Projekt

Obecné

Profil

Stáhnout (231 KB) Statistiky
| Větev: | Revize:
1
'use strict';
2

    
3
Object.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

    
16
function 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

    
25
var 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

    
33
var 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

    
43
var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\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";
44
var nonASCIIidentifierChars = "\u200C\u200D\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\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

    
46
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
47
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
48

    
49
nonASCIIidentifierStartChars = 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
57
var 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
59
var 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.
64
function 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

    
77
function 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

    
88
function 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
100
var 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

    
124
function 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

    
132
var _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

    
148
var 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

    
164
var 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

    
190
var 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

    
216
var beforeExpr = true;
217
var startsExpr = true;
218
var isLoop = true;
219
var isAssign = true;
220
var prefix = true;
221
var postfix = true;
222

    
223
var 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

    
240
var 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

    
255
var 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

    
266
var 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

    
328
var 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.
369
Object.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

    
376
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
377
var lineBreakG = new RegExp(lineBreak.source, "g");
378

    
379
function isNewLine(code) {
380
  return code === 10 || code === 13 || code === 0x2028 || code === 0x2029;
381
}
382

    
383
var 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

    
389
var 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

    
398
var 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

    
412
types.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

    
429
types.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

    
439
types.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

    
444
types.dollarBraceL.updateContext = function () {
445
  this.state.context.push(types$1.templateQuasi);
446
  this.state.exprAllowed = true;
447
};
448

    
449
types.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

    
455
types.incDec.updateContext = function () {
456
  // tokExprAllowed stays unchanged
457
};
458

    
459
types._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

    
467
types.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

    
479
var Position = function Position(line, col) {
480
  classCallCheck(this, Position);
481

    
482
  this.line = line;
483
  this.column = col;
484
};
485

    
486
var 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

    
499
function 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

    
512
var 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

    
651
var 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

    
663
function 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

    
672
var 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

    
1557
var plugins = {};
1558
var frozenDeprecatedWildcardPluginList = ["jsx", "doExpressions", "objectRestSpread", "decorators", "classProperties", "exportExtensions", "asyncGenerators", "functionBind", "functionSent", "dynamicImport", "flow"];
1559

    
1560
var 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

    
1679
var pp = Parser.prototype;
1680

    
1681
// ## Parser utilities
1682

    
1683
// TODO
1684

    
1685
pp.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

    
1694
pp.isRelational = function (op) {
1695
  return this.match(types.relational) && this.state.value === op;
1696
};
1697

    
1698
// TODO
1699

    
1700
pp.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

    
1710
pp.isContextual = function (name) {
1711
  return this.match(types.name) && this.state.value === name;
1712
};
1713

    
1714
// Consumes contextual keyword if possible.
1715

    
1716
pp.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

    
1722
pp.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

    
1728
pp.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

    
1734
pp.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

    
1741
pp.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

    
1748
pp.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

    
1755
pp.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

    
1766
var 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

    
1775
pp$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

    
1787
var loopLabel = { kind: "loop" };
1788
var switchLabel = { kind: "switch" };
1789

    
1790
// TODO
1791

    
1792
pp$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

    
1816
pp$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

    
1915
pp$1.takeDecorators = function (node) {
1916
  if (this.state.decorators.length) {
1917
    node.decorators = this.state.decorators;
1918
    this.state.decorators = [];
1919
  }
1920
};
1921

    
1922
pp$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

    
1937
pp$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

    
1947
pp$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

    
1974
pp$1.parseDebuggerStatement = function (node) {
1975
  this.next();
1976
  this.semicolon();
1977
  return this.finishNode(node, "DebuggerStatement");
1978
};
1979

    
1980
pp$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

    
1999
pp$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

    
2051
pp$1.parseFunctionStatement = function (node) {
2052
  this.next();
2053
  return this.parseFunction(node, true);
2054
};
2055

    
2056
pp$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

    
2064
pp$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

    
2085
pp$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

    
2126
pp$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

    
2136
var empty = [];
2137

    
2138
pp$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

    
2167
pp$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

    
2174
pp$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

    
2183
pp$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

    
2191
pp$1.parseEmptyStatement = function (node) {
2192
  this.next();
2193
  return this.finishNode(node, "EmptyStatement");
2194
};
2195

    
2196
pp$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

    
2234
pp$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

    
2244
pp$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

    
2251
pp$1.isValidDirective = function (stmt) {
2252
  return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized;
2253
};
2254

    
2255
pp$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

    
2299
pp$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

    
2314
pp$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

    
2333
pp$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

    
2354
pp$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

    
2362
pp$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

    
2393
pp$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

    
2401
pp$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

    
2410
pp$1.isClassProperty = function () {
2411
  return this.match(types.eq) || this.match(types.semi) || this.match(types.braceR);
2412
};
2413

    
2414
pp$1.isClassMethod = function () {
2415
  return this.match(types.parenL);
2416
};
2417

    
2418
pp$1.isNonstaticConstructor = function (method) {
2419
  return !method.computed && !method.static && (method.key.name === "constructor" || // Identifier
2420
  method.key.value === "constructor" // Literal
2421
  );
2422
};
2423

    
2424
pp$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

    
2568
pp$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

    
2582
pp$1.parseClassMethod = function (classBody, method, isGenerator, isAsync) {
2583
  this.parseMethod(method, isGenerator, isAsync);
2584
  classBody.body.push(this.finishNode(method, "ClassMethod"));
2585
};
2586

    
2587
pp$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

    
2599
pp$1.parseClassSuper = function (node) {
2600
  node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
2601
};
2602

    
2603
// Parses module export declaration.
2604

    
2605
pp$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

    
2665
pp$1.parseExportDeclaration = function () {
2666
  return this.parseStatement(true);
2667
};
2668

    
2669
pp$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

    
2682
pp$1.parseExportSpecifiersMaybe = function (node) {
2683
  if (this.eat(types.comma)) {
2684
    node.specifiers = node.specifiers.concat(this.parseExportSpecifiers());
2685
  }
2686
};
2687

    
2688
pp$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

    
2703
pp$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

    
2707
pp$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

    
2765
pp$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

    
2811
pp$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

    
2818
pp$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

    
2824
pp$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

    
2859
pp$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

    
2878
pp$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

    
2916
pp$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

    
2929
pp$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

    
2936
var pp$2 = Parser.prototype;
2937

    
2938
// Convert existing expression atom to assignable pattern
2939
// if possible.
2940

    
2941
pp$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

    
3017
pp$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

    
3042
pp$2.toReferencedList = function (exprList) {
3043
  return exprList;
3044
};
3045

    
3046
// Parses spread element.
3047

    
3048
pp$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

    
3055
pp$2.parseRest = function () {
3056
  var node = this.startNode();
3057
  this.next();
3058
  node.argument = this.parseBindingIdentifier();
3059
  return this.finishNode(node, "RestElement");
3060
};
3061

    
3062
pp$2.shouldAllowYieldIdentifier = function () {
3063
  return this.match(types._yield) && !this.state.strict && !this.state.inGenerator;
3064
};
3065

    
3066
pp$2.parseBindingIdentifier = function () {
3067
  return this.parseIdentifier(this.shouldAllowYieldIdentifier());
3068
};
3069

    
3070
// Parses lvalue (assignable) atom.
3071

    
3072
pp$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

    
3094
pp$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

    
3127
pp$2.parseAssignableListItemTypes = function (param) {
3128
  return param;
3129
};
3130

    
3131
// Parses assignment pattern around given atom if possible.
3132

    
3133
pp$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

    
3148
pp$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

    
3258
var 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

    
3265
pp$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
3279
pp$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

    
3303
pp$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

    
3322
pp$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

    
3378
pp$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

    
3387
pp$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

    
3401
pp$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

    
3418
pp$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

    
3446
pp$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

    
3490
pp$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

    
3507
pp$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

    
3555
pp$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

    
3584
pp$3.shouldParseAsyncArrow = function () {
3585
  return this.match(types.arrow);
3586
};
3587

    
3588
pp$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

    
3595
pp$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

    
3606
pp$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

    
3754
pp$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

    
3764
pp$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

    
3775
pp$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

    
3787
pp$3.parseParenExpression = function () {
3788
  this.expect(types.parenL);
3789
  var val = this.parseExpression();
3790
  this.expect(types.parenR);
3791
  return val;
3792
};
3793

    
3794
pp$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

    
3881
pp$3.shouldParseArrow = function () {
3882
  return !this.canInsertSemicolon();
3883
};
3884

    
3885
pp$3.parseArrow = function (node) {
3886
  if (this.eat(types.arrow)) {
3887
    return node;
3888
  }
3889
};
3890

    
3891
pp$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

    
3899
pp$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

    
3927
pp$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

    
3945
pp$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

    
3963
pp$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

    
4069
pp$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
4080
pp$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

    
4092
pp$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

    
4113
pp$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

    
4139
pp$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

    
4147
pp$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

    
4164
pp$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

    
4173
pp$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

    
4187
pp$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

    
4194
pp$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.
4220
pp$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

    
4288
pp$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

    
4305
pp$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

    
4321
pp$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

    
4345
pp$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

    
4357
pp$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

    
4371
pp$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

    
4386
var pp$4 = Parser.prototype;
4387
var commentKeys = ["leadingComments", "trailingComments", "innerComments"];
4388

    
4389
var 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

    
4415
pp$4.startNode = function () {
4416
  return new Node(this.state.start, this.state.startLoc, this.filename);
4417
};
4418

    
4419
pp$4.startNodeAt = function (pos, loc) {
4420
  return new Node(pos, loc, this.filename);
4421
};
4422

    
4423
function 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

    
4433
pp$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

    
4439
pp$4.finishNodeAt = function (node, type, pos, loc) {
4440
  return finishNodeAt.call(this, node, type, pos, loc);
4441
};
4442

    
4443
var 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

    
4451
pp$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

    
4486
function last(stack) {
4487
  return stack[stack.length - 1];
4488
}
4489

    
4490
var pp$6 = Parser.prototype;
4491

    
4492
pp$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

    
4498
pp$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

    
4661
var pp$7 = Parser.prototype;
4662

    
4663
pp$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

    
4680
pp$7.estreeParseLiteral = function (value) {
4681
  return this.parseLiteral(value, "Literal");
4682
};
4683

    
4684
pp$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

    
4699
function isSimpleProperty(node) {
4700
  return node && node.type === "Property" && node.kind === "init" && node.method === false;
4701
}
4702

    
4703
var 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

    
4979
var primitiveTypes = ["any", "mixed", "empty", "bool", "boolean", "number", "string", "void", "null"];
4980

    
4981
var pp$8 = Parser.prototype;
4982

    
4983
pp$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

    
4993
pp$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

    
5013
pp$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

    
5032
pp$8.flowParseDeclareClass = function (node) {
5033
  this.next();
5034
  this.flowParseInterfaceish(node, true);
5035
  return this.finishNode(node, "DeclareClass");
5036
};
5037

    
5038
pp$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

    
5075
pp$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

    
5101
pp$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

    
5114
pp$8.flowParseDeclareVariable = function (node) {
5115
  this.next();
5116
  node.id = this.flowParseTypeAnnotatableIdentifier();
5117
  this.semicolon();
5118
  return this.finishNode(node, "DeclareVariable");
5119
};
5120

    
5121
pp$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

    
5157
pp$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

    
5167
pp$8.flowParseDeclareTypeAlias = function (node) {
5168
  this.next();
5169
  this.flowParseTypeAlias(node);
5170
  return this.finishNode(node, "DeclareTypeAlias");
5171
};
5172

    
5173
pp$8.flowParseDeclareOpaqueType = function (node) {
5174
  this.next();
5175
  this.flowParseOpaqueType(node, true);
5176
  return this.finishNode(node, "DeclareOpaqueType");
5177
};
5178

    
5179
pp$8.flowParseDeclareInterface = function (node) {
5180
  this.next();
5181
  this.flowParseInterfaceish(node);
5182
  return this.finishNode(node, "DeclareInterface");
5183
};
5184

    
5185
// Interfaces
5186

    
5187
pp$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

    
5215
pp$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

    
5228
pp$8.flowParseInterface = function (node) {
5229
  this.flowParseInterfaceish(node, false);
5230
  return this.finishNode(node, "InterfaceDeclaration");
5231
};
5232

    
5233
pp$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

    
5243
pp$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

    
5260
pp$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

    
5287
pp$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

    
5305
pp$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

    
5332
pp$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

    
5353
pp$8.flowParseObjectPropertyKey = function () {
5354
  return this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true);
5355
};
5356

    
5357
pp$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

    
5376
pp$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

    
5402
pp$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

    
5412
pp$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

    
5420
pp$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

    
5514
pp$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

    
5520
pp$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

    
5535
pp$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

    
5548
pp$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

    
5555
pp$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

    
5569
pp$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

    
5590
pp$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

    
5598
pp$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

    
5614
pp$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.
5646
pp$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

    
5775
pp$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

    
5789
pp$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

    
5799
pp$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

    
5812
pp$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

    
5823
pp$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

    
5834
pp$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

    
5842
pp$8.flowParseTypeAnnotation = function () {
5843
  var node = this.startNode();
5844
  node.typeAnnotation = this.flowParseTypeInitialiser();
5845
  return this.finishNode(node, "TypeAnnotation");
5846
};
5847

    
5848
pp$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

    
5859
pp$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

    
5868
pp$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

    
5874
pp$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

    
5887
var 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

    
6535
var fromCodePoint = String.fromCodePoint;
6536

    
6537
if (!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

    
6580
var fromCodePoint$1 = fromCodePoint;
6581

    
6582
var 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

    
6838
var HEX_NUMBER = /^[\da-fA-F]+$/;
6839
var DECIMAL_NUMBER = /^\d+$/;
6840

    
6841
types$1.j_oTag = new TokContext("<tag", false);
6842
types$1.j_cTag = new TokContext("</tag", false);
6843
types$1.j_expr = new TokContext("<tag>...</tag>", true, true);
6844

    
6845
types.jsxName = new TokenType("jsxName");
6846
types.jsxText = new TokenType("jsxText", { beforeExpr: true });
6847
types.jsxTagStart = new TokenType("jsxTagStart", { startsExpr: true });
6848
types.jsxTagEnd = new TokenType("jsxTagEnd");
6849

    
6850
types.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

    
6856
types.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

    
6866
var pp$9 = Parser.prototype;
6867

    
6868
// Reads inline JSX contents token.
6869

    
6870
pp$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

    
6913
pp$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

    
6929
pp$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

    
6956
pp$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

    
6995
pp$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

    
7006
function 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

    
7022
pp$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

    
7037
pp$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

    
7052
pp$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

    
7067
pp$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

    
7093
pp$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

    
7100
pp$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

    
7113
pp$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

    
7127
pp$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

    
7142
pp$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

    
7156
pp$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

    
7166
pp$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

    
7220
pp$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

    
7227
var 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

    
7300
plugins.estree = estreePlugin;
7301
plugins.flow = flowPlugin;
7302
plugins.jsx = jsxPlugin;
7303

    
7304
function parse(input, options) {
7305
  return new Parser(options, input).parse();
7306
}
7307

    
7308
function 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

    
7316
exports.parse = parse;
7317
exports.parseExpression = parseExpression;
7318
exports.tokTypes = types;
    (1-1/1)