Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 70 additions & 53 deletions internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,18 @@ func (n *Node) Expression() *Node {
panic("Unhandled case in Node.Expression: " + n.Kind.String())
}

func (n *Node) RawText() string {
switch n.Kind {
case KindTemplateHead:
return n.AsTemplateHead().RawText
case KindTemplateMiddle:
return n.AsTemplateMiddle().RawText
case KindTemplateTail:
return n.AsTemplateTail().RawText
}
panic("Unhandled case in Node.RawText: " + n.Kind.String())
}

func (m *mutableNode) SetExpression(expr *Node) {
n := (*Node)(m)
switch n.Kind {
Expand Down Expand Up @@ -2057,59 +2069,63 @@ type NodeBase struct {
// Aliases for Node unions

type (
Statement = Node // Node with StatementBase
Declaration = Node // Node with DeclarationBase
Expression = Node // Node with ExpressionBase
TypeNode = Node // Node with TypeNodeBase
TypeElement = Node // Node with TypeElementBase
ClassElement = Node // Node with ClassElementBase
NamedMember = Node // Node with NamedMemberBase
ObjectLiteralElement = Node // Node with ObjectLiteralElementBase
BlockOrExpression = Node // Block | Expression
AccessExpression = Node // PropertyAccessExpression | ElementAccessExpression
DeclarationName = Node // Identifier | PrivateIdentifier | StringLiteral | NumericLiteral | BigIntLiteral | NoSubstitutionTemplateLiteral | ComputedPropertyName | BindingPattern | ElementAccessExpression
ModuleName = Node // Identifier | StringLiteral
ModuleExportName = Node // Identifier | StringLiteral
PropertyName = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral
ModuleBody = Node // ModuleBlock | ModuleDeclaration
ForInitializer = Node // Expression | MissingDeclaration | VariableDeclarationList
ModuleReference = Node // Identifier | QualifiedName | ExternalModuleReference
NamedImportBindings = Node // NamespaceImport | NamedImports
NamedExportBindings = Node // NamespaceExport | NamedExports
MemberName = Node // Identifier | PrivateIdentifier
EntityName = Node // Identifier | QualifiedName
BindingName = Node // Identifier | BindingPattern
ModifierLike = Node // Modifier | Decorator
JsxChild = Node // JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
JsxAttributeLike = Node // JsxAttribute | JsxSpreadAttribute
JsxAttributeName = Node // Identifier | JsxNamespacedName
JsxAttributeValue = Node // StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
JsxTagNameExpression = Node // IdentifierReference | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName
ClassLikeDeclaration = Node // ClassDeclaration | ClassExpression
AccessorDeclaration = Node // GetAccessorDeclaration | SetAccessorDeclaration
LiteralLikeNode = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | TemplateLiteralLikeNode | JsxText
LiteralExpression = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | NoSubstitutionTemplateLiteral
UnionOrIntersectionTypeNode = Node // UnionTypeNode | IntersectionTypeNode
TemplateLiteralLikeNode = Node // TemplateHead | TemplateMiddle | TemplateTail
TemplateMiddleOrTail = Node // TemplateMiddle | TemplateTail
TemplateLiteral = Node // TemplateExpression | NoSubstitutionTemplateLiteral
TypePredicateParameterName = Node // Identifier | ThisTypeNode
ImportAttributeName = Node // Identifier | StringLiteral
LeftHandSideExpression = Node // subset of Expression
JSDocComment = Node // JSDocText | JSDocLink | JSDocLinkCode | JSDocLinkPlain;
JSDocTag = Node // Node with JSDocTagBase
SignatureDeclaration = Node // CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction;
StringLiteralLike = Node // StringLiteral | NoSubstitutionTemplateLiteral
AnyValidImportOrReExport = Node // (ImportDeclaration | ExportDeclaration | JSDocImportTag) & { moduleSpecifier: StringLiteral } | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral }} | RequireOrImportCall | ValidImportTypeNode
ValidImportTypeNode = Node // ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } }
NumericOrStringLikeLiteral = Node // StringLiteralLike | NumericLiteral
TypeOnlyImportDeclaration = Node // ImportClause | ImportEqualsDeclaration | ImportSpecifier | NamespaceImport with isTypeOnly: true
ObjectLiteralLike = Node // ObjectLiteralExpression | ObjectBindingPattern
ObjectTypeDeclaration = Node // ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode
JsxOpeningLikeElement = Node // JsxOpeningElement | JsxSelfClosingElement
NamedImportsOrExports = Node // NamedImports | NamedExports
BreakOrContinueStatement = Node // BreakStatement | ContinueStatement
CallLikeExpression = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression
Statement = Node // Node with StatementBase
Declaration = Node // Node with DeclarationBase
Expression = Node // Node with ExpressionBase
TypeNode = Node // Node with TypeNodeBase
TypeElement = Node // Node with TypeElementBase
ClassElement = Node // Node with ClassElementBase
NamedMember = Node // Node with NamedMemberBase
ObjectLiteralElement = Node // Node with ObjectLiteralElementBase
BlockOrExpression = Node // Block | Expression
AccessExpression = Node // PropertyAccessExpression | ElementAccessExpression
DeclarationName = Node // Identifier | PrivateIdentifier | StringLiteral | NumericLiteral | BigIntLiteral | NoSubstitutionTemplateLiteral | ComputedPropertyName | BindingPattern | ElementAccessExpression
ModuleName = Node // Identifier | StringLiteral
ModuleExportName = Node // Identifier | StringLiteral
PropertyName = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral
ModuleBody = Node // ModuleBlock | ModuleDeclaration
ForInitializer = Node // Expression | MissingDeclaration | VariableDeclarationList
ModuleReference = Node // Identifier | QualifiedName | ExternalModuleReference
NamedImportBindings = Node // NamespaceImport | NamedImports
NamedExportBindings = Node // NamespaceExport | NamedExports
MemberName = Node // Identifier | PrivateIdentifier
EntityName = Node // Identifier | QualifiedName
BindingName = Node // Identifier | BindingPattern
ModifierLike = Node // Modifier | Decorator
JsxChild = Node // JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
JsxAttributeLike = Node // JsxAttribute | JsxSpreadAttribute
JsxAttributeName = Node // Identifier | JsxNamespacedName
JsxAttributeValue = Node // StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
JsxTagNameExpression = Node // IdentifierReference | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName
ClassLikeDeclaration = Node // ClassDeclaration | ClassExpression
AccessorDeclaration = Node // GetAccessorDeclaration | SetAccessorDeclaration
LiteralLikeNode = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | TemplateLiteralLikeNode | JsxText
LiteralExpression = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | NoSubstitutionTemplateLiteral
UnionOrIntersectionTypeNode = Node // UnionTypeNode | IntersectionTypeNode
TemplateLiteralLikeNode = Node // TemplateHead | TemplateMiddle | TemplateTail
TemplateMiddleOrTail = Node // TemplateMiddle | TemplateTail
TemplateLiteral = Node // TemplateExpression | NoSubstitutionTemplateLiteral
TypePredicateParameterName = Node // Identifier | ThisTypeNode
ImportAttributeName = Node // Identifier | StringLiteral
LeftHandSideExpression = Node // subset of Expression
JSDocComment = Node // JSDocText | JSDocLink | JSDocLinkCode | JSDocLinkPlain;
JSDocTag = Node // Node with JSDocTagBase
SignatureDeclaration = Node // CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction;
StringLiteralLike = Node // StringLiteral | NoSubstitutionTemplateLiteral
AnyValidImportOrReExport = Node // (ImportDeclaration | ExportDeclaration | JSDocImportTag) & { moduleSpecifier: StringLiteral } | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral }} | RequireOrImportCall | ValidImportTypeNode
ValidImportTypeNode = Node // ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } }
NumericOrStringLikeLiteral = Node // StringLiteralLike | NumericLiteral
TypeOnlyImportDeclaration = Node // ImportClause | ImportEqualsDeclaration | ImportSpecifier | NamespaceImport with isTypeOnly: true
ObjectLiteralLike = Node // ObjectLiteralExpression | ObjectBindingPattern
ObjectTypeDeclaration = Node // ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode
JsxOpeningLikeElement = Node // JsxOpeningElement | JsxSelfClosingElement
NamedImportsOrExports = Node // NamedImports | NamedExports
BreakOrContinueStatement = Node // BreakStatement | ContinueStatement
CallLikeExpression = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression
FunctionLikeDeclaration = Node // FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction
VariableOrParameterDeclaration = Node // VariableDeclaration | ParameterDeclaration
VariableOrPropertyDeclaration = Node // VariableDeclaration | PropertyDeclaration
CallOrNewExpression = Node // CallExpression | NewExpression
)

// Aliases for node singletons
Expand Down Expand Up @@ -2160,6 +2176,7 @@ type (
LiteralType = Node
JSDocNode = Node
BindingPatternNode = Node
TypePredicateNodeNode = Node
)

type (
Expand Down
23 changes: 23 additions & 0 deletions internal/ast/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -3860,3 +3860,26 @@ func IsJSDocNameReferenceContext(node *Node) bool {
func IsImportOrImportEqualsDeclaration(node *Node) bool {
return IsImportDeclaration(node) || IsImportEqualsDeclaration(node)
}

func HasContextSensitiveParameters(node *Node) bool {
// Functions with type parameters are not context sensitive.
if node.TypeParameters() == nil {
// Functions with any parameters that lack type annotations are context sensitive.
if core.Some(node.Parameters(), func(p *Node) bool { return p.Type() == nil }) {
return true
}
if !IsArrowFunction(node) {
// If the first parameter is not an explicit 'this' parameter, then the function has
// an implicit 'this' parameter which is subject to contextual typing.
parameter := core.FirstOrNil(node.Parameters())
if parameter == nil || !IsThisParameter(parameter) {
return true
}
}
}
return false
}

func IsInfinityOrNaNString(name string) bool {
return name == "Infinity" || name == "-Infinity" || name == "NaN"
}
8 changes: 4 additions & 4 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -9763,7 +9763,7 @@ func (c *Checker) checkFunctionExpressionOrObjectLiteralMethod(node *ast.Node, c
}
if checkMode&CheckModeSkipContextSensitive != 0 && c.isContextSensitive(node) {
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
if node.Type() == nil && !hasContextSensitiveParameters(node) {
if node.Type() == nil && !ast.HasContextSensitiveParameters(node) {
// Return plain anyFunctionType if there is no possibility we'll make inferences from the return type
contextualSignature := c.getContextualSignature(node)
if contextualSignature != nil && c.couldContainTypeVariables(c.getReturnTypeOfSignature(contextualSignature)) {
Expand Down Expand Up @@ -23053,7 +23053,7 @@ func (c *Checker) computeEnumMemberValue(member *ast.Node, autoValue jsnum.Numbe
c.error(member.Name(), diagnostics.Computed_property_names_are_not_allowed_in_enums)
} else {
text := ast.GetTextOfPropertyName(member.Name())
if isNumericLiteralName(text) && !isInfinityOrNaNString(text) {
if isNumericLiteralName(text) && !ast.IsInfinityOrNaNString(text) {
c.error(member.Name(), diagnostics.An_enum_member_cannot_have_a_numeric_name)
}
}
Expand Down Expand Up @@ -23120,7 +23120,7 @@ func (c *Checker) evaluateEntity(expr *ast.Node, location *ast.Node) evaluator.R
return evaluator.NewResult(nil, false, false, false)
}
if expr.Kind == ast.KindIdentifier {
if isInfinityOrNaNString(expr.Text()) && (symbol == c.getGlobalSymbol(expr.Text(), ast.SymbolFlagsValue, nil /*diagnostic*/)) {
if ast.IsInfinityOrNaNString(expr.Text()) && (symbol == c.getGlobalSymbol(expr.Text(), ast.SymbolFlagsValue, nil /*diagnostic*/)) {
// Technically we resolved a global lib file here, but the decision to treat this as numeric
// is more predicated on the fact that the single-file resolution *didn't* resolve to a
// different meaning of `Infinity` or `NaN`. Transpilers handle this no problem.
Expand Down Expand Up @@ -29554,7 +29554,7 @@ func (c *Checker) isContextSensitive(node *ast.Node) bool {
}

func (c *Checker) isContextSensitiveFunctionLikeDeclaration(node *ast.Node) bool {
return hasContextSensitiveParameters(node) || c.hasContextSensitiveReturnExpression(node)
return ast.HasContextSensitiveParameters(node) || c.hasContextSensitiveReturnExpression(node)
}

func (c *Checker) hasContextSensitiveReturnExpression(node *ast.Node) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/checker/grammarchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
if c.reportObviousDecoratorErrors(node) || c.reportObviousModifierErrors(node) {
return true
}
if ast.IsParameter(node) && ast.IsThisParameter(node) {
if ast.IsThisParameter(node) {
return c.grammarErrorOnFirstToken(node, diagnostics.Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters)
}
blockScopeKind := ast.NodeFlagsNone
Expand Down
13 changes: 9 additions & 4 deletions internal/checker/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func createPrinterWithDefaults(emitContext *printer.EmitContext) *printer.Printe
return printer.NewPrinter(printer.PrinterOptions{}, printer.PrintHandlers{}, emitContext)
}

func createPrinterWithRemoveComments(emitContext *printer.EmitContext) *printer.Printer {
func CreatePrinterWithRemoveComments(emitContext *printer.EmitContext) *printer.Printer {
return printer.NewPrinter(printer.PrinterOptions{RemoveComments: true}, printer.PrintHandlers{}, emitContext)
}

Expand Down Expand Up @@ -199,7 +199,7 @@ func (c *Checker) typeToStringEx(t *Type, enclosingDeclaration *ast.Node, flags
if t == c.unresolvedType {
printer = createPrinterWithDefaults(nodeBuilder.EmitContext())
} else {
printer = createPrinterWithRemoveComments(nodeBuilder.EmitContext())
printer = CreatePrinterWithRemoveComments(nodeBuilder.EmitContext())
}
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
Expand Down Expand Up @@ -262,7 +262,7 @@ func (c *Checker) symbolToStringEx(symbol *ast.Symbol, enclosingDeclaration *ast
if enclosingDeclaration != nil && enclosingDeclaration.Kind == ast.KindSourceFile {
printer_ = createPrinterWithRemoveCommentsNeverAsciiEscape(nodeBuilder.EmitContext())
} else {
printer_ = createPrinterWithRemoveComments(nodeBuilder.EmitContext())
printer_ = CreatePrinterWithRemoveComments(nodeBuilder.EmitContext())
}

var builder func(symbol *ast.Symbol, meaning ast.SymbolFlags, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node
Expand Down Expand Up @@ -325,7 +325,7 @@ func (c *Checker) typePredicateToStringEx(typePredicate *TypePredicate, enclosin
nodeBuilder := c.getNodeBuilder()
combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors | nodebuilder.FlagsWriteTypeParametersInQualifiedName
predicate := nodeBuilder.TypePredicateToTypePredicateNode(typePredicate, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil) // TODO: GH#18217
printer_ := createPrinterWithRemoveComments(nodeBuilder.EmitContext())
printer_ := CreatePrinterWithRemoveComments(nodeBuilder.EmitContext())
var sourceFile *ast.SourceFile
if enclosingDeclaration != nil {
sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration)
Expand Down Expand Up @@ -377,3 +377,8 @@ func (c *Checker) TypeToTypeNode(t *Type, enclosingDeclaration *ast.Node, flags
nodeBuilder := c.getNodeBuilder()
return nodeBuilder.TypeToTypeNode(t, enclosingDeclaration, flags, nodebuilder.InternalFlagsNone, nil)
}

func (c *Checker) TypePredicateToTypePredicateNode(t *TypePredicate, enclosingDeclaration *ast.Node, flags nodebuilder.Flags) *ast.TypePredicateNodeNode {
nodeBuilder := c.getNodeBuilder()
return nodeBuilder.TypePredicateToTypePredicateNode(t, enclosingDeclaration, flags, nodebuilder.InternalFlagsNone, nil)
}
4 changes: 4 additions & 0 deletions internal/checker/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -833,3 +833,7 @@ func isArrayLiteralOrObjectLiteralDestructuringPattern(node *ast.Node) bool {
// [x, [a, b, c] ] = someExpression
return isArrayLiteralOrObjectLiteralDestructuringPattern(parent)
}

func (c *Checker) GetSignatureFromDeclaration(node *ast.Node) *Signature {
return c.getSignatureFromDeclaration(node)
}
10 changes: 10 additions & 0 deletions internal/checker/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,10 @@ func (t *Type) IsIndex() bool {
return t.flags&TypeFlagsIndex != 0
}

func (t *Type) IsTupleType() bool {
return isTupleType(t)
}

// TypeData

type TypeData interface {
Expand Down Expand Up @@ -929,6 +933,7 @@ type TupleElementInfo struct {
}

func (t *TupleElementInfo) TupleElementFlags() ElementFlags { return t.flags }
func (t *TupleElementInfo) LabeledDeclaration() *ast.Node { return t.labeledDeclaration }

type TupleType struct {
InterfaceType
Expand All @@ -947,6 +952,7 @@ func (t *TupleType) ElementFlags() []ElementFlags {
}
return elementFlags
}
func (t *TupleType) ElementInfos() []TupleElementInfo { return t.elementInfos }

// SingleSignatureType

Expand Down Expand Up @@ -1192,6 +1198,10 @@ type TypePredicate struct {
t *Type
}

func (typePredicate *TypePredicate) Type() *Type {
return typePredicate.t
}

// IndexInfo

type IndexInfo struct {
Expand Down
Loading