@babel/parser
Version:
A JavaScript parser
1,396 lines (1,395 loc) • 94.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _types = require("../../tokenizer/types");
var _context = require("../../tokenizer/context");
var _location = require("../../util/location");
var _scopeflags = require("../../util/scopeflags");
var _scope = require("./scope");
var _productionParameter = require("../../util/production-parameter");
var _parseError = require("../../parse-error");
var _node = require("../../parser/node");
var _lval = require("../../parser/lval");
const getOwn = (object, key) => Object.hasOwnProperty.call(object, key) && object[key];
function nonNull(x) {
if (x == null) {
throw new Error(`Unexpected ${x} value.`);
}
return x;
}
function assert(x) {
if (!x) {
throw new Error("Assert fail");
}
}
const TSErrors = (0, _parseError.ParseErrorEnum)`typescript`({
AbstractMethodHasImplementation: ({
methodName
}) => `Method '${methodName}' cannot have an implementation because it is marked abstract.`,
AbstractPropertyHasInitializer: ({
propertyName
}) => `Property '${propertyName}' cannot have an initializer because it is marked abstract.`,
AccesorCannotDeclareThisParameter: "'get' and 'set' accessors cannot declare 'this' parameters.",
AccesorCannotHaveTypeParameters: "An accessor cannot have type parameters.",
AccessorCannotBeOptional: "An 'accessor' property cannot be declared optional.",
ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier.",
ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier.",
ConstInitiailizerMustBeStringOrNumericLiteralOrLiteralEnumReference: "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.",
ConstructorHasTypeParameters: "Type parameters cannot appear on a constructor declaration.",
DeclareAccessor: ({
kind
}) => `'declare' is not allowed in ${kind}ters.`,
DeclareClassFieldHasInitializer: "Initializers are not allowed in ambient contexts.",
DeclareFunctionHasImplementation: "An implementation cannot be declared in ambient contexts.",
DuplicateAccessibilityModifier: ({
modifier
}) => `Accessibility modifier already seen.`,
DuplicateModifier: ({
modifier
}) => `Duplicate modifier: '${modifier}'.`,
EmptyHeritageClauseType: ({
token
}) => `'${token}' list cannot be empty.`,
EmptyTypeArguments: "Type argument list cannot be empty.",
EmptyTypeParameters: "Type parameter list cannot be empty.",
ExpectedAmbientAfterExportDeclare: "'export declare' must be followed by an ambient declaration.",
ImportAliasHasImportType: "An import alias can not use 'import type'.",
ImportReflectionHasImportType: "An `import module` declaration can not use `type` modifier",
IncompatibleModifiers: ({
modifiers
}) => `'${modifiers[0]}' modifier cannot be used with '${modifiers[1]}' modifier.`,
IndexSignatureHasAbstract: "Index signatures cannot have the 'abstract' modifier.",
IndexSignatureHasAccessibility: ({
modifier
}) => `Index signatures cannot have an accessibility modifier ('${modifier}').`,
IndexSignatureHasDeclare: "Index signatures cannot have the 'declare' modifier.",
IndexSignatureHasOverride: "'override' modifier cannot appear on an index signature.",
IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier.",
InitializerNotAllowedInAmbientContext: "Initializers are not allowed in ambient contexts.",
InvalidModifierOnTypeMember: ({
modifier
}) => `'${modifier}' modifier cannot appear on a type member.`,
InvalidModifierOnTypeParameter: ({
modifier
}) => `'${modifier}' modifier cannot appear on a type parameter.`,
InvalidModifierOnTypeParameterPositions: ({
modifier
}) => `'${modifier}' modifier can only appear on a type parameter of a class, interface or type alias.`,
InvalidModifiersOrder: ({
orderedModifiers
}) => `'${orderedModifiers[0]}' modifier must precede '${orderedModifiers[1]}' modifier.`,
InvalidPropertyAccessAfterInstantiationExpression: "Invalid property access after an instantiation expression. " + "You can either wrap the instantiation expression in parentheses, or delete the type arguments.",
InvalidTupleMemberLabel: "Tuple members must be labeled with a simple identifier.",
MissingInterfaceName: "'interface' declarations must be followed by an identifier.",
MixedLabeledAndUnlabeledElements: "Tuple members must all have names or all not have names.",
NonAbstractClassHasAbstractMethod: "Abstract methods can only appear within an abstract class.",
NonClassMethodPropertyHasAbstractModifer: "'abstract' modifier can only appear on a class, method, or property declaration.",
OptionalTypeBeforeRequired: "A required element cannot follow an optional element.",
OverrideNotInSubClass: "This member cannot have an 'override' modifier because its containing class does not extend another class.",
PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.",
PrivateElementHasAbstract: "Private elements cannot have the 'abstract' modifier.",
PrivateElementHasAccessibility: ({
modifier
}) => `Private elements cannot have an accessibility modifier ('${modifier}').`,
ReadonlyForMethodSignature: "'readonly' modifier can only appear on a property declaration or index signature.",
ReservedArrowTypeParam: "This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma, as in `<T,>() => ...`.",
ReservedTypeAssertion: "This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead.",
SetAccesorCannotHaveOptionalParameter: "A 'set' accessor cannot have an optional parameter.",
SetAccesorCannotHaveRestParameter: "A 'set' accessor cannot have rest parameter.",
SetAccesorCannotHaveReturnType: "A 'set' accessor cannot have a return type annotation.",
SingleTypeParameterWithoutTrailingComma: ({
typeParameterName
}) => `Single type parameter ${typeParameterName} should have a trailing comma. Example usage: <${typeParameterName},>.`,
StaticBlockCannotHaveModifier: "Static class blocks cannot have any modifier.",
TupleOptionalAfterType: "A labeled tuple optional element must be declared using a question mark after the name and before the colon (`name?: type`), rather than after the type (`name: type?`).",
TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.",
TypeImportCannotSpecifyDefaultAndNamed: "A type-only import can specify a default import or named bindings, but not both.",
TypeModifierIsUsedInTypeExports: "The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement.",
TypeModifierIsUsedInTypeImports: "The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement.",
UnexpectedParameterModifier: "A parameter property is only allowed in a constructor implementation.",
UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.",
UnexpectedTypeAnnotation: "Did not expect a type annotation here.",
UnexpectedTypeCastInParameter: "Unexpected type cast in parameter position.",
UnsupportedImportTypeArgument: "Argument in a type import must be a string literal.",
UnsupportedParameterPropertyKind: "A parameter property may not be declared using a binding pattern.",
UnsupportedSignatureParameterKind: ({
type
}) => `Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${type}.`
});
function keywordTypeFromName(value) {
switch (value) {
case "any":
return "TSAnyKeyword";
case "boolean":
return "TSBooleanKeyword";
case "bigint":
return "TSBigIntKeyword";
case "never":
return "TSNeverKeyword";
case "number":
return "TSNumberKeyword";
case "object":
return "TSObjectKeyword";
case "string":
return "TSStringKeyword";
case "symbol":
return "TSSymbolKeyword";
case "undefined":
return "TSUndefinedKeyword";
case "unknown":
return "TSUnknownKeyword";
default:
return undefined;
}
}
function tsIsAccessModifier(modifier) {
return modifier === "private" || modifier === "public" || modifier === "protected";
}
function tsIsVarianceAnnotations(modifier) {
return modifier === "in" || modifier === "out";
}
var _default = superClass => class TypeScriptParserMixin extends superClass {
constructor(...args) {
super(...args);
this.tsParseInOutModifiers = this.tsParseModifiers.bind(this, {
allowedModifiers: ["in", "out"],
disallowedModifiers: ["const", "public", "private", "protected", "readonly", "declare", "abstract", "override"],
errorTemplate: TSErrors.InvalidModifierOnTypeParameter
});
this.tsParseConstModifier = this.tsParseModifiers.bind(this, {
allowedModifiers: ["const"],
disallowedModifiers: ["in", "out"],
errorTemplate: TSErrors.InvalidModifierOnTypeParameterPositions
});
this.tsParseInOutConstModifiers = this.tsParseModifiers.bind(this, {
allowedModifiers: ["in", "out", "const"],
disallowedModifiers: ["public", "private", "protected", "readonly", "declare", "abstract", "override"],
errorTemplate: TSErrors.InvalidModifierOnTypeParameter
});
}
getScopeHandler() {
return _scope.default;
}
tsIsIdentifier() {
return (0, _types.tokenIsIdentifier)(this.state.type);
}
tsTokenCanFollowModifier() {
return (this.match(0) || this.match(5) || this.match(55) || this.match(21) || this.match(136) || this.isLiteralPropertyName()) && !this.hasPrecedingLineBreak();
}
tsNextTokenCanFollowModifier() {
this.next();
return this.tsTokenCanFollowModifier();
}
tsParseModifier(allowedModifiers, stopOnStartOfClassStaticBlock) {
if (!(0, _types.tokenIsIdentifier)(this.state.type) && this.state.type !== 58 && this.state.type !== 75) {
return undefined;
}
const modifier = this.state.value;
if (allowedModifiers.indexOf(modifier) !== -1) {
if (stopOnStartOfClassStaticBlock && this.tsIsStartOfStaticBlocks()) {
return undefined;
}
if (this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) {
return modifier;
}
}
return undefined;
}
tsParseModifiers({
allowedModifiers,
disallowedModifiers,
stopOnStartOfClassStaticBlock,
errorTemplate = TSErrors.InvalidModifierOnTypeMember
}, modified) {
const enforceOrder = (loc, modifier, before, after) => {
if (modifier === before && modified[after]) {
this.raise(TSErrors.InvalidModifiersOrder, {
at: loc,
orderedModifiers: [before, after]
});
}
};
const incompatible = (loc, modifier, mod1, mod2) => {
if (modified[mod1] && modifier === mod2 || modified[mod2] && modifier === mod1) {
this.raise(TSErrors.IncompatibleModifiers, {
at: loc,
modifiers: [mod1, mod2]
});
}
};
for (;;) {
const {
startLoc
} = this.state;
const modifier = this.tsParseModifier(allowedModifiers.concat(disallowedModifiers != null ? disallowedModifiers : []), stopOnStartOfClassStaticBlock);
if (!modifier) break;
if (tsIsAccessModifier(modifier)) {
if (modified.accessibility) {
this.raise(TSErrors.DuplicateAccessibilityModifier, {
at: startLoc,
modifier
});
} else {
enforceOrder(startLoc, modifier, modifier, "override");
enforceOrder(startLoc, modifier, modifier, "static");
enforceOrder(startLoc, modifier, modifier, "readonly");
modified.accessibility = modifier;
}
} else if (tsIsVarianceAnnotations(modifier)) {
if (modified[modifier]) {
this.raise(TSErrors.DuplicateModifier, {
at: startLoc,
modifier
});
}
modified[modifier] = true;
enforceOrder(startLoc, modifier, "in", "out");
} else {
if (Object.hasOwnProperty.call(modified, modifier)) {
this.raise(TSErrors.DuplicateModifier, {
at: startLoc,
modifier
});
} else {
enforceOrder(startLoc, modifier, "static", "readonly");
enforceOrder(startLoc, modifier, "static", "override");
enforceOrder(startLoc, modifier, "override", "readonly");
enforceOrder(startLoc, modifier, "abstract", "override");
incompatible(startLoc, modifier, "declare", "override");
incompatible(startLoc, modifier, "static", "abstract");
}
modified[modifier] = true;
}
if (disallowedModifiers != null && disallowedModifiers.includes(modifier)) {
this.raise(errorTemplate, {
at: startLoc,
modifier
});
}
}
}
tsIsListTerminator(kind) {
switch (kind) {
case "EnumMembers":
case "TypeMembers":
return this.match(8);
case "HeritageClauseElement":
return this.match(5);
case "TupleElementTypes":
return this.match(3);
case "TypeParametersOrArguments":
return this.match(48);
}
}
tsParseList(kind, parseElement) {
const result = [];
while (!this.tsIsListTerminator(kind)) {
result.push(parseElement());
}
return result;
}
tsParseDelimitedList(kind, parseElement, refTrailingCommaPos) {
return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true, refTrailingCommaPos));
}
tsParseDelimitedListWorker(kind, parseElement, expectSuccess, refTrailingCommaPos) {
const result = [];
let trailingCommaPos = -1;
for (;;) {
if (this.tsIsListTerminator(kind)) {
break;
}
trailingCommaPos = -1;
const element = parseElement();
if (element == null) {
return undefined;
}
result.push(element);
if (this.eat(12)) {
trailingCommaPos = this.state.lastTokStart;
continue;
}
if (this.tsIsListTerminator(kind)) {
break;
}
if (expectSuccess) {
this.expect(12);
}
return undefined;
}
if (refTrailingCommaPos) {
refTrailingCommaPos.value = trailingCommaPos;
}
return result;
}
tsParseBracketedList(kind, parseElement, bracket, skipFirstToken, refTrailingCommaPos) {
if (!skipFirstToken) {
if (bracket) {
this.expect(0);
} else {
this.expect(47);
}
}
const result = this.tsParseDelimitedList(kind, parseElement, refTrailingCommaPos);
if (bracket) {
this.expect(3);
} else {
this.expect(48);
}
return result;
}
tsParseImportType() {
const node = this.startNode();
this.expect(83);
this.expect(10);
if (!this.match(131)) {
this.raise(TSErrors.UnsupportedImportTypeArgument, {
at: this.state.startLoc
});
}
node.argument = super.parseExprAtom();
this.expect(11);
if (this.eat(16)) {
node.qualifier = this.tsParseEntityName();
}
if (this.match(47)) {
node.typeParameters = this.tsParseTypeArguments();
}
return this.finishNode(node, "TSImportType");
}
tsParseEntityName(allowReservedWords = true) {
let entity = this.parseIdentifier(allowReservedWords);
while (this.eat(16)) {
const node = this.startNodeAtNode(entity);
node.left = entity;
node.right = this.parseIdentifier(allowReservedWords);
entity = this.finishNode(node, "TSQualifiedName");
}
return entity;
}
tsParseTypeReference() {
const node = this.startNode();
node.typeName = this.tsParseEntityName();
if (!this.hasPrecedingLineBreak() && this.match(47)) {
node.typeParameters = this.tsParseTypeArguments();
}
return this.finishNode(node, "TSTypeReference");
}
tsParseThisTypePredicate(lhs) {
this.next();
const node = this.startNodeAtNode(lhs);
node.parameterName = lhs;
node.typeAnnotation = this.tsParseTypeAnnotation(false);
node.asserts = false;
return this.finishNode(node, "TSTypePredicate");
}
tsParseThisTypeNode() {
const node = this.startNode();
this.next();
return this.finishNode(node, "TSThisType");
}
tsParseTypeQuery() {
const node = this.startNode();
this.expect(87);
if (this.match(83)) {
node.exprName = this.tsParseImportType();
} else {
node.exprName = this.tsParseEntityName();
}
if (!this.hasPrecedingLineBreak() && this.match(47)) {
node.typeParameters = this.tsParseTypeArguments();
}
return this.finishNode(node, "TSTypeQuery");
}
tsParseTypeParameter(parseModifiers) {
const node = this.startNode();
parseModifiers(node);
node.name = this.tsParseTypeParameterName();
node.constraint = this.tsEatThenParseType(81);
node.default = this.tsEatThenParseType(29);
return this.finishNode(node, "TSTypeParameter");
}
tsTryParseTypeParameters(parseModifiers) {
if (this.match(47)) {
return this.tsParseTypeParameters(parseModifiers);
}
}
tsParseTypeParameters(parseModifiers) {
const node = this.startNode();
if (this.match(47) || this.match(140)) {
this.next();
} else {
this.unexpected();
}
const refTrailingCommaPos = {
value: -1
};
node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this, parseModifiers), false, true, refTrailingCommaPos);
if (node.params.length === 0) {
this.raise(TSErrors.EmptyTypeParameters, {
at: node
});
}
if (refTrailingCommaPos.value !== -1) {
this.addExtra(node, "trailingComma", refTrailingCommaPos.value);
}
return this.finishNode(node, "TSTypeParameterDeclaration");
}
tsFillSignature(returnToken, signature) {
const returnTokenRequired = returnToken === 19;
const paramsKey = "parameters";
const returnTypeKey = "typeAnnotation";
signature.typeParameters = this.tsTryParseTypeParameters(this.tsParseConstModifier);
this.expect(10);
signature[paramsKey] = this.tsParseBindingListForSignature();
if (returnTokenRequired) {
signature[returnTypeKey] = this.tsParseTypeOrTypePredicateAnnotation(returnToken);
} else if (this.match(returnToken)) {
signature[returnTypeKey] = this.tsParseTypeOrTypePredicateAnnotation(returnToken);
}
}
tsParseBindingListForSignature() {
const list = super.parseBindingList(11, 41, _lval.ParseBindingListFlags.IS_FUNCTION_PARAMS);
for (const pattern of list) {
const {
type
} = pattern;
if (type === "AssignmentPattern" || type === "TSParameterProperty") {
this.raise(TSErrors.UnsupportedSignatureParameterKind, {
at: pattern,
type
});
}
}
return list;
}
tsParseTypeMemberSemicolon() {
if (!this.eat(12) && !this.isLineTerminator()) {
this.expect(13);
}
}
tsParseSignatureMember(kind, node) {
this.tsFillSignature(14, node);
this.tsParseTypeMemberSemicolon();
return this.finishNode(node, kind);
}
tsIsUnambiguouslyIndexSignature() {
this.next();
if ((0, _types.tokenIsIdentifier)(this.state.type)) {
this.next();
return this.match(14);
}
return false;
}
tsTryParseIndexSignature(node) {
if (!(this.match(0) && this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))) {
return;
}
this.expect(0);
const id = this.parseIdentifier();
id.typeAnnotation = this.tsParseTypeAnnotation();
this.resetEndLocation(id);
this.expect(3);
node.parameters = [id];
const type = this.tsTryParseTypeAnnotation();
if (type) node.typeAnnotation = type;
this.tsParseTypeMemberSemicolon();
return this.finishNode(node, "TSIndexSignature");
}
tsParsePropertyOrMethodSignature(node, readonly) {
if (this.eat(17)) node.optional = true;
const nodeAny = node;
if (this.match(10) || this.match(47)) {
if (readonly) {
this.raise(TSErrors.ReadonlyForMethodSignature, {
at: node
});
}
const method = nodeAny;
if (method.kind && this.match(47)) {
this.raise(TSErrors.AccesorCannotHaveTypeParameters, {
at: this.state.curPosition()
});
}
this.tsFillSignature(14, method);
this.tsParseTypeMemberSemicolon();
const paramsKey = "parameters";
const returnTypeKey = "typeAnnotation";
if (method.kind === "get") {
if (method[paramsKey].length > 0) {
this.raise(_parseError.Errors.BadGetterArity, {
at: this.state.curPosition()
});
if (this.isThisParam(method[paramsKey][0])) {
this.raise(TSErrors.AccesorCannotDeclareThisParameter, {
at: this.state.curPosition()
});
}
}
} else if (method.kind === "set") {
if (method[paramsKey].length !== 1) {
this.raise(_parseError.Errors.BadSetterArity, {
at: this.state.curPosition()
});
} else {
const firstParameter = method[paramsKey][0];
if (this.isThisParam(firstParameter)) {
this.raise(TSErrors.AccesorCannotDeclareThisParameter, {
at: this.state.curPosition()
});
}
if (firstParameter.type === "Identifier" && firstParameter.optional) {
this.raise(TSErrors.SetAccesorCannotHaveOptionalParameter, {
at: this.state.curPosition()
});
}
if (firstParameter.type === "RestElement") {
this.raise(TSErrors.SetAccesorCannotHaveRestParameter, {
at: this.state.curPosition()
});
}
}
if (method[returnTypeKey]) {
this.raise(TSErrors.SetAccesorCannotHaveReturnType, {
at: method[returnTypeKey]
});
}
} else {
method.kind = "method";
}
return this.finishNode(method, "TSMethodSignature");
} else {
const property = nodeAny;
if (readonly) property.readonly = true;
const type = this.tsTryParseTypeAnnotation();
if (type) property.typeAnnotation = type;
this.tsParseTypeMemberSemicolon();
return this.finishNode(property, "TSPropertySignature");
}
}
tsParseTypeMember() {
const node = this.startNode();
if (this.match(10) || this.match(47)) {
return this.tsParseSignatureMember("TSCallSignatureDeclaration", node);
}
if (this.match(77)) {
const id = this.startNode();
this.next();
if (this.match(10) || this.match(47)) {
return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node);
} else {
node.key = this.createIdentifier(id, "new");
return this.tsParsePropertyOrMethodSignature(node, false);
}
}
this.tsParseModifiers({
allowedModifiers: ["readonly"],
disallowedModifiers: ["declare", "abstract", "private", "protected", "public", "static", "override"]
}, node);
const idx = this.tsTryParseIndexSignature(node);
if (idx) {
return idx;
}
super.parsePropertyName(node);
if (!node.computed && node.key.type === "Identifier" && (node.key.name === "get" || node.key.name === "set") && this.tsTokenCanFollowModifier()) {
node.kind = node.key.name;
super.parsePropertyName(node);
}
return this.tsParsePropertyOrMethodSignature(node, !!node.readonly);
}
tsParseTypeLiteral() {
const node = this.startNode();
node.members = this.tsParseObjectTypeMembers();
return this.finishNode(node, "TSTypeLiteral");
}
tsParseObjectTypeMembers() {
this.expect(5);
const members = this.tsParseList("TypeMembers", this.tsParseTypeMember.bind(this));
this.expect(8);
return members;
}
tsIsStartOfMappedType() {
this.next();
if (this.eat(53)) {
return this.isContextual(120);
}
if (this.isContextual(120)) {
this.next();
}
if (!this.match(0)) {
return false;
}
this.next();
if (!this.tsIsIdentifier()) {
return false;
}
this.next();
return this.match(58);
}
tsParseMappedTypeParameter() {
const node = this.startNode();
node.name = this.tsParseTypeParameterName();
node.constraint = this.tsExpectThenParseType(58);
return this.finishNode(node, "TSTypeParameter");
}
tsParseMappedType() {
const node = this.startNode();
this.expect(5);
if (this.match(53)) {
node.readonly = this.state.value;
this.next();
this.expectContextual(120);
} else if (this.eatContextual(120)) {
node.readonly = true;
}
this.expect(0);
node.typeParameter = this.tsParseMappedTypeParameter();
node.nameType = this.eatContextual(93) ? this.tsParseType() : null;
this.expect(3);
if (this.match(53)) {
node.optional = this.state.value;
this.next();
this.expect(17);
} else if (this.eat(17)) {
node.optional = true;
}
node.typeAnnotation = this.tsTryParseType();
this.semicolon();
this.expect(8);
return this.finishNode(node, "TSMappedType");
}
tsParseTupleType() {
const node = this.startNode();
node.elementTypes = this.tsParseBracketedList("TupleElementTypes", this.tsParseTupleElementType.bind(this), true, false);
let seenOptionalElement = false;
let labeledElements = null;
node.elementTypes.forEach(elementNode => {
var _labeledElements;
const {
type
} = elementNode;
if (seenOptionalElement && type !== "TSRestType" && type !== "TSOptionalType" && !(type === "TSNamedTupleMember" && elementNode.optional)) {
this.raise(TSErrors.OptionalTypeBeforeRequired, {
at: elementNode
});
}
seenOptionalElement || (seenOptionalElement = type === "TSNamedTupleMember" && elementNode.optional || type === "TSOptionalType");
let checkType = type;
if (type === "TSRestType") {
elementNode = elementNode.typeAnnotation;
checkType = elementNode.type;
}
const isLabeled = checkType === "TSNamedTupleMember";
(_labeledElements = labeledElements) != null ? _labeledElements : labeledElements = isLabeled;
if (labeledElements !== isLabeled) {
this.raise(TSErrors.MixedLabeledAndUnlabeledElements, {
at: elementNode
});
}
});
return this.finishNode(node, "TSTupleType");
}
tsParseTupleElementType() {
const {
startLoc
} = this.state;
const rest = this.eat(21);
let labeled;
let label;
let optional;
let type;
const isWord = (0, _types.tokenIsKeywordOrIdentifier)(this.state.type);
const chAfterWord = isWord ? this.lookaheadCharCode() : null;
if (chAfterWord === 58) {
labeled = true;
optional = false;
label = this.parseIdentifier(true);
this.expect(14);
type = this.tsParseType();
} else if (chAfterWord === 63) {
optional = true;
const startLoc = this.state.startLoc;
const wordName = this.state.value;
const typeOrLabel = this.tsParseNonArrayType();
if (this.lookaheadCharCode() === 58) {
labeled = true;
label = this.createIdentifier(this.startNodeAt(startLoc), wordName);
this.expect(17);
this.expect(14);
type = this.tsParseType();
} else {
labeled = false;
type = typeOrLabel;
this.expect(17);
}
} else {
type = this.tsParseType();
optional = this.eat(17);
labeled = this.eat(14);
}
if (labeled) {
let labeledNode;
if (label) {
labeledNode = this.startNodeAtNode(label);
labeledNode.optional = optional;
labeledNode.label = label;
labeledNode.elementType = type;
if (this.eat(17)) {
labeledNode.optional = true;
this.raise(TSErrors.TupleOptionalAfterType, {
at: this.state.lastTokStartLoc
});
}
} else {
labeledNode = this.startNodeAtNode(type);
labeledNode.optional = optional;
this.raise(TSErrors.InvalidTupleMemberLabel, {
at: type
});
labeledNode.label = type;
labeledNode.elementType = this.tsParseType();
}
type = this.finishNode(labeledNode, "TSNamedTupleMember");
} else if (optional) {
const optionalTypeNode = this.startNodeAtNode(type);
optionalTypeNode.typeAnnotation = type;
type = this.finishNode(optionalTypeNode, "TSOptionalType");
}
if (rest) {
const restNode = this.startNodeAt(startLoc);
restNode.typeAnnotation = type;
type = this.finishNode(restNode, "TSRestType");
}
return type;
}
tsParseParenthesizedType() {
const node = this.startNode();
this.expect(10);
node.typeAnnotation = this.tsParseType();
this.expect(11);
return this.finishNode(node, "TSParenthesizedType");
}
tsParseFunctionOrConstructorType(type, abstract) {
const node = this.startNode();
if (type === "TSConstructorType") {
node.abstract = !!abstract;
if (abstract) this.next();
this.next();
}
this.tsInAllowConditionalTypesContext(() => this.tsFillSignature(19, node));
return this.finishNode(node, type);
}
tsParseLiteralTypeNode() {
const node = this.startNode();
switch (this.state.type) {
case 132:
case 133:
case 131:
case 85:
case 86:
node.literal = super.parseExprAtom();
break;
default:
this.unexpected();
}
return this.finishNode(node, "TSLiteralType");
}
tsParseTemplateLiteralType() {
const node = this.startNode();
node.literal = super.parseTemplate(false);
return this.finishNode(node, "TSLiteralType");
}
parseTemplateSubstitution() {
if (this.state.inType) return this.tsParseType();
return super.parseTemplateSubstitution();
}
tsParseThisTypeOrThisTypePredicate() {
const thisKeyword = this.tsParseThisTypeNode();
if (this.isContextual(114) && !this.hasPrecedingLineBreak()) {
return this.tsParseThisTypePredicate(thisKeyword);
} else {
return thisKeyword;
}
}
tsParseNonArrayType() {
switch (this.state.type) {
case 131:
case 132:
case 133:
case 85:
case 86:
return this.tsParseLiteralTypeNode();
case 53:
if (this.state.value === "-") {
const node = this.startNode();
const nextToken = this.lookahead();
if (nextToken.type !== 132 && nextToken.type !== 133) {
this.unexpected();
}
node.literal = this.parseMaybeUnary();
return this.finishNode(node, "TSLiteralType");
}
break;
case 78:
return this.tsParseThisTypeOrThisTypePredicate();
case 87:
return this.tsParseTypeQuery();
case 83:
return this.tsParseImportType();
case 5:
return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this)) ? this.tsParseMappedType() : this.tsParseTypeLiteral();
case 0:
return this.tsParseTupleType();
case 10:
;
return this.tsParseParenthesizedType();
case 25:
case 24:
return this.tsParseTemplateLiteralType();
default:
{
const {
type
} = this.state;
if ((0, _types.tokenIsIdentifier)(type) || type === 88 || type === 84) {
const nodeType = type === 88 ? "TSVoidKeyword" : type === 84 ? "TSNullKeyword" : keywordTypeFromName(this.state.value);
if (nodeType !== undefined && this.lookaheadCharCode() !== 46) {
const node = this.startNode();
this.next();
return this.finishNode(node, nodeType);
}
return this.tsParseTypeReference();
}
}
}
this.unexpected();
}
tsParseArrayTypeOrHigher() {
let type = this.tsParseNonArrayType();
while (!this.hasPrecedingLineBreak() && this.eat(0)) {
if (this.match(3)) {
const node = this.startNodeAtNode(type);
node.elementType = type;
this.expect(3);
type = this.finishNode(node, "TSArrayType");
} else {
const node = this.startNodeAtNode(type);
node.objectType = type;
node.indexType = this.tsParseType();
this.expect(3);
type = this.finishNode(node, "TSIndexedAccessType");
}
}
return type;
}
tsParseTypeOperator() {
const node = this.startNode();
const operator = this.state.value;
this.next();
node.operator = operator;
node.typeAnnotation = this.tsParseTypeOperatorOrHigher();
if (operator === "readonly") {
this.tsCheckTypeAnnotationForReadOnly(node);
}
return this.finishNode(node, "TSTypeOperator");
}
tsCheckTypeAnnotationForReadOnly(node) {
switch (node.typeAnnotation.type) {
case "TSTupleType":
case "TSArrayType":
return;
default:
this.raise(TSErrors.UnexpectedReadonly, {
at: node
});
}
}
tsParseInferType() {
const node = this.startNode();
this.expectContextual(113);
const typeParameter = this.startNode();
typeParameter.name = this.tsParseTypeParameterName();
typeParameter.constraint = this.tsTryParse(() => this.tsParseConstraintForInferType());
node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter");
return this.finishNode(node, "TSInferType");
}
tsParseConstraintForInferType() {
if (this.eat(81)) {
const constraint = this.tsInDisallowConditionalTypesContext(() => this.tsParseType());
if (this.state.inDisallowConditionalTypesContext || !this.match(17)) {
return constraint;
}
}
}
tsParseTypeOperatorOrHigher() {
const isTypeOperator = (0, _types.tokenIsTSTypeOperator)(this.state.type) && !this.state.containsEsc;
return isTypeOperator ? this.tsParseTypeOperator() : this.isContextual(113) ? this.tsParseInferType() : this.tsInAllowConditionalTypesContext(() => this.tsParseArrayTypeOrHigher());
}
tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) {
const node = this.startNode();
const hasLeadingOperator = this.eat(operator);
const types = [];
do {
types.push(parseConstituentType());
} while (this.eat(operator));
if (types.length === 1 && !hasLeadingOperator) {
return types[0];
}
node.types = types;
return this.finishNode(node, kind);
}
tsParseIntersectionTypeOrHigher() {
return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), 45);
}
tsParseUnionTypeOrHigher() {
return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), 43);
}
tsIsStartOfFunctionType() {
if (this.match(47)) {
return true;
}
return this.match(10) && this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this));
}
tsSkipParameterStart() {
if ((0, _types.tokenIsIdentifier)(this.state.type) || this.match(78)) {
this.next();
return true;
}
if (this.match(5)) {
const {
errors
} = this.state;
const previousErrorCount = errors.length;
try {
this.parseObjectLike(8, true);
return errors.length === previousErrorCount;
} catch (_unused) {
return false;
}
}
if (this.match(0)) {
this.next();
const {
errors
} = this.state;
const previousErrorCount = errors.length;
try {
super.parseBindingList(3, 93, _lval.ParseBindingListFlags.ALLOW_EMPTY);
return errors.length === previousErrorCount;
} catch (_unused2) {
return false;
}
}
return false;
}
tsIsUnambiguouslyStartOfFunctionType() {
this.next();
if (this.match(11) || this.match(21)) {
return true;
}
if (this.tsSkipParameterStart()) {
if (this.match(14) || this.match(12) || this.match(17) || this.match(29)) {
return true;
}
if (this.match(11)) {
this.next();
if (this.match(19)) {
return true;
}
}
}
return false;
}
tsParseTypeOrTypePredicateAnnotation(returnToken) {
return this.tsInType(() => {
const t = this.startNode();
this.expect(returnToken);
const node = this.startNode();
const asserts = !!this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this));
if (asserts && this.match(78)) {
let thisTypePredicate = this.tsParseThisTypeOrThisTypePredicate();
if (thisTypePredicate.type === "TSThisType") {
node.parameterName = thisTypePredicate;
node.asserts = true;
node.typeAnnotation = null;
thisTypePredicate = this.finishNode(node, "TSTypePredicate");
} else {
this.resetStartLocationFromNode(thisTypePredicate, node);
thisTypePredicate.asserts = true;
}
t.typeAnnotation = thisTypePredicate;
return this.finishNode(t, "TSTypeAnnotation");
}
const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this));
if (!typePredicateVariable) {
if (!asserts) {
return this.tsParseTypeAnnotation(false, t);
}
node.parameterName = this.parseIdentifier();
node.asserts = asserts;
node.typeAnnotation = null;
t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
return this.finishNode(t, "TSTypeAnnotation");
}
const type = this.tsParseTypeAnnotation(false);
node.parameterName = typePredicateVariable;
node.typeAnnotation = type;
node.asserts = asserts;
t.typeAnnotation = this.finishNode(node, "TSTypePredicate");
return this.finishNode(t, "TSTypeAnnotation");
});
}
tsTryParseTypeOrTypePredicateAnnotation() {
if (this.match(14)) {
return this.tsParseTypeOrTypePredicateAnnotation(14);
}
}
tsTryParseTypeAnnotation() {
if (this.match(14)) {
return this.tsParseTypeAnnotation();
}
}
tsTryParseType() {
return this.tsEatThenParseType(14);
}
tsParseTypePredicatePrefix() {
const id = this.parseIdentifier();
if (this.isContextual(114) && !this.hasPrecedingLineBreak()) {
this.next();
return id;
}
}
tsParseTypePredicateAsserts() {
if (this.state.type !== 107) {
return false;
}
const containsEsc = this.state.containsEsc;
this.next();
if (!(0, _types.tokenIsIdentifier)(this.state.type) && !this.match(78)) {
return false;
}
if (containsEsc) {
this.raise(_parseError.Errors.InvalidEscapedReservedWord, {
at: this.state.lastTokStartLoc,
reservedWord: "asserts"
});
}
return true;
}
tsParseTypeAnnotation(eatColon = true, t = this.startNode()) {
this.tsInType(() => {
if (eatColon) this.expect(14);
t.typeAnnotation = this.tsParseType();
});
return this.finishNode(t, "TSTypeAnnotation");
}
tsParseType() {
assert(this.state.inType);
const type = this.tsParseNonConditionalType();
if (this.state.inDisallowConditionalTypesContext || this.hasPrecedingLineBreak() || !this.eat(81)) {
return type;
}
const node = this.startNodeAtNode(type);
node.checkType = type;
node.extendsType = this.tsInDisallowConditionalTypesContext(() => this.tsParseNonConditionalType());
this.expect(17);
node.trueType = this.tsInAllowConditionalTypesContext(() => this.tsParseType());
this.expect(14);
node.falseType = this.tsInAllowConditionalTypesContext(() => this.tsParseType());
return this.finishNode(node, "TSConditionalType");
}
isAbstractConstructorSignature() {
return this.isContextual(122) && this.lookahead().type === 77;
}
tsParseNonConditionalType() {
if (this.tsIsStartOfFunctionType()) {
return this.tsParseFunctionOrConstructorType("TSFunctionType");
}
if (this.match(77)) {
return this.tsParseFunctionOrConstructorType("TSConstructorType");
} else if (this.isAbstractConstructorSignature()) {
return this.tsParseFunctionOrConstructorType("TSConstructorType", true);
}
return this.tsParseUnionTypeOrHigher();
}
tsParseTypeAssertion() {
if (this.getPluginOption("typescript", "disallowAmbiguousJSXLike")) {
this.raise(TSErrors.ReservedTypeAssertion, {
at: this.state.startLoc
});
}
const node = this.startNode();
node.typeAnnotation = this.tsInType(() => {
this.next();
return this.match(75) ? this.tsParseTypeReference() : this.tsParseType();
});
this.expect(48);
node.expression = this.parseMaybeUnary();
return this.finishNode(node, "TSTypeAssertion");
}
tsParseHeritageClause(token) {
const originalStartLoc = this.state.startLoc;
const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", () => {
const node = this.startNode();
node.expression = this.tsParseEntityName();
if (this.match(47)) {
node.typeParameters = this.tsParseTypeArguments();
}
return this.finishNode(node, "TSExpressionWithTypeArguments");
});
if (!delimitedList.length) {
this.raise(TSErrors.EmptyHeritageClauseType, {
at: originalStartLoc,
token
});
}
return delimitedList;
}
tsParseInterfaceDeclaration(node, properties = {}) {
if (this.hasFollowingLineBreak()) return null;
this.expectContextual(127);
if (properties.declare) node.declare = true;
if ((0, _types.tokenIsIdentifier)(this.state.type)) {
node.id = this.parseIdentifier();
this.checkIdentifier(node.id, _scopeflags.BIND_TS_INTERFACE);
} else {
node.id = null;
this.raise(TSErrors.MissingInterfaceName, {
at: this.state.startLoc
});
}
node.typeParameters = this.tsTryParseTypeParameters(this.tsParseInOutConstModifiers);
if (this.eat(81)) {
node.extends = this.tsParseHeritageClause("extends");
}
const body = this.startNode();
body.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this));
node.body = this.finishNode(body, "TSInterfaceBody");
return this.finishNode(node, "TSInterfaceDeclaration");
}
tsParseTypeAliasDeclaration(node) {
node.id = this.parseIdentifier();
this.checkIdentifier(node.id, _scopeflags.BIND_TS_TYPE);
node.typeAnnotation = this.tsInType(() => {
node.typeParameters = this.tsTryParseTypeParameters(this.tsParseInOutModifiers);
this.expect(29);
if (this.isContextual(112) && this.lookahead().type !== 16) {
const node = this.startNode();
this.next();
return this.finishNode(node, "TSIntrinsicKeyword");
}
return this.tsParseType();
});
this.semicolon();
return this.finishNode(node, "TSTypeAliasDeclaration");
}
tsInNoContext(cb) {
const oldContext = this.state.context;
this.state.context = [oldContext[0]];
try {
return cb();
} finally {
this.state.context = oldContext;
}
}
tsInType(cb) {
const oldInType = this.state.inType;
this.state.inType = true;
try {
return cb();
} finally {
this.state.inType = oldInType;
}
}
tsInDisallowConditionalTypesContext(cb) {
const oldInDisallowConditionalTypesContext = this.state.inDisallowConditionalTypesContext;
this.state.inDisallowConditionalTypesContext = true;
try {
return cb();
} finally {
this.state.inDisallowConditionalTypesContext = oldInDisallowConditionalTypesContext;
}
}
tsInAllowConditionalTypesContext(cb) {
const oldInDisallowConditionalTypesContext = this.state.inDisallowConditionalTypesContext;
this.state.inDisallowConditionalTypesContext = false;
try {
return cb();
} finally {
this.state.inDisallowConditionalTypesContext = oldInDisallowConditionalTypesContext;
}
}
tsEatThenParseType(token) {
if (this.match(token)) {
return this.tsNextThenParseType();
}
}
tsExpectThenParseType(token) {
return this.tsInType(() => {
this.expect(token);
return this.tsParseType();
});
}
tsNextThenParseType() {
return this.tsInType(() => {
this.next();
return this.tsParseType();
});
}
tsParseEnumMember() {
const node = this.startNode();
node.id = this.match(131) ? super.parseStringLiteral(this.state.value) : this.parseIdentifier(true);
if (this.eat(29)) {
node.initializer = super.parseMaybeAssignAllowIn();
}
return this.finishNode(node, "TSEnumMember");
}
tsParseEnumDeclaration(node, properties = {}) {
if (properties.const) node.const = true;
if (properties.declare) node.declare = true;
this.expectContextual(124);
node.id = this.parseIdentifier();
this.checkIdentifier(node.id, node.const ? _scopeflags.BIND_TS_CONST_ENUM : _scopeflags.BIND_TS_ENUM);
this.expect(5);
node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this));
this.expect(8);
return this.finishNode(node, "TSEnumDeclaration");
}
tsParseModuleBlock() {
const node = this.startNode();
this.scope.enter(_scopeflags.SCOPE_OTHER);
this.expect(5);
super.parseBlockOrModuleBlockBody(node.body = [], undefined, true, 8);
this.scope.exit();
return this.finishNode(node, "TSModuleBlock");
}
tsParseModuleOrNamespaceDeclaration(node, nested = false) {
node.id = this.parseIdentifier();
if (!nested) {
this.checkIdentifier(node.id, _scopeflags.BIND_TS_NAMESPACE);
}
if (this.eat(16)) {
const inner = this.startNode();
this.tsParseModuleOrNamespaceDeclaration(inner, true);
node.body = inner;
} else {
this.scope.enter(_scopeflags.SCOPE_TS_MODULE);
this.prodParam.enter(_productionParameter.PARAM);
node.body = this.tsParseModuleBlock();
this.prodParam.exit();
this.scope.exit();
}
return this.finishNode(node, "TSModuleDeclaration");
}
tsParseAmbientExternalModuleDeclaration(node) {
if (this.isContextual(110)) {
node.global = true;
node.id = this.parseIdentifier();
} else if (this.match(131)) {
node.id = super.parseStringLiteral(this.state.value);
} else {
this.unexpected();
}
if (this.match(5)) {
this.scope.enter(_scopeflags.SCOPE_TS_MODULE);
this.prodParam.enter(_productionParameter.PARAM);
node.body = this.tsParseModuleBlock();
this.prodParam.exit();
this.scope.exit();
} else {
this.semicolon();
}
return this.finishNode(node, "TSModuleDeclaration");
}
tsParseImportEqualsDeclaration(node, maybeDefaultIdentifier, isExport) {
node.isExport = isExport || false;
node.id = maybeDefaultIdentifier || this.parseIdentifier();
this.checkIdentifier(node.id, _scopeflags.BIND_FLAGS_TS_IMPORT);
this.expect(29);
const moduleReference = this.tsParseModuleReference();
if (node.importKind === "type" && moduleReference.type !== "TSExternalModuleReference") {
this.raise(TSErrors.ImportAliasHasImportType, {
at: moduleReference
});
}
node.moduleReference = moduleReference;
this.semicolon();
return this.finishNode(node, "TSImportEqualsDeclaration");
}
tsIsExternalModuleReference() {
return this.isContextual(117) && this.lookaheadCharCode() === 40;
}
tsParseModuleReference() {
return this.tsIsExternalModuleReference() ? this.tsParseExternalModuleReference() : this.tsParseEntityName(false);
}
tsParseExternalModuleReference() {
const node = this.startNode();
this.expectContextual(117);
this.expect(10);
if (!this.match(131)) {
this.unexpected();
}
node.expression = super.parseExprAtom();
this.expect(11);
this.sawUnambiguousESM = true;
return this.finishNode(node, "TSExternalModuleReference");
}
tsLookAhead(f) {
const state = this.state.clone();
const res = f();
this.state = state;
return res;
}
tsTryParseAndCatch(f) {
const result = this.tryParse(abort => f() || abort());
if (result.aborted || !result.node) return;
if (result.error) this.state = result.failState;
return result.node;
}
tsTryParse(f) {
const state = this.state.clone();
const result = f();
if (result !== undefined && result !== false) {
return result;
}
this.state = state;
}
tsTryParseDeclare(nany) {
if (this.isLineTerminator()) {
return;
}
let startType = this.state.type;
let kind;
if (this.isContextual(99)) {
startType = 74;
kind = "let";
}
return this.tsInAmbientContext(() => {
switch (startType) {
case 68:
nany.declare = true;
return super.parseFunctionStatement(nany, false, false);
case 80:
nany.declare = true;
return this.parseClass(nany, true, false);
case 124:
return this.tsParseEnumDeclaration(nany, {
declare: true
});
case 110:
return this.tsParseAmbientExternalModuleDeclaration(nany);
case 75:
case 74:
if (!this.match(75) || !this.isLookaheadContextual("enum")) {
nany.declare = true;
return this.parseVarStatement(nany, kind || this.state.value, true);
}
this.expect(75);
return this.tsParseEnumDeclaration(nany, {
const: true,
declare: true
});
case 127:
{
const r