From 1dbed86e5003f1c98b6c784250e5dbe74c8bbba5 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Sun, 12 May 2024 23:03:45 +0800 Subject: [PATCH] update:find overload definition cross package --- gopls/internal/lsp/source/definition_gox.go | 65 +++++++++++++++++---- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/gopls/internal/lsp/source/definition_gox.go b/gopls/internal/lsp/source/definition_gox.go index a9e0b796b73..fb422233eeb 100644 --- a/gopls/internal/lsp/source/definition_gox.go +++ b/gopls/internal/lsp/source/definition_gox.go @@ -9,6 +9,7 @@ import ( "fmt" "go/types" "log" + "strings" "github.com/goplus/gop/ast" "github.com/goplus/gop/token" @@ -16,6 +17,8 @@ import ( "golang.org/x/tools/gopls/internal/goxls" "golang.org/x/tools/gopls/internal/goxls/parserutil" "golang.org/x/tools/gopls/internal/lsp/protocol" + "golang.org/x/tools/gopls/internal/lsp/safetoken" + "golang.org/x/tools/gopls/internal/span" "golang.org/x/tools/internal/event" ) @@ -84,16 +87,11 @@ func GopDefinition(ctx context.Context, snapshot Snapshot, fh FileHandle, positi return nil, nil } - var anonyOvFunc *ast.FuncLit - if fun, ok := obj.(*types.Func); ok { - for ov := range pkg.GopTypesInfo().Implicits { - if v, ok := ov.(*ast.FuncLit); ok { - if v.Pos() == fun.Pos() { - anonyOvFunc = v - break - } - } - } + var anonyOvFunc *ast.FuncLit //goxls:overload anonymous member + if ovPkg, ovFuncLit, ovObj, ok := IsOverloadAnonymousMember(ctx, snapshot, pkg, obj); ok { + pkg = ovPkg + obj = ovObj + anonyOvFunc = ovFuncLit } if goxls.DbgDefinition { @@ -299,3 +297,50 @@ func gopImportDefinition(ctx context.Context, s Snapshot, pkg Package, pgf *Pars return locs, nil } + +// goxls:match in current package & variants +func IsOverloadAnonymousMember(ctx context.Context, snapshot Snapshot, pkg Package, obj types.Object) (Package, *ast.FuncLit, types.Object, bool) { + if _, ok := obj.(*types.Func); !ok { + return nil, nil, nil, false + } + + declPosn := safetoken.StartPosition(pkg.FileSet(), obj.Pos()) + declURI := span.URIFromPath(declPosn.Filename) + + inPkg := func(searchPkg Package) (*ast.FuncLit, types.Object, bool) { + fset := searchPkg.FileSet() + for ov, om := range searchPkg.GopTypesInfo().Implicits { + if anonyOvFunc, ok := ov.(*ast.FuncLit); ok { + funPos := safetoken.StartPosition(fset, anonyOvFunc.Pos()) + if declPosn.Offset == funPos.Offset { + return anonyOvFunc, om, true + } + } + } + return nil, nil, false + } + + // goxls:match in current package + if funcLit, ovObj, ok := inPkg(pkg); ok { + return pkg, funcLit, ovObj, true + } + + // goxls:match in variants package + if strings.HasSuffix(string(declURI), ".gop") { + variants, err := snapshot.MetadataForFile(ctx, declURI) + if err != nil { + return nil, nil, nil, false + } + for _, m := range variants { + varPkgs, err := snapshot.TypeCheck(ctx, m.ID) + if err != nil { + return nil, nil, nil, false + } + varPkg := varPkgs[0] + if funcLit, ovObj, ok := inPkg(varPkg); ok { + return varPkg, funcLit, ovObj, true + } + } + } + return nil, nil, nil, false +}