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
2 changes: 1 addition & 1 deletion internal/fourslash/tests/completionDetailSignature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function foo(x: any): any {
Label: "foo",
Kind: PtrTo(lsproto.CompletionItemKindFunction),
SortText: PtrTo(string(ls.SortTextLocationPriority)),
Detail: PtrTo("function foo(x: string): string\nfunction foo(x: number): number"),
Detail: PtrTo("function foo(x: string): string\nfunction foo(x: number): number (+1 overload)"),
},
},
},
Expand Down
21 changes: 16 additions & 5 deletions internal/ls/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"slices"
"strconv"
"strings"

"github.com/microsoft/typescript-go/internal/ast"
Expand Down Expand Up @@ -243,26 +244,30 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
}
case flags&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0:
prefix := core.IfElse(flags&ast.SymbolFlagsMethod != 0, "(method) ", "function ")
// Get all signatures from the symbol for overload count
allSignatures := c.GetSignaturesOfType(c.GetTypeOfSymbol(symbol), checker.SignatureKindCall)
if ast.IsIdentifier(node) && ast.IsFunctionLikeDeclaration(node.Parent) && node.Parent.Name() == node {
declaration = node.Parent
signatures := []*checker.Signature{c.GetSignatureFromDeclaration(declaration)}
writeSignatures(&b, c, signatures, container, isAlias, prefix, symbol)
writeSignatures(&b, c, signatures, len(allSignatures), container, isAlias, prefix, symbol)
} else {
signatures := getSignaturesAtLocation(c, symbol, checker.SignatureKindCall, node)
if len(signatures) == 1 {
if d := signatures[0].Declaration(); d != nil && d.Flags&ast.NodeFlagsJSDoc == 0 {
declaration = d
}
}
writeSignatures(&b, c, signatures, container, isAlias, prefix, symbol)
writeSignatures(&b, c, signatures, len(allSignatures), container, isAlias, prefix, symbol)
}
case flags&(ast.SymbolFlagsClass|ast.SymbolFlagsInterface) != 0:
if node.Kind == ast.KindThisKeyword || ast.IsThisInTypeQuery(node) {
b.WriteString("this")
} else if node.Kind == ast.KindConstructorKeyword && (ast.IsConstructorDeclaration(node.Parent) || ast.IsConstructSignatureDeclaration(node.Parent)) {
declaration = node.Parent
signatures := []*checker.Signature{c.GetSignatureFromDeclaration(declaration)}
writeSignatures(&b, c, signatures, container, isAlias, "constructor ", symbol)
// Get all construct signatures for overload count
allSignatures := c.GetSignaturesOfType(c.GetTypeOfSymbol(symbol), checker.SignatureKindConstruct)
writeSignatures(&b, c, signatures, len(allSignatures), container, isAlias, "constructor ", symbol)
} else {
var signatures []*checker.Signature
if flags&ast.SymbolFlagsClass != 0 && getCallOrNewExpression(node) != nil {
Expand All @@ -272,7 +277,7 @@ func getQuickInfoAndDeclarationAtLocation(c *checker.Checker, symbol *ast.Symbol
if d := signatures[0].Declaration(); d != nil && d.Flags&ast.NodeFlagsJSDoc == 0 {
declaration = d
}
writeSignatures(&b, c, signatures, container, isAlias, "constructor ", symbol)
writeSignatures(&b, c, signatures, len(signatures), container, isAlias, "constructor ", symbol)
} else {
b.WriteString(core.IfElse(flags&ast.SymbolFlagsClass != 0, "class ", "interface "))
b.WriteString(c.SymbolToStringEx(symbol, container, ast.SymbolFlagsNone, symbolFormatFlags))
Expand Down Expand Up @@ -411,7 +416,7 @@ func writeTypeParams(b *strings.Builder, c *checker.Checker, params []*checker.T
}
}

func writeSignatures(b *strings.Builder, c *checker.Checker, signatures []*checker.Signature, container *ast.Node, isAlias bool, prefix string, symbol *ast.Symbol) {
func writeSignatures(b *strings.Builder, c *checker.Checker, signatures []*checker.Signature, totalOverloadCount int, container *ast.Node, isAlias bool, prefix string, symbol *ast.Symbol) {
for i, sig := range signatures {
if i != 0 {
b.WriteString("\n")
Expand All @@ -427,6 +432,12 @@ func writeSignatures(b *strings.Builder, c *checker.Checker, signatures []*check
b.WriteString(c.SymbolToStringEx(symbol, container, ast.SymbolFlagsNone, symbolFormatFlags))
b.WriteString(c.SignatureToStringEx(sig, container, typeFormatFlags|checker.TypeFormatFlagsWriteCallStyleSignature|checker.TypeFormatFlagsWriteTypeArgumentsOfSignature))
}
// Add overload count suffix if there are multiple overloads
if totalOverloadCount > 1 {
b.WriteString(" (+")
b.WriteString(strconv.Itoa(totalOverloadCount - 1))
b.WriteString(core.IfElse(totalOverloadCount == 2, " overload)", " overloads)"))
}
}

func containsTypedefTag(jsdoc *ast.Node) bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
// ^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | (method) ThingWithDeprecations.subscribe(observer?: PartialObserver<void>): Subscription
// | (method) ThingWithDeprecations.subscribe(observer?: PartialObserver<void>): Subscription (+2 overloads)
// | ```
// |
// | ----------------------------------------------------------------------
Expand All @@ -46,7 +46,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\n(method) ThingWithDeprecations.subscribe(observer?: PartialObserver<void>): Subscription\n```\n"
"value": "```tsx\n(method) ThingWithDeprecations.subscribe(observer?: PartialObserver<void>): Subscription (+2 overloads)\n```\n"
},
"range": {
"start": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
// ^^
// | ----------------------------------------------------------------------
// | ```tsx
// | function f1(a: number): any
// | function f1(a: number): any (+1 overload)
// | ```
// | fn f1 with number
// |
Expand All @@ -336,7 +336,7 @@
// ^^
// | ----------------------------------------------------------------------
// | ```tsx
// | function f1(b: string): any
// | function f1(b: string): any (+1 overload)
// | ```
// |
// | ----------------------------------------------------------------------
Expand Down Expand Up @@ -1385,7 +1385,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nfunction f1(a: number): any\n```\nfn f1 with number\n\n*@param* `b` — about b\n"
"value": "```tsx\nfunction f1(a: number): any (+1 overload)\n```\nfn f1 with number\n\n*@param* `b` — about b\n"
},
"range": {
"start": {
Expand All @@ -1412,7 +1412,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nfunction f1(b: string): any\n```\n"
"value": "```tsx\nfunction f1(b: string): any (+1 overload)\n```\n"
},
"range": {
"start": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,23 @@
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithOverloads(x: string): cWithOverloads
// | constructor cWithOverloads(x: string): cWithOverloads (+1 overload)
// | ```
// |
// | ----------------------------------------------------------------------
// constructor(x: number);
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithOverloads(x: number): cWithOverloads
// | constructor cWithOverloads(x: number): cWithOverloads (+1 overload)
// | ```
// |
// | ----------------------------------------------------------------------
// constructor(x: any) {
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithOverloads(x: any): cWithOverloads
// | constructor cWithOverloads(x: any): cWithOverloads (+1 overload)
// | ```
// |
// | ----------------------------------------------------------------------
Expand Down Expand Up @@ -118,31 +118,31 @@
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithMultipleOverloads(x: string): cWithMultipleOverloads
// | constructor cWithMultipleOverloads(x: string): cWithMultipleOverloads (+2 overloads)
// | ```
// |
// | ----------------------------------------------------------------------
// constructor(x: number);
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithMultipleOverloads(x: number): cWithMultipleOverloads
// | constructor cWithMultipleOverloads(x: number): cWithMultipleOverloads (+2 overloads)
// | ```
// |
// | ----------------------------------------------------------------------
// constructor(x: boolean);
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithMultipleOverloads(x: boolean): cWithMultipleOverloads
// | constructor cWithMultipleOverloads(x: boolean): cWithMultipleOverloads (+2 overloads)
// | ```
// |
// | ----------------------------------------------------------------------
// constructor(x: any) {
// ^^^^^^^^^^^
// | ----------------------------------------------------------------------
// | ```tsx
// | constructor cWithMultipleOverloads(x: any): cWithMultipleOverloads
// | constructor cWithMultipleOverloads(x: any): cWithMultipleOverloads (+2 overloads)
// | ```
// |
// | ----------------------------------------------------------------------
Expand Down Expand Up @@ -357,7 +357,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithOverloads(x: string): cWithOverloads\n```\n"
"value": "```tsx\nconstructor cWithOverloads(x: string): cWithOverloads (+1 overload)\n```\n"
},
"range": {
"start": {
Expand All @@ -384,7 +384,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithOverloads(x: number): cWithOverloads\n```\n"
"value": "```tsx\nconstructor cWithOverloads(x: number): cWithOverloads (+1 overload)\n```\n"
},
"range": {
"start": {
Expand All @@ -411,7 +411,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithOverloads(x: any): cWithOverloads\n```\n"
"value": "```tsx\nconstructor cWithOverloads(x: any): cWithOverloads (+1 overload)\n```\n"
},
"range": {
"start": {
Expand Down Expand Up @@ -600,7 +600,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithMultipleOverloads(x: string): cWithMultipleOverloads\n```\n"
"value": "```tsx\nconstructor cWithMultipleOverloads(x: string): cWithMultipleOverloads (+2 overloads)\n```\n"
},
"range": {
"start": {
Expand All @@ -627,7 +627,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithMultipleOverloads(x: number): cWithMultipleOverloads\n```\n"
"value": "```tsx\nconstructor cWithMultipleOverloads(x: number): cWithMultipleOverloads (+2 overloads)\n```\n"
},
"range": {
"start": {
Expand All @@ -654,7 +654,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithMultipleOverloads(x: boolean): cWithMultipleOverloads\n```\n"
"value": "```tsx\nconstructor cWithMultipleOverloads(x: boolean): cWithMultipleOverloads (+2 overloads)\n```\n"
},
"range": {
"start": {
Expand All @@ -681,7 +681,7 @@
"item": {
"contents": {
"kind": "markdown",
"value": "```tsx\nconstructor cWithMultipleOverloads(x: any): cWithMultipleOverloads\n```\n"
"value": "```tsx\nconstructor cWithMultipleOverloads(x: any): cWithMultipleOverloads (+2 overloads)\n```\n"
},
"range": {
"start": {
Expand Down
Loading