mirror of https://github.com/golang/go.git
internal/lsp/source: do not panic in "var func" outgoing callhierarchy
When trying to get outgoing call hierarchy from an var func like:
func main() {
foo := func() {}
foo()
}
gopls crashed with a panic.
This change makes it return an empty call hierarchy instead.
It also adds support for testing outgoing calls where the expected
result is 0 items, to be able to test this change.
Fixes golang/go#43376
Change-Id: Icd91bf54cb4fbd5203f5865f0ff9d81365c27d5d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/279469
Trust: Pontus Leitzler <leitzler@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Pontus Leitzler <leitzler@gmail.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
2b0845dc78
commit
b1c90890d2
|
|
@ -193,7 +193,9 @@ func OutgoingCalls(ctx context.Context, snapshot Snapshot, fh FileHandle, pos pr
|
|||
if _, ok := identifier.Declaration.obj.Type().Underlying().(*types.Signature); !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if identifier.Declaration.node == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if len(identifier.Declaration.MappedRange) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,14 @@ var x = func() { //@mark(hierarchyLiteral, "func"),mark(hierarchyLiteralOut, "x"
|
|||
}
|
||||
|
||||
// D is exported to test incoming/outgoing calls across packages
|
||||
func D() { //@mark(hierarchyD, "D"),incomingcalls(hierarchyD, hierarchyA, hierarchyB, hierarchyC, hierarchyLiteral, incomingA),outgoingcalls(hierarchyD, hierarchyE, hierarchyF, hierarchyG, hierarchyLiteralOut, outgoingB)
|
||||
func D() { //@mark(hierarchyD, "D"),incomingcalls(hierarchyD, hierarchyA, hierarchyB, hierarchyC, hierarchyLiteral, incomingA),outgoingcalls(hierarchyD, hierarchyE, hierarchyF, hierarchyG, hierarchyLiteralOut, outgoingB, hierarchyFoo)
|
||||
e()
|
||||
x()
|
||||
F()
|
||||
g()
|
||||
outgoing.B()
|
||||
foo := func() {} //@mark(hierarchyFoo, "foo"),incomingcalls(hierarchyFoo, hierarchyD),outgoingcalls(hierarchyFoo)
|
||||
foo()
|
||||
}
|
||||
|
||||
func e() {} //@mark(hierarchyE, "e")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
-- summary --
|
||||
CallHierarchyCount = 1
|
||||
CallHierarchyCount = 2
|
||||
CodeLensCount = 5
|
||||
CompletionsCount = 258
|
||||
CompletionSnippetCount = 88
|
||||
|
|
|
|||
|
|
@ -1131,6 +1131,9 @@ func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) {
|
|||
}
|
||||
|
||||
func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) {
|
||||
if data.CallHierarchy[src] == nil {
|
||||
data.CallHierarchy[src] = &CallHierarchyResult{}
|
||||
}
|
||||
for _, call := range calls {
|
||||
m, err := data.Mapper(call.URI())
|
||||
if err != nil {
|
||||
|
|
@ -1141,19 +1144,11 @@ func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) {
|
|||
data.t.Fatal(err)
|
||||
}
|
||||
// we're only comparing protocol.range
|
||||
if data.CallHierarchy[src] != nil {
|
||||
data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls,
|
||||
protocol.CallHierarchyItem{
|
||||
URI: protocol.DocumentURI(call.URI()),
|
||||
Range: rng,
|
||||
})
|
||||
} else {
|
||||
data.CallHierarchy[src] = &CallHierarchyResult{
|
||||
OutgoingCalls: []protocol.CallHierarchyItem{
|
||||
{URI: protocol.DocumentURI(call.URI()), Range: rng},
|
||||
},
|
||||
}
|
||||
}
|
||||
data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls,
|
||||
protocol.CallHierarchyItem{
|
||||
URI: protocol.DocumentURI(call.URI()),
|
||||
Range: rng,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue