Skip to content

Commit 40bb997

Browse files
committed
update:find overload definition cross package
1 parent 5f93130 commit 40bb997

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

gopls/internal/lsp/source/definition_gox.go

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import (
99
"fmt"
1010
"go/types"
1111
"log"
12+
"strings"
1213

1314
"github.com/goplus/gop/ast"
1415
"github.com/goplus/gop/token"
1516
"golang.org/x/tools/gopls/internal/bug"
1617
"golang.org/x/tools/gopls/internal/goxls"
1718
"golang.org/x/tools/gopls/internal/goxls/parserutil"
1819
"golang.org/x/tools/gopls/internal/lsp/protocol"
20+
"golang.org/x/tools/gopls/internal/lsp/safetoken"
21+
"golang.org/x/tools/gopls/internal/span"
1922
"golang.org/x/tools/internal/event"
2023
)
2124

@@ -84,16 +87,11 @@ func GopDefinition(ctx context.Context, snapshot Snapshot, fh FileHandle, positi
8487
return nil, nil
8588
}
8689

87-
var anonyOvFunc *ast.FuncLit
88-
if fun, ok := obj.(*types.Func); ok {
89-
for ov := range pkg.GopTypesInfo().Implicits {
90-
if v, ok := ov.(*ast.FuncLit); ok {
91-
if v.Pos() == fun.Pos() {
92-
anonyOvFunc = v
93-
break
94-
}
95-
}
96-
}
90+
var anonyOvFunc *ast.FuncLit //goxls:overload anonymous member
91+
if ovPkg, ovFuncLit, ovObj, ok := IsOverloadAnonymousMember(ctx, snapshot, pkg, obj); ok {
92+
pkg = ovPkg
93+
obj = ovObj
94+
anonyOvFunc = ovFuncLit
9795
}
9896

9997
if goxls.DbgDefinition {
@@ -299,3 +297,50 @@ func gopImportDefinition(ctx context.Context, s Snapshot, pkg Package, pgf *Pars
299297

300298
return locs, nil
301299
}
300+
301+
// goxls:match in current package & variants
302+
func IsOverloadAnonymousMember(ctx context.Context, snapshot Snapshot, pkg Package, obj types.Object) (Package, *ast.FuncLit, types.Object, bool) {
303+
if _, ok := obj.(*types.Func); !ok {
304+
return nil, nil, nil, false
305+
}
306+
declPosn := safetoken.StartPosition(pkg.FileSet(), obj.Pos())
307+
declURI := span.URIFromPath(declPosn.Filename)
308+
309+
// goxls:match in current package
310+
if funcLit, ovObj, ok := isOverloadAnonyMemberInPkg(pkg, declPosn); ok {
311+
return pkg, funcLit, ovObj, true
312+
}
313+
314+
// goxls:match in variants package
315+
if strings.HasSuffix(string(declURI), ".gop") {
316+
variants, err := snapshot.MetadataForFile(ctx, declURI)
317+
if err != nil {
318+
return nil, nil, nil, false
319+
}
320+
for _, m := range variants {
321+
varPkgs, err := snapshot.TypeCheck(ctx, m.ID)
322+
if err != nil {
323+
return nil, nil, nil, false
324+
}
325+
varPkg := varPkgs[0]
326+
if funcLit, ovObj, ok := isOverloadAnonyMemberInPkg(varPkg, declPosn); ok {
327+
return varPkg, funcLit, ovObj, true
328+
}
329+
}
330+
}
331+
return nil, nil, nil, false
332+
}
333+
334+
// returns the overload anonymous member function
335+
func isOverloadAnonyMemberInPkg(pkg Package, matchFuncPos token.Position) (*ast.FuncLit, types.Object, bool) {
336+
fset := pkg.FileSet()
337+
for ov, om := range pkg.GopTypesInfo().Implicits {
338+
if anonyOvFunc, ok := ov.(*ast.FuncLit); ok {
339+
funPos := safetoken.StartPosition(fset, anonyOvFunc.Pos())
340+
if matchFuncPos.Offset == funPos.Offset {
341+
return anonyOvFunc, om, true
342+
}
343+
}
344+
}
345+
return nil, nil, false
346+
}

0 commit comments

Comments
 (0)