} else { // A leading comment for an anonymous class had been stolen by its first ClassMethod, // so this takes back the leading comment. // See also: https://github.com/eslint/espree/issues/158 for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { if (lastChild.leadingComments[i].end <= node.start) { node.leadingComments = lastChild.leadingComments.splice(0, i + 1); break; } } } } } else if (this.state.leadingComments.length > 0) { if (last(this.state.leadingComments).end <= node.start) { if (this.state.commentPreviousNode) { for (j = 0; j < this.state.leadingComments.length; j++) { if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { this.state.leadingComments.splice(j, 1); j--; } } } if (this.state.leadingComments.length > 0) { node.leadingComments = this.state.leadingComments; this.state.leadingComments = []; } } else { // https://github.com/eslint/espree/issues/2 // // In special cases, such as return (without a value) and // debugger, all comments will end up as leadingComments and // will otherwise be eliminated. This step runs when the // commentStack is empty and there are comments left // in leadingComments. // // This loop figures out the stopping point between the actual // leading and trailing comments by finding the location of the // first comment that comes after the given node. for (i = 0; i < this.state.leadingComments.length; i++) { if (this.state.leadingComments[i].end > node.start) { break; } } // Split the array based on the location of the first comment // that comes after the node. Keep in mind that this could // result in an empty array, and if so, the array must be // deleted. node.leadingComments = this.state.leadingComments.slice(0, i); if (node.leadingComments.length === 0) { node.leadingComments = null; } // Similarly, trailing comments are attached later. The variable // must be reset to null if there are no trailing comments. trailingComments = this.state.leadingComments.slice(i); if (trailingComments.length === 0) { trailingComments = null; } } } this.state.commentPreviousNode = node; if (trailingComments) { if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) { node.innerComments = trailingComments; } else { node.trailingComments = trailingComments; } } stack.push(node); }; 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("stmtToDirective", function (inner) { return function (stmt) { var directive = inner.call(this, stmt); var value = stmt.expression.value; // Reset value to the actual value as in estree mode we want // the stmt to have the real value and not the raw value directive.value.value = value; return directive; }; }); 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 () { return function (classBody, method, isGenerator, isAsync) { this.parseMethod(method, isGenerator, isAsync); if (method.typeParameters) { method.value.typeParameters = method.typeParameters; delete method.typeParameters; } classBody.body.push(this.finishNode(method, "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 _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } return inner.call.apply(inner, [this].concat(args)); } }; }); instance.extend("parseLiteral", function (inner) { return function () { for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } 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 _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) { args[_key5 - 1] = arguments[_key5]; } 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 _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { args[_key6] = arguments[_key6]; } 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 _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) { node.kind = "init"; node.type = "Property"; } return node; }; }); instance.extend("toAssignable", function (inner) { return function (node, isBinding) { for (var _len8 = arguments.length, args = Array(_len8 > 2 ? _len8 - 2 : 0), _key8 = 2; _key8 < _len8; _key8++) { args[_key8 - 2] = arguments[_key8]; } 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 primitiveTypes = ["any", "mixed", "empty", "bool", "boolean", "number", "string", "void", "null"]; var pp$8 = Parser.prototype; pp$8.flowParseTypeInitialiser = function (tok) { var oldInType = this.state.inType; this.state.inType = true; this.expect(tok || types.colon); var type = this.flowParseType(); this.state.inType = oldInType; return type; }; 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$8.flowParseDeclareFunction = function (node) { this.next(); var id = node.id = this.parseIdentifier(); var typeNode = this.startNode(); var typeContainer = this.startNode(); if (this.isRelational("<")) { typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); } else { typeNode.typeParameters = null; } this.expect(types.parenL); var tmp = this.flowParseFunctionTypeParams(); typeNode.params = tmp.params; typeNode.rest = tmp.rest; this.expect(types.parenR); 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); this.semicolon(); return this.finishNode(node, "DeclareFunction"); }; pp$8.flowParseDeclare = function (node) { if (this.match(types._class)) { return this.flowParseDeclareClass(node); } else if (this.match(types._function)) { return this.flowParseDeclareFunction(node); } else if (this.match(types._var)) { return this.flowParseDeclareVariable(node); } else if (this.isContextual("module")) { if (this.lookahead().type === types.dot) { return this.flowParseDeclareModuleExports(node); } else { return this.flowParseDeclareModule(node); } } else if (this.isContextual("type")) { return this.flowParseDeclareTypeAlias(node); } else if (this.isContextual("opaque")) { return this.flowParseDeclareOpaqueType(node); } else if (this.isContextual("interface")) { return this.flowParseDeclareInterface(node); } else if (this.match(types._export)) { return this.flowParseDeclareExportDeclaration(node); } else { this.unexpected(); } }; pp$8.flowParseDeclareExportDeclaration = function (node) { this.expect(types._export); if (this.isContextual("opaque") // declare export opaque ... ) { node.declaration = this.flowParseDeclare(this.startNode()); node.default = false; return this.finishNode(node, "DeclareExportDeclaration"); } throw this.unexpected(); }; pp$8.flowParseDeclareVariable = function (node) { this.next(); node.id = this.flowParseTypeAnnotatableIdentifier(); this.semicolon(); return this.finishNode(node, "DeclareVariable"); }; pp$8.flowParseDeclareModule = function (node) { this.next(); if (this.match(types.string)) { node.id = this.parseExprAtom(); } else { node.id = this.parseIdentifier(); } var bodyNode = node.body = this.startNode(); var body = bodyNode.body = []; this.expect(types.braceL); while (!this.match(types.braceR)) { 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.parseImport(_bodyNode); } else { this.expectContextual("declare", "Only declares and type imports are allowed inside declare module"); _bodyNode = this.flowParseDeclare(_bodyNode, true); } body.push(_bodyNode); } this.expect(types.braceR); this.finishNode(bodyNode, "BlockStatement"); return this.finishNode(node, "DeclareModule"); }; 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$8.flowParseDeclareTypeAlias = function (node) { this.next(); this.flowParseTypeAlias(node); return this.finishNode(node, "DeclareTypeAlias"); }; pp$8.flowParseDeclareOpaqueType = function (node) { this.next(); this.flowParseOpaqueType(node, true); return this.finishNode(node, "DeclareOpaqueType"); }; pp$8.flowParseDeclareInterface = function (node) { this.next(); this.flowParseInterfaceish(node); return this.finishNode(node, "DeclareInterface"); }; // Interfaces pp$8.flowParseInterfaceish = function (node) { node.id = this.parseIdentifier(); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } else { node.typeParameters = null; } node.extends = []; node.mixins = []; if (this.eat(types._extends)) { do { node.extends.push(this.flowParseInterfaceExtends()); } while (this.eat(types.comma)); } if (this.isContextual("mixins")) { this.next(); do { node.mixins.push(this.flowParseInterfaceExtends()); } while (this.eat(types.comma)); } node.body = this.flowParseObjectType(true, false, false); }; pp$8.flowParseInterfaceExtends = function () { var node = this.startNode(); node.id = this.flowParseQualifiedTypeIdentifier(); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterInstantiation(); } else { node.typeParameters = null; } return this.finishNode(node, "InterfaceExtends"); }; 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$8.flowParseTypeAlias = function (node) { node.id = this.flowParseRestrictedIdentifier(); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } else { node.typeParameters = null; } node.right = this.flowParseTypeInitialiser(types.eq); this.semicolon(); return this.finishNode(node, "TypeAlias"); }; // Opaque type aliases pp$8.flowParseOpaqueType = function (node, declare) { this.expectContextual("type"); node.id = this.flowParseRestrictedIdentifier(); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } else { node.typeParameters = null; } // Parse the supertype node.supertype = null; if (this.match(types.colon)) { node.supertype = this.flowParseTypeInitialiser(types.colon); } node.impltype = null; if (!declare) { node.impltype = this.flowParseTypeInitialiser(types.eq); } this.semicolon(); return this.finishNode(node, "OpaqueType"); }; // Type annotations pp$8.flowParseTypeParameter = function () { var node = this.startNode(); var variance = this.flowParseVariance(); var ident = this.flowParseTypeAnnotatableIdentifier(); node.name = ident.name; node.variance = variance; node.bound = ident.typeAnnotation; if (this.match(types.eq)) { this.eat(types.eq); node.default = this.flowParseType(); } return this.finishNode(node, "TypeParameter"); }; pp$8.flowParseTypeParameterDeclaration = function () { var oldInType = this.state.inType; var node = this.startNode(); node.params = []; this.state.inType = true; // istanbul ignore else: this condition is already checked at all call sites if (this.isRelational("<") || this.match(types.jsxTagStart)) { this.next(); } else { this.unexpected(); } do { node.params.push(this.flowParseTypeParameter()); if (!this.isRelational(">")) { this.expect(types.comma); } } while (!this.isRelational(">")); this.expectRelational(">"); this.state.inType = oldInType; return this.finishNode(node, "TypeParameterDeclaration"); }; pp$8.flowParseTypeParameterInstantiation = function () { var node = this.startNode(); var oldInType = this.state.inType; node.params = []; this.state.inType = true; this.expectRelational("<"); while (!this.isRelational(">")) { node.params.push(this.flowParseType()); if (!this.isRelational(">")) { this.expect(types.comma); } } this.expectRelational(">"); this.state.inType = oldInType; return this.finishNode(node, "TypeParameterInstantiation"); }; pp$8.flowParseObjectPropertyKey = function () { return this.match(types.num) || this.match(types.string) ? this.parseExprAtom() : this.parseIdentifier(true); }; pp$8.flowParseObjectTypeIndexer = function (node, isStatic, variance) { node.static = isStatic; this.expect(types.bracketL); 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; this.flowObjectTypeSemicolon(); return this.finishNode(node, "ObjectTypeIndexer"); }; pp$8.flowParseObjectTypeMethodish = function (node) { node.params = []; node.rest = null; node.typeParameters = null; if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } this.expect(types.parenL); while (!this.match(types.parenR) && !this.match(types.ellipsis)) { node.params.push(this.flowParseFunctionTypeParam()); if (!this.match(types.parenR)) { this.expect(types.comma); } } if (this.eat(types.ellipsis)) { node.rest = this.flowParseFunctionTypeParam(); } this.expect(types.parenR); node.returnType = this.flowParseTypeInitialiser(); return this.finishNode(node, "FunctionTypeAnnotation"); }; 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; node.key = key; node.optional = false; this.flowObjectTypeSemicolon(); return this.finishNode(node, "ObjectTypeProperty"); }; pp$8.flowParseObjectTypeCallProperty = function (node, isStatic) { var valueNode = this.startNode(); node.static = isStatic; node.value = this.flowParseObjectTypeMethodish(valueNode); this.flowObjectTypeSemicolon(); return this.finishNode(node, "ObjectTypeCallProperty"); }; pp$8.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { var oldInType = this.state.inType; this.state.inType = true; var nodeStart = this.startNode(); var node = void 0; var propertyKey = void 0; var isStatic = false; nodeStart.callProperties = []; nodeStart.properties = []; nodeStart.indexers = []; var endDelim = void 0; var exact = void 0; if (allowExact && this.match(types.braceBarL)) { this.expect(types.braceBarL); endDelim = types.braceBarR; exact = true; } else { this.expect(types.braceL); endDelim = types.braceR; exact = false; } nodeStart.exact = exact; while (!this.match(endDelim)) { var optional = false; 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(); isStatic = true; } var variancePos = this.state.start; var variance = this.flowParseVariance(); if (this.match(types.bracketL)) { nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); } else if (this.match(types.parenL) || this.isRelational("<")) { if (variance) { this.unexpected(variancePos); } nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); } else { if (this.match(types.ellipsis)) { if (!allowSpread) { this.unexpected(null, "Spread operator cannot appear in class or interface definitions"); } if (variance) { this.unexpected(variance.start, "Spread properties cannot have variance"); } this.expect(types.ellipsis); node.argument = this.flowParseType(); this.flowObjectTypeSemicolon(); nodeStart.properties.push(this.finishNode(node, "ObjectTypeSpreadProperty")); } else { propertyKey = this.flowParseObjectPropertyKey(); if (this.isRelational("<") || this.match(types.parenL)) { // This is a method property if (variance) { this.unexpected(variance.start); } nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey)); } else { if (this.eat(types.question)) { optional = true; } node.key = propertyKey; node.value = this.flowParseTypeInitialiser(); node.optional = optional; node.static = isStatic; node.variance = variance; this.flowObjectTypeSemicolon(); nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty")); } } } isStatic = false; } this.expect(endDelim); var out = this.finishNode(nodeStart, "ObjectTypeAnnotation"); this.state.inType = oldInType; return out; }; pp$8.flowObjectTypeSemicolon = function () { if (!this.eat(types.semi) && !this.eat(types.comma) && !this.match(types.braceR) && !this.match(types.braceBarR)) { this.unexpected(); } }; pp$8.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) { startPos = startPos || this.state.start; startLoc = startLoc || this.state.startLoc; var node = id || this.parseIdentifier(); while (this.eat(types.dot)) { var node2 = this.startNodeAt(startPos, startLoc); node2.qualification = node; node2.id = this.parseIdentifier(); node = this.finishNode(node2, "QualifiedTypeIdentifier"); } return node; }; pp$8.flowParseGenericType = function (startPos, startLoc, id) { var node = this.startNodeAt(startPos, startLoc); node.typeParameters = null; node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterInstantiation(); } return this.finishNode(node, "GenericTypeAnnotation"); }; pp$8.flowParseTypeofType = function () { var node = this.startNode(); this.expect(types._typeof); node.argument = this.flowParsePrimaryType(); return this.finishNode(node, "TypeofTypeAnnotation"); }; pp$8.flowParseTupleType = function () { var node = this.startNode(); node.types = []; this.expect(types.bracketL); // We allow trailing commas while (this.state.pos < this.input.length && !this.match(types.bracketR)) { node.types.push(this.flowParseType()); if (this.match(types.bracketR)) break; this.expect(types.comma); } this.expect(types.bracketR); return this.finishNode(node, "TupleTypeAnnotation"); }; pp$8.flowParseFunctionTypeParam = function () { var name = null; var optional = false; var typeAnnotation = null; var node = this.startNode(); 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 = typeAnnotation; return this.finishNode(node, "FunctionTypeParam"); }; pp$8.reinterpretTypeAsFunctionTypeParam = function (type) { var node = this.startNodeAt(type.start, type.loc.start); 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); } } if (this.eat(types.ellipsis)) { ret.rest = this.flowParseFunctionTypeParam(); } return ret; }; pp$8.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) { switch (id.name) { case "any": return this.finishNode(node, "AnyTypeAnnotation"); case "void": return this.finishNode(node, "VoidTypeAnnotation"); case "bool": case "boolean": return this.finishNode(node, "BooleanTypeAnnotation"); case "mixed": return this.finishNode(node, "MixedTypeAnnotation"); case "empty": return this.finishNode(node, "EmptyTypeAnnotation"); case "number": return this.finishNode(node, "NumberTypeAnnotation"); case "string": return this.finishNode(node, "StringTypeAnnotation"); default: return this.flowParseGenericType(startPos, startLoc, 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$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: return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); case types.braceL: return this.flowParseObjectType(false, false, true); case types.braceBarL: return this.flowParseObjectType(false, true, true); case types.bracketL: return this.flowParseTupleType(); case types.relational: if (this.state.value === "<") { node.typeParameters = this.flowParseTypeParameterDeclaration(); this.expect(types.parenL); tmp = this.flowParseFunctionTypeParams(); node.params = tmp.params; node.rest = tmp.rest; this.expect(types.parenR); this.expect(types.arrow); node.returnType = this.flowParseType(); return this.finishNode(node, "FunctionTypeAnnotation"); } break; case types.parenL: this.next(); // Check to see if this is actually a grouped type if (!this.match(types.parenR) && !this.match(types.ellipsis)) { if (this.match(types.name)) { var token = this.lookahead().type; isGroupedType = token !== types.question && token !== types.colon; } else { isGroupedType = true; } } if (isGroupedType) { this.state.noAnonFunctionType = false; type = this.flowParseType(); 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(); } node.params = tmp.params; node.rest = tmp.rest; this.expect(types.parenR); this.expect(types.arrow); node.returnType = this.flowParseType(); node.typeParameters = null; return this.finishNode(node, "FunctionTypeAnnotation"); case types.string: return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); case types._true:case types._false: node.value = this.match(types._true); this.next(); return this.finishNode(node, "BooleanLiteralTypeAnnotation"); case types.plusMin: if (this.state.value === "-") { this.next(); if (!this.match(types.num)) this.unexpected(null, "Unexpected token, expected number"); return this.parseLiteral(-this.state.value, "NumericLiteralTypeAnnotation", node.start, node.loc.start); } this.unexpected(); case types.num: return this.parseLiteral(this.state.value, "NumericLiteralTypeAnnotation"); case types._null: node.value = this.match(types._null); this.next(); return this.finishNode(node, "NullLiteralTypeAnnotation"); case types._this: node.value = this.match(types._this); this.next(); return this.finishNode(node, "ThisTypeAnnotation"); case types.star: this.next(); return this.finishNode(node, "ExistentialTypeParam"); default: if (this.state.type.keyword === "typeof") { return this.flowParseTypeofType(); } } this.unexpected(); }; 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); type = this.finishNode(node, "ArrayTypeAnnotation"); } return type; }; pp$8.flowParsePrefixType = function () { var node = this.startNode(); if (this.eat(types.question)) { node.typeAnnotation = this.flowParsePrefixType(); return this.finishNode(node, "NullableTypeAnnotation"); } else { return this.flowParsePostfixType(); } }; pp$8.flowParseAnonFunctionWithoutParens = function () { var param = this.flowParsePrefixType(); if (!this.state.noAnonFunctionType && this.eat(types.arrow)) { var node = this.startNodeAt(param.start, param.loc.start); 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(); this.eat(types.bitwiseAND); var type = this.flowParseAnonFunctionWithoutParens(); node.types = [type]; while (this.eat(types.bitwiseAND)) { node.types.push(this.flowParseAnonFunctionWithoutParens()); } return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); }; pp$8.flowParseUnionType = function () { var node = this.startNode(); this.eat(types.bitwiseOR); var type = this.flowParseIntersectionType(); node.types = [type]; while (this.eat(types.bitwiseOR)) { node.types.push(this.flowParseIntersectionType()); } return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); }; pp$8.flowParseType = function () { var oldInType = this.state.inType; this.state.inType = true; var type = this.flowParseUnionType(); this.state.inType = oldInType; return type; }; pp$8.flowParseTypeAnnotation = function () { var node = this.startNode(); node.typeAnnotation = this.flowParseTypeInitialiser(); return this.finishNode(node, "TypeAnnotation"); }; 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); } return ident; }; 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$8.flowParseVariance = function () { var variance = null; if (this.match(types.plusMin)) { if (this.state.value === "+") { variance = "plus"; } else if (this.state.value === "-") { variance = "minus"; } this.next(); } return variance; }; var flowPlugin = function (instance) { // plain function return types: function name(): string {} instance.extend("parseFunctionBody", function (inner) { return function (node, allowExpression) { 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.flowParseTypeAndPredicateAnnotation(); } return inner.call(this, node, allowExpression); }; }); // interfaces instance.extend("parseStatement", function (inner) { return function (declaration, topLevel) { // strict mode handling of `interface` since it's a reserved word if (this.state.strict && this.match(types.name) && this.state.value === "interface") { var node = this.startNode(); this.next(); return this.flowParseInterface(node); } else { return inner.call(this, declaration, topLevel); } }; }); // declares, interfaces and type aliases instance.extend("parseExpressionStatement", function (inner) { return function (node, expr) { if (expr.type === "Identifier") { if (expr.name === "declare") { if (this.match(types._class) || this.match(types.name) || this.match(types._function) || this.match(types._var) || this.match(types._export)) { return this.flowParseDeclare(node); } } else if (this.match(types.name)) { if (expr.name === "interface") { return this.flowParseInterface(node); } else if (expr.name === "type") { return this.flowParseTypeAlias(node); } else if (expr.name === "opaque") { return this.flowParseOpaqueType(node, false); } } } return inner.call(this, node, expr); }; }); // export type instance.extend("shouldParseExportDeclaration", function (inner) { return function () { return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || inner.call(this); }; }); instance.extend("isExportDefaultSpecifier", function (inner) { return function () { if (this.match(types.name) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque")) { return false; } return inner.call(this); }; }); instance.extend("parseConditional", function (inner) { return function (expr, noIn, startPos, startLoc, refNeedsArrowPos) { // only do the expensive clone if there is a question mark // and if we come from inside parens if (refNeedsArrowPos && this.match(types.question)) { var state = this.state.clone(); try { return inner.call(this, expr, noIn, startPos, startLoc); } catch (err) { if (err instanceof SyntaxError) { this.state = state; refNeedsArrowPos.start = err.pos || this.state.start; return expr; } else { // istanbul ignore next: no such error is expected throw err; } } } return inner.call(this, expr, noIn, startPos, startLoc); }; }); instance.extend("parseParenItem", function (inner) { return function (node, startPos, startLoc) { node = inner.call(this, node, startPos, startLoc); if (this.eat(types.question)) { node.optional = true; } if (this.match(types.colon)) { var typeCastNode = this.startNodeAt(startPos, startLoc); typeCastNode.expression = node; typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); return this.finishNode(typeCastNode, "TypeCastExpression"); } return node; }; }); instance.extend("parseExport", function (inner) { return function (node) { node = inner.call(this, node); if (node.type === "ExportNamedDeclaration") { node.exportKind = node.exportKind || "value"; } return node; }; }); instance.extend("parseExportDeclaration", function (inner) { return function (node) { if (this.isContextual("type")) { node.exportKind = "type"; var declarationNode = this.startNode(); this.next(); if (this.match(types.braceL)) { // export type { foo, bar }; node.specifiers = this.parseExportSpecifiers(); this.parseExportFrom(node); return null; } else { // export type Foo = Bar; return this.flowParseTypeAlias(declarationNode); } } else if (this.isContextual("opaque")) { node.exportKind = "type"; var _declarationNode = this.startNode(); this.next(); // export opaque type Foo = Bar; return this.flowParseOpaqueType(_declarationNode, false); } else if (this.isContextual("interface")) { node.exportKind = "type"; var _declarationNode2 = this.startNode(); this.next(); return this.flowParseInterface(_declarationNode2); } else { return inner.call(this, node); } }; }); instance.extend("parseClassId", function (inner) { return function (node) { inner.apply(this, arguments); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } }; }); // don't consider `void` to be a keyword as then it'll use the void token type // and set startExpr instance.extend("isKeyword", function (inner) { return function (name) { if (this.state.inType && name === "void") { return false; } else { return inner.call(this, name); } }; }); // ensure that inside flow types, we bypass the jsx parser plugin instance.extend("readToken", function (inner) { return function (code) { if (this.state.inType && (code === 62 || code === 60)) { return this.finishOp(types.relational, 1); } else { return inner.call(this, code); } }; }); // don't lex any token as a jsx one inside a flow type instance.extend("jsx_readToken", function (inner) { return function () { if (!this.state.inType) return inner.call(this); }; }); instance.extend("toAssignable", function (inner) { return function (node, isBinding, contextDescription) { if (node.type === "TypeCastExpression") { return inner.call(this, this.typeCastToParameter(node), isBinding, contextDescription); } else { return inner.call(this, node, isBinding, contextDescription); } }; }); // turn type casts that we found in function parameter head into type annotated params instance.extend("toAssignableList", function (inner) { return function (exprList, isBinding, contextDescription) { for (var i = 0; i < exprList.length; i++) { var expr = exprList[i]; if (expr && expr.type === "TypeCastExpression") { exprList[i] = this.typeCastToParameter(expr); } } return inner.call(this, exprList, isBinding, contextDescription); }; }); // this is a list of nodes, from something like a call expression, we need to filter the // type casts that we've found that are illegal in this context instance.extend("toReferencedList", function () { return function (exprList) { for (var i = 0; i < exprList.length; i++) { var expr = exprList[i]; if (expr && expr._exprListItem && expr.type === "TypeCastExpression") { this.raise(expr.start, "Unexpected type cast"); } } return exprList; }; }); // 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 () { var container = this.startNode(); 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; container.typeAnnotation = this.flowParseTypeAnnotation(); return this.finishNode(container, "TypeCastExpression"); } else { return node; } }; }); instance.extend("checkLVal", function (inner) { return function (node) { if (node.type !== "TypeCastExpression") { return inner.apply(this, arguments); } }; }); // parse class property type annotations instance.extend("parseClassProperty", function (inner) { return function (node) { delete node.variancePos; if (this.match(types.colon)) { node.typeAnnotation = this.flowParseTypeAnnotation(); } return inner.call(this, node); }; }); // determine whether or not we're currently in the position where a class method would appear instance.extend("isClassMethod", function (inner) { return function () { return this.isRelational("<") || inner.call(this); }; }); // determine whether or not we're currently in the position where a class property would appear instance.extend("isClassProperty", function (inner) { return function () { return this.match(types.colon) || inner.call(this); }; }); instance.extend("isNonstaticConstructor", function (inner) { return function (method) { return !this.match(types.colon) && inner.call(this, method); }; }); // parse type parameters for class methods instance.extend("parseClassMethod", function (inner) { return function (classBody, method) { if (method.variance) { this.unexpected(method.variancePos); } delete method.variance; delete method.variancePos; if (this.isRelational("<")) { method.typeParameters = this.flowParseTypeParameterDeclaration(); } 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)); }; }); // parse a the super class type parameters and implements instance.extend("parseClassSuper", function (inner) { return function (node, isStatement) { inner.call(this, node, isStatement); if (node.superClass && this.isRelational("<")) { node.superTypeParameters = this.flowParseTypeParameterInstantiation(); } if (this.isContextual("implements")) { this.next(); var implemented = node.implements = []; do { var _node = this.startNode(); _node.id = this.parseIdentifier(); if (this.isRelational("<")) { _node.typeParameters = this.flowParseTypeParameterInstantiation(); } else { _node.typeParameters = null; } implemented.push(this.finishNode(_node, "ClassImplements")); } while (this.eat(types.comma)); } }; }); instance.extend("parsePropertyName", function (inner) { return function (node) { var variancePos = this.state.start; var variance = this.flowParseVariance(); var key = inner.call(this, node); node.variance = variance; node.variancePos = variancePos; return key; }; }); // parse type parameters for object method shorthand instance.extend("parseObjPropValue", function (inner) { return function (prop) { if (prop.variance) { this.unexpected(prop.variancePos); } delete prop.variance; delete prop.variancePos; var typeParameters = void 0; // method shorthand if (this.isRelational("<")) { typeParameters = this.flowParseTypeParameterDeclaration(); if (!this.match(types.parenL)) this.unexpected(); } inner.apply(this, arguments); // add typeParameters if we found them if (typeParameters) { (prop.value || prop).typeParameters = typeParameters; } }; }); instance.extend("parseAssignableListItemTypes", function () { return function (param) { if (this.eat(types.question)) { param.optional = true; } if (this.match(types.colon)) { param.typeAnnotation = this.flowParseTypeAnnotation(); } this.finishNode(param, param.type); return param; }; }); instance.extend("parseMaybeDefault", function (inner) { return function () { for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } var node = inner.apply(this, args); if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { this.raise(node.typeAnnotation.start, "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`"); } return node; }; }); // parse typeof and type imports instance.extend("parseImportSpecifiers", function (inner) { return function (node) { node.importKind = "value"; var kind = null; if (this.match(types._typeof)) { kind = "typeof"; } else if (this.isContextual("type")) { kind = "type"; } if (kind) { var lh = this.lookahead(); if (lh.type === types.name && lh.value !== "from" || lh.type === types.braceL || lh.type === types.star) { this.next(); node.importKind = kind; } } inner.call(this, node); }; }); // 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) { if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } inner.call(this, node); }; }); // parse flow type annotations on variable declarator heads - let foo: string = bar instance.extend("parseVarHead", function (inner) { return function (decl) { inner.call(this, decl); if (this.match(types.colon)) { decl.id.typeAnnotation = this.flowParseTypeAnnotation(); this.finishNode(decl.id, decl.id.type); } }; }); // parse the return type of an async arrow function - let foo = (async (): number => {}); 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); }; }); // todo description instance.extend("shouldParseAsyncArrow", function (inner) { return function () { return this.match(types.colon) || inner.call(this); }; }); // We need to support type parameter declarations for arrow functions. This // is tricky. There are three situations we need to handle // // 1. This is either JSX or an arrow function. We'll try JSX first. If that // fails, we'll try an arrow function. If that fails, we'll throw the JSX // error. // 2. This is an arrow function. We'll parse the type parameter declaration, // parse the rest, make sure the rest is an arrow function, and go from // there // 3. This is neither. Just call the inner function instance.extend("parseMaybeAssign", function (inner) { return function () { var jsxError = null; for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } if (types.jsxTagStart && this.match(types.jsxTagStart)) { var state = this.state.clone(); try { return inner.apply(this, args); } catch (err) { if (err instanceof SyntaxError) { this.state = state; // Remove `tc.j_expr` and `tc.j_oTag` from context added // by parsing `jsxTagStart` to stop the JSX plugin from // messing with the tokens this.state.context.length -= 2; jsxError = err; } else { // istanbul ignore next: no such error is expected throw err; } } } if (jsxError != null || this.isRelational("<")) { var arrowExpression = void 0; var typeParameters = void 0; try { typeParameters = this.flowParseTypeParameterDeclaration(); arrowExpression = inner.apply(this, args); arrowExpression.typeParameters = typeParameters; arrowExpression.start = typeParameters.start; arrowExpression.loc.start = typeParameters.loc.start; } catch (err) { throw jsxError || err; } if (arrowExpression.type === "ArrowFunctionExpression") { return arrowExpression; } else if (jsxError != null) { throw jsxError; } else { this.raise(typeParameters.start, "Expected an arrow function after this type parameter declaration"); } } return inner.apply(this, args); }; }); // handle return types for arrow functions instance.extend("parseArrow", function (inner) { return function (node) { if (this.match(types.colon)) { var state = this.state.clone(); try { 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 node.returnType = returnType; } catch (err) { if (err instanceof SyntaxError) { this.state = state; } else { // istanbul ignore next: no such error is expected throw err; } } } return inner.call(this, node); }; }); instance.extend("shouldParseArrow", function (inner) { return function () { return this.match(types.colon) || inner.call(this); }; }); }; // 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: "&", apos: "'", lt: "<", gt: ">", nbsp: "\xA0", iexcl: "\xA1", cent: "\xA2", pound: "\xA3", curren: "\xA4", yen: "\xA5", brvbar: "\xA6", sect: "\xA7", uml: "\xA8", copy: "\xA9", ordf: "\xAA", laquo: "\xAB", not: "\xAC", shy: "\xAD", reg: "\xAE", macr: "\xAF", deg: "\xB0", plusmn: "\xB1", sup2: "\xB2", sup3: "\xB3", acute: "\xB4", micro: "\xB5", para: "\xB6", middot: "\xB7", cedil: "\xB8", sup1: "\xB9", ordm: "\xBA", raquo: "\xBB", frac14: "\xBC", frac12: "\xBD", frac34: "\xBE", iquest: "\xBF", Agrave: "\xC0", Aacute: "\xC1", Acirc: "\xC2", Atilde: "\xC3", Auml: "\xC4", Aring: "\xC5", AElig: "\xC6", Ccedil: "\xC7", Egrave: "\xC8", Eacute: "\xC9", Ecirc: "\xCA", Euml: "\xCB", Igrave: "\xCC", Iacute: "\xCD", Icirc: "\xCE", Iuml: "\xCF", ETH: "\xD0", Ntilde: "\xD1", Ograve: "\xD2", Oacute: "\xD3", Ocirc: "\xD4", Otilde: "\xD5", Ouml: "\xD6", times: "\xD7", Oslash: "\xD8", Ugrave: "\xD9", Uacute: "\xDA", Ucirc: "\xDB", Uuml: "\xDC", Yacute: "\xDD", THORN: "\xDE", szlig: "\xDF", agrave: "\xE0", aacute: "\xE1", acirc: "\xE2", atilde: "\xE3", auml: "\xE4", aring: "\xE5", aelig: "\xE6", ccedil: "\xE7", egrave: "\xE8", eacute: "\xE9", ecirc: "\xEA", euml: "\xEB", igrave: "\xEC", iacute: "\xED", icirc: "\xEE", iuml: "\xEF", eth: "\xF0", ntilde: "\xF1", ograve: "\xF2", oacute: "\xF3", ocirc: "\xF4", otilde: "\xF5", ouml: "\xF6", divide: "\xF7", oslash: "\xF8", ugrave: "\xF9", uacute: "\xFA", ucirc: "\xFB", uuml: "\xFC", yacute: "\xFD", thorn: "\xFE", yuml: "\xFF", OElig: "\u0152", oelig: "\u0153", Scaron: "\u0160", scaron: "\u0161", Yuml: "\u0178", fnof: "\u0192", circ: "\u02C6", tilde: "\u02DC", Alpha: "\u0391", Beta: "\u0392", Gamma: "\u0393", Delta: "\u0394", Epsilon: "\u0395", Zeta: "\u0396", Eta: "\u0397", Theta: "\u0398", Iota: "\u0399", Kappa: "\u039A", Lambda: "\u039B", Mu: "\u039C", Nu: "\u039D", Xi: "\u039E", Omicron: "\u039F", Pi: "\u03A0", Rho: "\u03A1", Sigma: "\u03A3", Tau: "\u03A4", Upsilon: "\u03A5", Phi: "\u03A6", Chi: "\u03A7", Psi: "\u03A8", Omega: "\u03A9", alpha: "\u03B1", beta: "\u03B2", gamma: "\u03B3", delta: "\u03B4", epsilon: "\u03B5", zeta: "\u03B6", eta: "\u03B7", theta: "\u03B8", iota: "\u03B9", kappa: "\u03BA", lambda: "\u03BB", mu: "\u03BC", nu: "\u03BD", xi: "\u03BE", omicron: "\u03BF", pi: "\u03C0", rho: "\u03C1", sigmaf: "\u03C2", sigma: "\u03C3", tau: "\u03C4", upsilon: "\u03C5", phi: "\u03C6", chi: "\u03C7", psi: "\u03C8", omega: "\u03C9", thetasym: "\u03D1", upsih: "\u03D2", piv: "\u03D6", ensp: "\u2002", emsp: "\u2003", thinsp: "\u2009", zwnj: "\u200C", zwj: "\u200D", lrm: "\u200E", rlm: "\u200F", ndash: "\u2013", mdash: "\u2014", lsquo: "\u2018", rsquo: "\u2019", sbquo: "\u201A", ldquo: "\u201C", rdquo: "\u201D", bdquo: "\u201E", dagger: "\u2020", Dagger: "\u2021", bull: "\u2022", hellip: "\u2026", permil: "\u2030", prime: "\u2032", Prime: "\u2033", lsaquo: "\u2039", rsaquo: "\u203A", oline: "\u203E", frasl: "\u2044", euro: "\u20AC", image: "\u2111", weierp: "\u2118", real: "\u211C", trade: "\u2122", alefsym: "\u2135", larr: "\u2190", uarr: "\u2191", rarr: "\u2192", darr: "\u2193", harr: "\u2194", crarr: "\u21B5", lArr: "\u21D0", uArr: "\u21D1", rArr: "\u21D2", dArr: "\u21D3", hArr: "\u21D4", forall: "\u2200", part: "\u2202", exist: "\u2203", empty: "\u2205", nabla: "\u2207", isin: "\u2208", notin: "\u2209", ni: "\u220B", prod: "\u220F", sum: "\u2211", minus: "\u2212", lowast: "\u2217", radic: "\u221A", prop: "\u221D", infin: "\u221E", ang: "\u2220", and: "\u2227", or: "\u2228", cap: "\u2229", cup: "\u222A", "int": "\u222B", there4: "\u2234", sim: "\u223C", cong: "\u2245", asymp: "\u2248", ne: "\u2260", equiv: "\u2261", le: "\u2264", ge: "\u2265", sub: "\u2282", sup: "\u2283", nsub: "\u2284", sube: "\u2286", supe: "\u2287", oplus: "\u2295", otimes: "\u2297", perp: "\u22A5", sdot: "\u22C5", lceil: "\u2308", rceil: "\u2309", lfloor: "\u230A", rfloor: "\u230B", lang: "\u2329", rang: "\u232A", loz: "\u25CA", spades: "\u2660", clubs: "\u2663", hearts: "\u2665", diams: "\u2666" }; var HEX_NUMBER = /^[\da-fA-F]+$/; var DECIMAL_NUMBER = /^\d+$/; types$1.j_oTag = new TokContext("<tag", false); types$1.j_cTag = new TokContext("</tag", false); types$1.j_expr = new TokContext("<tag>...</tag>", true, true); types.jsxName = new TokenType("jsxName"); types.jsxText = new TokenType("jsxText", { beforeExpr: true }); types.jsxTagStart = new TokenType("jsxTagStart", { startsExpr: true }); types.jsxTagEnd = new TokenType("jsxTagEnd"); types.jsxTagStart.updateContext = function () { this.state.context.push(types$1.j_expr); // treat as beginning of JSX expression this.state.context.push(types$1.j_oTag); // start opening tag context this.state.exprAllowed = false; }; types.jsxTagEnd.updateContext = function (prevType) { var out = this.state.context.pop(); if (out === types$1.j_oTag && prevType === types.slash || out === types$1.j_cTag) { this.state.context.pop(); this.state.exprAllowed = this.curContext() === types$1.j_expr; } else { this.state.exprAllowed = true; } }; var pp$9 = Parser.prototype; // Reads inline JSX contents token. pp$9.jsxReadToken = function () { var out = ""; var chunkStart = this.state.pos; for (;;) { if (this.state.pos >= this.input.length) { this.raise(this.state.start, "Unterminated JSX contents"); } var ch = this.input.charCodeAt(this.state.pos); switch (ch) { case 60: // "<" case 123: // "{" if (this.state.pos === this.state.start) { if (ch === 60 && this.state.exprAllowed) { ++this.state.pos; return this.finishToken(types.jsxTagStart); } return this.getTokenFromCode(ch); } out += this.input.slice(chunkStart, this.state.pos); return this.finishToken(types.jsxText, out); case 38: // "&" out += this.input.slice(chunkStart, this.state.pos); out += this.jsxReadEntity(); chunkStart = this.state.pos; break; default: if (isNewLine(ch)) { out += this.input.slice(chunkStart, this.state.pos); out += this.jsxReadNewLine(true); chunkStart = this.state.pos; } else { ++this.state.pos; } } } }; pp$9.jsxReadNewLine = function (normalizeCRLF) { var ch = this.input.charCodeAt(this.state.pos); var out = void 0; ++this.state.pos; if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { ++this.state.pos; out = normalizeCRLF ? "\n" : "\r\n"; } else { out = String.fromCharCode(ch); } ++this.state.curLine; this.state.lineStart = this.state.pos; return out; }; pp$9.jsxReadString = function (quote) { var out = ""; var chunkStart = ++this.state.pos; for (;;) { if (this.state.pos >= this.input.length) { this.raise(this.state.start, "Unterminated string constant"); } var ch = this.input.charCodeAt(this.state.pos); if (ch === quote) break; if (ch === 38) { // "&" out += this.input.slice(chunkStart, this.state.pos); out += this.jsxReadEntity(); chunkStart = this.state.pos; } else if (isNewLine(ch)) { out += this.input.slice(chunkStart, this.state.pos); out += this.jsxReadNewLine(false); chunkStart = this.state.pos; } else { ++this.state.pos; } } out += this.input.slice(chunkStart, this.state.pos++); return this.finishToken(types.string, out); }; pp$9.jsxReadEntity = function () { var str = ""; var count = 0; var entity = void 0; var ch = this.input[this.state.pos]; var startPos = ++this.state.pos; while (this.state.pos < this.input.length && count++ < 10) { ch = this.input[this.state.pos++]; if (ch === ";") { if (str[0] === "#") { if (str[1] === "x") { str = str.substr(2); if (HEX_NUMBER.test(str)) entity = fromCodePoint$1(parseInt(str, 16)); } else { str = str.substr(1); if (DECIMAL_NUMBER.test(str)) entity = fromCodePoint$1(parseInt(str, 10)); } } else { entity = XHTMLEntities[str]; } break; } str += ch; } if (!entity) { this.state.pos = startPos; return "&"; } return entity; }; // Read a JSX identifier (valid tag or attribute name). // // Optimized version since JSX identifiers can"t contain // escape characters and so can be read as single slice. // Also assumes that first character was already checked // by isIdentifierStart in readToken. pp$9.jsxReadWord = function () { var ch = void 0; var start = this.state.pos; do { ch = this.input.charCodeAt(++this.state.pos); } while (isIdentifierChar(ch) || ch === 45); // "-" return this.finishToken(types.jsxName, this.input.slice(start, this.state.pos)); }; // Transforms JSX element name to string. function getQualifiedJSXName(object) { if (object.type === "JSXIdentifier") { return object.name; } if (object.type === "JSXNamespacedName") { return object.namespace.name + ":" + object.name.name; } if (object.type === "JSXMemberExpression") { return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property); } } // Parse next token as JSX identifier pp$9.jsxParseIdentifier = function () { var node = this.startNode(); if (this.match(types.jsxName)) { node.name = this.state.value; } else if (this.state.type.keyword) { node.name = this.state.type.keyword; } else { this.unexpected(); } this.next(); return this.finishNode(node, "JSXIdentifier"); }; // Parse namespaced identifier. 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; var node = this.startNodeAt(startPos, startLoc); node.namespace = name; node.name = this.jsxParseIdentifier(); return this.finishNode(node, "JSXNamespacedName"); }; // Parses element name in any form - namespaced, member // or single identifier. 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); newNode.object = node; newNode.property = this.jsxParseIdentifier(); node = this.finishNode(newNode, "JSXMemberExpression"); } return node; }; // Parses any type of JSX attribute value. pp$9.jsxParseAttributeValue = function () { var node = void 0; switch (this.state.type) { case types.braceL: node = this.jsxParseExpressionContainer(); if (node.expression.type === "JSXEmptyExpression") { this.raise(node.start, "JSX attributes must only be assigned a non-empty expression"); } else { return node; } case types.jsxTagStart: case types.string: node = this.parseExprAtom(); node.extra = null; return node; default: this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text"); } }; // JSXEmptyExpression is unique type since it doesn't actually parse anything, // 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$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$9.jsxParseSpreadChild = function () { var node = this.startNode(); this.expect(types.braceL); this.expect(types.ellipsis); node.expression = this.parseExpression(); this.expect(types.braceR); return this.finishNode(node, "JSXSpreadChild"); }; // Parses JSX expression enclosed into curly brackets. pp$9.jsxParseExpressionContainer = function () { var node = this.startNode(); this.next(); if (this.match(types.braceR)) { node.expression = this.jsxParseEmptyExpression(); } else { node.expression = this.parseExpression(); } this.expect(types.braceR); return this.finishNode(node, "JSXExpressionContainer"); }; // Parses following JSX attribute name-value pair. pp$9.jsxParseAttribute = function () { var node = this.startNode(); if (this.eat(types.braceL)) { this.expect(types.ellipsis); node.argument = this.parseMaybeAssign(); this.expect(types.braceR); return this.finishNode(node, "JSXSpreadAttribute"); } node.name = this.jsxParseNamespacedName(); node.value = this.eat(types.eq) ? this.jsxParseAttributeValue() : null; return this.finishNode(node, "JSXAttribute"); }; // Parses JSX opening tag starting after "<". pp$9.jsxParseOpeningElementAt = function (startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); node.attributes = []; node.name = this.jsxParseElementName(); while (!this.match(types.slash) && !this.match(types.jsxTagEnd)) { node.attributes.push(this.jsxParseAttribute()); } node.selfClosing = this.eat(types.slash); this.expect(types.jsxTagEnd); return this.finishNode(node, "JSXOpeningElement"); }; // Parses JSX closing tag starting after "</". pp$9.jsxParseClosingElementAt = function (startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); node.name = this.jsxParseElementName(); this.expect(types.jsxTagEnd); return this.finishNode(node, "JSXClosingElement"); }; // Parses entire JSX element, including it"s opening tag // (starting after "<"), attributes, contents and closing tag. pp$9.jsxParseElementAt = function (startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); var children = []; var openingElement = this.jsxParseOpeningElementAt(startPos, startLoc); var closingElement = null; if (!openingElement.selfClosing) { contents: for (;;) { switch (this.state.type) { case types.jsxTagStart: startPos = this.state.start;startLoc = this.state.startLoc; this.next(); if (this.eat(types.slash)) { closingElement = this.jsxParseClosingElementAt(startPos, startLoc); break contents; } children.push(this.jsxParseElementAt(startPos, startLoc)); break; case types.jsxText: children.push(this.parseExprAtom()); break; case types.braceL: if (this.lookahead().type === types.ellipsis) { children.push(this.jsxParseSpreadChild()); } else { children.push(this.jsxParseExpressionContainer()); } break; // istanbul ignore next - should never happen default: this.unexpected(); } } if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { this.raise(closingElement.start, "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">"); } } node.openingElement = openingElement; node.closingElement = closingElement; node.children = children; if (this.match(types.relational) && this.state.value === "<") { this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); } return this.finishNode(node, "JSXElement"); }; // Parses entire JSX element from current position. pp$9.jsxParseElement = function () { var startPos = this.state.start; var startLoc = this.state.startLoc; this.next(); return this.jsxParseElementAt(startPos, startLoc); }; var jsxPlugin = function (instance) { instance.extend("parseExprAtom", function (inner) { return function (refShortHandDefaultPos) { if (this.match(types.jsxText)) { var node = this.parseLiteral(this.state.value, "JSXText"); // https://github.com/babel/babel/issues/2078 node.extra = null; return node; } else if (this.match(types.jsxTagStart)) { return this.jsxParseElement(); } else { return inner.call(this, refShortHandDefaultPos); } }; }); 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) { return this.jsxReadToken(); } if (context === types$1.j_oTag || context === types$1.j_cTag) { if (isIdentifierStart(code)) { return this.jsxReadWord(); } if (code === 62) { ++this.state.pos; return this.finishToken(types.jsxTagEnd); } if ((code === 34 || code === 39) && context === types$1.j_oTag) { return this.jsxReadString(code); } } if (code === 60 && this.state.exprAllowed) { ++this.state.pos; return this.finishToken(types.jsxTagStart); } return inner.call(this, code); }; }); instance.extend("updateContext", function (inner) { return function (prevType) { if (this.match(types.braceL)) { var curContext = this.curContext(); if (curContext === types$1.j_oTag) { this.state.context.push(types$1.braceExpression); } else if (curContext === types$1.j_expr) { this.state.context.push(types$1.templateQuasi); } else { inner.call(this, prevType); } this.state.exprAllowed = true; } else if (this.match(types.slash) && prevType === types.jsxTagStart) { this.state.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore this.state.context.push(types$1.j_cTag); // reconsider as closing tag context this.state.exprAllowed = false; } else { return inner.call(this, prevType); } }; }); }; plugins.estree = estreePlugin; plugins.flow = flowPlugin; plugins.jsx = jsxPlugin; function parse(input, options) { return new Parser(options, input).parse(); } 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; adminSystem - Gogs: Go Git Service

Нет описания

createGraphFromNodeEdge.js 2.1KB

    var zrUtil = require("zrender/lib/core/util"); var List = require("../../data/List"); var Graph = require("../../data/Graph"); var linkList = require("../../data/helper/linkList"); var createDimensions = require("../../data/helper/createDimensions"); var CoordinateSystem = require("../../CoordinateSystem"); var createListFromArray = require("./createListFromArray"); function _default(nodes, edges, seriesModel, directed, beforeLink) { // ??? TODO // support dataset? var graph = new Graph(directed); for (var i = 0; i < nodes.length; i++) { graph.addNode(zrUtil.retrieve( // Id, name, dataIndex nodes[i].id, nodes[i].name, i), i); } var linkNameList = []; var validEdges = []; var linkCount = 0; for (var i = 0; i < edges.length; i++) { var link = edges[i]; var source = link.source; var target = link.target; // addEdge may fail when source or target not exists if (graph.addEdge(source, target, linkCount)) { validEdges.push(link); linkNameList.push(zrUtil.retrieve(link.id, source + ' > ' + target)); linkCount++; } } var coordSys = seriesModel.get('coordinateSystem'); var nodeData; if (coordSys === 'cartesian2d' || coordSys === 'polar') { nodeData = createListFromArray(nodes, seriesModel); } else { // FIXME var coordSysCtor = CoordinateSystem.get(coordSys); // FIXME var dimensionNames = createDimensions(nodes, { coordDimensions: (coordSysCtor && coordSysCtor.type !== 'view' ? coordSysCtor.dimensions || [] : []).concat(['value']) }); nodeData = new List(dimensionNames, seriesModel); nodeData.initData(nodes); } var edgeData = new List(['value'], seriesModel); edgeData.initData(validEdges, linkNameList); beforeLink && beforeLink(nodeData, edgeData); linkList({ mainData: nodeData, struct: graph, structAttr: 'graph', datas: { node: nodeData, edge: edgeData }, datasAttr: { node: 'data', edge: 'edgeData' } }); // Update dataIndex of nodes and edges because invalid edge may be removed graph.update(); return graph; } module.exports = _default;