vendor tsgo

This commit is contained in:
2026-07-09 16:50:43 -04:00
parent c06ea2e5a4
commit 98978e4930
5804 changed files with 1556156 additions and 101 deletions

View File

@@ -0,0 +1,717 @@
package ast
import (
"fmt"
)
type OperatorPrecedence int
const (
// Expression:
// AssignmentExpression
// Expression `,` AssignmentExpression
OperatorPrecedenceComma OperatorPrecedence = iota
// NOTE: `Spread` is higher than `Comma` due to how it is parsed in |ElementList|
// SpreadElement:
// `...` AssignmentExpression
OperatorPrecedenceSpread
// AssignmentExpression:
// ConditionalExpression
// YieldExpression
// ArrowFunction
// AsyncArrowFunction
// LeftHandSideExpression `=` AssignmentExpression
// LeftHandSideExpression AssignmentOperator AssignmentExpression
//
// NOTE: AssignmentExpression is broken down into several precedences due to the requirements
// of the parenthesizer rules.
// AssignmentExpression: YieldExpression
// YieldExpression:
// `yield`
// `yield` AssignmentExpression
// `yield` `*` AssignmentExpression
OperatorPrecedenceYield
// AssignmentExpression: LeftHandSideExpression `=` AssignmentExpression
// AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression
// AssignmentOperator: one of
// `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `>>>=` `&=` `^=` `|=` `**=`
OperatorPrecedenceAssignment
// NOTE: `Conditional` is considered higher than `Assignment` here, but in reality they have
// the same precedence.
// AssignmentExpression: ConditionalExpression
// ConditionalExpression:
// ShortCircuitExpression
// ShortCircuitExpression `?` AssignmentExpression `:` AssignmentExpression
OperatorPrecedenceConditional
// LogicalORExpression:
// LogicalANDExpression
// LogicalORExpression `||` LogicalANDExpression
OperatorPrecedenceLogicalOR
// LogicalANDExpression:
// BitwiseORExpression
// LogicalANDExprerssion `&&` BitwiseORExpression
OperatorPrecedenceLogicalAND
// BitwiseORExpression:
// BitwiseXORExpression
// BitwiseORExpression `|` BitwiseXORExpression
OperatorPrecedenceBitwiseOR
// BitwiseXORExpression:
// BitwiseANDExpression
// BitwiseXORExpression `^` BitwiseANDExpression
OperatorPrecedenceBitwiseXOR
// BitwiseANDExpression:
// EqualityExpression
// BitwiseANDExpression `&` EqualityExpression
OperatorPrecedenceBitwiseAND
// EqualityExpression:
// RelationalExpression
// EqualityExpression `==` RelationalExpression
// EqualityExpression `!=` RelationalExpression
// EqualityExpression `===` RelationalExpression
// EqualityExpression `!==` RelationalExpression
OperatorPrecedenceEquality
// RelationalExpression:
// ShiftExpression
// RelationalExpression `<` ShiftExpression
// RelationalExpression `>` ShiftExpression
// RelationalExpression `<=` ShiftExpression
// RelationalExpression `>=` ShiftExpression
// RelationalExpression `instanceof` ShiftExpression
// RelationalExpression `in` ShiftExpression
// [+TypeScript] RelationalExpression `as` Type
OperatorPrecedenceRelational
// ShiftExpression:
// AdditiveExpression
// ShiftExpression `<<` AdditiveExpression
// ShiftExpression `>>` AdditiveExpression
// ShiftExpression `>>>` AdditiveExpression
OperatorPrecedenceShift
// AdditiveExpression:
// MultiplicativeExpression
// AdditiveExpression `+` MultiplicativeExpression
// AdditiveExpression `-` MultiplicativeExpression
OperatorPrecedenceAdditive
// MultiplicativeExpression:
// ExponentiationExpression
// MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
// MultiplicativeOperator: one of `*`, `/`, `%`
OperatorPrecedenceMultiplicative
// ExponentiationExpression:
// UnaryExpression
// UpdateExpression `**` ExponentiationExpression
OperatorPrecedenceExponentiation
// UnaryExpression:
// UpdateExpression
// `delete` UnaryExpression
// `void` UnaryExpression
// `typeof` UnaryExpression
// `+` UnaryExpression
// `-` UnaryExpression
// `~` UnaryExpression
// `!` UnaryExpression
// AwaitExpression
// UpdateExpression: // TODO: Do we need to investigate the precedence here?
// `++` UnaryExpression
// `--` UnaryExpression
OperatorPrecedenceUnary
// UpdateExpression:
// LeftHandSideExpression
// LeftHandSideExpression `++`
// LeftHandSideExpression `--`
OperatorPrecedenceUpdate
// LeftHandSideExpression:
// NewExpression
// NewExpression:
// MemberExpression
// `new` NewExpression
OperatorPrecedenceLeftHandSide
// LeftHandSideExpression:
// OptionalExpression
// OptionalExpression:
// MemberExpression OptionalChain
// CallExpression OptionalChain
// OptionalExpression OptionalChain
OperatorPrecedenceOptionalChain
// LeftHandSideExpression:
// CallExpression
// CallExpression:
// CoverCallExpressionAndAsyncArrowHead
// SuperCall
// ImportCall
// CallExpression Arguments
// CallExpression `[` Expression `]`
// CallExpression `.` IdentifierName
// CallExpression TemplateLiteral
// MemberExpression:
// PrimaryExpression
// MemberExpression `[` Expression `]`
// MemberExpression `.` IdentifierName
// MemberExpression TemplateLiteral
// SuperProperty
// MetaProperty
// `new` MemberExpression Arguments
OperatorPrecedenceMember
// TODO: JSXElement?
// PrimaryExpression:
// `this`
// IdentifierReference
// Literal
// ArrayLiteral
// ObjectLiteral
// FunctionExpression
// ClassExpression
// GeneratorExpression
// AsyncFunctionExpression
// AsyncGeneratorExpression
// RegularExpressionLiteral
// TemplateLiteral
OperatorPrecedencePrimary
// PrimaryExpression:
// CoverParenthesizedExpressionAndArrowParameterList
OperatorPrecedenceParentheses
OperatorPrecedenceLowest = OperatorPrecedenceComma
OperatorPrecedenceHighest = OperatorPrecedenceParentheses
OperatorPrecedenceDisallowComma = OperatorPrecedenceYield
// ShortCircuitExpression:
// LogicalORExpression
// CoalesceExpression
// CoalesceExpression:
// CoalesceExpressionHead `??` BitwiseORExpression
// CoalesceExpressionHead:
// CoalesceExpression
// BitwiseORExpression
OperatorPrecedenceCoalesce = OperatorPrecedenceLogicalOR
// -1 is lower than all other precedences. Returning it will cause binary expression
// parsing to stop.
OperatorPrecedenceInvalid OperatorPrecedence = -1
)
func getOperator(expression *Expression) Kind {
switch expression.Kind {
case KindBinaryExpression:
return expression.AsBinaryExpression().OperatorToken.Kind
case KindPrefixUnaryExpression:
return expression.AsPrefixUnaryExpression().Operator
case KindPostfixUnaryExpression:
return expression.AsPostfixUnaryExpression().Operator
default:
return expression.Kind
}
}
// Gets the precedence of an expression
func GetExpressionPrecedence(expression *Expression) OperatorPrecedence {
operator := getOperator(expression)
var flags OperatorPrecedenceFlags
if expression.Kind == KindNewExpression && expression.ArgumentList() == nil {
flags = OperatorPrecedenceFlagsNewWithoutArguments
} else if IsOptionalChain(expression) {
flags = OperatorPrecedenceFlagsOptionalChain
}
return GetOperatorPrecedence(expression.Kind, operator, flags)
}
type OperatorPrecedenceFlags int
const (
OperatorPrecedenceFlagsNone OperatorPrecedenceFlags = 0
OperatorPrecedenceFlagsNewWithoutArguments OperatorPrecedenceFlags = 1 << 0
OperatorPrecedenceFlagsOptionalChain OperatorPrecedenceFlags = 1 << 1
)
// Gets the precedence of an operator
func GetOperatorPrecedence(nodeKind Kind, operatorKind Kind, flags OperatorPrecedenceFlags) OperatorPrecedence {
switch nodeKind {
case KindSpreadElement:
return OperatorPrecedenceSpread
case KindYieldExpression:
return OperatorPrecedenceYield
// !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting
case KindArrowFunction:
return OperatorPrecedenceAssignment
case KindConditionalExpression:
return OperatorPrecedenceConditional
case KindBinaryExpression:
switch operatorKind {
case KindCommaToken:
return OperatorPrecedenceComma
case KindEqualsToken,
KindPlusEqualsToken,
KindMinusEqualsToken,
KindAsteriskAsteriskEqualsToken,
KindAsteriskEqualsToken,
KindSlashEqualsToken,
KindPercentEqualsToken,
KindLessThanLessThanEqualsToken,
KindGreaterThanGreaterThanEqualsToken,
KindGreaterThanGreaterThanGreaterThanEqualsToken,
KindAmpersandEqualsToken,
KindCaretEqualsToken,
KindBarEqualsToken,
KindBarBarEqualsToken,
KindAmpersandAmpersandEqualsToken,
KindQuestionQuestionEqualsToken:
return OperatorPrecedenceAssignment
default:
return GetBinaryOperatorPrecedence(operatorKind)
}
// TODO: Should prefix `++` and `--` be moved to the `Update` precedence?
case KindTypeAssertionExpression,
KindNonNullExpression,
KindPrefixUnaryExpression,
KindTypeOfExpression,
KindVoidExpression,
KindDeleteExpression,
KindAwaitExpression:
return OperatorPrecedenceUnary
case KindPostfixUnaryExpression:
return OperatorPrecedenceUpdate
// !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting
case KindPropertyAccessExpression, KindElementAccessExpression:
if flags&OperatorPrecedenceFlagsOptionalChain != 0 {
return OperatorPrecedenceOptionalChain
}
return OperatorPrecedenceMember
case KindCallExpression:
if flags&OperatorPrecedenceFlagsOptionalChain != 0 {
return OperatorPrecedenceOptionalChain
}
return OperatorPrecedenceMember
// !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting
case KindNewExpression:
if flags&OperatorPrecedenceFlagsNewWithoutArguments != 0 {
return OperatorPrecedenceLeftHandSide
}
return OperatorPrecedenceMember
// !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting
case KindTaggedTemplateExpression, KindMetaProperty, KindExpressionWithTypeArguments:
return OperatorPrecedenceMember
case KindAsExpression,
KindSatisfiesExpression:
return OperatorPrecedenceRelational
case KindThisKeyword,
KindSuperKeyword,
KindImportKeyword,
KindIdentifier,
KindPrivateIdentifier,
KindNullKeyword,
KindTrueKeyword,
KindFalseKeyword,
KindNumericLiteral,
KindBigIntLiteral,
KindStringLiteral,
KindArrayLiteralExpression,
KindObjectLiteralExpression,
KindFunctionExpression,
KindClassExpression,
KindRegularExpressionLiteral,
KindNoSubstitutionTemplateLiteral,
KindTemplateExpression,
KindOmittedExpression,
KindJsxElement,
KindJsxSelfClosingElement,
KindJsxFragment,
KindMissingDeclaration:
return OperatorPrecedencePrimary
// !!! By necessity, this differs from the old compiler to support emit. consider backporting
case KindParenthesizedExpression:
return OperatorPrecedenceParentheses
default:
return OperatorPrecedenceInvalid
}
}
// Gets the precedence of a binary operator
func GetBinaryOperatorPrecedence(operatorKind Kind) OperatorPrecedence {
switch operatorKind {
case KindQuestionQuestionToken:
return OperatorPrecedenceCoalesce
case KindBarBarToken:
return OperatorPrecedenceLogicalOR
case KindAmpersandAmpersandToken:
return OperatorPrecedenceLogicalAND
case KindBarToken:
return OperatorPrecedenceBitwiseOR
case KindCaretToken:
return OperatorPrecedenceBitwiseXOR
case KindAmpersandToken:
return OperatorPrecedenceBitwiseAND
case KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken:
return OperatorPrecedenceEquality
case KindLessThanToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken,
KindInstanceOfKeyword, KindInKeyword, KindAsKeyword, KindSatisfiesKeyword:
return OperatorPrecedenceRelational
case KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken:
return OperatorPrecedenceShift
case KindPlusToken, KindMinusToken:
return OperatorPrecedenceAdditive
case KindAsteriskToken, KindSlashToken, KindPercentToken:
return OperatorPrecedenceMultiplicative
case KindAsteriskAsteriskToken:
return OperatorPrecedenceExponentiation
}
// -1 is lower than all other precedences. Returning it will cause binary expression
// parsing to stop.
return OperatorPrecedenceInvalid
}
// Gets the leftmost expression of an expression, e.g. `a` in `a.b`, `a[b]`, `a++`, `a+b`, `a?b:c`, `a as B`, etc.
func GetLeftmostExpression(node *Expression, stopAtCallExpressions bool) *Expression {
for {
switch node.Kind {
case KindPostfixUnaryExpression:
node = node.AsPostfixUnaryExpression().Operand
continue
case KindBinaryExpression:
node = node.AsBinaryExpression().Left
continue
case KindConditionalExpression:
node = node.AsConditionalExpression().Condition
continue
case KindTaggedTemplateExpression:
node = node.AsTaggedTemplateExpression().Tag
continue
case KindCallExpression:
if stopAtCallExpressions {
return node
}
fallthrough
case KindAsExpression,
KindElementAccessExpression,
KindPropertyAccessExpression,
KindNonNullExpression,
KindPartiallyEmittedExpression,
KindSatisfiesExpression:
node = node.Expression()
continue
}
return node
}
}
type TypePrecedence int32
const (
// Conditional precedence (lowest)
//
// Type[Extends]:
// ConditionalTypeNode[?Extends]
//
// ConditionalTypeNode[Extends]:
// [~Extends] UnionTypeNode `extends` Type[+Extends] `?` Type[~Extends] `:` Type[~Extends]
//
TypePrecedenceConditional TypePrecedence = iota
// JSDoc precedence (optional and variadic types)
//
// JSDocType:
// `...`? Type `=`?
TypePrecedenceJSDoc
// Function precedence
//
// Type[Extends]:
// ConditionalTypeNode[?Extends]
// FunctionTypeNode[?Extends]
// ConstructorTypeNode[?Extends]
//
// ConditionalTypeNode[Extends]:
// UnionTypeNode
//
// FunctionTypeNode[Extends]:
// TypeParameters? ArrowParameters `=>` Type[?Extends]
//
// ConstructorTypeNode[Extends]:
// `abstract`? TypeParameters? ArrowParameters `=>` Type[?Extends]
//
TypePrecedenceFunction
// Union precedence
//
// UnionTypeNode:
// `|`? UnionTypeNoBar
//
// UnionTypeNoBar:
// IntersectionTypeNode
// UnionTypeNoBar `|` IntersectionTypeNode
//
TypePrecedenceUnion
// Intersection precedence
//
// IntersectionTypeNode:
// `&`? IntersectionTypeNoAmpersand
//
// IntersectionTypeNoAmpersand:
// TypeOperatorNode
// IntersectionTypeNoAmpersand `&` TypeOperatorNode
//
TypePrecedenceIntersection
// TypeOperatorNode precedence
//
// TypeOperatorNode:
// PostfixType
// InferTypeNode
// `keyof` TypeOperatorNode
// `unique` TypeOperatorNode
// `readonly` PostfixType
//
// InferTypeNode:
// `infer` BindingIdentifier
// `infer` BindingIdentifier `extends` Type[+Extends]
//
TypePrecedenceTypeOperator
// Postfix precedence
//
// PostfixType:
// NonArrayType
// OptionalTypeNode
// ArrayTypeNode
// IndexedAccessTypeNode
//
// OptionalTypeNode:
// PostfixType `?`
//
// ArrayTypeNode:
// PostfixType `[` `]`
//
// IndexedAccessTypeNode:
// PostfixType `[` Type[~Extends] `]`
//
TypePrecedencePostfix
// NonArray precedence (highest)
//
// NonArrayType:
// KeywordType
// LiteralTypeNode
// ThisTypeNode
// ImportType
// TypeQueryNode
// MappedTypeNode
// TypeLiteralNode
// TupleTypeNode
// ParenthesizedTypeNode
// TypePredicateNode
// TypeReferenceNode
// TemplateType
//
// KeywordType: one of
// `any` `unknown` `string` `number` `bigint`
// `symbol` `boolean` `undefined` `never` `object`
// `intrinsic` `void`
//
// LiteralTypeNode:
// StringLiteral
// NoSubstitutionTemplateLiteral
// NumericLiteral
// BigIntLiteral
// `-` NumericLiteral
// `-` BigIntLiteral
// `true`
// `false`
// `null`
//
// ThisTypeNode:
// `this`
//
// ImportType:
// `typeof`? `import` `(` Type[~Extends] `,`? `)` ImportTypeQualifier? TypeArguments?
// `typeof`? `import` `(` Type[~Extends] `,` ImportTypeAttributes `,`? `)` ImportTypeQualifier? TypeArguments?
//
// ImportTypeQualifier:
// `.` EntityName
//
// ImportTypeAttributes:
// `{` `with` `:` ImportAttributes `,`? `}`
//
// TypeQueryNode:
//
// MappedTypeNode:
// `{` MappedTypePrefix? MappedTypePropertyName MappedTypeSuffix? `:` Type[~Extends] `;` `}`
//
// MappedTypePrefix:
// `readonly`
// `+` `readonly`
// `-` `readonly`
//
// MappedTypePropertyName:
// `[` BindingIdentifier `in` Type[~Extends] `]`
// `[` BindingIdentifier `in` Type[~Extends] `as` Type[~Extends] `]`
//
// MappedTypeSuffix:
// `?`
// `+` `?`
// `-` `?`
//
// TypeLiteralNode:
// `{` TypeElementList `}`
//
// TypeElementList:
// [empty]
// TypeElementList TypeElement
//
// TypeElement:
// PropertySignatureDeclaration
// MethodSignatureDeclaration
// IndexSignatureDeclaration
// CallSignatureDeclaration
// ConstructSignatureDeclaration
//
// PropertySignatureDeclaration:
// PropertyName `?`? TypeAnnotation? `;`
//
// MethodSignatureDeclaration:
// PropertyName `?`? TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;`
// `get` PropertyName TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` // GetAccessorDeclaration
// `set` PropertyName TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` // SetAccessorDeclaration
//
// IndexSignatureDeclaration:
// `[` IdentifierName`]` TypeAnnotation `;`
//
// CallSignatureDeclaration:
// TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;`
//
// ConstructSignatureDeclaration:
// `new` TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;`
//
// TupleTypeNode:
// `[` `]`
// `[` NamedTupleElementTypes `,`? `]`
// `[` TupleElementTypes `,`? `]`
//
// NamedTupleElementTypes:
// NamedTupleMember
// NamedTupleElementTypes `,` NamedTupleMember
//
// NamedTupleMember:
// IdentifierName `?`? `:` Type[~Extends]
// `...` IdentifierName `:` Type[~Extends]
//
// TupleElementTypes:
// TupleElementType
// TupleElementTypes `,` TupleElementType
//
// TupleElementType:
// Type[~Extends]
// OptionalTypeNode
// RestTypeNode
//
// RestTypeNode:
// `...` Type[~Extends]
//
// ParenthesizedTypeNode:
// `(` Type[~Extends] `)`
//
// TypePredicateNode:
// `asserts`? TypePredicateParameterName
// `asserts`? TypePredicateParameterName `is` Type[~Extends]
//
// TypePredicateParameterName:
// `this`
// IdentifierReference
//
// TypeReferenceNode:
// EntityName TypeArguments?
//
// TemplateType:
// TemplateHead Type[~Extends] TemplateTypeSpans
//
// TemplateTypeSpans:
// TemplateTail
// TemplateTypeMiddleList TemplateTail
//
// TemplateTypeMiddleList:
// TemplateMiddle Type[~Extends]
// TemplateTypeMiddleList TemplateMiddle Type[~Extends]
//
// TypeArguments:
// `<` TypeArgumentList `,`? `>`
//
// TypeArgumentList:
// Type[~Extends]
// TypeArgumentList `,` Type[~Extends]
//
TypePrecedenceNonArray
TypePrecedenceLowest = TypePrecedenceConditional
TypePrecedenceHighest = TypePrecedenceNonArray
)
// Gets the precedence of a TypeNode
func GetTypeNodePrecedence(n *TypeNode) TypePrecedence {
switch n.Kind {
case KindConditionalType:
return TypePrecedenceConditional
case KindJSDocOptionalType, KindJSDocVariadicType:
return TypePrecedenceJSDoc
case KindFunctionType, KindConstructorType:
return TypePrecedenceFunction
case KindUnionType:
return TypePrecedenceUnion
case KindIntersectionType:
return TypePrecedenceIntersection
case KindTypeOperator:
return TypePrecedenceTypeOperator
case KindInferType:
if n.AsInferTypeNode().TypeParameter.AsTypeParameterDeclaration().Constraint != nil {
// `infer T extends U` must be treated as FunctionTypeNode precedence as the `extends` clause eagerly consumes
// TypeNode
return TypePrecedenceFunction
}
return TypePrecedenceTypeOperator
case KindIndexedAccessType, KindArrayType, KindOptionalType:
return TypePrecedencePostfix
case KindTypeQuery:
// TypeQueryNode is actually a NonArrayType, but we treat it as TypeOperatorNode
// precedence so that it is parenthesized when used in a PostfixType
// context (e.g., `(typeof C)[]` instead of `typeof C[]`)
return TypePrecedenceTypeOperator
case KindAnyKeyword,
KindUnknownKeyword,
KindStringKeyword,
KindNumberKeyword,
KindBigIntKeyword,
KindSymbolKeyword,
KindBooleanKeyword,
KindUndefinedKeyword,
KindNeverKeyword,
KindObjectKeyword,
KindIntrinsicKeyword,
KindVoidKeyword,
KindJSDocAllType,
KindJSDocNullableType,
KindJSDocNonNullableType,
KindLiteralType,
KindTypePredicate,
KindTypeReference,
KindTypeLiteral,
KindTupleType,
KindRestType,
KindParenthesizedType,
KindThisType,
KindMappedType,
KindNamedTupleMember,
KindTemplateLiteralType,
KindImportType,
// These occur in pseudo-types like `f<T>.C`, where `f` is a generic function and `C` is a local type
KindPropertyAccessExpression,
KindExpressionWithTypeArguments:
return TypePrecedenceNonArray
default:
panic(fmt.Sprintf("unhandled TypeNode: %v", n.Kind))
}
}