Skip to content

Commit db968bc

Browse files
authored
Port inlay hints (#1705)
1 parent 37d1a5e commit db968bc

File tree

165 files changed

+12775
-165
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+12775
-165
lines changed

internal/ast/ast.go

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,18 @@ func (n *Node) Expression() *Node {
414414
panic("Unhandled case in Node.Expression: " + n.Kind.String())
415415
}
416416

417+
func (n *Node) RawText() string {
418+
switch n.Kind {
419+
case KindTemplateHead:
420+
return n.AsTemplateHead().RawText
421+
case KindTemplateMiddle:
422+
return n.AsTemplateMiddle().RawText
423+
case KindTemplateTail:
424+
return n.AsTemplateTail().RawText
425+
}
426+
panic("Unhandled case in Node.RawText: " + n.Kind.String())
427+
}
428+
417429
func (m *MutableNode) SetExpression(expr *Node) {
418430
n := (*Node)(m)
419431
switch n.Kind {
@@ -2059,59 +2071,63 @@ type NodeBase struct {
20592071
// Aliases for Node unions
20602072

20612073
type (
2062-
Statement = Node // Node with StatementBase
2063-
Declaration = Node // Node with DeclarationBase
2064-
Expression = Node // Node with ExpressionBase
2065-
TypeNode = Node // Node with TypeNodeBase
2066-
TypeElement = Node // Node with TypeElementBase
2067-
ClassElement = Node // Node with ClassElementBase
2068-
NamedMember = Node // Node with NamedMemberBase
2069-
ObjectLiteralElement = Node // Node with ObjectLiteralElementBase
2070-
BlockOrExpression = Node // Block | Expression
2071-
AccessExpression = Node // PropertyAccessExpression | ElementAccessExpression
2072-
DeclarationName = Node // Identifier | PrivateIdentifier | StringLiteral | NumericLiteral | BigIntLiteral | NoSubstitutionTemplateLiteral | ComputedPropertyName | BindingPattern | ElementAccessExpression
2073-
ModuleName = Node // Identifier | StringLiteral
2074-
ModuleExportName = Node // Identifier | StringLiteral
2075-
PropertyName = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral
2076-
ModuleBody = Node // ModuleBlock | ModuleDeclaration
2077-
ForInitializer = Node // Expression | MissingDeclaration | VariableDeclarationList
2078-
ModuleReference = Node // Identifier | QualifiedName | ExternalModuleReference
2079-
NamedImportBindings = Node // NamespaceImport | NamedImports
2080-
NamedExportBindings = Node // NamespaceExport | NamedExports
2081-
MemberName = Node // Identifier | PrivateIdentifier
2082-
EntityName = Node // Identifier | QualifiedName
2083-
BindingName = Node // Identifier | BindingPattern
2084-
ModifierLike = Node // Modifier | Decorator
2085-
JsxChild = Node // JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
2086-
JsxAttributeLike = Node // JsxAttribute | JsxSpreadAttribute
2087-
JsxAttributeName = Node // Identifier | JsxNamespacedName
2088-
JsxAttributeValue = Node // StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
2089-
JsxTagNameExpression = Node // IdentifierReference | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName
2090-
ClassLikeDeclaration = Node // ClassDeclaration | ClassExpression
2091-
AccessorDeclaration = Node // GetAccessorDeclaration | SetAccessorDeclaration
2092-
LiteralLikeNode = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | TemplateLiteralLikeNode | JsxText
2093-
LiteralExpression = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | NoSubstitutionTemplateLiteral
2094-
UnionOrIntersectionTypeNode = Node // UnionTypeNode | IntersectionTypeNode
2095-
TemplateLiteralLikeNode = Node // TemplateHead | TemplateMiddle | TemplateTail
2096-
TemplateMiddleOrTail = Node // TemplateMiddle | TemplateTail
2097-
TemplateLiteral = Node // TemplateExpression | NoSubstitutionTemplateLiteral
2098-
TypePredicateParameterName = Node // Identifier | ThisTypeNode
2099-
ImportAttributeName = Node // Identifier | StringLiteral
2100-
LeftHandSideExpression = Node // subset of Expression
2101-
JSDocComment = Node // JSDocText | JSDocLink | JSDocLinkCode | JSDocLinkPlain;
2102-
JSDocTag = Node // Node with JSDocTagBase
2103-
SignatureDeclaration = Node // CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction;
2104-
StringLiteralLike = Node // StringLiteral | NoSubstitutionTemplateLiteral
2105-
AnyValidImportOrReExport = Node // (ImportDeclaration | ExportDeclaration | JSDocImportTag) & { moduleSpecifier: StringLiteral } | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral }} | RequireOrImportCall | ValidImportTypeNode
2106-
ValidImportTypeNode = Node // ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } }
2107-
NumericOrStringLikeLiteral = Node // StringLiteralLike | NumericLiteral
2108-
TypeOnlyImportDeclaration = Node // ImportClause | ImportEqualsDeclaration | ImportSpecifier | NamespaceImport with isTypeOnly: true
2109-
ObjectLiteralLike = Node // ObjectLiteralExpression | ObjectBindingPattern
2110-
ObjectTypeDeclaration = Node // ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode
2111-
JsxOpeningLikeElement = Node // JsxOpeningElement | JsxSelfClosingElement
2112-
NamedImportsOrExports = Node // NamedImports | NamedExports
2113-
BreakOrContinueStatement = Node // BreakStatement | ContinueStatement
2114-
CallLikeExpression = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression
2074+
Statement = Node // Node with StatementBase
2075+
Declaration = Node // Node with DeclarationBase
2076+
Expression = Node // Node with ExpressionBase
2077+
TypeNode = Node // Node with TypeNodeBase
2078+
TypeElement = Node // Node with TypeElementBase
2079+
ClassElement = Node // Node with ClassElementBase
2080+
NamedMember = Node // Node with NamedMemberBase
2081+
ObjectLiteralElement = Node // Node with ObjectLiteralElementBase
2082+
BlockOrExpression = Node // Block | Expression
2083+
AccessExpression = Node // PropertyAccessExpression | ElementAccessExpression
2084+
DeclarationName = Node // Identifier | PrivateIdentifier | StringLiteral | NumericLiteral | BigIntLiteral | NoSubstitutionTemplateLiteral | ComputedPropertyName | BindingPattern | ElementAccessExpression
2085+
ModuleName = Node // Identifier | StringLiteral
2086+
ModuleExportName = Node // Identifier | StringLiteral
2087+
PropertyName = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral
2088+
ModuleBody = Node // ModuleBlock | ModuleDeclaration
2089+
ForInitializer = Node // Expression | MissingDeclaration | VariableDeclarationList
2090+
ModuleReference = Node // Identifier | QualifiedName | ExternalModuleReference
2091+
NamedImportBindings = Node // NamespaceImport | NamedImports
2092+
NamedExportBindings = Node // NamespaceExport | NamedExports
2093+
MemberName = Node // Identifier | PrivateIdentifier
2094+
EntityName = Node // Identifier | QualifiedName
2095+
BindingName = Node // Identifier | BindingPattern
2096+
ModifierLike = Node // Modifier | Decorator
2097+
JsxChild = Node // JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
2098+
JsxAttributeLike = Node // JsxAttribute | JsxSpreadAttribute
2099+
JsxAttributeName = Node // Identifier | JsxNamespacedName
2100+
JsxAttributeValue = Node // StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
2101+
JsxTagNameExpression = Node // IdentifierReference | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName
2102+
ClassLikeDeclaration = Node // ClassDeclaration | ClassExpression
2103+
AccessorDeclaration = Node // GetAccessorDeclaration | SetAccessorDeclaration
2104+
LiteralLikeNode = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | TemplateLiteralLikeNode | JsxText
2105+
LiteralExpression = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | NoSubstitutionTemplateLiteral
2106+
UnionOrIntersectionTypeNode = Node // UnionTypeNode | IntersectionTypeNode
2107+
TemplateLiteralLikeNode = Node // TemplateHead | TemplateMiddle | TemplateTail
2108+
TemplateMiddleOrTail = Node // TemplateMiddle | TemplateTail
2109+
TemplateLiteral = Node // TemplateExpression | NoSubstitutionTemplateLiteral
2110+
TypePredicateParameterName = Node // Identifier | ThisTypeNode
2111+
ImportAttributeName = Node // Identifier | StringLiteral
2112+
LeftHandSideExpression = Node // subset of Expression
2113+
JSDocComment = Node // JSDocText | JSDocLink | JSDocLinkCode | JSDocLinkPlain;
2114+
JSDocTag = Node // Node with JSDocTagBase
2115+
SignatureDeclaration = Node // CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction;
2116+
StringLiteralLike = Node // StringLiteral | NoSubstitutionTemplateLiteral
2117+
AnyValidImportOrReExport = Node // (ImportDeclaration | ExportDeclaration | JSDocImportTag) & { moduleSpecifier: StringLiteral } | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral }} | RequireOrImportCall | ValidImportTypeNode
2118+
ValidImportTypeNode = Node // ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } }
2119+
NumericOrStringLikeLiteral = Node // StringLiteralLike | NumericLiteral
2120+
TypeOnlyImportDeclaration = Node // ImportClause | ImportEqualsDeclaration | ImportSpecifier | NamespaceImport with isTypeOnly: true
2121+
ObjectLiteralLike = Node // ObjectLiteralExpression | ObjectBindingPattern
2122+
ObjectTypeDeclaration = Node // ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode
2123+
JsxOpeningLikeElement = Node // JsxOpeningElement | JsxSelfClosingElement
2124+
NamedImportsOrExports = Node // NamedImports | NamedExports
2125+
BreakOrContinueStatement = Node // BreakStatement | ContinueStatement
2126+
CallLikeExpression = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression
2127+
FunctionLikeDeclaration = Node // FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction
2128+
VariableOrParameterDeclaration = Node // VariableDeclaration | ParameterDeclaration
2129+
VariableOrPropertyDeclaration = Node // VariableDeclaration | PropertyDeclaration
2130+
CallOrNewExpression = Node // CallExpression | NewExpression
21152131
)
21162132

21172133
// Aliases for node singletons
@@ -2162,6 +2178,7 @@ type (
21622178
LiteralType = Node
21632179
JSDocNode = Node
21642180
BindingPatternNode = Node
2181+
TypePredicateNodeNode = Node
21652182
)
21662183

21672184
type (

internal/ast/utilities.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,3 +3898,26 @@ func GetContainingFunction(node *Node) *Node {
38983898
func IsImplicitlyExportedJSTypeAlias(node *Node) bool {
38993899
return IsJSTypeAliasDeclaration(node) && IsSourceFile(node.Parent) && IsExternalOrCommonJSModule(node.Parent.AsSourceFile())
39003900
}
3901+
3902+
func HasContextSensitiveParameters(node *Node) bool {
3903+
// Functions with type parameters are not context sensitive.
3904+
if node.TypeParameters() == nil {
3905+
// Functions with any parameters that lack type annotations are context sensitive.
3906+
if core.Some(node.Parameters(), func(p *Node) bool { return p.Type() == nil }) {
3907+
return true
3908+
}
3909+
if !IsArrowFunction(node) {
3910+
// If the first parameter is not an explicit 'this' parameter, then the function has
3911+
// an implicit 'this' parameter which is subject to contextual typing.
3912+
parameter := core.FirstOrNil(node.Parameters())
3913+
if parameter == nil || !IsThisParameter(parameter) {
3914+
return true
3915+
}
3916+
}
3917+
}
3918+
return false
3919+
}
3920+
3921+
func IsInfinityOrNaNString(name string) bool {
3922+
return name == "Infinity" || name == "-Infinity" || name == "NaN"
3923+
}

internal/checker/checker.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9821,7 +9821,7 @@ func (c *Checker) checkFunctionExpressionOrObjectLiteralMethod(node *ast.Node, c
98219821
}
98229822
if checkMode&CheckModeSkipContextSensitive != 0 && c.isContextSensitive(node) {
98239823
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
9824-
if node.Type() == nil && !hasContextSensitiveParameters(node) {
9824+
if node.Type() == nil && !ast.HasContextSensitiveParameters(node) {
98259825
// Return plain anyFunctionType if there is no possibility we'll make inferences from the return type
98269826
contextualSignature := c.getContextualSignature(node)
98279827
if contextualSignature != nil && c.couldContainTypeVariables(c.getReturnTypeOfSignature(contextualSignature)) {
@@ -23229,7 +23229,7 @@ func (c *Checker) computeEnumMemberValue(member *ast.Node, autoValue jsnum.Numbe
2322923229
c.error(member.Name(), diagnostics.An_enum_member_cannot_have_a_numeric_name)
2323023230
} else {
2323123231
text := ast.GetTextOfPropertyName(member.Name())
23232-
if isNumericLiteralName(text) && !isInfinityOrNaNString(text) {
23232+
if isNumericLiteralName(text) && !ast.IsInfinityOrNaNString(text) {
2323323233
c.error(member.Name(), diagnostics.An_enum_member_cannot_have_a_numeric_name)
2323423234
}
2323523235
}
@@ -23296,7 +23296,7 @@ func (c *Checker) evaluateEntity(expr *ast.Node, location *ast.Node) evaluator.R
2329623296
return evaluator.NewResult(nil, false, false, false)
2329723297
}
2329823298
if expr.Kind == ast.KindIdentifier {
23299-
if isInfinityOrNaNString(expr.Text()) && (symbol == c.getGlobalSymbol(expr.Text(), ast.SymbolFlagsValue, nil /*diagnostic*/)) {
23299+
if ast.IsInfinityOrNaNString(expr.Text()) && (symbol == c.getGlobalSymbol(expr.Text(), ast.SymbolFlagsValue, nil /*diagnostic*/)) {
2330023300
// Technically we resolved a global lib file here, but the decision to treat this as numeric
2330123301
// is more predicated on the fact that the single-file resolution *didn't* resolve to a
2330223302
// different meaning of `Infinity` or `NaN`. Transpilers handle this no problem.
@@ -29728,7 +29728,7 @@ func (c *Checker) isContextSensitive(node *ast.Node) bool {
2972829728
}
2972929729

2973029730
func (c *Checker) isContextSensitiveFunctionLikeDeclaration(node *ast.Node) bool {
29731-
return hasContextSensitiveParameters(node) || c.hasContextSensitiveReturnExpression(node)
29731+
return ast.HasContextSensitiveParameters(node) || c.hasContextSensitiveReturnExpression(node)
2973229732
}
2973329733

2973429734
func (c *Checker) hasContextSensitiveReturnExpression(node *ast.Node) bool {

internal/checker/grammarchecks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
214214
if c.reportObviousDecoratorErrors(node) || c.reportObviousModifierErrors(node) {
215215
return true
216216
}
217-
if ast.IsParameter(node) && ast.IsThisParameter(node) {
217+
if ast.IsThisParameter(node) {
218218
return c.grammarErrorOnFirstToken(node, diagnostics.Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters)
219219
}
220220
blockScopeKind := ast.NodeFlagsNone

internal/checker/nodebuilderimpl.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,13 +3064,13 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode {
30643064
if t.flags&TypeFlagsTemplateLiteral != 0 {
30653065
texts := t.AsTemplateLiteralType().texts
30663066
types := t.AsTemplateLiteralType().types
3067-
templateHead := b.f.NewTemplateHead(texts[0], texts[0], ast.TokenFlagsNone)
3067+
templateHead := b.f.NewTemplateHead(texts[0], "", ast.TokenFlagsNone)
30683068
templateSpans := b.f.NewNodeList(core.MapIndex(types, func(t *Type, i int) *ast.Node {
30693069
var res *ast.TemplateMiddleOrTail
30703070
if i < len(types)-1 {
3071-
res = b.f.NewTemplateMiddle(texts[i+1], texts[i+1], ast.TokenFlagsNone)
3071+
res = b.f.NewTemplateMiddle(texts[i+1], "", ast.TokenFlagsNone)
30723072
} else {
3073-
res = b.f.NewTemplateTail(texts[i+1], texts[i+1], ast.TokenFlagsNone)
3073+
res = b.f.NewTemplateTail(texts[i+1], "", ast.TokenFlagsNone)
30743074
}
30753075
return b.f.NewTemplateLiteralTypeSpan(b.typeToTypeNode(t), res)
30763076
}))

internal/checker/printer.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,8 @@ func (c *Checker) TypeToTypeNode(t *Type, enclosingDeclaration *ast.Node, flags
377377
nodeBuilder := c.getNodeBuilder()
378378
return nodeBuilder.TypeToTypeNode(t, enclosingDeclaration, flags, nodebuilder.InternalFlagsNone, nil)
379379
}
380+
381+
func (c *Checker) TypePredicateToTypePredicateNode(t *TypePredicate, enclosingDeclaration *ast.Node, flags nodebuilder.Flags) *ast.TypePredicateNodeNode {
382+
nodeBuilder := c.getNodeBuilder()
383+
return nodeBuilder.TypePredicateToTypePredicateNode(t, enclosingDeclaration, flags, nodebuilder.InternalFlagsNone, nil)
384+
}

internal/checker/services.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,3 +809,7 @@ func (c *Checker) getTypeOfAssignmentPattern(expr *ast.Node) *Type {
809809
elementType := core.OrElse(c.checkIteratedTypeOrElementType(IterationUseDestructuring, typeOfArrayLiteral, c.undefinedType, expr.Parent), c.errorType)
810810
return c.checkArrayLiteralDestructuringElementAssignment(node, typeOfArrayLiteral, slices.Index(node.AsArrayLiteralExpression().Elements.Nodes, expr), elementType, CheckModeNormal)
811811
}
812+
813+
func (c *Checker) GetSignatureFromDeclaration(node *ast.Node) *Signature {
814+
return c.getSignatureFromDeclaration(node)
815+
}

internal/checker/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,10 @@ func (t *Type) IsIndex() bool {
715715
return t.flags&TypeFlagsIndex != 0
716716
}
717717

718+
func (t *Type) IsTupleType() bool {
719+
return isTupleType(t)
720+
}
721+
718722
// TypeData
719723

720724
type TypeData interface {
@@ -924,6 +928,7 @@ type TupleElementInfo struct {
924928
}
925929

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

928933
type TupleType struct {
929934
InterfaceType
@@ -942,6 +947,7 @@ func (t *TupleType) ElementFlags() []ElementFlags {
942947
}
943948
return elementFlags
944949
}
950+
func (t *TupleType) ElementInfos() []TupleElementInfo { return t.elementInfos }
945951

946952
// InstantiationExpressionType
947953

@@ -1180,6 +1186,10 @@ type TypePredicate struct {
11801186
t *Type
11811187
}
11821188

1189+
func (typePredicate *TypePredicate) Type() *Type {
1190+
return typePredicate.t
1191+
}
1192+
11831193
// IndexInfo
11841194

11851195
type IndexInfo struct {

internal/checker/utilities.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,25 +1117,6 @@ func getBindingElementPropertyName(node *ast.Node) *ast.Node {
11171117
return node.Name()
11181118
}
11191119

1120-
func hasContextSensitiveParameters(node *ast.Node) bool {
1121-
// Functions with type parameters are not context sensitive.
1122-
if node.TypeParameters() == nil {
1123-
// Functions with any parameters that lack type annotations are context sensitive.
1124-
if core.Some(node.Parameters(), func(p *ast.Node) bool { return p.Type() == nil }) {
1125-
return true
1126-
}
1127-
if !ast.IsArrowFunction(node) {
1128-
// If the first parameter is not an explicit 'this' parameter, then the function has
1129-
// an implicit 'this' parameter which is subject to contextual typing.
1130-
parameter := core.FirstOrNil(node.Parameters())
1131-
if parameter == nil || !ast.IsThisParameter(parameter) {
1132-
return true
1133-
}
1134-
}
1135-
}
1136-
return false
1137-
}
1138-
11391120
func isCallChain(node *ast.Node) bool {
11401121
return ast.IsCallExpression(node) && node.Flags&ast.NodeFlagsOptionalChain != 0
11411122
}

internal/core/text.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,11 @@ func (t TextRange) Overlaps(t2 TextRange) bool {
6464
end := min(t.end, t2.end)
6565
return start < end
6666
}
67+
68+
// Similar to Overlaps, but treats touching ranges as intersecting.
69+
// For example, [0, 5) intersects [5, 10).
70+
func (t TextRange) Intersects(t2 TextRange) bool {
71+
start := max(t.pos, t2.pos)
72+
end := min(t.end, t2.end)
73+
return start <= end
74+
}

0 commit comments

Comments
 (0)