import { eat , lookaheadType , lookaheadTypeAndKeyword , match , next , nextTemplateToken , popTypeContext , pushTypeContext , } from "../tokenizer/index" ; import { ContextualKeyword } from "../tokenizer/keywords" ; import { TokenType , TokenType as tt } from "../tokenizer/types" ; import { state } from "../traverser/base" ; import { atPossibleAsync , baseParseMaybeAssign , baseParseSubscript , parseCallExpressionArguments , parseExprAtom , parseExpression , parseFunctionBody , parseIdentifier , parseLiteral , parseMaybeAssign , parseMaybeUnary , parsePropertyName , parseTemplate , StopState , } from "../traverser/expression" ; import { parseBindingIdentifier , parseBindingList , parseImportedIdentifier } from "../traverser/lval" ; import { baseParseMaybeDecoratorArguments , parseBlockBody , parseClass , parseClassProperty , parseClassPropertyName , parseFunction , parseFunctionParams , parsePostMemberNameModifiers , parseStatement , parseVarStatement , } from "../traverser/statement" ; import { canInsertSemicolon , eatContextual , expect , expectContextual , hasPrecedingLineBreak , isContextual , isLineTerminator , isLookaheadContextual , semicolon , unexpected , } from "../traverser/util" ; function tsIsIdentifier ( ) { return match ( tt . name ) ; } function isLiteralPropertyName ( ) { return ( match ( tt . name ) || ( ( state . type & TokenType . IS_KEYWORD ) !== 0 ) || match ( tt . string ) || match ( tt . num ) || match ( tt . bigint ) || match ( tt . decimal ) ) ; } function tsNextTokenCanFollowModifier ( ) { const snapshot = state . snapshot ( ) ; next ( ) ; const canFollowModifier = ( match ( tt . bracketL ) || match ( tt . braceL ) || match ( tt . star ) || match ( tt . ellipsis ) || match ( tt . hash ) || isLiteralPropertyName ( ) ) && ! hasPrecedingLineBreak ( ) ; if ( canFollowModifier ) { return true ; } else { state . restoreFromSnapshot ( snapshot ) ; return false ; } } /** Parses a modifier matching one the given modifier names. */ export function tsParseModifier ( allowedModifiers ) { if ( ! match ( tt . name ) ) { return - 1 ; } const modifier = state . contextualKeyword ; if ( allowedModifiers . indexOf ( modifier ) !== - 1 && tsNextTokenCanFollowModifier ( ) ) { switch ( modifier ) { case ContextualKeyword . _readonly : state . tokens [ state . tokens . length - 1 ] . type = tt . _readonly ; break ; case ContextualKeyword . _abstract : state . tokens [ state . tokens . length - 1 ] . type = tt . _abstract ; break ; case ContextualKeyword . _static : state . tokens [ state . tokens . length - 1 ] . type = tt . _static ; break ; case ContextualKeyword . _public : state . tokens [ state . tokens . length - 1 ] . type = tt . _public ; break ; case ContextualKeyword . _private : state . tokens [ state . tokens . length - 1 ] . type = tt . _private ; break ; case ContextualKeyword . _protected : state . tokens [ state . tokens . length - 1 ] . type = tt . _protected ; break ; case ContextualKeyword . _declare : state . tokens [ state . tokens . length - 1 ] . type = tt . _declare ; break ; default : break ; } return modifier ; } return - 1 ; } function tsParseEntityName ( ) { parseIdentifier ( ) ; while ( eat ( tt . dot ) ) { parseIdentifier ( ) ; } } function tsParseTypeReference ( ) { tsParseEntityName ( ) ; if ( ! hasPrecedingLineBreak ( ) && match ( tt . lessThan ) ) { tsParseTypeArguments ( ) ; } } function tsParseThisTypePredicate ( ) { next ( ) ; tsParseTypeAnnotation ( ) ; } function tsParseThisTypeNode ( ) { next ( ) ; } function tsParseTypeQuery ( ) { expect ( tt . _typeof ) ; if ( match ( tt . _import ) ) { tsParseImportType ( ) ; } else { tsParseEntityName ( ) ; } } function tsParseImportType ( ) { expect ( tt . _import ) ; expect ( tt . parenL ) ; expect ( tt . string ) ; expect ( tt . parenR ) ; if ( eat ( tt . dot ) ) { tsParseEntityName ( ) ; } if ( match ( tt . lessThan ) ) { tsParseTypeArguments ( ) ; } } function tsParseTypeParameter ( ) { parseIdentifier ( ) ; if ( eat ( tt . _extends ) ) { tsParseType ( ) ; } if ( eat ( tt . eq ) ) { tsParseType ( ) ; } } export function tsTryParseTypeParameters ( ) { if ( match ( tt . lessThan ) ) { tsParseTypeParameters ( ) ; } } function tsParseTypeParameters ( ) { const oldIsType = pushTypeContext ( 0 ) ; if ( match ( tt . lessThan ) || match ( tt . typeParameterStart ) ) { next ( ) ; } else { unexpected ( ) ; } while ( ! eat ( tt . greaterThan ) && ! state . error ) { tsParseTypeParameter ( ) ; eat ( tt . comma ) ; } popTypeContext ( oldIsType ) ; } function tsFillSignature ( returnToken ) { const returnTokenRequired = returnToken === tt . arrow ; tsTryParseTypeParameters ( ) ; expect ( tt . parenL ) ; tsParseBindingListForSignature ( false ) ; if ( returnTokenRequired ) { tsParseTypeOrTypePredicateAnnotation ( returnToken ) ; } else if ( match ( returnToken ) ) { tsParseTypeOrTypePredicateAnnotation ( returnToken ) ; } } function tsParseBindingListForSignature ( isBlockScope ) { parseBindingList ( tt . parenR , isBlockScope ) ; } function tsParseTypeMemberSemicolon ( ) { if ( ! eat ( tt . comma ) ) { semicolon ( ) ; } } function tsParseSignatureMember ( ) { tsFillSignature ( tt . colon ) ; tsParseTypeMemberSemicolon ( ) ; } function tsIsUnambiguouslyIndexSignature ( ) { const snapshot = state . snapshot ( ) ; next ( ) ; const isIndexSignature = eat ( tt . name ) && match ( tt . colon ) ; state . restoreFromSnapshot ( snapshot ) ; return isIndexSignature ; } function tsTryParseIndexSignature ( ) { if ( ! ( match ( tt . bracketL ) && tsIsUnambiguouslyIndexSignature ( ) ) ) { return false ; } const oldIsType = pushTypeContext ( 0 ) ; expect ( tt . bracketL ) ; parseIdentifier ( ) ; tsParseTypeAnnotation ( ) ; expect ( tt . bracketR ) ; tsTryParseTypeAnnotation ( ) ; tsParseTypeMemberSemicolon ( ) ; popTypeContext ( oldIsType ) ; return true ; } function tsParsePropertyOrMethodSignature ( isReadonly ) { eat ( tt . question ) ; if ( ! isReadonly && ( match ( tt . parenL ) || match ( tt . lessThan ) ) ) { tsFillSignature ( tt . colon ) ; tsParseTypeMemberSemicolon ( ) ; } else { tsTryParseTypeAnnotation ( ) ; tsParseTypeMemberSemicolon ( ) ; } } function tsParseTypeMember ( ) { if ( match ( tt . parenL ) || match ( tt . lessThan ) ) { tsParseSignatureMember ( ) ; return ; } if ( match ( tt . _new ) ) { next ( ) ; if ( match ( tt . parenL ) || match ( tt . lessThan ) ) { tsParseSignatureMember ( ) ; } else { tsParsePropertyOrMethodSignature ( false ) ; } return ; } const readonly = ! ! tsParseModifier ( [ ContextualKeyword . _readonly ] ) ; const found = tsTryParseIndexSignature ( ) ; if ( found ) { return ; } parsePropertyName ( ) ; tsParsePropertyOrMethodSignature ( readonly ) ; } function tsParseTypeLiteral ( ) { tsParseObjectTypeMembers ( ) ; } function tsParseObjectTypeMembers ( ) { expect ( tt . braceL ) ; while ( ! eat ( tt . braceR ) && ! state . error ) { tsParseTypeMember ( ) ; } } function tsLookaheadIsStartOfMappedType ( ) { const snapshot = state . snapshot ( ) ; const isStartOfMappedType = tsIsStartOfMappedType ( ) ; state . restoreFromSnapshot ( snapshot ) ; return isStartOfMappedType ; } function tsIsStartOfMappedType ( ) { next ( ) ; if ( eat ( tt . plus ) || eat ( tt . minus ) ) { return isContextual ( ContextualKeyword . _readonly ) ; } if ( isContextual ( ContextualKeyword . _readonly ) ) { next ( ) ; } if ( ! match ( tt . bracketL ) ) { return false ; } next ( ) ; if ( ! tsIsIdentifier ( ) ) { return false ; } next ( ) ; return match ( tt . _in ) ; } function tsParseMappedTypeParameter ( ) { parseIdentifier ( ) ; expect ( tt . _in ) ; tsParseType ( ) ; } function tsParseMappedType ( ) { expect ( tt . braceL ) ; if ( match ( tt . plus ) || match ( tt . minus ) ) { next ( ) ; expectContextual ( ContextualKeyword . _readonly ) ; } else { eatContextual ( ContextualKeyword . _readonly ) ; } expect ( tt . bracketL ) ; tsParseMappedTypeParameter ( ) ; if ( eatContextual ( ContextualKeyword . _as ) ) { tsParseType ( ) ; } expect ( tt . bracketR ) ; if ( match ( tt . plus ) || match ( tt . minus ) ) { next ( ) ; expect ( tt . question ) ; } else { eat ( tt . question ) ; } tsTryParseType ( ) ; semicolon ( ) ; expect ( tt . braceR ) ; } function tsParseTupleType ( ) { expect ( tt . bracketL ) ; while ( ! eat ( tt . bracketR ) && ! state . error ) { tsParseTupleElementType ( ) ; eat ( tt . comma ) ; } } function tsParseTupleElementType ( ) { if ( eat ( tt . ellipsis ) ) { tsParseType ( ) ; } else { tsParseType ( ) ; eat ( tt . question ) ; } if ( eat ( tt . colon ) ) { tsParseType ( ) ; } } function tsParseParenthesizedType ( ) { expect ( tt . parenL ) ; tsParseType ( ) ; expect ( tt . parenR ) ; } function tsParseTemplateLiteralType ( ) { nextTemplateToken ( ) ; nextTemplateToken ( ) ; while ( ! match ( tt . backQuote ) && ! state . error ) { expect ( tt . dollarBraceL ) ; tsParseType ( ) ; nextTemplateToken ( ) ; nextTemplateToken ( ) ; } next ( ) ; } enum FunctionType { TSFunctionType , TSConstructorType } function tsParseFunctionOrConstructorType ( type ) { if ( type === FunctionType . TSConstructorType ) { expect ( tt . _new ) ; } tsFillSignature ( tt . arrow ) ; } function tsParseNonArrayType ( ) { switch ( state . type ) { case tt . name : tsParseTypeReference ( ) ; return ; case tt . _void : case tt . _null : next ( ) ; return ; case tt . string : case tt . num : case tt . bigint : case tt . decimal : case tt . _true : case tt . _false : parseLiteral ( ) ; return ; case tt . minus : next ( ) ; parseLiteral ( ) ; return ; case tt . _this : { tsParseThisTypeNode ( ) ; if ( isContextual ( ContextualKeyword . _is ) && ! hasPrecedingLineBreak ( ) ) { tsParseThisTypePredicate ( ) ; } return ; } case tt . _typeof : tsParseTypeQuery ( ) ; return ; case tt . _import : tsParseImportType ( ) ; return ; case tt . braceL : if ( tsLookaheadIsStartOfMappedType ( ) ) { tsParseMappedType ( ) ; } else { tsParseTypeLiteral ( ) ; } return ; case tt . bracketL : tsParseTupleType ( ) ; return ; case tt . parenL : tsParseParenthesizedType ( ) ; return ; case tt . backQuote : tsParseTemplateLiteralType ( ) ; return ; default : if ( state . type & TokenType . IS_KEYWORD ) { next ( ) ; state . tokens [ state . tokens . length - 1 ] . type = tt . name ; return ; } break ; } unexpected ( ) ; } function tsParseArrayTypeOrHigher ( ) { tsParseNonArrayType ( ) ; while ( ! hasPrecedingLineBreak ( ) && eat ( tt . bracketL ) ) { if ( ! eat ( tt . bracketR ) ) { tsParseType ( ) ; expect ( tt . bracketR ) ; } } } function tsParseInferType ( ) { expectContextual ( ContextualKeyword . _infer ) ; parseIdentifier ( ) ; } function tsParseTypeOperatorOrHigher ( ) { if ( isContextual ( ContextualKeyword . _keyof ) || isContextual ( ContextualKeyword . _unique ) || isContextual ( ContextualKeyword . _readonly ) ) { next ( ) ; tsParseTypeOperatorOrHigher ( ) ; } else if ( isContextual ( ContextualKeyword . _infer ) ) { tsParseInferType ( ) ; } else { tsParseArrayTypeOrHigher ( ) ; } } function tsParseIntersectionTypeOrHigher ( ) { eat ( tt . bitwiseAND ) ; tsParseTypeOperatorOrHigher ( ) ; if ( match ( tt . bitwiseAND ) ) { while ( eat ( tt . bitwiseAND ) ) { tsParseTypeOperatorOrHigher ( ) ; } } } function tsParseUnionTypeOrHigher ( ) { eat ( tt . bitwiseOR ) ; tsParseIntersectionTypeOrHigher ( ) ; if ( match ( tt . bitwiseOR ) ) { while ( eat ( tt . bitwiseOR ) ) { tsParseIntersectionTypeOrHigher ( ) ; } } } function tsIsStartOfFunctionType ( ) { if ( match ( tt . lessThan ) ) { return true ; } return match ( tt . parenL ) && tsLookaheadIsUnambiguouslyStartOfFunctionType ( ) ; } function tsSkipParameterStart ( ) { if ( match ( tt . name ) || match ( tt . _this ) ) { next ( ) ; return true ; } if ( match ( tt . braceL ) || match ( tt . bracketL ) ) { let depth = 1 ; next ( ) ; while ( depth > 0 && ! state . error ) { if ( match ( tt . braceL ) || match ( tt . bracketL ) ) { depth ++ ; } else if ( match ( tt . braceR ) || match ( tt . bracketR ) ) { depth -- ; } next ( ) ; } return true ; } return false ; } function tsLookaheadIsUnambiguouslyStartOfFunctionType ( ) { const snapshot = state . snapshot ( ) ; const isUnambiguouslyStartOfFunctionType = tsIsUnambiguouslyStartOfFunctionType ( ) ; state . restoreFromSnapshot ( snapshot ) ; return isUnambiguouslyStartOfFunctionType ; } function tsIsUnambiguouslyStartOfFunctionType ( ) { next ( ) ; if ( match ( tt . parenR ) || match ( tt . ellipsis ) ) { return true ; } if ( tsSkipParameterStart ( ) ) { if ( match ( tt . colon ) || match ( tt . comma ) || match ( tt . question ) || match ( tt . eq ) ) { return true ; } if ( match ( tt . parenR ) ) { next ( ) ; if ( match ( tt . arrow ) ) { return true ; } } } return false ; } function tsParseTypeOrTypePredicateAnnotation ( returnToken ) { const oldIsType = pushTypeContext ( 0 ) ; expect ( returnToken ) ; const finishedReturn = tsParseTypePredicateOrAssertsPrefix ( ) ; if ( ! finishedReturn ) { tsParseType ( ) ; } popTypeContext ( oldIsType ) ; } function tsTryParseTypeOrTypePredicateAnnotation ( ) { if ( match ( tt . colon ) ) { tsParseTypeOrTypePredicateAnnotation ( tt . colon ) ; } } export function tsTryParseTypeAnnotation ( ) { if ( match ( tt . colon ) ) { tsParseTypeAnnotation ( ) ; } } function tsTryParseType ( ) { if ( eat ( tt . colon ) ) { tsParseType ( ) ; } } /**
 * Detect a few special return syntax cases: `x is T`, `asserts x`, `asserts x is T`,
 * `asserts this is T`.
 *
 * Returns true if we parsed the return type, false if there's still a type to be parsed.
 */ function tsParseTypePredicateOrAssertsPrefix ( ) { const snapshot = state . snapshot ( ) ; if ( isContextual ( ContextualKeyword . _asserts ) && ! hasPrecedingLineBreak ( ) ) { next ( ) ; if ( eatContextual ( ContextualKeyword . _is ) ) { tsParseType ( ) ; return true ; } else if ( tsIsIdentifier ( ) || match ( tt . _this ) ) { next ( ) ; if ( eatContextual ( ContextualKeyword . _is ) ) { tsParseType ( ) ; } return true ; } else { state . restoreFromSnapshot ( snapshot ) ; return false ; } } else if ( tsIsIdentifier ( ) || match ( tt . _this ) ) { next ( ) ; if ( isContextual ( ContextualKeyword . _is ) && ! hasPrecedingLineBreak ( ) ) { next ( ) ; tsParseType ( ) ; return true ; } else { state . restoreFromSnapshot ( snapshot ) ; return false ; } } return false ; } export function tsParseTypeAnnotation ( ) { const oldIsType = pushTypeContext ( 0 ) ; expect ( tt . colon ) ; tsParseType ( ) ; popTypeContext ( oldIsType ) ; } export function tsParseType ( ) { tsParseNonConditionalType ( ) ; if ( hasPrecedingLineBreak ( ) || ! eat ( tt . _extends ) ) { return ; } tsParseNonConditionalType ( ) ; expect ( tt . question ) ; tsParseType ( ) ; expect ( tt . colon ) ; tsParseType ( ) ; } export function tsParseNonConditionalType ( ) { if ( tsIsStartOfFunctionType ( ) ) { tsParseFunctionOrConstructorType ( FunctionType . TSFunctionType ) ; return ; } if ( match ( tt . _new ) ) { tsParseFunctionOrConstructorType ( FunctionType . TSConstructorType ) ; return ; } tsParseUnionTypeOrHigher ( ) ; } export function tsParseTypeAssertion ( ) { const oldIsType = pushTypeContext ( 1 ) ; tsParseType ( ) ; expect ( tt . greaterThan ) ; popTypeContext ( oldIsType ) ; parseMaybeUnary ( ) ; } function tsParseHeritageClause ( ) { while ( ! match ( tt . braceL ) && ! state . error ) { tsParseExpressionWithTypeArguments ( ) ; eat ( tt . comma ) ; } } function tsParseExpressionWithTypeArguments ( ) { tsParseEntityName ( ) ; if ( match ( tt . lessThan ) ) { tsParseTypeArguments ( ) ; } } function tsParseInterfaceDeclaration ( ) { parseBindingIdentifier ( false ) ; tsTryParseTypeParameters ( ) ; if ( eat ( tt . _extends ) ) { tsParseHeritageClause ( ) ; } tsParseObjectTypeMembers ( ) ; } function tsParseTypeAliasDeclaration ( ) { parseBindingIdentifier ( false ) ; tsTryParseTypeParameters ( ) ; expect ( tt . eq ) ; tsParseType ( ) ; semicolon ( ) ; } function tsParseEnumMember ( ) { if ( match ( tt . string ) ) { parseLiteral ( ) ; } else { parseIdentifier ( ) ; } if ( eat ( tt . eq ) ) { const eqIndex = state . tokens . length - 1 ; parseMaybeAssign ( ) ; state . tokens [ eqIndex ] . rhsEndIndex = state . tokens . length ; } } function tsParseEnumDeclaration ( ) { parseBindingIdentifier ( false ) ; expect ( tt . braceL ) ; while ( ! eat ( tt . braceR ) && ! state . error ) { tsParseEnumMember ( ) ; eat ( tt . comma ) ; } } function tsParseModuleBlock ( ) { expect ( tt . braceL ) ; parseBlockBody ( tt . braceR ) ; } function tsParseModuleOrNamespaceDeclaration ( ) { parseBindingIdentifier ( false ) ; if ( eat ( tt . dot ) ) { tsParseModuleOrNamespaceDeclaration ( ) ; } else { tsParseModuleBlock ( ) ; } } function tsParseAmbientExternalModuleDeclaration ( ) { if ( isContextual ( ContextualKeyword . _global ) ) { parseIdentifier ( ) ; } else if ( match ( tt . string ) ) { parseExprAtom ( ) ; } else { unexpected ( ) ; } if ( match ( tt . braceL ) ) { tsParseModuleBlock ( ) ; } else { semicolon ( ) ; } } export function tsParseImportEqualsDeclaration ( ) { parseImportedIdentifier ( ) ; expect ( tt . eq ) ; tsParseModuleReference ( ) ; semicolon ( ) ; } function tsIsExternalModuleReference ( ) { return isContextual ( ContextualKeyword . _require ) && lookaheadType ( ) === tt . parenL ; } function tsParseModuleReference ( ) { if ( tsIsExternalModuleReference ( ) ) { tsParseExternalModuleReference ( ) ; } else { tsParseEntityName ( ) ; } } function tsParseExternalModuleReference ( ) { expectContextual ( ContextualKeyword . _require ) ; expect ( tt . parenL ) ; if ( ! match ( tt . string ) ) { unexpected ( ) ; } parseLiteral ( ) ; expect ( tt . parenR ) ; } function tsTryParseDeclare ( ) { if ( isLineTerminator ( ) ) { return false ; } switch ( state . type ) { case tt . _function : { const oldIsType = pushTypeContext ( 1 ) ; next ( ) ; const functionStart = state . start ; parseFunction ( functionStart , true ) ; popTypeContext ( oldIsType ) ; return true ; } case tt . _class : { const oldIsType = pushTypeContext ( 1 ) ; parseClass ( true , false ) ; popTypeContext ( oldIsType ) ; return true ; } case tt . _const : { if ( match ( tt . _const ) && isLookaheadContextual ( ContextualKeyword . _enum ) ) { const oldIsType = pushTypeContext ( 1 ) ; expect ( tt . _const ) ; expectContextual ( ContextualKeyword . _enum ) ; state . tokens [ state . tokens . length - 1 ] . type = tt . _enum ; tsParseEnumDeclaration ( ) ; popTypeContext ( oldIsType ) ; return true ; } } case tt . _var : case tt . _let : { const oldIsType = pushTypeContext ( 1 ) ; parseVarStatement ( state . type ) ; popTypeContext ( oldIsType ) ; return true ; } case tt . name : { const oldIsType = pushTypeContext ( 1 ) ; const contextualKeyword = state . contextualKeyword ; let matched = false ; if ( contextualKeyword === ContextualKeyword . _global ) { tsParseAmbientExternalModuleDeclaration ( ) ; matched = true ; } else { matched = tsParseDeclaration ( contextualKeyword , true ) ; } popTypeContext ( oldIsType ) ; return matched ; } default : return false ; } } function tsTryParseExportDeclaration ( ) { return tsParseDeclaration ( state . contextualKeyword , true ) ; } function tsParseExpressionStatement ( contextualKeyword ) { switch ( contextualKeyword ) { case ContextualKeyword . _declare : { const declareTokenIndex = state . tokens . length - 1 ; const matched = tsTryParseDeclare ( ) ; if ( matched ) { state . tokens [ declareTokenIndex ] . type = tt . _declare ; return true ; } break ; } case ContextualKeyword . _global : if ( match ( tt . braceL ) ) { tsParseModuleBlock ( ) ; return true ; } break ; default : return tsParseDeclaration ( contextualKeyword , false ) ; } return false ; } function tsParseDeclaration ( contextualKeyword , isBeforeToken ) { switch ( contextualKeyword ) { case ContextualKeyword . _abstract : if ( tsCheckLineTerminatorAndMatch ( tt . _class , isBeforeToken ) ) { if ( isBeforeToken ) next ( ) ; state . tokens [ state . tokens . length - 1 ] . type = tt . _abstract ; parseClass ( true , false ) ; return true ; } break ; case ContextualKeyword . _enum : if ( tsCheckLineTerminatorAndMatch ( tt . name , isBeforeToken ) ) { if ( isBeforeToken ) next ( ) ; state . tokens [ state . tokens . length - 1 ] . type = tt . _enum ; tsParseEnumDeclaration ( ) ; return true ; } break ; case ContextualKeyword . _interface : if ( tsCheckLineTerminatorAndMatch ( tt . name , isBeforeToken ) ) { const oldIsType = pushTypeContext ( 1 ) ; if ( isBeforeToken ) next ( ) ; tsParseInterfaceDeclaration ( ) ; popTypeContext ( oldIsType ) ; return true ; } break ; case ContextualKeyword . _module : if ( isBeforeToken ) next ( ) ; if ( match ( tt . string ) ) { const oldIsType = pushTypeContext ( isBeforeToken ? 2 : 1 ) ; tsParseAmbientExternalModuleDeclaration ( ) ; popTypeContext ( oldIsType ) ; return true ; } else if ( tsCheckLineTerminatorAndMatch ( tt . name , isBeforeToken ) ) { const oldIsType = pushTypeContext ( isBeforeToken ? 2 : 1 ) ; if ( isBeforeToken ) next ( ) ; tsParseModuleOrNamespaceDeclaration ( ) ; popTypeContext ( oldIsType ) ; return true ; } break ; case ContextualKeyword . _namespace : if ( tsCheckLineTerminatorAndMatch ( tt . name , isBeforeToken ) ) { const oldIsType = pushTypeContext ( 1 ) ; if ( isBeforeToken ) next ( ) ; tsParseModuleOrNamespaceDeclaration ( ) ; popTypeContext ( oldIsType ) ; return true ; } break ; case ContextualKeyword . _type : if ( tsCheckLineTerminatorAndMatch ( tt . name , isBeforeToken ) ) { const oldIsType = pushTypeContext ( 1 ) ; if ( isBeforeToken ) next ( ) ; tsParseTypeAliasDeclaration ( ) ; popTypeContext ( oldIsType ) ; return true ; } break ; default : break ; } return false ; } function tsCheckLineTerminatorAndMatch ( tokenType , isBeforeToken ) { return ! isLineTerminator ( ) && ( isBeforeToken || match ( tokenType ) ) ; } function tsTryParseGenericAsyncArrowFunction ( ) { const snapshot = state . snapshot ( ) ; tsParseTypeParameters ( ) ; parseFunctionParams ( ) ; tsTryParseTypeOrTypePredicateAnnotation ( ) ; expect ( tt . arrow ) ; if ( state . error ) { state . restoreFromSnapshot ( snapshot ) ; return false ; } parseFunctionBody ( true ) ; return true ; } function tsParseTypeArguments ( ) { const oldIsType = pushTypeContext ( 0 ) ; expect ( tt . lessThan ) ; while ( ! eat ( tt . greaterThan ) && ! state . error ) { tsParseType ( ) ; eat ( tt . comma ) ; } popTypeContext ( oldIsType ) ; } export function tsIsDeclarationStart ( ) { if ( match ( tt . name ) ) { switch ( state . contextualKeyword ) { case ContextualKeyword . _abstract : case ContextualKeyword . _declare : case ContextualKeyword . _enum : case ContextualKeyword . _interface : case ContextualKeyword . _module : case ContextualKeyword . _namespace : case ContextualKeyword . _type : return true ; default : break ; } } return false ; } export function tsParseFunctionBodyAndFinish ( functionStart ) { if ( match ( tt . colon ) ) { tsParseTypeOrTypePredicateAnnotation ( tt . colon ) ; } if ( ! match ( tt . braceL ) && isLineTerminator ( ) ) { let i = state . tokens . length - 1 ; while ( i >= 0 && ( state . tokens [ i ] . start >= functionStart || state . tokens [ i ] . type === tt . _default || state . tokens [ i ] . type === tt . _export ) ) { state . tokens [ i ] . isType = true ; i -- ; } return ; } parseFunctionBody ( false ) ; } export function tsParseSubscript ( startTokenIndex , noCalls , stopState ) { if ( ! hasPrecedingLineBreak ( ) && eat ( tt . bang ) ) { state . tokens [ state . tokens . length - 1 ] . type = tt . nonNullAssertion ; return ; } if ( match ( tt . lessThan ) ) { const snapshot = state . snapshot ( ) ; if ( ! noCalls && atPossibleAsync ( ) ) { const asyncArrowFn = tsTryParseGenericAsyncArrowFunction ( ) ; if ( asyncArrowFn ) { return ; } } tsParseTypeArguments ( ) ; if ( ! noCalls && eat ( tt . parenL ) ) { state . tokens [ state . tokens . length - 1 ] . subscriptStartIndex = startTokenIndex ; parseCallExpressionArguments ( ) ; } else if ( match ( tt . backQuote ) ) { parseTemplate ( ) ; } else { unexpected ( ) ; } if ( state . error ) { state . restoreFromSnapshot ( snapshot ) ; } else { return ; } } else if ( ! noCalls && match ( tt . questionDot ) && lookaheadType ( ) === tt . lessThan ) { next ( ) ; state . tokens [ state . tokens . length - 1 ] . subscriptStartIndex = startTokenIndex ; tsParseTypeArguments ( ) ; expect ( tt . parenL ) ; parseCallExpressionArguments ( ) ; } baseParseSubscript ( startTokenIndex , noCalls , stopState ) ; } export function tsStartParseNewArguments ( ) { if ( match ( tt . lessThan ) ) { const snapshot = state . snapshot ( ) ; state . type = tt . typeParameterStart ; tsParseTypeArguments ( ) ; if ( ! match ( tt . parenL ) ) { unexpected ( ) ; } if ( state . error ) { state . restoreFromSnapshot ( snapshot ) ; } } } export function tsTryParseExport ( ) { if ( match ( tt . _import ) ) { expect ( tt . _import ) ; tsParseImportEqualsDeclaration ( ) ; return true ; } else if ( eat ( tt . eq ) ) { parseExpression ( ) ; semicolon ( ) ; return true ; } else if ( eatContextual ( ContextualKeyword . _as ) ) { expectContextual ( ContextualKeyword . _namespace ) ; parseIdentifier ( ) ; semicolon ( ) ; return true ; } else { if ( isContextual ( ContextualKeyword . _type ) && lookaheadType ( ) === tt . braceL ) { next ( ) ; } return false ; } } export function tsTryParseExportDefaultExpression ( ) { if ( isContextual ( ContextualKeyword . _abstract ) && lookaheadType ( ) === tt . _class ) { state . type = tt . _abstract ; next ( ) ; parseClass ( true , true ) ; return true ; } if ( isContextual ( ContextualKeyword . _interface ) ) { const oldIsType = pushTypeContext ( 2 ) ; tsParseDeclaration ( ContextualKeyword . _interface , true ) ; popTypeContext ( oldIsType ) ; return true ; } return false ; } export function tsTryParseStatementContent ( ) { if ( state . type === tt . _const ) { const ahead = lookaheadTypeAndKeyword ( ) ; if ( ahead . type === tt . name && ahead . contextualKeyword === ContextualKeyword . _enum ) { expect ( tt . _const ) ; expectContextual ( ContextualKeyword . _enum ) ; state . tokens [ state . tokens . length - 1 ] . type = tt . _enum ; tsParseEnumDeclaration ( ) ; return true ; } } return false ; } export function tsParseAccessModifier ( ) { tsParseModifier ( [ ContextualKeyword . _public , ContextualKeyword . _protected , ContextualKeyword . _private , ] ) ; } export function tsTryParseClassMemberWithIsStatic ( isStatic ) { let isAbstract = false ; let isReadonly = false ; while ( true ) { const mod = tsParseModifier ( [ ContextualKeyword . _abstract , ContextualKeyword . _readonly , ContextualKeyword . _declare , ] ) ; if ( mod == - 1 ) { break ; } if ( mod === ContextualKeyword . _readonly ) { isReadonly = true ; } if ( mod === ContextualKeyword . _abstract ) { isAbstract = true ; } } if ( ! isAbstract && ! isStatic ) { const found = tsTryParseIndexSignature ( ) ; if ( found ) { return true ; } } if ( isReadonly ) { parseClassPropertyName ( ) ; parsePostMemberNameModifiers ( ) ; parseClassProperty ( ) ; return true ; } return false ; } export function tsParseIdentifierStatement ( contextualKeyword ) { const matched = tsParseExpressionStatement ( contextualKeyword ) ; if ( ! matched ) { semicolon ( ) ; } } export function tsParseExportDeclaration ( ) { const isDeclare = eatContextual ( ContextualKeyword . _declare ) ; if ( isDeclare ) { state . tokens [ state . tokens . length - 1 ] . type = tt . _declare ; } let matchedDeclaration = false ; if ( match ( tt . name ) ) { if ( isDeclare ) { const oldIsType = pushTypeContext ( 2 ) ; matchedDeclaration = tsTryParseExportDeclaration ( ) ; popTypeContext ( oldIsType ) ; } else { matchedDeclaration = tsTryParseExportDeclaration ( ) ; } } if ( ! matchedDeclaration ) { if ( isDeclare ) { const oldIsType = pushTypeContext ( 2 ) ; parseStatement ( true ) ; popTypeContext ( oldIsType ) ; } else { parseStatement ( true ) ; } } } export function tsAfterParseClassSuper ( hasSuper ) { if ( hasSuper && match ( tt . lessThan ) ) { tsParseTypeArguments ( ) ; } if ( eatContextual ( ContextualKeyword . _implements ) ) { state . tokens [ state . tokens . length - 1 ] . type = tt . _implements ; const oldIsType = pushTypeContext ( 1 ) ; tsParseHeritageClause ( ) ; popTypeContext ( oldIsType ) ; } } export function tsStartParseObjPropValue ( ) { tsTryParseTypeParameters ( ) ; } export function tsStartParseFunctionParams ( ) { tsTryParseTypeParameters ( ) ; } export function tsAfterParseVarHead ( ) { const oldIsType = pushTypeContext ( 0 ) ; eat ( tt . bang ) ; tsTryParseTypeAnnotation ( ) ; popTypeContext ( oldIsType ) ; } export function tsStartParseAsyncArrowFromCallExpression ( ) { if ( match ( tt . colon ) ) { tsParseTypeAnnotation ( ) ; } } export function tsParseMaybeAssign ( noIn , isWithinParens ) { return tsParseMaybeAssignWithoutJSX ( noIn , isWithinParens ) ; } export function tsParseMaybeAssignWithoutJSX ( noIn , isWithinParens ) { if ( ! match ( tt . lessThan ) ) { return baseParseMaybeAssign ( noIn , isWithinParens ) ; } const snapshot = state . snapshot ( ) ; tsParseTypeParameters ( ) ; const wasArrow = baseParseMaybeAssign ( noIn , isWithinParens ) ; if ( ! wasArrow ) { unexpected ( ) ; } if ( state . error ) { state . restoreFromSnapshot ( snapshot ) ; } else { return wasArrow ; } return baseParseMaybeAssign ( noIn , isWithinParens ) ; } export function tsParseArrow ( ) { if ( match ( tt . colon ) ) { const snapshot = state . snapshot ( ) ; tsParseTypeOrTypePredicateAnnotation ( tt . colon ) ; if ( canInsertSemicolon ( ) ) unexpected ( ) ; if ( ! match ( tt . arrow ) ) unexpected ( ) ; if ( state . error ) { state . restoreFromSnapshot ( snapshot ) ; } } return eat ( tt . arrow ) ; } export function tsParseAssignableListItemTypes ( ) { const oldIsType = pushTypeContext ( 0 ) ; eat ( tt . question ) ; tsTryParseTypeAnnotation ( ) ; popTypeContext ( oldIsType ) ; } export function tsParseMaybeDecoratorArguments ( ) { if ( match ( tt . lessThan ) ) { tsParseTypeArguments ( ) ; } baseParseMaybeDecoratorArguments ( ) ; }