From 377464f22d123ff56e607b9bd8f78d5a684f5c36 Mon Sep 17 00:00:00 2001 From: Karthik Nayak Date: Tue, 1 Jun 2021 21:44:13 +0000 Subject: [PATCH] internal/lsp: include function literals in outgoing call hierarchy Currently we don't consider function literals in outgoing call hierarchy, because we only consider expressions of type `ast.SelectorExpr` and `ast.Ident`. So function literals are skipped. Fix this by ensuring we traverse through other types even if we don't add the type itself as an outgoing call hierarchy. Fixes golang/go#43438 Signed-off-by: Karthik Nayak Change-Id: I9eacbd5ec7a68224518bf0e405319adeb673c853 GitHub-Last-Rev: 3e7118a8fd090b339a3eacf32fa8d62e05a76b87 GitHub-Pull-Request: golang/tools#320 Reviewed-on: https://go-review.googlesource.com/c/tools/+/323809 Reviewed-by: Rebecca Stambler Trust: Rebecca Stambler Trust: Peter Weinberger --- internal/lsp/source/call_hierarchy.go | 4 ++++ internal/lsp/testdata/callhierarchy/callhierarchy.go | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/lsp/source/call_hierarchy.go b/internal/lsp/source/call_hierarchy.go index bebdd4eec3..26ef07ebb7 100644 --- a/internal/lsp/source/call_hierarchy.go +++ b/internal/lsp/source/call_hierarchy.go @@ -223,6 +223,10 @@ func collectCallExpressions(fset *token.FileSet, mapper *protocol.ColumnMapper, start, end = n.Sel.NamePos, call.Lparen case *ast.Ident: start, end = n.NamePos, call.Lparen + case *ast.FuncLit: + // while we don't add the function literal as an 'outgoing' call + // we still want to traverse into it + return true default: // ignore any other kind of call expressions // for ex: direct function literal calls since that's not an 'outgoing' call diff --git a/internal/lsp/testdata/callhierarchy/callhierarchy.go b/internal/lsp/testdata/callhierarchy/callhierarchy.go index 410e18cbdb..58c23bdd63 100644 --- a/internal/lsp/testdata/callhierarchy/callhierarchy.go +++ b/internal/lsp/testdata/callhierarchy/callhierarchy.go @@ -30,11 +30,14 @@ func D() { //@mark(hierarchyD, "D"),incomingcalls(hierarchyD, hierarchyA, hierar e() x() F() - g() outgoing.B() foo := func() {} //@mark(hierarchyFoo, "foo"),incomingcalls(hierarchyFoo, hierarchyD),outgoingcalls(hierarchyFoo) foo() + func() { + g() + }() + var i Interface = impl{} i.H() i.I()