Skip to content

Commit fb9f909

Browse files
committed
Go to the name of the function
1 parent a5454eb commit fb9f909

File tree

6 files changed

+77
-22
lines changed

6 files changed

+77
-22
lines changed

Diff for: internal/ast/utilities.go

+5
Original file line numberDiff line numberDiff line change
@@ -2650,3 +2650,8 @@ func getPragmaArgument(pragma *Pragma, name string) string {
26502650
}
26512651
return ""
26522652
}
2653+
2654+
func IsRightSideOfPropertyAccess(node *Node) bool {
2655+
parent := node.Parent
2656+
return IsPropertyAccessExpression(parent) && parent.AsPropertyAccessExpression().Name() == node
2657+
}

Diff for: internal/checker/checker.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -5584,7 +5584,7 @@ func (c *Checker) checkDecorators(node *ast.Node) {
55845584

55855585
func (c *Checker) checkDecorator(node *ast.Node) {
55865586
c.checkGrammarDecorator(node.AsDecorator())
5587-
signature := c.getResolvedSignature(node, nil, CheckModeNormal)
5587+
signature := c.GetResolvedSignature(node, nil, CheckModeNormal)
55885588
c.checkDeprecatedSignature(signature, node)
55895589
returnType := c.getReturnTypeOfSignature(signature)
55905590
if returnType.flags&TypeFlagsAny != 0 {
@@ -7820,7 +7820,7 @@ func (c *Checker) checkImportCallExpression(node *ast.Node) *Type {
78207820
*/
78217821
func (c *Checker) checkCallExpression(node *ast.Node, checkMode CheckMode) *Type {
78227822
c.checkGrammarTypeArguments(node, node.TypeArgumentList())
7823-
signature := c.getResolvedSignature(node, nil /*candidatesOutArray*/, checkMode)
7823+
signature := c.GetResolvedSignature(node, nil /*candidatesOutArray*/, checkMode)
78247824
if signature == c.resolvingSignature {
78257825
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
78267826
// returns a function type. We defer checking and return silentNeverType.
@@ -7864,7 +7864,7 @@ func (c *Checker) checkDeprecatedSignature(sig *Signature, node *ast.Node) {
78647864
}
78657865
if sig.declaration != nil && sig.declaration.Flags&ast.NodeFlagsDeprecated != 0 {
78667866
suggestionNode := c.getDeprecatedSuggestionNode(node)
7867-
name := tryGetPropertyAccessOrIdentifierToString(getInvokedExpression(node))
7867+
name := tryGetPropertyAccessOrIdentifierToString(GetInvokedExpression(node))
78687868
c.addDeprecatedSuggestionWithSignature(suggestionNode, sig.declaration, name, c.signatureToString(sig))
78697869
}
78707870
}
@@ -7901,7 +7901,7 @@ func (c *Checker) isSymbolOrSymbolForCall(node *ast.Node) bool {
79017901
* the function will fill it up with appropriate candidate signatures
79027902
* @return a signature of the call-like expression or undefined if one can't be found
79037903
*/
7904-
func (c *Checker) getResolvedSignature(node *ast.Node, candidatesOutArray *[]*Signature, checkMode CheckMode) *Signature {
7904+
func (c *Checker) GetResolvedSignature(node *ast.Node, candidatesOutArray *[]*Signature, checkMode CheckMode) *Signature {
79057905
links := c.signatureLinks.Get(node)
79067906
// If getResolvedSignature has already been called, we will have cached the resolvedSignature.
79077907
// However, it is possible that either candidatesOutArray was not passed in the first time,
@@ -9521,7 +9521,7 @@ func (c *Checker) checkTaggedTemplateExpression(node *ast.Node) *Type {
95219521
if !c.checkGrammarTaggedTemplateChain(node.AsTaggedTemplateExpression()) {
95229522
c.checkGrammarTypeArguments(node, node.TypeArgumentList())
95239523
}
9524-
signature := c.getResolvedSignature(node, nil, CheckModeNormal)
9524+
signature := c.GetResolvedSignature(node, nil, CheckModeNormal)
95259525
c.checkDeprecatedSignature(signature, node)
95269526
return c.getReturnTypeOfSignature(signature)
95279527
}
@@ -10961,7 +10961,7 @@ func (c *Checker) isUncalledFunctionReference(node *ast.Node, symbol *ast.Symbol
1096110961
if parent == nil {
1096210962
parent = node.Parent
1096310963
}
10964-
if isCallLikeExpression(parent) {
10964+
if IsCallLikeExpression(parent) {
1096510965
return isCallOrNewExpression(parent) && ast.IsIdentifier(node) && c.hasMatchingArgument(parent, node)
1096610966
}
1096710967
return core.Every(symbol.Declarations, func(d *ast.Node) bool {
@@ -12261,7 +12261,7 @@ func (c *Checker) checkInstanceOfExpression(left *ast.Expression, right *ast.Exp
1226112261
if !IsTypeAny(leftType) && c.allTypesAssignableToKind(leftType, TypeFlagsPrimitive) {
1226212262
c.error(left, diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter)
1226312263
}
12264-
signature := c.getResolvedSignature(left.Parent, nil /*candidatesOutArray*/, checkMode)
12264+
signature := c.GetResolvedSignature(left.Parent, nil /*candidatesOutArray*/, checkMode)
1226512265
if signature == c.resolvingSignature {
1226612266
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
1226712267
// returns a function type. We defer checking and return silentNeverType.
@@ -27529,7 +27529,7 @@ func (c *Checker) getContextualTypeForArgumentAtIndex(callTarget *ast.Node, argI
2752927529
if c.signatureLinks.Get(callTarget).resolvedSignature == c.resolvingSignature {
2753027530
signature = c.resolvingSignature
2753127531
} else {
27532-
signature = c.getResolvedSignature(callTarget, nil, CheckModeNormal)
27532+
signature = c.GetResolvedSignature(callTarget, nil, CheckModeNormal)
2753327533
}
2753427534
if isJsxOpeningLikeElement(callTarget) && argIndex == 0 {
2753527535
return c.getEffectiveFirstArgumentForJsxSignature(signature, callTarget)

Diff for: internal/checker/flow.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2040,7 +2040,7 @@ func (c *Checker) getEffectsSignature(node *ast.Node) *Signature {
20402040
case len(signatures) == 1 && signatures[0].typeParameters == nil:
20412041
signature = signatures[0]
20422042
case core.Some(signatures, c.hasTypePredicateOrNeverReturnType):
2043-
signature = c.getResolvedSignature(node, nil, CheckModeNormal)
2043+
signature = c.GetResolvedSignature(node, nil, CheckModeNormal)
20442044
}
20452045
if !(signature != nil && c.hasTypePredicateOrNeverReturnType(signature)) {
20462046
signature = c.unknownSignature

Diff for: internal/checker/jsx.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (c *Checker) checkJsxOpeningLikeElementOrOpeningFragment(node *ast.Node) {
125125
c.checkJsxPreconditions(node)
126126
c.markJsxAliasReferenced(node)
127127
if isNodeOpeningLikeElement {
128-
sig := c.getResolvedSignature(node, nil, CheckModeNormal)
128+
sig := c.GetResolvedSignature(node, nil, CheckModeNormal)
129129
c.checkDeprecatedSignature(sig, node)
130130
elementTypeConstraint := c.getJsxElementTypeTypeAt(node)
131131
if elementTypeConstraint != nil {

Diff for: internal/checker/utilities.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,7 @@ func isThisTypeParameter(t *Type) bool {
12941294
return t.flags&TypeFlagsTypeParameter != 0 && t.AsTypeParameter().isThisType
12951295
}
12961296

1297-
func isCallLikeExpression(node *ast.Node) bool {
1297+
func IsCallLikeExpression(node *ast.Node) bool {
12981298
switch node.Kind {
12991299
case ast.KindJsxOpeningElement, ast.KindJsxSelfClosingElement, ast.KindCallExpression, ast.KindNewExpression,
13001300
ast.KindTaggedTemplateExpression, ast.KindDecorator:
@@ -1829,6 +1829,10 @@ func getNonRestParameterCount(sig *Signature) int {
18291829
return len(sig.parameters) - core.IfElse(signatureHasRestParameter(sig), 1, 0)
18301830
}
18311831

1832+
func GetDeclaration(sig *Signature) *ast.Node {
1833+
return sig.declaration
1834+
}
1835+
18321836
func minAndMax[T any](slice []T, getValue func(value T) int) (int, int) {
18331837
var minValue, maxValue int
18341838
for i, element := range slice {
@@ -2113,7 +2117,7 @@ func tryGetPropertyAccessOrIdentifierToString(expr *ast.Node) string {
21132117
return ""
21142118
}
21152119

2116-
func getInvokedExpression(node *ast.Node) *ast.Node {
2120+
func GetInvokedExpression(node *ast.Node) *ast.Node {
21172121
switch node.Kind {
21182122
case ast.KindTaggedTemplateExpression:
21192123
return node.AsTaggedTemplateExpression().Tag

Diff for: internal/ls/definition.go

+56-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package ls
33
import (
44
"github.com/microsoft/typescript-go/internal/ast"
55
"github.com/microsoft/typescript-go/internal/astnav"
6+
"github.com/microsoft/typescript-go/internal/checker"
67
"github.com/microsoft/typescript-go/internal/core"
78
"github.com/microsoft/typescript-go/internal/scanner"
89
)
@@ -15,25 +16,70 @@ func (l *LanguageService) ProvideDefinitions(fileName string, position int) []Lo
1516
}
1617

1718
checker := program.GetTypeChecker()
19+
calledDeclaration := tryGetSignatureDeclaration(checker, node)
20+
if calledDeclaration != nil {
21+
name := ast.GetNameOfDeclaration(calledDeclaration)
22+
if name != nil {
23+
return createLocationsFromDeclarations([]*ast.Node{name})
24+
}
25+
}
26+
1827
if symbol := checker.GetSymbolAtLocation(node); symbol != nil {
1928
if symbol.Flags&ast.SymbolFlagsAlias != 0 {
2029
if resolved, ok := checker.ResolveAlias(symbol); ok {
2130
symbol = resolved
2231
}
2332
}
2433

25-
locations := make([]Location, 0, len(symbol.Declarations))
26-
for _, decl := range symbol.Declarations {
27-
file := ast.GetSourceFileOfNode(decl)
28-
loc := decl.Loc
29-
pos := scanner.GetTokenPosOfNode(decl, file, false /*includeJSDoc*/)
34+
return createLocationsFromDeclarations(symbol.Declarations)
35+
}
36+
return nil
37+
}
38+
39+
func createLocationsFromDeclarations(declarations []*ast.Node) []Location {
40+
locations := make([]Location, 0, len(declarations))
41+
for _, decl := range declarations {
42+
file := ast.GetSourceFileOfNode(decl)
43+
loc := decl.Loc
44+
pos := scanner.GetTokenPosOfNode(decl, file, false /*includeJSDoc*/)
45+
46+
locations = append(locations, Location{
47+
FileName: file.FileName(),
48+
Range: core.NewTextRange(pos, loc.End()),
49+
})
50+
}
51+
return locations
52+
}
3053

31-
locations = append(locations, Location{
32-
FileName: file.FileName(),
33-
Range: core.NewTextRange(pos, loc.End()),
34-
})
54+
/** Returns a CallLikeExpression where `node` is the target being invoked. */
55+
func getAncestorCallLikeExpression(node *ast.Node) *ast.Node {
56+
target := ast.FindAncestor(node, func(n *ast.Node) bool {
57+
return !ast.IsRightSideOfPropertyAccess(n)
58+
})
59+
60+
callLike := target.Parent
61+
if callLike != nil && checker.IsCallLikeExpression(callLike) && checker.GetInvokedExpression(callLike) == target {
62+
return callLike
63+
}
64+
65+
return nil
66+
}
67+
68+
func tryGetSignatureDeclaration(typeChecker *checker.Checker, node *ast.Node) *ast.Node {
69+
var signature *checker.Signature
70+
callLike := getAncestorCallLikeExpression(node)
71+
if callLike != nil {
72+
signature = typeChecker.GetResolvedSignature(callLike, nil, checker.CheckModeNormal)
73+
}
74+
75+
// Don't go to a function type, go to the value having that type.
76+
var declaration *ast.Node
77+
if signature != nil && checker.GetDeclaration(signature) != nil {
78+
declaration = checker.GetDeclaration(signature)
79+
if ast.IsFunctionLike(declaration) && !ast.IsFunctionTypeNode(declaration) {
80+
return declaration
3581
}
36-
return locations
3782
}
83+
3884
return nil
3985
}

0 commit comments

Comments
 (0)