diff options
Diffstat (limited to 'node_modules/babylon/lib/index.js')
-rw-r--r-- | node_modules/babylon/lib/index.js | 1625 |
1 files changed, 1173 insertions, 452 deletions
diff --git a/node_modules/babylon/lib/index.js b/node_modules/babylon/lib/index.js index 55b333359..f64e4b116 100644 --- a/node_modules/babylon/lib/index.js +++ b/node_modules/babylon/lib/index.js @@ -30,7 +30,7 @@ var reservedWords = { // And the keywords -var isKeyword$1 = 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"); +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"); // ## Character categories @@ -53,7 +53,9 @@ nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; // offset starts at 0x10000, and each pair of numbers represents an // offset to the next range, and then a size of the range. They were // generated by `bin/generate-identifier-regex.js`. +// eslint-disable-next-line comma-spacing 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]; +// eslint-disable-next-line comma-spacing 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]; // This has a complexity linear to the value of the code. The @@ -100,6 +102,9 @@ var defaultOptions = { sourceType: "script", // Source filename. sourceFilename: undefined, + // Line from which to start counting source. Useful for + // integration with other tools. + startLine: 1, // When enabled, a return at the top level is not considered an // error. allowReturnOutsideFunction: false, @@ -124,7 +129,71 @@ function getOptions(opts) { return options; } -function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + + + + + + + + + + + +var inherits = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; +}; + + + + + + + + + + + +var possibleConstructorReturn = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; +}; // ## Token types @@ -144,10 +213,16 @@ function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Co // to know when parsing a label, in order to allow or disallow // continue jumps to that label. +var beforeExpr = true; +var startsExpr = true; +var isLoop = true; +var isAssign = true; +var prefix = true; +var postfix = true; + var TokenType = function TokenType(label) { var conf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck$2(this, TokenType); + classCallCheck(this, TokenType); this.label = label; this.keyword = conf.keyword; @@ -162,39 +237,59 @@ var TokenType = function TokenType(label) { this.updateContext = null; }; -function binop(name, prec) { - return new TokenType(name, { beforeExpr: true, binop: prec }); -} -var beforeExpr = { beforeExpr: true }; -var startsExpr = { startsExpr: true }; +var KeywordTokenType = function (_TokenType) { + inherits(KeywordTokenType, _TokenType); + + function KeywordTokenType(name) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, KeywordTokenType); + + options.keyword = name; + + return possibleConstructorReturn(this, _TokenType.call(this, name, options)); + } + + return KeywordTokenType; +}(TokenType); + +var BinopTokenType = function (_TokenType2) { + inherits(BinopTokenType, _TokenType2); + + function BinopTokenType(name, prec) { + classCallCheck(this, BinopTokenType); + return possibleConstructorReturn(this, _TokenType2.call(this, name, { beforeExpr: beforeExpr, binop: prec })); + } + + return BinopTokenType; +}(TokenType); var types = { - num: new TokenType("num", startsExpr), - regexp: new TokenType("regexp", startsExpr), - string: new TokenType("string", startsExpr), - name: new TokenType("name", startsExpr), + num: new TokenType("num", { startsExpr: startsExpr }), + regexp: new TokenType("regexp", { startsExpr: startsExpr }), + string: new TokenType("string", { startsExpr: startsExpr }), + name: new TokenType("name", { startsExpr: startsExpr }), eof: new TokenType("eof"), // Punctuation token types. - bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }), + bracketL: new TokenType("[", { beforeExpr: beforeExpr, startsExpr: startsExpr }), bracketR: new TokenType("]"), - braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }), - braceBarL: new TokenType("{|", { beforeExpr: true, startsExpr: true }), + braceL: new TokenType("{", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + braceBarL: new TokenType("{|", { beforeExpr: beforeExpr, startsExpr: startsExpr }), braceR: new TokenType("}"), braceBarR: new TokenType("|}"), - parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }), + parenL: new TokenType("(", { beforeExpr: beforeExpr, startsExpr: startsExpr }), parenR: new TokenType(")"), - comma: new TokenType(",", beforeExpr), - semi: new TokenType(";", beforeExpr), - colon: new TokenType(":", beforeExpr), - doubleColon: new TokenType("::", beforeExpr), + comma: new TokenType(",", { beforeExpr: beforeExpr }), + semi: new TokenType(";", { beforeExpr: beforeExpr }), + colon: new TokenType(":", { beforeExpr: beforeExpr }), + doubleColon: new TokenType("::", { beforeExpr: beforeExpr }), dot: new TokenType("."), - question: new TokenType("?", beforeExpr), - arrow: new TokenType("=>", beforeExpr), + question: new TokenType("?", { beforeExpr: beforeExpr }), + arrow: new TokenType("=>", { beforeExpr: beforeExpr }), template: new TokenType("template"), - ellipsis: new TokenType("...", beforeExpr), - backQuote: new TokenType("`", startsExpr), - dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }), + ellipsis: new TokenType("...", { beforeExpr: beforeExpr }), + backQuote: new TokenType("`", { startsExpr: startsExpr }), + dollarBraceL: new TokenType("${", { beforeExpr: beforeExpr, startsExpr: startsExpr }), at: new TokenType("@"), // Operators. These carry several kinds of properties to help the @@ -211,74 +306,69 @@ var types = { // binary operators with a very low precedence, that should result // in AssignmentExpression nodes. - eq: new TokenType("=", { beforeExpr: true, isAssign: true }), - assign: new TokenType("_=", { beforeExpr: true, isAssign: true }), - incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }), - prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }), - logicalOR: binop("||", 1), - logicalAND: binop("&&", 2), - bitwiseOR: binop("|", 3), - bitwiseXOR: binop("^", 4), - bitwiseAND: binop("&", 5), - equality: binop("==/!=", 6), - relational: binop("</>", 7), - bitShift: binop("<</>>", 8), - plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }), - modulo: binop("%", 10), - star: binop("*", 10), - slash: binop("/", 10), - exponent: new TokenType("**", { beforeExpr: true, binop: 11, rightAssociative: true }) + eq: new TokenType("=", { beforeExpr: beforeExpr, isAssign: isAssign }), + assign: new TokenType("_=", { beforeExpr: beforeExpr, isAssign: isAssign }), + incDec: new TokenType("++/--", { prefix: prefix, postfix: postfix, startsExpr: startsExpr }), + prefix: new TokenType("prefix", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }), + logicalOR: new BinopTokenType("||", 1), + logicalAND: new BinopTokenType("&&", 2), + bitwiseOR: new BinopTokenType("|", 3), + bitwiseXOR: new BinopTokenType("^", 4), + bitwiseAND: new BinopTokenType("&", 5), + equality: new BinopTokenType("==/!=", 6), + relational: new BinopTokenType("</>", 7), + bitShift: new BinopTokenType("<</>>", 8), + plusMin: new TokenType("+/-", { beforeExpr: beforeExpr, binop: 9, prefix: prefix, startsExpr: startsExpr }), + modulo: new BinopTokenType("%", 10), + star: new BinopTokenType("*", 10), + slash: new BinopTokenType("/", 10), + exponent: new TokenType("**", { beforeExpr: beforeExpr, binop: 11, rightAssociative: true }) +}; + +var keywords = { + "break": new KeywordTokenType("break"), + "case": new KeywordTokenType("case", { beforeExpr: beforeExpr }), + "catch": new KeywordTokenType("catch"), + "continue": new KeywordTokenType("continue"), + "debugger": new KeywordTokenType("debugger"), + "default": new KeywordTokenType("default", { beforeExpr: beforeExpr }), + "do": new KeywordTokenType("do", { isLoop: isLoop, beforeExpr: beforeExpr }), + "else": new KeywordTokenType("else", { beforeExpr: beforeExpr }), + "finally": new KeywordTokenType("finally"), + "for": new KeywordTokenType("for", { isLoop: isLoop }), + "function": new KeywordTokenType("function", { startsExpr: startsExpr }), + "if": new KeywordTokenType("if"), + "return": new KeywordTokenType("return", { beforeExpr: beforeExpr }), + "switch": new KeywordTokenType("switch"), + "throw": new KeywordTokenType("throw", { beforeExpr: beforeExpr }), + "try": new KeywordTokenType("try"), + "var": new KeywordTokenType("var"), + "let": new KeywordTokenType("let"), + "const": new KeywordTokenType("const"), + "while": new KeywordTokenType("while", { isLoop: isLoop }), + "with": new KeywordTokenType("with"), + "new": new KeywordTokenType("new", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + "this": new KeywordTokenType("this", { startsExpr: startsExpr }), + "super": new KeywordTokenType("super", { startsExpr: startsExpr }), + "class": new KeywordTokenType("class"), + "extends": new KeywordTokenType("extends", { beforeExpr: beforeExpr }), + "export": new KeywordTokenType("export"), + "import": new KeywordTokenType("import"), + "yield": new KeywordTokenType("yield", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + "null": new KeywordTokenType("null", { startsExpr: startsExpr }), + "true": new KeywordTokenType("true", { startsExpr: startsExpr }), + "false": new KeywordTokenType("false", { startsExpr: startsExpr }), + "in": new KeywordTokenType("in", { beforeExpr: beforeExpr, binop: 7 }), + "instanceof": new KeywordTokenType("instanceof", { beforeExpr: beforeExpr, binop: 7 }), + "typeof": new KeywordTokenType("typeof", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }), + "void": new KeywordTokenType("void", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }), + "delete": new KeywordTokenType("delete", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }) }; // Map keyword names to token types. - -var keywords = {}; - -// Succinct definitions of keyword token types -function kw(name) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - options.keyword = name; - keywords[name] = types["_" + name] = new TokenType(name, options); -} - -kw("break"); -kw("case", beforeExpr); -kw("catch"); -kw("continue"); -kw("debugger"); -kw("default", beforeExpr); -kw("do", { isLoop: true, beforeExpr: true }); -kw("else", beforeExpr); -kw("finally"); -kw("for", { isLoop: true }); -kw("function", startsExpr); -kw("if"); -kw("return", beforeExpr); -kw("switch"); -kw("throw", beforeExpr); -kw("try"); -kw("var"); -kw("let"); -kw("const"); -kw("while", { isLoop: true }); -kw("with"); -kw("new", { beforeExpr: true, startsExpr: true }); -kw("this", startsExpr); -kw("super", startsExpr); -kw("class"); -kw("extends", beforeExpr); -kw("export"); -kw("import"); -kw("yield", { beforeExpr: true, startsExpr: true }); -kw("null", startsExpr); -kw("true", startsExpr); -kw("false", startsExpr); -kw("in", { beforeExpr: true, binop: 7 }); -kw("instanceof", { beforeExpr: true, binop: 7 }); -kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true }); -kw("void", { beforeExpr: true, prefix: true, startsExpr: true }); -kw("delete", { beforeExpr: true, prefix: true, startsExpr: true }); +Object.keys(keywords).forEach(function (name) { + types["_" + name] = keywords[name]; +}); // Matches a whole line break (where CRLF is considered a single // line break). Used to count lines. @@ -292,14 +382,12 @@ function isNewLine(code) { var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; -function _classCallCheck$3(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - // The algorithm used to determine whether a regexp can appear at a // given point in the program is loosely based on sweet.js' approach. // See https://github.com/mozilla/sweet.js/wiki/design var TokContext = function TokContext(token, isExpr, preserveSpace, override) { - _classCallCheck$3(this, TokContext); + classCallCheck(this, TokContext); this.token = token; this.isExpr = !!isExpr; @@ -385,20 +473,18 @@ types.backQuote.updateContext = function () { this.state.exprAllowed = false; }; -function _classCallCheck$4(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - // These are used when `options.locations` is on, for the // `startLoc` and `endLoc` properties. var Position = function Position(line, col) { - _classCallCheck$4(this, Position); + classCallCheck(this, Position); this.line = line; this.column = col; }; var SourceLocation = function SourceLocation(start, end) { - _classCallCheck$4(this, SourceLocation); + classCallCheck(this, SourceLocation); this.start = start; this.end = end; @@ -423,11 +509,9 @@ function getLineInfo(input, offset) { } } -function _classCallCheck$5(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var State = function () { function State() { - _classCallCheck$5(this, State); + classCallCheck(this, State); } State.prototype.init = function init(options, input) { @@ -437,7 +521,7 @@ var State = function () { this.potentialArrowAt = -1; - this.inMethod = this.inFunction = this.inGenerator = this.inAsync = this.inType = false; + this.inMethod = this.inFunction = this.inGenerator = this.inAsync = this.inPropertyName = this.inType = this.noAnonFunctionType = false; this.labels = []; @@ -452,7 +536,7 @@ var State = function () { this.commentStack = []; this.pos = this.lineStart = 0; - this.curLine = 1; + this.curLine = options.startLine; this.type = types.eof; this.value = null; @@ -558,16 +642,12 @@ var State = function () { return State; }(); -function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/* eslint indent: 0 */ - // Object type used to represent tokens. Note that normally, tokens // simply exist as properties on the parser object. This is only // used for the onToken callback and the external tokenizer. var Token = function Token(state) { - _classCallCheck$1(this, Token); + classCallCheck(this, Token); this.type = state.type; this.value = state.value; @@ -589,7 +669,7 @@ function codePointToString(code) { var Tokenizer = function () { function Tokenizer(options, input) { - _classCallCheck$1(this, Tokenizer); + classCallCheck(this, Tokenizer); this.state = new State(); this.state.init(options, input); @@ -628,8 +708,8 @@ var Tokenizer = function () { // TODO - Tokenizer.prototype.isKeyword = function isKeyword(word) { - return isKeyword$1(word); + Tokenizer.prototype.isKeyword = function isKeyword$$1(word) { + return isKeyword(word); }; // TODO @@ -721,8 +801,8 @@ var Tokenizer = function () { Tokenizer.prototype.skipBlockComment = function skipBlockComment() { var startLoc = this.state.curPosition(); - var start = this.state.pos, - end = this.input.indexOf("*/", this.state.pos += 2); + var start = this.state.pos; + var end = this.input.indexOf("*/", this.state.pos += 2); if (end === -1) this.raise(this.state.pos - 2, "Unterminated comment"); this.state.pos = end + 2; @@ -1072,9 +1152,9 @@ var Tokenizer = function () { }; Tokenizer.prototype.readRegexp = function readRegexp() { + var start = this.state.pos; var escaped = void 0, - inClass = void 0, - start = this.state.pos; + inClass = void 0; for (;;) { if (this.state.pos >= this.input.length) this.raise(start, "Unterminated regular expression"); var ch = this.input.charAt(this.state.pos); @@ -1115,11 +1195,12 @@ var Tokenizer = function () { // will return `null` unless the integer has exactly `len` digits. Tokenizer.prototype.readInt = function readInt(radix, len) { - var start = this.state.pos, - total = 0; + var start = this.state.pos; + var total = 0; + for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { - var code = this.input.charCodeAt(this.state.pos), - val = void 0; + var code = this.input.charCodeAt(this.state.pos); + var val = void 0; if (code >= 97) { val = code - 97 + 10; // a } else if (code >= 65) { @@ -1149,9 +1230,10 @@ var Tokenizer = function () { // Read an integer, octal integer, or floating-point number. Tokenizer.prototype.readNumber = function readNumber(startsWithDot) { - var start = this.state.pos, - isFloat = false, - octal = this.input.charCodeAt(this.state.pos) === 48; + var start = this.state.pos; + var octal = this.input.charCodeAt(this.state.pos) === 48; + var isFloat = false; + if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); var next = this.input.charCodeAt(this.state.pos); if (next === 46) { @@ -1170,8 +1252,8 @@ var Tokenizer = function () { } if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number"); - var str = this.input.slice(start, this.state.pos), - val = void 0; + var str = this.input.slice(start, this.state.pos); + var val = void 0; if (isFloat) { val = parseFloat(str); } else if (!octal || str.length === 1) { @@ -1187,8 +1269,8 @@ var Tokenizer = function () { // Read a string value, interpreting backslash-escapes. Tokenizer.prototype.readCodePoint = function readCodePoint() { - var ch = this.input.charCodeAt(this.state.pos), - code = void 0; + var ch = this.input.charCodeAt(this.state.pos); + var code = void 0; if (ch === 123) { var codePos = ++this.state.pos; @@ -1412,8 +1494,9 @@ var Tokenizer = function () { }; Tokenizer.prototype.updateContext = function updateContext(prevType) { - var update = void 0, - type = this.state.type; + var type = this.state.type; + var update = void 0; + if (type.keyword && prevType === types.dot) { this.state.exprAllowed = false; } else if (update = type.updateContext) { @@ -1426,27 +1509,21 @@ var Tokenizer = function () { return Tokenizer; }(); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var plugins = {}; +var frozenDeprecatedWildcardPluginList = ["jsx", "doExpressions", "objectRestSpread", "decorators", "classProperties", "exportExtensions", "asyncGenerators", "functionBind", "functionSent", "dynamicImport", "flow"]; var Parser = function (_Tokenizer) { - _inherits(Parser, _Tokenizer); + inherits(Parser, _Tokenizer); function Parser(options, input) { - _classCallCheck(this, Parser); + classCallCheck(this, Parser); options = getOptions(options); - var _this = _possibleConstructorReturn(this, _Tokenizer.call(this, options, input)); + var _this = possibleConstructorReturn(this, _Tokenizer.call(this, options, input)); _this.options = options; _this.inModule = _this.options.sourceType === "module"; - _this.isReservedWord = reservedWords[6]; _this.input = input; _this.plugins = _this.loadPlugins(_this.options.plugins); _this.filename = options.sourceFilename; @@ -1458,15 +1535,49 @@ var Parser = function (_Tokenizer) { return _this; } + Parser.prototype.isReservedWord = function isReservedWord(word) { + if (word === "await") { + return this.inModule; + } else { + return reservedWords[6](word); + } + }; + Parser.prototype.hasPlugin = function hasPlugin(name) { - return !!(this.plugins["*"] || this.plugins[name]); + if (this.plugins["*"] && frozenDeprecatedWildcardPluginList.indexOf(name) > -1) { + return true; + } + + return !!this.plugins[name]; }; Parser.prototype.extend = function extend(name, f) { this[name] = f(this[name]); }; + Parser.prototype.loadAllPlugins = function loadAllPlugins() { + var _this2 = this; + + // ensure flow plugin loads last, also ensure estree is not loaded with * + var pluginNames = Object.keys(plugins).filter(function (name) { + return name !== "flow" && name !== "estree"; + }); + pluginNames.push("flow"); + + pluginNames.forEach(function (name) { + var plugin = plugins[name]; + if (plugin) plugin(_this2); + }); + }; + Parser.prototype.loadPlugins = function loadPlugins(pluginList) { + // TODO: Deprecate "*" option in next major version of Babylon + if (pluginList.indexOf("*") >= 0) { + this.loadAllPlugins(); + + return { "*": true }; + } + var pluginMap = {}; if (pluginList.indexOf("flow") >= 0) { @@ -1477,6 +1588,14 @@ var Parser = function (_Tokenizer) { pluginList.push("flow"); } + if (pluginList.indexOf("estree") >= 0) { + // ensure estree plugin loads first + pluginList = pluginList.filter(function (plugin) { + return plugin !== "estree"; + }); + pluginList.unshift("estree"); + } + for (var _iterator = pluginList, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; @@ -1512,8 +1631,6 @@ var Parser = function (_Tokenizer) { return Parser; }(Tokenizer); -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - var pp = Parser.prototype; // ## Parser utilities @@ -1599,7 +1716,6 @@ pp.unexpected = function (pos) { this.raise(pos != null ? pos : this.state.start, messageOrType); }; -/* eslint indent: 0 */ /* eslint max-len: 0 */ var pp$1 = Parser.prototype; @@ -1657,8 +1773,8 @@ pp$1.parseStatement = function (declaration, topLevel) { this.parseDecorators(true); } - var starttype = this.state.type, - node = this.startNode(); + var starttype = this.state.type; + var node = this.startNode(); // Most types of statements are recognized by the keyword they // start with. Many are trivial to parse, some require a bit of @@ -1679,7 +1795,6 @@ pp$1.parseStatement = function (declaration, topLevel) { case types._class: if (!declaration) this.unexpected(); - this.takeDecorators(node); return this.parseClass(node, true); case types._if: @@ -1761,7 +1876,8 @@ pp$1.takeDecorators = function (node) { pp$1.parseDecorators = function (allowExport) { while (this.match(types.at)) { - this.state.decorators.push(this.parseDecorator()); + var decorator = this.parseDecorator(); + this.state.decorators.push(decorator); } if (allowExport && this.match(types._export)) { @@ -1854,8 +1970,8 @@ pp$1.parseForStatement = function (node) { } if (this.match(types._var) || this.match(types._let) || this.match(types._const)) { - var _init = this.startNode(), - varKind = this.state.type; + var _init = this.startNode(); + var varKind = this.state.type; this.next(); this.parseVar(_init, true, varKind); this.finishNode(_init, "VariableDeclaration"); @@ -2087,7 +2203,9 @@ pp$1.parseBlock = function (allowDirectives) { return this.finishNode(node, "BlockStatement"); }; -// TODO +pp$1.isValidDirective = function (stmt) { + return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized; +}; pp$1.parseBlockBody = function (node, allowDirectives, topLevel, end) { node.body = []; @@ -2104,7 +2222,7 @@ pp$1.parseBlockBody = function (node, allowDirectives, topLevel, end) { var stmt = this.parseStatement(true, topLevel); - if (allowDirectives && !parsedNonDirective && stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized) { + if (allowDirectives && !parsedNonDirective && this.isValidDirective(stmt)) { var directive = this.stmtToDirective(stmt); node.directives.push(directive); @@ -2237,6 +2355,7 @@ pp$1.parseFunctionParams = function (node) { pp$1.parseClass = function (node, isStatement, optionalId) { this.next(); + this.takeDecorators(node); this.parseClassId(node, isStatement, optionalId); this.parseClassSuper(node); this.parseClassBody(node); @@ -2267,6 +2386,9 @@ pp$1.parseClassBody = function (node) { while (!this.eat(types.braceR)) { if (this.eat(types.semi)) { + if (decorators.length > 0) { + this.raise(this.state.lastTokEnd, "Decorators must not be followed by a semicolon"); + } continue; } @@ -2331,7 +2453,9 @@ pp$1.parseClassBody = function (node) { } // disallow invalid constructors - var isConstructor = !isConstructorCall && !method.static && (key.type === "Identifier" && key.name === "constructor" || key.type === "StringLiteral" && key.value === "constructor"); + var isConstructor = !isConstructorCall && !method.static && (key.name === "constructor" || // Identifier + key.value === "constructor" // Literal + ); if (isConstructor) { if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class"); if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier"); @@ -2342,7 +2466,9 @@ pp$1.parseClassBody = function (node) { } // disallow static prototype method - var isStaticPrototype = method.static && (key.type === "Identifier" && key.name === "prototype" || key.type === "StringLiteral" && key.value === "prototype"); + var isStaticPrototype = method.static && (key.name === "prototype" || // Identifier + key.value === "prototype" // Literal + ); if (isStaticPrototype) { this.raise(key.start, "Classes may not have static property named prototype"); } @@ -2362,18 +2488,8 @@ pp$1.parseClassBody = function (node) { this.parseClassMethod(classBody, method, isGenerator, isAsync); - // get methods aren't allowed to have any parameters - // set methods must have exactly 1 parameter if (isGetSet) { - var paramCount = method.kind === "get" ? 0 : 1; - if (method.params.length !== paramCount) { - var start = method.start; - if (method.kind === "get") { - this.raise(start, "getter should have no params"); - } else { - this.raise(start, "setter should have exactly one param"); - } - } + this.checkGetterSetterParamCount(method); } } @@ -2467,7 +2583,7 @@ pp$1.parseExport = function (node) { if (needsSemi) this.semicolon(); this.checkExport(node, true, true); return this.finishNode(node, "ExportDefaultDeclaration"); - } else if (this.state.type.keyword || this.shouldParseExportDeclaration()) { + } else if (this.shouldParseExportDeclaration()) { node.specifiers = []; node.source = null; node.declaration = this.parseExportDeclaration(node); @@ -2520,7 +2636,7 @@ pp$1.parseExportFrom = function (node, expect) { }; pp$1.shouldParseExportDeclaration = function () { - return this.isContextual("async"); + 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"); }; pp$1.checkExport = function (node, checkNames, isDefault) { @@ -2676,7 +2792,7 @@ pp$1.parseExportSpecifiers = function () { // Parses import declaration. pp$1.parseImport = function (node) { - this.next(); + this.eat(types._import); // import '...' if (this.match(types.string)) { @@ -2698,8 +2814,8 @@ pp$1.parseImportSpecifiers = function (node) { var first = true; if (this.match(types.name)) { // import defaultObj, { x, y as z } from '...' - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdentifier(), startPos, startLoc)); if (!this.eat(types.comma)) return; } @@ -2719,16 +2835,30 @@ pp$1.parseImportSpecifiers = function (node) { if (first) { first = false; } else { + // Detect an attempt to deep destructure + if (this.eat(types.colon)) { + this.unexpected(null, "ES2015 named imports do not destructure. Use another statement for destructuring after the import."); + } + this.expect(types.comma); if (this.eat(types.braceR)) break; } - var _specifier3 = this.startNode(); - _specifier3.imported = this.parseIdentifier(true); - _specifier3.local = this.eatContextual("as") ? this.parseIdentifier() : _specifier3.imported.__clone(); - this.checkLVal(_specifier3.local, true, undefined, "import specifier"); - node.specifiers.push(this.finishNode(_specifier3, "ImportSpecifier")); + this.parseImportSpecifier(node); + } +}; + +pp$1.parseImportSpecifier = function (node) { + var specifier = this.startNode(); + specifier.imported = this.parseIdentifier(true); + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + this.checkReservedWord(specifier.imported.name, specifier.start, true, true); + specifier.local = specifier.imported.__clone(); } + this.checkLVal(specifier.local, true, undefined, "import specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); }; pp$1.parseImportSpecifierDefault = function (id, startPos, startLoc) { @@ -2738,8 +2868,6 @@ pp$1.parseImportSpecifierDefault = function (id, startPos, startLoc) { return this.finishNode(node, "ImportDefaultSpecifier"); }; -/* eslint indent: 0 */ - var pp$2 = Parser.prototype; // Convert existing expression atom to assignable pattern @@ -2953,9 +3081,7 @@ pp$2.parseMaybeDefault = function (startPos, startLoc, left) { pp$2.checkLVal = function (expr, isBinding, checkClashes, contextDescription) { switch (expr.type) { case "Identifier": - if (this.state.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name))) { - this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); - } + this.checkReservedWord(expr.name, expr.start, false, true); if (checkClashes) { // we need to prefix this with an underscore for the cases where we have a key of @@ -3042,7 +3168,6 @@ pp$2.checkLVal = function (expr, isBinding, checkClashes, contextDescription) { } }; -/* eslint indent: 0 */ /* eslint max-len: 0 */ // A recursive descent parser operates by defining functions for all @@ -3071,31 +3196,28 @@ var pp$3 = Parser.prototype; // strict mode, init properties are also not allowed to be repeated. pp$3.checkPropClash = function (prop, propHash) { - if (prop.computed) return; + if (prop.computed || prop.kind) return; var key = prop.key; - var name = void 0; - switch (key.type) { - case "Identifier": - name = key.name; - break; - - case "StringLiteral": - case "NumericLiteral": - name = String(key.value); - break; - - // istanbul ignore next: non-computed property keys are always one of the above - default: - return; - } + // It is either an Identifier or a String/NumericLiteral + var name = key.type === "Identifier" ? key.name : String(key.value); - if (name === "__proto__" && !prop.kind) { + if (name === "__proto__") { if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); propHash.proto = true; } }; +// Convenience method to parse an Expression only +pp$3.getExpression = function () { + this.nextToken(); + var expr = this.parseExpression(); + if (!this.match(types.eof)) { + this.unexpected(); + } + return expr; +}; + // ### Expression parsing // These nest, from the most general expression type at the top to @@ -3112,8 +3234,8 @@ pp$3.checkPropClash = function (prop, propHash) { // delayed syntax error at correct position). pp$3.parseExpression = function (noIn, refShorthandDefaultPos) { - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); if (this.match(types.comma)) { var node = this.startNodeAt(startPos, startLoc); @@ -3187,8 +3309,8 @@ pp$3.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse, // Parse a ternary conditional (`?:`) operator. pp$3.parseMaybeConditional = function (noIn, refShorthandDefaultPos, refNeedsArrowPos) { - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; var expr = this.parseExprOps(noIn, refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; @@ -3210,8 +3332,8 @@ pp$3.parseConditional = function (expr, noIn, startPos, startLoc) { // Start the precedence parser. pp$3.parseExprOps = function (noIn, refShorthandDefaultPos) { - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; var expr = this.parseMaybeUnary(refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) { return expr; @@ -3280,8 +3402,8 @@ pp$3.parseMaybeUnary = function (refShorthandDefaultPos) { return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; var expr = this.parseExprSubscripts(refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; while (this.state.type.postfix && !this.canInsertSemicolon()) { @@ -3299,8 +3421,8 @@ pp$3.parseMaybeUnary = function (refShorthandDefaultPos) { // Parse call, dot, and `[]`-subscript expressions. pp$3.parseExprSubscripts = function (refShorthandDefaultPos) { - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; var potentialArrowAt = this.state.potentialArrowAt; var expr = this.parseExprAtom(refShorthandDefaultPos); @@ -3364,10 +3486,10 @@ pp$3.parseSubscripts = function (base, startPos, startLoc, noCalls) { }; pp$3.parseCallExpressionArguments = function (close, possibleAsyncArrow) { + var elts = []; var innerParenStart = void 0; + var first = true; - var elts = [], - first = true; while (!this.eat(close)) { if (first) { first = false; @@ -3381,7 +3503,7 @@ pp$3.parseCallExpressionArguments = function (close, possibleAsyncArrow) { innerParenStart = this.state.start; } - elts.push(this.parseExprListItem(undefined, possibleAsyncArrow ? { start: 0 } : undefined)); + elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { start: 0 } : undefined, possibleAsyncArrow ? { start: 0 } : undefined)); } // we found an async arrow function so let's not allow any inner parens @@ -3404,8 +3526,8 @@ pp$3.parseAsyncArrowFromCallExpression = function (node, call) { // Parse a no-call expression (like argument of `new` or `::` operators). pp$3.parseNoCallExpr = function () { - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); }; @@ -3415,8 +3537,9 @@ pp$3.parseNoCallExpr = function () { // or `{}`. pp$3.parseExprAtom = function (refShorthandDefaultPos) { - var node = void 0, - canBeArrow = this.state.potentialArrowAt === this.state.start; + var canBeArrow = this.state.potentialArrowAt === this.state.start; + var node = void 0; + switch (this.state.type) { case types._super: if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { @@ -3582,10 +3705,13 @@ pp$3.parseMetaProperty = function (node, meta, propertyName) { return this.finishNode(node, "MetaProperty"); }; -pp$3.parseLiteral = function (value, type) { - var node = this.startNode(); +pp$3.parseLiteral = function (value, type, startPos, startLoc) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + + var node = this.startNodeAt(startPos, startLoc); this.addExtra(node, "rawValue", value); - this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); + this.addExtra(node, "raw", this.input.slice(startPos, this.state.end)); node.value = value; this.next(); return this.finishNode(node, type); @@ -3605,14 +3731,15 @@ pp$3.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArr var val = void 0; this.expect(types.parenL); - var innerStartPos = this.state.start, - innerStartLoc = this.state.startLoc; - var exprList = [], - first = true; - var refShorthandDefaultPos = { start: 0 }, - spreadStart = void 0, - optionalCommaStart = void 0; + var innerStartPos = this.state.start; + var innerStartLoc = this.state.startLoc; + var exprList = []; + var refShorthandDefaultPos = { start: 0 }; var refNeedsArrowPos = { start: 0 }; + var first = true; + var spreadStart = void 0; + var optionalCommaStart = void 0; + while (!this.match(types.parenR)) { if (first) { first = false; @@ -3625,8 +3752,8 @@ pp$3.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArr } if (this.match(types.ellipsis)) { - var spreadNodeStartPos = this.state.start, - spreadNodeStartLoc = this.state.startLoc; + var spreadNodeStartPos = this.state.start; + var spreadNodeStartLoc = this.state.startLoc; spreadStart = this.state.start; exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartLoc, spreadNodeStartPos)); break; @@ -3787,8 +3914,9 @@ pp$3.parseObj = function (isPattern, refShorthandDefaultPos) { } if (this.hasPlugin("objectRestSpread") && this.match(types.ellipsis)) { - prop = this.parseSpread(); + prop = this.parseSpread(isPattern ? { start: 0 } : undefined); prop.type = isPattern ? "RestProperty" : "SpreadProperty"; + if (isPattern) this.toAssignable(prop.argument, true, "object pattern"); node.properties.push(prop); if (isPattern) { var position = this.state.start; @@ -3827,6 +3955,7 @@ pp$3.parseObj = function (isPattern, refShorthandDefaultPos) { var asyncId = this.parseIdentifier(); if (this.match(types.colon) || this.match(types.parenL) || this.match(types.braceR) || this.match(types.eq) || this.match(types.comma)) { prop.key = asyncId; + prop.computed = false; } else { isAsync = true; if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(types.star); @@ -3857,46 +3986,60 @@ pp$3.parseObj = function (isPattern, refShorthandDefaultPos) { return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); }; -pp$3.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) { +pp$3.isGetterOrSetterMethod = function (prop, isPattern) { + return !isPattern && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.match(types.string) || // get "string"() {} + this.match(types.num) || // get 1() {} + this.match(types.bracketL) || // get ["string"]() {} + this.match(types.name) || // get foo() {} + this.state.type.keyword // get debugger() {} + ); +}; + +// get methods aren't allowed to have any parameters +// set methods must have exactly 1 parameter +pp$3.checkGetterSetterParamCount = function (method) { + var paramCount = method.kind === "get" ? 0 : 1; + if (method.params.length !== paramCount) { + var start = method.start; + if (method.kind === "get") { + this.raise(start, "getter should have no params"); + } else { + this.raise(start, "setter should have exactly one param"); + } + } +}; + +pp$3.parseObjectMethod = function (prop, isGenerator, isAsync, isPattern) { if (isAsync || isGenerator || this.match(types.parenL)) { if (isPattern) this.unexpected(); prop.kind = "method"; prop.method = true; this.parseMethod(prop, isGenerator, isAsync); - return this.finishNode(prop, "ObjectMethod"); - } - if (this.eat(types.colon)) { - prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); - return this.finishNode(prop, "ObjectProperty"); + return this.finishNode(prop, "ObjectMethod"); } - if (!isPattern && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && !this.match(types.comma) && !this.match(types.braceR)) { + if (this.isGetterOrSetterMethod(prop, isPattern)) { if (isGenerator || isAsync) this.unexpected(); prop.kind = prop.key.name; this.parsePropertyName(prop); - this.parseMethod(prop, false); - var paramCount = prop.kind === "get" ? 0 : 1; - if (prop.params.length !== paramCount) { - var start = prop.start; - if (prop.kind === "get") { - this.raise(start, "getter should have no params"); - } else { - this.raise(start, "setter should have exactly one param"); - } - } + this.parseMethod(prop); + this.checkGetterSetterParamCount(prop); + return this.finishNode(prop, "ObjectMethod"); } +}; + +pp$3.parseObjectProperty = function (prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { + if (this.eat(types.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); + + return this.finishNode(prop, "ObjectProperty"); + } if (!prop.computed && prop.key.type === "Identifier") { if (isPattern) { - var illegalBinding = this.isKeyword(prop.key.name); - if (!illegalBinding && this.state.strict) { - illegalBinding = reservedWords.strictBind(prop.key.name) || reservedWords.strict(prop.key.name); - } - if (illegalBinding) { - this.raise(prop.key.start, "Binding " + prop.key.name); - } + this.checkReservedWord(prop.key.name, prop.key.start, true, true); prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); } else if (this.match(types.eq) && refShorthandDefaultPos) { if (!refShorthandDefaultPos.start) { @@ -3907,10 +4050,17 @@ pp$3.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsyn prop.value = prop.key.__clone(); } prop.shorthand = true; + return this.finishNode(prop, "ObjectProperty"); } +}; - this.unexpected(); +pp$3.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) { + var node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos); + + if (!node) this.unexpected(); + + return node; }; pp$3.parsePropertyName = function (prop) { @@ -3918,11 +4068,14 @@ pp$3.parsePropertyName = function (prop) { prop.computed = true; prop.key = this.parseMaybeAssign(); this.expect(types.bracketR); - return prop.key; } else { prop.computed = false; - return prop.key = this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true); + var oldInPropertyName = this.state.inPropertyName; + this.state.inPropertyName = true; + prop.key = this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true); + this.state.inPropertyName = oldInPropertyName; } + return prop.key; }; // Initialize empty function node. @@ -3942,7 +4095,7 @@ pp$3.parseMethod = function (node, isGenerator, isAsync) { this.initFunction(node, isAsync); this.expect(types.parenL); node.params = this.parseBindingList(types.parenR); - node.generator = isGenerator; + node.generator = !!isGenerator; this.parseFunctionBody(node); this.state.inMethod = oldInMethod; return node; @@ -3957,8 +4110,32 @@ pp$3.parseArrowExpression = function (node, params, isAsync) { return this.finishNode(node, "ArrowFunctionExpression"); }; -// Parse function body and check parameters. +pp$3.isStrictBody = function (node, isExpression) { + if (!isExpression && node.body.directives.length) { + for (var _iterator2 = node.body.directives, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } + + var directive = _ref2; + + if (directive.value.value === "use strict") { + return true; + } + } + } + + return false; +}; +// Parse function body and check parameters. pp$3.parseFunctionBody = function (node, allowExpression) { var isExpression = allowExpression && !this.match(types.braceL); @@ -3970,9 +4147,9 @@ pp$3.parseFunctionBody = function (node, allowExpression) { } else { // Start a new scope with regard to labels and the `inFunction` // flag (restore them to their old value afterwards). - var oldInFunc = this.state.inFunction, - oldInGen = this.state.inGenerator, - oldLabels = this.state.labels; + var oldInFunc = this.state.inFunction; + var oldInGen = this.state.inGenerator; + var oldLabels = this.state.labels; this.state.inFunction = true;this.state.inGenerator = node.generator;this.state.labels = []; node.body = this.parseBlock(true); node.expression = false; @@ -3983,37 +4160,10 @@ pp$3.parseFunctionBody = function (node, allowExpression) { // If this is a strict mode function, verify that argument names // are not repeated, and it does not try to bind the words `eval` // or `arguments`. - var checkLVal = this.state.strict; - var isStrict = false; - - // arrow function - if (allowExpression) checkLVal = true; - - // normal function - if (!isExpression && node.body.directives.length) { - for (var _iterator2 = node.body.directives, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - var directive = _ref2; + var isStrict = this.isStrictBody(node, isExpression); + // Also check when allowExpression === true for arrow functions + var checkLVal = this.state.strict || allowExpression || isStrict; - if (directive.value.value === "use strict") { - isStrict = true; - checkLVal = true; - break; - } - } - } - - // if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") { this.raise(node.id.start, "Binding yield in strict mode"); } @@ -4055,8 +4205,9 @@ pp$3.parseFunctionBody = function (node, allowExpression) { // for array literals). pp$3.parseExprList = function (close, allowEmpty, refShorthandDefaultPos) { - var elts = [], - first = true; + var elts = []; + var first = true; + while (!this.eat(close)) { if (first) { first = false; @@ -4070,14 +4221,14 @@ pp$3.parseExprList = function (close, allowEmpty, refShorthandDefaultPos) { return elts; }; -pp$3.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) { +pp$3.parseExprListItem = function (allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) { var elt = void 0; if (allowEmpty && this.match(types.comma)) { elt = null; } else if (this.match(types.ellipsis)) { elt = this.parseSpread(refShorthandDefaultPos); } else { - elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem); + elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos); } return elt; }; @@ -4088,14 +4239,13 @@ pp$3.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) { pp$3.parseIdentifier = function (liberal) { var node = this.startNode(); + if (!liberal) { + this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false); + } if (this.match(types.name)) { - if (!liberal && this.state.strict && reservedWords.strict(this.state.value)) { - this.raise(this.state.start, "The keyword '" + this.state.value + "' is reserved"); - } - node.name = this.state.value; - } else if (liberal && this.state.type.keyword) { + } else if (this.state.type.keyword) { node.name = this.state.type.keyword; } else { this.unexpected(); @@ -4111,6 +4261,16 @@ pp$3.parseIdentifier = function (liberal) { return this.finishNode(node, "Identifier"); }; +pp$3.checkReservedWord = function (word, startLoc, checkKeywords, isBinding) { + if (this.isReservedWord(word) || checkKeywords && this.isKeyword(word)) { + this.raise(startLoc, word + " is a reserved word"); + } + + if (this.state.strict && (reservedWords.strict(word) || isBinding && reservedWords.strictBind(word))) { + this.raise(startLoc, word + " is a reserved word in strict mode"); + } +}; + // Parses await expression inside async function. pp$3.parseAwait = function (node) { @@ -4140,8 +4300,6 @@ pp$3.parseYield = function () { return this.finishNode(node, "YieldExpression"); }; -function _classCallCheck$6(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - // Start an AST node, attaching a start offset. var pp$4 = Parser.prototype; @@ -4149,7 +4307,7 @@ var commentKeys = ["leadingComments", "trailingComments", "innerComments"]; var Node = function () { function Node(pos, loc, filename) { - _classCallCheck$6(this, Node); + classCallCheck(this, Node); this.type = ""; this.start = pos; @@ -4376,32 +4534,373 @@ pp$6.processComment = function (node) { stack.push(node); }; -/* eslint indent: 0 */ +var pp$7 = Parser.prototype; + +pp$7.estreeParseRegExpLiteral = function (_ref) { + var pattern = _ref.pattern, + flags = _ref.flags; + + var regex = null; + try { + regex = new RegExp(pattern, flags); + } catch (e) { + // In environments that don't support these flags value will + // be null as the regex can't be represented natively. + } + var node = this.estreeParseLiteral(regex); + node.regex = { pattern: pattern, flags: flags }; + + return node; +}; + +pp$7.estreeParseLiteral = function (value) { + return this.parseLiteral(value, "Literal"); +}; + +pp$7.directiveToStmt = function (directive) { + var directiveLiteral = directive.value; + + var stmt = this.startNodeAt(directive.start, directive.loc.start); + var expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); + + expression.value = directiveLiteral.value; + expression.raw = directiveLiteral.extra.raw; + + stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); + stmt.directive = directiveLiteral.extra.raw.slice(1, -1); + + return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); +}; + +function isSimpleProperty(node) { + return node && node.type === "Property" && node.kind === "init" && node.method === false; +} + +var estreePlugin = function (instance) { + instance.extend("checkDeclaration", function (inner) { + return function (node) { + if (isSimpleProperty(node)) { + this.checkDeclaration(node.value); + } else { + inner.call(this, node); + } + }; + }); + + instance.extend("checkGetterSetterParamCount", function () { + return function (prop) { + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.start; + if (prop.kind === "get") { + this.raise(start, "getter should have no params"); + } else { + this.raise(start, "setter should have exactly one param"); + } + } + }; + }); + + instance.extend("checkLVal", function (inner) { + return function (expr, isBinding, checkClashes) { + var _this = this; + + switch (expr.type) { + case "ObjectPattern": + expr.properties.forEach(function (prop) { + _this.checkLVal(prop.type === "Property" ? prop.value : prop, isBinding, checkClashes, "object destructuring pattern"); + }); + break; + default: + for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { + args[_key - 3] = arguments[_key]; + } + + inner.call.apply(inner, [this, expr, isBinding, checkClashes].concat(args)); + } + }; + }); + + instance.extend("checkPropClash", function () { + return function (prop, propHash) { + if (prop.computed || !isSimpleProperty(prop)) return; + + var key = prop.key; + // It is either an Identifier or a String/NumericLiteral + var name = key.type === "Identifier" ? key.name : String(key.value); + + if (name === "__proto__") { + if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); + propHash.proto = true; + } + }; + }); + + instance.extend("isStrictBody", function () { + return function (node, isExpression) { + if (!isExpression && node.body.body.length > 0) { + for (var _iterator = node.body.body, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref2; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref2 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref2 = _i.value; + } + + var directive = _ref2; + + if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") { + if (directive.expression.value === "use strict") return true; + } else { + // Break for the first non literal expression + break; + } + } + } + + return false; + }; + }); + + instance.extend("isValidDirective", function () { + return function (stmt) { + return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && (!stmt.expression.extra || !stmt.expression.extra.parenthesized); + }; + }); + + instance.extend("parseBlockBody", function (inner) { + return function (node) { + var _this2 = this; + + for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + inner.call.apply(inner, [this, node].concat(args)); + + node.directives.reverse().forEach(function (directive) { + node.body.unshift(_this2.directiveToStmt(directive)); + }); + delete node.directives; + }; + }); + + instance.extend("parseClassMethod", function (inner) { + return function (classBody) { + for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { + args[_key3 - 1] = arguments[_key3]; + } + + inner.call.apply(inner, [this, classBody].concat(args)); + + var body = classBody.body; + body[body.length - 1].type = "MethodDefinition"; + }; + }); + + instance.extend("parseExprAtom", function (inner) { + return function () { + switch (this.state.type) { + case types.regexp: + return this.estreeParseRegExpLiteral(this.state.value); + + case types.num: + case types.string: + return this.estreeParseLiteral(this.state.value); + + case types._null: + return this.estreeParseLiteral(null); + + case types._true: + return this.estreeParseLiteral(true); + + case types._false: + return this.estreeParseLiteral(false); + + default: + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + return inner.call.apply(inner, [this].concat(args)); + } + }; + }); + + instance.extend("parseLiteral", function (inner) { + return function () { + for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { + args[_key5] = arguments[_key5]; + } + + var node = inner.call.apply(inner, [this].concat(args)); + node.raw = node.extra.raw; + delete node.extra; + + return node; + }; + }); + + instance.extend("parseMethod", function (inner) { + return function (node) { + var funcNode = this.startNode(); + funcNode.kind = node.kind; // provide kind, so inner method correctly sets state + + for (var _len6 = arguments.length, args = Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) { + args[_key6 - 1] = arguments[_key6]; + } + + funcNode = inner.call.apply(inner, [this, funcNode].concat(args)); + delete funcNode.kind; + node.value = this.finishNode(funcNode, "FunctionExpression"); + + return node; + }; + }); + + instance.extend("parseObjectMethod", function (inner) { + return function () { + for (var _len7 = arguments.length, args = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) { + args[_key7] = arguments[_key7]; + } + + var node = inner.call.apply(inner, [this].concat(args)); + + if (node) { + if (node.kind === "method") node.kind = "init"; + node.type = "Property"; + } + + return node; + }; + }); + + instance.extend("parseObjectProperty", function (inner) { + return function () { + for (var _len8 = arguments.length, args = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) { + args[_key8] = arguments[_key8]; + } + + var node = inner.call.apply(inner, [this].concat(args)); + + if (node) { + node.kind = "init"; + node.type = "Property"; + } + + return node; + }; + }); + + instance.extend("toAssignable", function (inner) { + return function (node, isBinding) { + for (var _len9 = arguments.length, args = Array(_len9 > 2 ? _len9 - 2 : 0), _key9 = 2; _key9 < _len9; _key9++) { + args[_key9 - 2] = arguments[_key9]; + } + + if (isSimpleProperty(node)) { + this.toAssignable.apply(this, [node.value, isBinding].concat(args)); + + return node; + } else if (node.type === "ObjectExpression") { + node.type = "ObjectPattern"; + for (var _iterator2 = node.properties, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref3; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref3 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref3 = _i2.value; + } + + var prop = _ref3; + + if (prop.kind === "get" || prop.kind === "set") { + this.raise(prop.key.start, "Object pattern can't contain getter or setter"); + } else if (prop.method) { + this.raise(prop.key.start, "Object pattern can't contain methods"); + } else { + this.toAssignable(prop, isBinding, "object destructuring pattern"); + } + } + + return node; + } + + return inner.call.apply(inner, [this, node, isBinding].concat(args)); + }; + }); +}; + /* eslint max-len: 0 */ -var pp$7 = Parser.prototype; +var primitiveTypes = ["any", "mixed", "empty", "bool", "boolean", "number", "string", "void", "null"]; -pp$7.flowParseTypeInitialiser = function (tok, allowLeadingPipeOrAnd) { +var pp$8 = Parser.prototype; + +pp$8.flowParseTypeInitialiser = function (tok) { var oldInType = this.state.inType; this.state.inType = true; this.expect(tok || types.colon); - if (allowLeadingPipeOrAnd) { - if (this.match(types.bitwiseAND) || this.match(types.bitwiseOR)) { - this.next(); - } - } + var type = this.flowParseType(); this.state.inType = oldInType; return type; }; -pp$7.flowParseDeclareClass = function (node) { +pp$8.flowParsePredicate = function () { + var node = this.startNode(); + var moduloLoc = this.state.startLoc; + var moduloPos = this.state.start; + this.expect(types.modulo); + var checksLoc = this.state.startLoc; + this.expectContextual("checks"); + // Force '%' and 'checks' to be adjacent + if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) { + this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here."); + } + if (this.eat(types.parenL)) { + node.expression = this.parseExpression(); + this.expect(types.parenR); + return this.finishNode(node, "DeclaredPredicate"); + } else { + return this.finishNode(node, "InferredPredicate"); + } +}; + +pp$8.flowParseTypeAndPredicateInitialiser = function () { + var oldInType = this.state.inType; + this.state.inType = true; + this.expect(types.colon); + var type = null; + var predicate = null; + if (this.match(types.modulo)) { + this.state.inType = oldInType; + predicate = this.flowParsePredicate(); + } else { + type = this.flowParseType(); + this.state.inType = oldInType; + if (this.match(types.modulo)) { + predicate = this.flowParsePredicate(); + } + } + return [type, predicate]; +}; + +pp$8.flowParseDeclareClass = function (node) { this.next(); this.flowParseInterfaceish(node, true); return this.finishNode(node, "DeclareClass"); }; -pp$7.flowParseDeclareFunction = function (node) { +pp$8.flowParseDeclareFunction = function (node) { this.next(); var id = node.id = this.parseIdentifier(); @@ -4420,9 +4919,15 @@ pp$7.flowParseDeclareFunction = function (node) { typeNode.params = tmp.params; typeNode.rest = tmp.rest; this.expect(types.parenR); - typeNode.returnType = this.flowParseTypeInitialiser(); + var predicate = null; + + var _flowParseTypeAndPred = this.flowParseTypeAndPredicateInitialiser(); + + typeNode.returnType = _flowParseTypeAndPred[0]; + predicate = _flowParseTypeAndPred[1]; typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); + typeContainer.predicate = predicate; id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); this.finishNode(id, id.type); @@ -4432,7 +4937,7 @@ pp$7.flowParseDeclareFunction = function (node) { return this.finishNode(node, "DeclareFunction"); }; -pp$7.flowParseDeclare = function (node) { +pp$8.flowParseDeclare = function (node) { if (this.match(types._class)) { return this.flowParseDeclareClass(node); } else if (this.match(types._function)) { @@ -4454,14 +4959,14 @@ pp$7.flowParseDeclare = function (node) { } }; -pp$7.flowParseDeclareVariable = function (node) { +pp$8.flowParseDeclareVariable = function (node) { this.next(); node.id = this.flowParseTypeAnnotatableIdentifier(); this.semicolon(); return this.finishNode(node, "DeclareVariable"); }; -pp$7.flowParseDeclareModule = function (node) { +pp$8.flowParseDeclareModule = function (node) { this.next(); if (this.match(types.string)) { @@ -4474,11 +4979,22 @@ pp$7.flowParseDeclareModule = function (node) { var body = bodyNode.body = []; this.expect(types.braceL); while (!this.match(types.braceR)) { - var node2 = this.startNode(); + var _bodyNode = this.startNode(); + + if (this.match(types._import)) { + var lookahead = this.lookahead(); + if (lookahead.value !== "type" && lookahead.value !== "typeof") { + this.unexpected(null, "Imports within a `declare module` body must always be `import type` or `import typeof`"); + } - this.expectContextual("declare", "Unexpected token. Only declares are allowed inside declare module"); + this.parseImport(_bodyNode); + } else { + this.expectContextual("declare", "Only declares and type imports are allowed inside declare module"); - body.push(this.flowParseDeclare(node2)); + _bodyNode = this.flowParseDeclare(_bodyNode, true); + } + + body.push(_bodyNode); } this.expect(types.braceR); @@ -4486,21 +5002,23 @@ pp$7.flowParseDeclareModule = function (node) { return this.finishNode(node, "DeclareModule"); }; -pp$7.flowParseDeclareModuleExports = function (node) { +pp$8.flowParseDeclareModuleExports = function (node) { this.expectContextual("module"); this.expect(types.dot); this.expectContextual("exports"); node.typeAnnotation = this.flowParseTypeAnnotation(); + this.semicolon(); + return this.finishNode(node, "DeclareModuleExports"); }; -pp$7.flowParseDeclareTypeAlias = function (node) { +pp$8.flowParseDeclareTypeAlias = function (node) { this.next(); this.flowParseTypeAlias(node); return this.finishNode(node, "DeclareTypeAlias"); }; -pp$7.flowParseDeclareInterface = function (node) { +pp$8.flowParseDeclareInterface = function (node) { this.next(); this.flowParseInterfaceish(node); return this.finishNode(node, "DeclareInterface"); @@ -4508,7 +5026,7 @@ pp$7.flowParseDeclareInterface = function (node) { // Interfaces -pp$7.flowParseInterfaceish = function (node, allowStatic) { +pp$8.flowParseInterfaceish = function (node, allowStatic) { node.id = this.parseIdentifier(); if (this.isRelational("<")) { @@ -4536,7 +5054,7 @@ pp$7.flowParseInterfaceish = function (node, allowStatic) { node.body = this.flowParseObjectType(allowStatic); }; -pp$7.flowParseInterfaceExtends = function () { +pp$8.flowParseInterfaceExtends = function () { var node = this.startNode(); node.id = this.flowParseQualifiedTypeIdentifier(); @@ -4549,15 +5067,23 @@ pp$7.flowParseInterfaceExtends = function () { return this.finishNode(node, "InterfaceExtends"); }; -pp$7.flowParseInterface = function (node) { +pp$8.flowParseInterface = function (node) { this.flowParseInterfaceish(node, false); return this.finishNode(node, "InterfaceDeclaration"); }; +pp$8.flowParseRestrictedIdentifier = function (liberal) { + if (primitiveTypes.indexOf(this.state.value) > -1) { + this.raise(this.state.start, "Cannot overwrite primitive type " + this.state.value); + } + + return this.parseIdentifier(liberal); +}; + // Type aliases -pp$7.flowParseTypeAlias = function (node) { - node.id = this.parseIdentifier(); +pp$8.flowParseTypeAlias = function (node) { + node.id = this.flowParseRestrictedIdentifier(); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); @@ -4565,8 +5091,7 @@ pp$7.flowParseTypeAlias = function (node) { node.typeParameters = null; } - node.right = this.flowParseTypeInitialiser(types.eq, - /*allowLeadingPipeOrAnd*/true); + node.right = this.flowParseTypeInitialiser(types.eq); this.semicolon(); return this.finishNode(node, "TypeAlias"); @@ -4574,7 +5099,7 @@ pp$7.flowParseTypeAlias = function (node) { // Type annotations -pp$7.flowParseTypeParameter = function () { +pp$8.flowParseTypeParameter = function () { var node = this.startNode(); var variance = this.flowParseVariance(); @@ -4592,7 +5117,7 @@ pp$7.flowParseTypeParameter = function () { return this.finishNode(node, "TypeParameter"); }; -pp$7.flowParseTypeParameterDeclaration = function () { +pp$8.flowParseTypeParameterDeclaration = function () { var oldInType = this.state.inType; var node = this.startNode(); node.params = []; @@ -4619,9 +5144,9 @@ pp$7.flowParseTypeParameterDeclaration = function () { return this.finishNode(node, "TypeParameterDeclaration"); }; -pp$7.flowParseTypeParameterInstantiation = function () { - var node = this.startNode(), - oldInType = this.state.inType; +pp$8.flowParseTypeParameterInstantiation = function () { + var node = this.startNode(); + var oldInType = this.state.inType; node.params = []; this.state.inType = true; @@ -4640,16 +5165,21 @@ pp$7.flowParseTypeParameterInstantiation = function () { return this.finishNode(node, "TypeParameterInstantiation"); }; -pp$7.flowParseObjectPropertyKey = function () { +pp$8.flowParseObjectPropertyKey = function () { return this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true); }; -pp$7.flowParseObjectTypeIndexer = function (node, isStatic, variance) { +pp$8.flowParseObjectTypeIndexer = function (node, isStatic, variance) { node.static = isStatic; this.expect(types.bracketL); - node.id = this.flowParseObjectPropertyKey(); - node.key = this.flowParseTypeInitialiser(); + if (this.lookahead().type === types.colon) { + node.id = this.flowParseObjectPropertyKey(); + node.key = this.flowParseTypeInitialiser(); + } else { + node.id = null; + node.key = this.flowParseType(); + } this.expect(types.bracketR); node.value = this.flowParseTypeInitialiser(); node.variance = variance; @@ -4658,7 +5188,7 @@ pp$7.flowParseObjectTypeIndexer = function (node, isStatic, variance) { return this.finishNode(node, "ObjectTypeIndexer"); }; -pp$7.flowParseObjectTypeMethodish = function (node) { +pp$8.flowParseObjectTypeMethodish = function (node) { node.params = []; node.rest = null; node.typeParameters = null; @@ -4684,7 +5214,7 @@ pp$7.flowParseObjectTypeMethodish = function (node) { return this.finishNode(node, "FunctionTypeAnnotation"); }; -pp$7.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) { +pp$8.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) { var node = this.startNodeAt(startPos, startLoc); node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(startPos, startLoc)); node.static = isStatic; @@ -4694,7 +5224,7 @@ pp$7.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) { return this.finishNode(node, "ObjectTypeProperty"); }; -pp$7.flowParseObjectTypeCallProperty = function (node, isStatic) { +pp$8.flowParseObjectTypeCallProperty = function (node, isStatic) { var valueNode = this.startNode(); node.static = isStatic; node.value = this.flowParseObjectTypeMethodish(valueNode); @@ -4702,7 +5232,7 @@ pp$7.flowParseObjectTypeCallProperty = function (node, isStatic) { return this.finishNode(node, "ObjectTypeCallProperty"); }; -pp$7.flowParseObjectType = function (allowStatic, allowExact) { +pp$8.flowParseObjectType = function (allowStatic, allowExact) { var oldInType = this.state.inType; this.state.inType = true; @@ -4731,8 +5261,8 @@ pp$7.flowParseObjectType = function (allowStatic, allowExact) { while (!this.match(endDelim)) { var optional = false; - var startPos = this.state.start, - startLoc = this.state.startLoc; + var startPos = this.state.start; + var startLoc = this.state.startLoc; node = this.startNode(); if (allowStatic && this.isContextual("static") && this.lookahead().type !== types.colon) { this.next(); @@ -4748,7 +5278,7 @@ pp$7.flowParseObjectType = function (allowStatic, allowExact) { if (variance) { this.unexpected(variancePos); } - nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, allowStatic)); + nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); } else { propertyKey = this.flowParseObjectPropertyKey(); if (this.isRelational("<") || this.match(types.parenL)) { @@ -4783,13 +5313,13 @@ pp$7.flowParseObjectType = function (allowStatic, allowExact) { return out; }; -pp$7.flowObjectTypeSemicolon = function () { +pp$8.flowObjectTypeSemicolon = function () { if (!this.eat(types.semi) && !this.eat(types.comma) && !this.match(types.braceR) && !this.match(types.braceBarR)) { this.unexpected(); } }; -pp$7.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) { +pp$8.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) { startPos = startPos || this.state.start; startLoc = startLoc || this.state.startLoc; var node = id || this.parseIdentifier(); @@ -4804,7 +5334,7 @@ pp$7.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) { return node; }; -pp$7.flowParseGenericType = function (startPos, startLoc, id) { +pp$8.flowParseGenericType = function (startPos, startLoc, id) { var node = this.startNodeAt(startPos, startLoc); node.typeParameters = null; @@ -4817,14 +5347,14 @@ pp$7.flowParseGenericType = function (startPos, startLoc, id) { return this.finishNode(node, "GenericTypeAnnotation"); }; -pp$7.flowParseTypeofType = function () { +pp$8.flowParseTypeofType = function () { var node = this.startNode(); this.expect(types._typeof); node.argument = this.flowParsePrimaryType(); return this.finishNode(node, "TypeofTypeAnnotation"); }; -pp$7.flowParseTupleType = function () { +pp$8.flowParseTupleType = function () { var node = this.startNode(); node.types = []; this.expect(types.bracketL); @@ -4838,21 +5368,40 @@ pp$7.flowParseTupleType = function () { return this.finishNode(node, "TupleTypeAnnotation"); }; -pp$7.flowParseFunctionTypeParam = function () { +pp$8.flowParseFunctionTypeParam = function () { + var name = null; var optional = false; + var typeAnnotation = null; var node = this.startNode(); - node.name = this.parseIdentifier(); - if (this.eat(types.question)) { - optional = true; + var lh = this.lookahead(); + if (lh.type === types.colon || lh.type === types.question) { + name = this.parseIdentifier(); + if (this.eat(types.question)) { + optional = true; + } + typeAnnotation = this.flowParseTypeInitialiser(); + } else { + typeAnnotation = this.flowParseType(); } + node.name = name; node.optional = optional; - node.typeAnnotation = this.flowParseTypeInitialiser(); + node.typeAnnotation = typeAnnotation; return this.finishNode(node, "FunctionTypeParam"); }; -pp$7.flowParseFunctionTypeParams = function () { - var ret = { params: [], rest: null }; - while (this.match(types.name)) { +pp$8.reinterpretTypeAsFunctionTypeParam = function (type) { + var node = this.startNodeAt(type.start, type.loc); + node.name = null; + node.optional = false; + node.typeAnnotation = type; + return this.finishNode(node, "FunctionTypeParam"); +}; + +pp$8.flowParseFunctionTypeParams = function () { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + + var ret = { params: params, rest: null }; + while (!this.match(types.parenR) && !this.match(types.ellipsis)) { ret.params.push(this.flowParseFunctionTypeParam()); if (!this.match(types.parenR)) { this.expect(types.comma); @@ -4864,7 +5413,7 @@ pp$7.flowParseFunctionTypeParams = function () { return ret; }; -pp$7.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) { +pp$8.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) { switch (id.name) { case "any": return this.finishNode(node, "AnyTypeAnnotation"); @@ -4896,13 +5445,14 @@ pp$7.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) { // The parsing of types roughly parallels the parsing of expressions, and // primary types are kind of like primary expressions...they're the // primitives with which other types are constructed. -pp$7.flowParsePrimaryType = function () { - var startPos = this.state.start, - startLoc = this.state.startLoc; +pp$8.flowParsePrimaryType = function () { + var startPos = this.state.start; + var startLoc = this.state.startLoc; var node = this.startNode(); var tmp = void 0; var type = void 0; var isGroupedType = false; + var oldNoAnonFunctionType = this.state.noAnonFunctionType; switch (this.state.type) { case types.name: @@ -4948,12 +5498,26 @@ pp$7.flowParsePrimaryType = function () { } if (isGroupedType) { + this.state.noAnonFunctionType = false; type = this.flowParseType(); - this.expect(types.parenR); - return type; + this.state.noAnonFunctionType = oldNoAnonFunctionType; + + // A `,` or a `) =>` means this is an anonymous function type + if (this.state.noAnonFunctionType || !(this.match(types.comma) || this.match(types.parenR) && this.lookahead().type === types.arrow)) { + this.expect(types.parenR); + return type; + } else { + // Eat a comma if there is one + this.eat(types.comma); + } + } + + if (type) { + tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]); + } else { + tmp = this.flowParseFunctionTypeParams(); } - tmp = this.flowParseFunctionTypeParams(); node.params = tmp.params; node.rest = tmp.rest; @@ -4962,16 +5526,13 @@ pp$7.flowParsePrimaryType = function () { this.expect(types.arrow); node.returnType = this.flowParseType(); + node.typeParameters = null; return this.finishNode(node, "FunctionTypeAnnotation"); case types.string: - node.value = this.state.value; - this.addExtra(node, "rawValue", node.value); - this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); - this.next(); - return this.finishNode(node, "StringLiteralTypeAnnotation"); + return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); case types._true:case types._false: node.value = this.match(types._true); @@ -4981,21 +5542,14 @@ pp$7.flowParsePrimaryType = function () { case types.plusMin: if (this.state.value === "-") { this.next(); - if (!this.match(types.num)) this.unexpected(); + if (!this.match(types.num)) this.unexpected(null, "Unexpected token, expected number"); - node.value = -this.state.value; - this.addExtra(node, "rawValue", node.value); - this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); - this.next(); - return this.finishNode(node, "NumericLiteralTypeAnnotation"); + return this.parseLiteral(-this.state.value, "NumericLiteralTypeAnnotation", node.start, node.loc.start); } + this.unexpected(); case types.num: - node.value = this.state.value; - this.addExtra(node, "rawValue", node.value); - this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); - this.next(); - return this.finishNode(node, "NumericLiteralTypeAnnotation"); + return this.parseLiteral(this.state.value, "NumericLiteralTypeAnnotation"); case types._null: node.value = this.match(types._null); @@ -5020,19 +5574,21 @@ pp$7.flowParsePrimaryType = function () { this.unexpected(); }; -pp$7.flowParsePostfixType = function () { - var node = this.startNode(); - var type = node.elementType = this.flowParsePrimaryType(); - if (this.match(types.bracketL)) { +pp$8.flowParsePostfixType = function () { + var startPos = this.state.start, + startLoc = this.state.startLoc; + var type = this.flowParsePrimaryType(); + while (!this.canInsertSemicolon() && this.match(types.bracketL)) { + var node = this.startNodeAt(startPos, startLoc); + node.elementType = type; this.expect(types.bracketL); this.expect(types.bracketR); - return this.finishNode(node, "ArrayTypeAnnotation"); - } else { - return type; + type = this.finishNode(node, "ArrayTypeAnnotation"); } + return type; }; -pp$7.flowParsePrefixType = function () { +pp$8.flowParsePrefixType = function () { var node = this.startNode(); if (this.eat(types.question)) { node.typeAnnotation = this.flowParsePrefixType(); @@ -5042,18 +5598,33 @@ pp$7.flowParsePrefixType = function () { } }; -pp$7.flowParseIntersectionType = function () { +pp$8.flowParseAnonFunctionWithoutParens = function () { + var param = this.flowParsePrefixType(); + if (!this.state.noAnonFunctionType && this.eat(types.arrow)) { + var node = this.startNodeAt(param.start, param.loc); + node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; + node.rest = null; + node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); + } + return param; +}; + +pp$8.flowParseIntersectionType = function () { var node = this.startNode(); - var type = this.flowParsePrefixType(); + this.eat(types.bitwiseAND); + var type = this.flowParseAnonFunctionWithoutParens(); node.types = [type]; while (this.eat(types.bitwiseAND)) { - node.types.push(this.flowParsePrefixType()); + node.types.push(this.flowParseAnonFunctionWithoutParens()); } return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); }; -pp$7.flowParseUnionType = function () { +pp$8.flowParseUnionType = function () { var node = this.startNode(); + this.eat(types.bitwiseOR); var type = this.flowParseIntersectionType(); node.types = [type]; while (this.eat(types.bitwiseOR)) { @@ -5062,7 +5633,7 @@ pp$7.flowParseUnionType = function () { return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); }; -pp$7.flowParseType = function () { +pp$8.flowParseType = function () { var oldInType = this.state.inType; this.state.inType = true; var type = this.flowParseUnionType(); @@ -5070,14 +5641,25 @@ pp$7.flowParseType = function () { return type; }; -pp$7.flowParseTypeAnnotation = function () { +pp$8.flowParseTypeAnnotation = function () { var node = this.startNode(); node.typeAnnotation = this.flowParseTypeInitialiser(); return this.finishNode(node, "TypeAnnotation"); }; -pp$7.flowParseTypeAnnotatableIdentifier = function () { - var ident = this.parseIdentifier(); +pp$8.flowParseTypeAndPredicateAnnotation = function () { + var node = this.startNode(); + + var _flowParseTypeAndPred2 = this.flowParseTypeAndPredicateInitialiser(); + + node.typeAnnotation = _flowParseTypeAndPred2[0]; + node.predicate = _flowParseTypeAndPred2[1]; + + return this.finishNode(node, "TypeAnnotation"); +}; + +pp$8.flowParseTypeAnnotatableIdentifier = function () { + var ident = this.flowParseRestrictedIdentifier(); if (this.match(types.colon)) { ident.typeAnnotation = this.flowParseTypeAnnotation(); this.finishNode(ident, ident.type); @@ -5085,13 +5667,13 @@ pp$7.flowParseTypeAnnotatableIdentifier = function () { return ident; }; -pp$7.typeCastToParameter = function (node) { +pp$8.typeCastToParameter = function (node) { node.expression.typeAnnotation = node.typeAnnotation; return this.finishNodeAt(node.expression, node.expression.type, node.typeAnnotation.end, node.typeAnnotation.loc.end); }; -pp$7.flowParseVariance = function () { +pp$8.flowParseVariance = function () { var variance = null; if (this.match(types.plusMin)) { if (this.state.value === "+") { @@ -5111,7 +5693,7 @@ var flowPlugin = function (instance) { if (this.match(types.colon) && !allowExpression) { // if allowExpression is true then we're parsing an arrow function and if // there's a return type then it's been handled elsewhere - node.returnType = this.flowParseTypeAnnotation(); + node.returnType = this.flowParseTypeAndPredicateAnnotation(); } return inner.call(this, node, allowExpression); @@ -5262,17 +5844,6 @@ var flowPlugin = function (instance) { }; }); - // ensure that inside property names, < isn't interpreted as JSX, but as a type parameter - instance.extend("parsePropertyName", function (inner) { - return function (prop) { - var oldInType = this.state.inType; - this.state.inType = true; - var out = inner.call(this, prop); - this.state.inType = oldInType; - return out; - }; - }); - // ensure that inside flow types, we bypass the jsx parser plugin instance.extend("readToken", function (inner) { return function (code) { @@ -5332,9 +5903,14 @@ var flowPlugin = function (instance) { // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents // the position where this function is called instance.extend("parseExprListItem", function (inner) { - return function (allowEmpty, refShorthandDefaultPos) { + return function () { var container = this.startNode(); - var node = inner.call(this, allowEmpty, refShorthandDefaultPos); + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var node = inner.call.apply(inner, [this].concat(args)); if (this.match(types.colon)) { container._exprListItem = true; container.expression = node; @@ -5373,8 +5949,8 @@ var flowPlugin = function (instance) { }); // parse type parameters for class methods - instance.extend("parseClassMethod", function () { - return function (classBody, method, isGenerator, isAsync) { + instance.extend("parseClassMethod", function (inner) { + return function (classBody, method) { if (method.variance) { this.unexpected(method.variancePos); } @@ -5383,8 +5959,12 @@ var flowPlugin = function (instance) { if (this.isRelational("<")) { method.typeParameters = this.flowParseTypeParameterDeclaration(); } - this.parseMethod(method, isGenerator, isAsync); - classBody.body.push(this.finishNode(method, "ClassMethod")); + + for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + + inner.call.apply(inner, [this, classBody, method].concat(args)); }; }); @@ -5464,8 +6044,8 @@ var flowPlugin = function (instance) { instance.extend("parseMaybeDefault", function (inner) { return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; + for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; } var node = inner.apply(this, args); @@ -5501,6 +6081,62 @@ var flowPlugin = function (instance) { }; }); + // parse import-type/typeof shorthand + instance.extend("parseImportSpecifier", function () { + return function (node) { + var specifier = this.startNode(); + var firstIdentLoc = this.state.start; + var firstIdent = this.parseIdentifier(true); + + var specifierTypeKind = null; + if (firstIdent.name === "type") { + specifierTypeKind = "type"; + } else if (firstIdent.name === "typeof") { + specifierTypeKind = "typeof"; + } + + var isBinding = false; + if (this.isContextual("as")) { + var as_ident = this.parseIdentifier(true); + if (specifierTypeKind !== null && !this.match(types.name) && !this.state.type.keyword) { + // `import {type as ,` or `import {type as }` + specifier.imported = as_ident; + specifier.importKind = specifierTypeKind; + specifier.local = as_ident.__clone(); + } else { + // `import {type as foo` + specifier.imported = firstIdent; + specifier.importKind = null; + specifier.local = this.parseIdentifier(); + } + } else if (specifierTypeKind !== null && (this.match(types.name) || this.state.type.keyword)) { + // `import {type foo` + specifier.imported = this.parseIdentifier(true); + specifier.importKind = specifierTypeKind; + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + isBinding = true; + specifier.local = specifier.imported.__clone(); + } + } else { + isBinding = true; + specifier.imported = firstIdent; + specifier.importKind = null; + specifier.local = specifier.imported.__clone(); + } + + if ((node.importKind === "type" || node.importKind === "typeof") && (specifier.importKind === "type" || specifier.importKind === "typeof")) { + 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`"); + } + + if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true); + + this.checkLVal(specifier.local, true, undefined, "import specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + }; + }); + // parse function type parameters - function foo<T>() {} instance.extend("parseFunctionParams", function (inner) { return function (node) { @@ -5526,7 +6162,10 @@ var flowPlugin = function (instance) { instance.extend("parseAsyncArrowFromCallExpression", function (inner) { return function (node, call) { if (this.match(types.colon)) { + var oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; node.returnType = this.flowParseTypeAnnotation(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; } return inner.call(this, node, call); @@ -5554,8 +6193,8 @@ var flowPlugin = function (instance) { return function () { var jsxError = null; - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; } if (types.jsxTagStart && this.match(types.jsxTagStart)) { @@ -5610,7 +6249,11 @@ var flowPlugin = function (instance) { if (this.match(types.colon)) { var state = this.state.clone(); try { - var returnType = this.flowParseTypeAnnotation(); + var oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; + var returnType = this.flowParseTypeAndPredicateAnnotation(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + if (this.canInsertSemicolon()) this.unexpected(); if (!this.match(types.arrow)) this.unexpected(); // assign after it is clear it is an arrow @@ -5646,6 +6289,74 @@ var flowPlugin = function (instance) { }); }; +// Adapted from String.fromcodepoint to export the function without modifying String +/*! https://mths.be/fromcodepoint v0.2.1 by @mathias */ + +// The MIT License (MIT) +// Copyright (c) Mathias Bynens +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +// associated documentation files (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, publish, distribute, +// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +var fromCodePoint = String.fromCodePoint; + +if (!fromCodePoint) { + var stringFromCharCode = String.fromCharCode; + var floor = Math.floor; + fromCodePoint = function fromCodePoint() { + var MAX_SIZE = 0x4000; + var codeUnits = []; + var highSurrogate = void 0; + var lowSurrogate = void 0; + var index = -1; + var length = arguments.length; + if (!length) { + return ""; + } + var result = ""; + while (++index < length) { + var codePoint = Number(arguments[index]); + if (!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` + codePoint < 0 || // not a valid Unicode code point + codePoint > 0x10FFFF || // not a valid Unicode code point + floor(codePoint) != codePoint // not an integer + ) { + throw RangeError("Invalid code point: " + codePoint); + } + if (codePoint <= 0xFFFF) { + // BMP code point + codeUnits.push(codePoint); + } else { + // Astral code point; split in surrogate halves + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + codePoint -= 0x10000; + highSurrogate = (codePoint >> 10) + 0xD800; + lowSurrogate = codePoint % 0x400 + 0xDC00; + codeUnits.push(highSurrogate, lowSurrogate); + } + if (index + 1 == length || codeUnits.length > MAX_SIZE) { + result += stringFromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result; + }; +} + +var fromCodePoint$1 = fromCodePoint; + var XHTMLEntities = { quot: "\"", amp: "&", @@ -5902,8 +6613,6 @@ var XHTMLEntities = { diams: "\u2666" }; -/* eslint indent: 0 */ - var HEX_NUMBER = /^[\da-fA-F]+$/; var DECIMAL_NUMBER = /^\d+$/; @@ -5932,11 +6641,11 @@ types.jsxTagEnd.updateContext = function (prevType) { } }; -var pp$8 = Parser.prototype; +var pp$9 = Parser.prototype; // Reads inline JSX contents token. -pp$8.jsxReadToken = function () { +pp$9.jsxReadToken = function () { var out = ""; var chunkStart = this.state.pos; for (;;) { @@ -5979,7 +6688,7 @@ pp$8.jsxReadToken = function () { } }; -pp$8.jsxReadNewLine = function (normalizeCRLF) { +pp$9.jsxReadNewLine = function (normalizeCRLF) { var ch = this.input.charCodeAt(this.state.pos); var out = void 0; ++this.state.pos; @@ -5995,7 +6704,7 @@ pp$8.jsxReadNewLine = function (normalizeCRLF) { return out; }; -pp$8.jsxReadString = function (quote) { +pp$9.jsxReadString = function (quote) { var out = ""; var chunkStart = ++this.state.pos; for (;;) { @@ -6022,7 +6731,7 @@ pp$8.jsxReadString = function (quote) { return this.finishToken(types.string, out); }; -pp$8.jsxReadEntity = function () { +pp$9.jsxReadEntity = function () { var str = ""; var count = 0; var entity = void 0; @@ -6035,10 +6744,10 @@ pp$8.jsxReadEntity = function () { if (str[0] === "#") { if (str[1] === "x") { str = str.substr(2); - if (HEX_NUMBER.test(str)) entity = String.fromCharCode(parseInt(str, 16)); + if (HEX_NUMBER.test(str)) entity = fromCodePoint$1(parseInt(str, 16)); } else { str = str.substr(1); - if (DECIMAL_NUMBER.test(str)) entity = String.fromCharCode(parseInt(str, 10)); + if (DECIMAL_NUMBER.test(str)) entity = fromCodePoint$1(parseInt(str, 10)); } } else { entity = XHTMLEntities[str]; @@ -6061,7 +6770,7 @@ pp$8.jsxReadEntity = function () { // Also assumes that first character was already checked // by isIdentifierStart in readToken. -pp$8.jsxReadWord = function () { +pp$9.jsxReadWord = function () { var ch = void 0; var start = this.state.pos; do { @@ -6088,7 +6797,7 @@ function getQualifiedJSXName(object) { // Parse next token as JSX identifier -pp$8.jsxParseIdentifier = function () { +pp$9.jsxParseIdentifier = function () { var node = this.startNode(); if (this.match(types.jsxName)) { node.name = this.state.value; @@ -6103,9 +6812,9 @@ pp$8.jsxParseIdentifier = function () { // Parse namespaced identifier. -pp$8.jsxParseNamespacedName = function () { - var startPos = this.state.start, - startLoc = this.state.startLoc; +pp$9.jsxParseNamespacedName = function () { + var startPos = this.state.start; + var startLoc = this.state.startLoc; var name = this.jsxParseIdentifier(); if (!this.eat(types.colon)) return name; @@ -6118,9 +6827,9 @@ pp$8.jsxParseNamespacedName = function () { // Parses element name in any form - namespaced, member // or single identifier. -pp$8.jsxParseElementName = function () { - var startPos = this.state.start, - startLoc = this.state.startLoc; +pp$9.jsxParseElementName = function () { + var startPos = this.state.start; + var startLoc = this.state.startLoc; var node = this.jsxParseNamespacedName(); while (this.eat(types.dot)) { var newNode = this.startNodeAt(startPos, startLoc); @@ -6133,7 +6842,7 @@ pp$8.jsxParseElementName = function () { // Parses any type of JSX attribute value. -pp$8.jsxParseAttributeValue = function () { +pp$9.jsxParseAttributeValue = function () { var node = void 0; switch (this.state.type) { case types.braceL: @@ -6159,14 +6868,14 @@ pp$8.jsxParseAttributeValue = function () { // and so it should start at the end of last read token (left brace) and finish // at the beginning of the next one (right brace). -pp$8.jsxParseEmptyExpression = function () { - var node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); - return this.finishNodeAt(node, "JSXEmptyExpression", this.start, this.startLoc); +pp$9.jsxParseEmptyExpression = function () { + var node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); + return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); }; // Parse JSX spread child -pp$8.jsxParseSpreadChild = function () { +pp$9.jsxParseSpreadChild = function () { var node = this.startNode(); this.expect(types.braceL); this.expect(types.ellipsis); @@ -6179,7 +6888,7 @@ pp$8.jsxParseSpreadChild = function () { // Parses JSX expression enclosed into curly brackets. -pp$8.jsxParseExpressionContainer = function () { +pp$9.jsxParseExpressionContainer = function () { var node = this.startNode(); this.next(); if (this.match(types.braceR)) { @@ -6193,7 +6902,7 @@ pp$8.jsxParseExpressionContainer = function () { // Parses following JSX attribute name-value pair. -pp$8.jsxParseAttribute = function () { +pp$9.jsxParseAttribute = function () { var node = this.startNode(); if (this.eat(types.braceL)) { this.expect(types.ellipsis); @@ -6208,7 +6917,7 @@ pp$8.jsxParseAttribute = function () { // Parses JSX opening tag starting after "<". -pp$8.jsxParseOpeningElementAt = function (startPos, startLoc) { +pp$9.jsxParseOpeningElementAt = function (startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); node.attributes = []; node.name = this.jsxParseElementName(); @@ -6222,7 +6931,7 @@ pp$8.jsxParseOpeningElementAt = function (startPos, startLoc) { // Parses JSX closing tag starting after "</". -pp$8.jsxParseClosingElementAt = function (startPos, startLoc) { +pp$9.jsxParseClosingElementAt = function (startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); node.name = this.jsxParseElementName(); this.expect(types.jsxTagEnd); @@ -6232,7 +6941,7 @@ pp$8.jsxParseClosingElementAt = function (startPos, startLoc) { // Parses entire JSX element, including it"s opening tag // (starting after "<"), attributes, contents and closing tag. -pp$8.jsxParseElementAt = function (startPos, startLoc) { +pp$9.jsxParseElementAt = function (startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); var children = []; var openingElement = this.jsxParseOpeningElementAt(startPos, startLoc); @@ -6286,9 +6995,9 @@ pp$8.jsxParseElementAt = function (startPos, startLoc) { // Parses entire JSX element from current position. -pp$8.jsxParseElement = function () { - var startPos = this.state.start, - startLoc = this.state.startLoc; +pp$9.jsxParseElement = function () { + var startPos = this.state.start; + var startLoc = this.state.startLoc; this.next(); return this.jsxParseElementAt(startPos, startLoc); }; @@ -6311,6 +7020,8 @@ var jsxPlugin = function (instance) { instance.extend("readToken", function (inner) { return function (code) { + if (this.state.inPropertyName) return inner.call(this, code); + var context = this.curContext(); if (context === types$1.j_expr) { @@ -6364,12 +7075,22 @@ var jsxPlugin = function (instance) { }); }; +plugins.estree = estreePlugin; plugins.flow = flowPlugin; plugins.jsx = jsxPlugin; -function parse$1(input, options) { +function parse(input, options) { return new Parser(options, input).parse(); } -exports.parse = parse$1; +function parseExpression(input, options) { + var parser = new Parser(options, input); + if (parser.options.strictMode) { + parser.state.strict = true; + } + return parser.getExpression(); +} + +exports.parse = parse; +exports.parseExpression = parseExpression; exports.tokTypes = types; |