Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: call hierarchy stops at a lambda #64451

Open
fredDJSonos opened this issue Nov 29, 2023 · 4 comments
Open

x/tools/gopls: call hierarchy stops at a lambda #64451

fredDJSonos opened this issue Nov 29, 2023 · 4 comments
Assignees
Labels
gopls Issues related to the Go language server, gopls. NeedsFix The path to resolution is known, but the work has not been done. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@fredDJSonos
Copy link

fredDJSonos commented Nov 29, 2023

gopls version

v0.14.2

go env

GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/fdejaeger/Library/Caches/go-build"
GOENV="/Users/fdejaeger/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/fdejaeger/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/fdejaeger/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/homebrew/Cellar/go/1.20.1/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.20.1/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.20.1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/6_/dn0ctd6j6l56r4d5d6rbj_jw0000gq/T/go-build4268109944=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

consider this code:

package foobar

func Foo() {
	bar()
}

func bar() {
	go func() { baz() }()
}

func baz() {
	bluh()
}

func bluh() {

}

From vscode, I’m asking about the call hierarchy at bluh

What did you expect to see?

I would like to see a call hierarchy that traverse the lambda definition and goes up to Foo

bluh
  +-- baz
       +-- bar.func()
          +-- bar
              +-- Foo

What did you see instead?

The call hierarchy stops at the first lambda.

bluh
  +-- baz
       +-- bar.func()

This is not very helpful to stop there. There are many situations where it makes sense to show the caller of the function that generates the lambda.

Editor and settings

{
    "go.testTimeout": "10s",
    "go.toolsManagement.autoUpdate": true,
    "go.formatTool": "custom",
    "go.alternateTools": {
        "customFormatter": "gofmt"
    }
}

Logs

No response

@fredDJSonos fredDJSonos added gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. labels Nov 29, 2023
@gopherbot gopherbot added this to the Unreleased milestone Nov 29, 2023
@adonovan
Copy link
Member

adonovan commented Dec 1, 2023

I agree, lambdas should ideally not be treated specially. However, the call hierarchy implementation assumes that the position supplied in the query is that of a function name, and then it finds all references to that name (which needn't actually be in function calls).

To support lambdas, it would need to detect that the specified position is a lambda not a name, and then find "references" to the anonymous function, which could be of two forms. In the first, the lambda is bound to a name:

 f = func(...) { ... } // <-- f becomes the unofficial name of this lambda

 f() // <-- this reference to f counts as a call of the lambda

In the second, it is called directly:

defer func() { ... } () // the final "()" counts as a call of the lambda

In other cases, when the connection between the lambda and its call is too hard to detect, gopls would continue to return void results like the one you reported:

ForEach(func(x int) { ... }) // we can't find any calls of this lambda.

In that case, it might be better to ignore the lambda entirely and treat its body just like part of the enclosing function.

@adonovan adonovan added the NeedsFix The path to resolution is known, but the work has not been done. label Dec 1, 2023
@findleyr
Copy link
Contributor

findleyr commented Dec 1, 2023

In that case, it might be better to ignore the lambda entirely and treat its body just like part of the enclosing function.

That sounds reasonable to me.

@adonovan
Copy link
Member

adonovan commented Dec 1, 2023

In that case, it might be better to ignore the lambda entirely and treat its body just like part of the enclosing function.

That sounds reasonable to me.

The quoted line was intended as just the residual part of a larger plan, but your comment made me realize that--without much more complex analysis--we can't identify calls to lambdas other than from their enclosing function, so there's no reason to distinguish them at all. That's a nice simplification. In other words, Call Hierarchy is about FuncDecls, and FuncLits are just more statements.

@gopherbot
Copy link

Change https://go.dev/cl/546736 mentions this issue: gopls/internal/lsp/source: ignore lambdas in call hierarchy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gopls Issues related to the Go language server, gopls. NeedsFix The path to resolution is known, but the work has not been done. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

5 participants