From 304cb25e6f87e8579ce57cd25954356990d984e6 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Mon, 29 Apr 2024 15:39:46 +0800 Subject: [PATCH 1/5] update:support overload function reference --- gopls/internal/lsp/source/references.go | 26 +++- .../regtest/misc/references_gox_test.go | 143 ++++++++++++++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 gopls/internal/regtest/misc/references_gox_test.go diff --git a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/references.go index b20ff683e73..4159b200124 100644 --- a/gopls/internal/lsp/source/references.go +++ b/gopls/internal/lsp/source/references.go @@ -615,12 +615,34 @@ func localReferences(pkg Package, targets map[types.Object]bool, correspond bool return true }) } + // TODO: method // goxls: looking for gop files for _, pgf := range pkg.CompiledGopFiles() { gopast.Inspect(pgf.File, func(n gopast.Node) bool { if id, ok := n.(*gopast.Ident); ok { - if obj, ok := pkg.GopTypesInfo().Uses[id]; ok && matches(obj) { - report(gopMustLocation(pgf, id), false) + if obj, ok := pkg.GopTypesInfo().Uses[id]; ok { + isOvObj := false + //goxls: overload func obj use the origin overload obj + if f, ok := obj.(*types.Func); ok && pkg.GopTypesInfo() != nil { + for ovid, ov := range pkg.GopTypesInfo().Overloads { + for _, o := range ov { + if equalOrigin(o, obj) { // obj is overload + if f.Type().(*types.Signature).Recv() != nil { + } else { + obj = pkg.GetTypes().Scope().Lookup(ovid.Name) + } + isOvObj = true + break + } + } + if isOvObj { + break + } + } + } + if matches(obj) { + report(gopMustLocation(pgf, id), false) + } } } return true diff --git a/gopls/internal/regtest/misc/references_gox_test.go b/gopls/internal/regtest/misc/references_gox_test.go new file mode 100644 index 00000000000..38c31b3def8 --- /dev/null +++ b/gopls/internal/regtest/misc/references_gox_test.go @@ -0,0 +1,143 @@ +package misc + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + . "golang.org/x/tools/gopls/internal/lsp/regtest" +) + +func TestReferencesOnOverloadDecl1(t *testing.T) { + const files = ` +-- go.mod -- +module mod.com + +go 1.12 +-- def.gop -- +func add = ( + func(a, b int) int { + return a + b + } + func(a, b string) string { + return a + b + } +) +-- test.gop -- +println add(1,2) +println add("Hello", "World") +` + Run(t, files, func(t *testing.T, env *Env) { + env.OpenFile("def.gop") + loc := env.GoToDefinition(env.RegexpSearch("def.gop", `add`)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := "def.gop 0:5-0:8\n" + // overload decl + "test.gop 0:8-0:11\n" + // overload int call + "test.gop 1:8-1:11\n" // overload string call + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } + }) +} +func TestReferencesOnOverloadDecl2(t *testing.T) { + const files = ` +-- go.mod -- +module mod.com + +go 1.12 +-- def.gop -- +func mulInt(a, b int) int { + return a * b +} + +func mulFloat(a, b float64) float64 { + return a * b +} + +func mul = ( + mulInt + func(a, b string) string { + return a + b + } + mulFloat +) +-- test.gop -- +println mul(100, 7) +println mul("Hello", "World") +println mul(1.2, 3.14) +` + Run(t, files, func(t *testing.T, env *Env) { + env.OpenFile("def.gop") + loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func (mul) = \(`)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := "def.gop 8:5-8:8\n" + // overload defintion + "def.gop 9:4-9:10\n" + // mutInt + "def.gop 13:4-13:12\n" + // mutFloat + "test.gop 0:8-0:11\n" + // overload int call + "test.gop 1:8-1:11\n" + // overload string call + "test.gop 2:8-2:11\n" // overload float call + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } + }) +} + +func TestReferencesOnOverloadDecl3(t *testing.T) { + const files = ` +-- go.mod -- +module mod.com + +go 1.12 +-- def.gop -- +type foo struct { +} +func (a *foo) mulInt(b int) *foo { + return a +} +func (a *foo) mulFoo(b *foo) *foo { + return a +} +func (foo).mul = ( + (foo).mulInt + (foo).mulFoo +) +-- test.gop -- +var a *foo +var c = a.mul(100) +` + Run(t, files, func(t *testing.T, env *Env) { + env.OpenFile("def.gop") + loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func \(foo\)\.(mul) = \(`)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := "def.gop 8:11-8:14\n" + + "test.gop 1:10-1:13\n" + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } + }) +} \ No newline at end of file From d84d8518437509febf44e05c6d2b68f97e00ea00 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Tue, 30 Apr 2024 10:30:22 +0800 Subject: [PATCH 2/5] update:use modified info.Overload --- gopls/internal/lsp/source/references.go | 22 ++------- .../regtest/misc/references_gox_test.go | 47 ++++++++++--------- 2 files changed, 27 insertions(+), 42 deletions(-) diff --git a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/references.go index 4159b200124..4bc724fefe7 100644 --- a/gopls/internal/lsp/source/references.go +++ b/gopls/internal/lsp/source/references.go @@ -615,30 +615,14 @@ func localReferences(pkg Package, targets map[types.Object]bool, correspond bool return true }) } - // TODO: method // goxls: looking for gop files for _, pgf := range pkg.CompiledGopFiles() { gopast.Inspect(pgf.File, func(n gopast.Node) bool { if id, ok := n.(*gopast.Ident); ok { if obj, ok := pkg.GopTypesInfo().Uses[id]; ok { - isOvObj := false - //goxls: overload func obj use the origin overload obj - if f, ok := obj.(*types.Func); ok && pkg.GopTypesInfo() != nil { - for ovid, ov := range pkg.GopTypesInfo().Overloads { - for _, o := range ov { - if equalOrigin(o, obj) { // obj is overload - if f.Type().(*types.Signature).Recv() != nil { - } else { - obj = pkg.GetTypes().Scope().Lookup(ovid.Name) - } - isOvObj = true - break - } - } - if isOvObj { - break - } - } + // goxls: use overload declaration to match + if overdecl, overloads := pkg.GopTypesInfo().OverloadOf(id); overdecl != nil && overloads != nil { + obj = overdecl } if matches(obj) { report(gopMustLocation(pgf, id), false) diff --git a/gopls/internal/regtest/misc/references_gox_test.go b/gopls/internal/regtest/misc/references_gox_test.go index 38c31b3def8..179853ee5f9 100644 --- a/gopls/internal/regtest/misc/references_gox_test.go +++ b/gopls/internal/regtest/misc/references_gox_test.go @@ -48,6 +48,7 @@ println add("Hello", "World") } }) } + func TestReferencesOnOverloadDecl2(t *testing.T) { const files = ` -- go.mod -- @@ -88,8 +89,6 @@ println mul(1.2, 3.14) } got := buf.String() want := "def.gop 8:5-8:8\n" + // overload defintion - "def.gop 9:4-9:10\n" + // mutInt - "def.gop 13:4-13:12\n" + // mutFloat "test.gop 0:8-0:11\n" + // overload int call "test.gop 1:8-1:11\n" + // overload string call "test.gop 2:8-2:11\n" // overload float call @@ -100,7 +99,7 @@ println mul(1.2, 3.14) } func TestReferencesOnOverloadDecl3(t *testing.T) { - const files = ` + const files = ` -- go.mod -- module mod.com @@ -120,24 +119,26 @@ func (foo).mul = ( ) -- test.gop -- var a *foo -var c = a.mul(100) +var b = a.mul(100) +var c = a.mul(a) ` - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("def.gop") - loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func \(foo\)\.(mul) = \(`)) - refs, err := env.Editor.References(env.Ctx, loc) - if err != nil { - t.Fatalf("references on (*s).Error failed: %v", err) - } - var buf strings.Builder - for _, ref := range refs { - fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) - } - got := buf.String() - want := "def.gop 8:11-8:14\n" + - "test.gop 1:10-1:13\n" - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) - } - }) -} \ No newline at end of file + Run(t, files, func(t *testing.T, env *Env) { + env.OpenFile("def.gop") + loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func \(foo\)\.(mul) = \(`)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := "def.gop 8:11-8:14\n" + + "test.gop 1:10-1:13\n" + + "test.gop 2:10-2:13\n" + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } + }) +} From f8d733dee1c05519bd5b1750db1e04411d73fd4f Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Tue, 7 May 2024 15:43:38 +0800 Subject: [PATCH 3/5] fix:overload member reference --- gopls/internal/lsp/source/references.go | 6 +- .../regtest/misc/references_gox_test.go | 105 +++++++++++++++++- 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/references.go index 4bc724fefe7..aa9b982550e 100644 --- a/gopls/internal/lsp/source/references.go +++ b/gopls/internal/lsp/source/references.go @@ -621,10 +621,8 @@ func localReferences(pkg Package, targets map[types.Object]bool, correspond bool if id, ok := n.(*gopast.Ident); ok { if obj, ok := pkg.GopTypesInfo().Uses[id]; ok { // goxls: use overload declaration to match - if overdecl, overloads := pkg.GopTypesInfo().OverloadOf(id); overdecl != nil && overloads != nil { - obj = overdecl - } - if matches(obj) { + overdecl, _ := pkg.GopTypesInfo().OverloadOf(id) + if matches(obj) || (overdecl != nil && matches(overdecl)) { report(gopMustLocation(pgf, id), false) } } diff --git a/gopls/internal/regtest/misc/references_gox_test.go b/gopls/internal/regtest/misc/references_gox_test.go index 179853ee5f9..d6b307eb1dd 100644 --- a/gopls/internal/regtest/misc/references_gox_test.go +++ b/gopls/internal/regtest/misc/references_gox_test.go @@ -14,7 +14,7 @@ func TestReferencesOnOverloadDecl1(t *testing.T) { -- go.mod -- module mod.com -go 1.12 +go 1.19 -- def.gop -- func add = ( func(a, b int) int { @@ -27,6 +27,22 @@ func add = ( -- test.gop -- println add(1,2) println add("Hello", "World") +-- gop_autogen.go -- +package main + +import "fmt" + +const _ = true +func add__0(a int, b int) int { + return a + b +} +func add__1(a string, b string) string { + return a + b +} +func main() { + fmt.Println(add__0(1, 2)) + fmt.Println(add__1("Hello", "World")) +} ` Run(t, files, func(t *testing.T, env *Env) { env.OpenFile("def.gop") @@ -54,7 +70,7 @@ func TestReferencesOnOverloadDecl2(t *testing.T) { -- go.mod -- module mod.com -go 1.12 +go 1.19 -- def.gop -- func mulInt(a, b int) int { return a * b @@ -75,7 +91,29 @@ func mul = ( println mul(100, 7) println mul("Hello", "World") println mul(1.2, 3.14) +-- gop_autogen.go -- +package main + +import "fmt" + +const _ = true +const Gopo_mul = "mulInt,,mulFloat" +func mulInt(a int, b int) int { + return a * b +} +func mul__1(a string, b string) string { + return a + b +} +func mulFloat(a float64, b float64) float64 { + return a * b +} +func main() { + fmt.Println(mulInt(100, 7)) + fmt.Println(mul__1("Hello", "World")) + fmt.Println(mulFloat(1.2, 3.14)) +} ` + // goxls: overload decl reference Run(t, files, func(t *testing.T, env *Env) { env.OpenFile("def.gop") loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func (mul) = \(`)) @@ -96,6 +134,26 @@ println mul(1.2, 3.14) t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) } }) + // goxls: overload member reference + Run(t, files, func(t *testing.T, env *Env) { + env.OpenFile("def.gop") + loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func mul = \(\n\s+(mulInt)`)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := "def.gop 0:5-0:11\n" + // mulInt + "def.gop 9:4-9:10\n" + // overload mulInt + "test.gop 0:8-0:11\n" // use overload mulInt + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } + }) } func TestReferencesOnOverloadDecl3(t *testing.T) { @@ -103,7 +161,7 @@ func TestReferencesOnOverloadDecl3(t *testing.T) { -- go.mod -- module mod.com -go 1.12 +go 1.19 -- def.gop -- type foo struct { } @@ -121,6 +179,28 @@ func (foo).mul = ( var a *foo var b = a.mul(100) var c = a.mul(a) +-- gop_autogen.go -- +package main + +const _ = true + +type foo struct { +} + +const Gopo_foo_mul = ".mulInt,.mulFoo" +func (a *foo) mulInt(b int) *foo { + return a +} +func (a *foo) mulFoo(b *foo) *foo { + return a +} + +var a *foo +var b = a.mulInt(100) +var c = a.mulFoo(a) + +func main() { +} ` Run(t, files, func(t *testing.T, env *Env) { env.OpenFile("def.gop") @@ -141,4 +221,23 @@ var c = a.mul(a) t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) } }) + Run(t, files, func(t *testing.T, env *Env) { + env.OpenFile("def.gop") + loc := env.GoToDefinition(env.RegexpSearch("def.gop", `\(foo\)\.(mulInt)`)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := "def.gop 2:14-2:20\n" + + "def.gop 9:10-9:16\n" + + "test.gop 1:10-1:13\n" + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } + }) } From 077305dd6c4ee66b3f652199d726aabbda2a2ded Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Sat, 5 Apr 2025 10:39:09 +0800 Subject: [PATCH 4/5] test:migrate ref test --- .../regtest/misc/references_gox_test.go | 178 ++++++++---------- 1 file changed, 80 insertions(+), 98 deletions(-) diff --git a/gopls/internal/regtest/misc/references_gox_test.go b/gopls/internal/regtest/misc/references_gox_test.go index d6b307eb1dd..33ee86537fa 100644 --- a/gopls/internal/regtest/misc/references_gox_test.go +++ b/gopls/internal/regtest/misc/references_gox_test.go @@ -9,7 +9,7 @@ import ( . "golang.org/x/tools/gopls/internal/lsp/regtest" ) -func TestReferencesOnOverloadDecl1(t *testing.T) { +func TestRefOverloadDeclAnony(t *testing.T) { const files = ` -- go.mod -- module mod.com @@ -44,28 +44,19 @@ func main() { fmt.Println(add__1("Hello", "World")) } ` - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("def.gop") - loc := env.GoToDefinition(env.RegexpSearch("def.gop", `add`)) - refs, err := env.Editor.References(env.Ctx, loc) - if err != nil { - t.Fatalf("references on (*s).Error failed: %v", err) - } - var buf strings.Builder - for _, ref := range refs { - fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) - } - got := buf.String() - want := "def.gop 0:5-0:8\n" + // overload decl - "test.gop 0:8-0:11\n" + // overload int call - "test.gop 1:8-1:11\n" // overload string call - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) - } - }) + testCases := []refTest{ + { + "def.gop", "add", []string{ + "def.gop 0:5-0:8", // overload decl + "test.gop 0:8-0:11", // overload int call + "test.gop 1:8-1:11", // overload string call + }, + }, + } + runFindRefTest(t, files, testCases) } -func TestReferencesOnOverloadDecl2(t *testing.T) { +func TestRefOverloadDeclNamedAndAnony(t *testing.T) { const files = ` -- go.mod -- module mod.com @@ -113,50 +104,32 @@ func main() { fmt.Println(mulFloat(1.2, 3.14)) } ` - // goxls: overload decl reference - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("def.gop") - loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func (mul) = \(`)) - refs, err := env.Editor.References(env.Ctx, loc) - if err != nil { - t.Fatalf("references on (*s).Error failed: %v", err) - } - var buf strings.Builder - for _, ref := range refs { - fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) - } - got := buf.String() - want := "def.gop 8:5-8:8\n" + // overload defintion - "test.gop 0:8-0:11\n" + // overload int call - "test.gop 1:8-1:11\n" + // overload string call - "test.gop 2:8-2:11\n" // overload float call - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) - } - }) - // goxls: overload member reference - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("def.gop") - loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func mul = \(\n\s+(mulInt)`)) - refs, err := env.Editor.References(env.Ctx, loc) - if err != nil { - t.Fatalf("references on (*s).Error failed: %v", err) - } - var buf strings.Builder - for _, ref := range refs { - fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) - } - got := buf.String() - want := "def.gop 0:5-0:11\n" + // mulInt - "def.gop 9:4-9:10\n" + // overload mulInt - "test.gop 0:8-0:11\n" // use overload mulInt - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) - } - }) + + testCases := []refTest{ + // goxls: overload reference + { + "def.gop", `func (mul) = \(`, + []string{ + "def.gop 8:5-8:8", // overload defintion + "test.gop 0:8-0:11", // overload int call + "test.gop 1:8-1:11", // overload string call + "test.gop 2:8-2:11", // overload float call + }, + }, + // goxls: overload member reference + { + "def.gop", `func mul = \(\n\s+(mulInt)`, + []string{ + "def.gop 0:5-0:11", // mulInt + "def.gop 9:4-9:10", // overload mulInt + "test.gop 0:8-0:11", // use overload mulInt + }, + }, + } + runFindRefTest(t, files, testCases) } -func TestReferencesOnOverloadDecl3(t *testing.T) { +func TestRefOverloadDeclMethod(t *testing.T) { const files = ` -- go.mod -- module mod.com @@ -202,42 +175,51 @@ var c = a.mulFoo(a) func main() { } ` + testCases := []refTest{ + { + "def.gop", `func \(foo\)\.(mul) = \(`, + []string{ + "def.gop 8:11-8:14", + "test.gop 1:10-1:13", + "test.gop 2:10-2:13", + }, + }, + { + "def.gop", `\(foo\)\.(mulInt)`, + []string{ + "def.gop 2:14-2:20", + "def.gop 9:10-9:16", + "test.gop 1:10-1:13", + }, + }, + } + runFindRefTest(t, files, testCases) +} + +type refTest struct { + defineFile string + defineLocReg string + refLocs []string +} + +func runFindRefTest(t *testing.T, files string, testCase []refTest) { Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("def.gop") - loc := env.GoToDefinition(env.RegexpSearch("def.gop", `func \(foo\)\.(mul) = \(`)) - refs, err := env.Editor.References(env.Ctx, loc) - if err != nil { - t.Fatalf("references on (*s).Error failed: %v", err) - } - var buf strings.Builder - for _, ref := range refs { - fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) - } - got := buf.String() - want := "def.gop 8:11-8:14\n" + - "test.gop 1:10-1:13\n" + - "test.gop 2:10-2:13\n" - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) - } - }) - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("def.gop") - loc := env.GoToDefinition(env.RegexpSearch("def.gop", `\(foo\)\.(mulInt)`)) - refs, err := env.Editor.References(env.Ctx, loc) - if err != nil { - t.Fatalf("references on (*s).Error failed: %v", err) - } - var buf strings.Builder - for _, ref := range refs { - fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) - } - got := buf.String() - want := "def.gop 2:14-2:20\n" + - "def.gop 9:10-9:16\n" + - "test.gop 1:10-1:13\n" - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + for _, test := range testCase { + env.OpenFile(test.defineFile) + loc := env.GoToDefinition(env.RegexpSearch(test.defineFile, test.defineLocReg)) + refs, err := env.Editor.References(env.Ctx, loc) + if err != nil { + t.Fatalf("references on (*s).Error failed: %v", err) + } + var buf strings.Builder + for _, ref := range refs { + fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range) + } + got := buf.String() + want := strings.Join(test.refLocs, "\n") + "\n" + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff) + } } }) } From 0ddf32afeb726d6e56be9b67f042d957feb980d2 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Tue, 8 Apr 2025 17:45:36 +0800 Subject: [PATCH 5/5] update:support find cross package overload decl reference --- gopls/internal/lsp/source/xrefs/xrefs_gox.go | 42 ++++-- .../regtest/misc/references_gox_test.go | 137 ++++++++++++++++++ 2 files changed, 164 insertions(+), 15 deletions(-) diff --git a/gopls/internal/lsp/source/xrefs/xrefs_gox.go b/gopls/internal/lsp/source/xrefs/xrefs_gox.go index f4456dd1c8e..4a2a3f80cfa 100644 --- a/gopls/internal/lsp/source/xrefs/xrefs_gox.go +++ b/gopls/internal/lsp/source/xrefs/xrefs_gox.go @@ -48,26 +48,38 @@ func gopIndex( obj = typeparams.OriginMethod(fn) } - objects := getObjects(obj.Pkg()) - gobObj, ok := objects[obj] - if !ok { - path, err := objectpathFor(obj) - if err != nil { - // Capitalized but not exported - // (e.g. local const/var/type). - return true + reportRef := func(obj types.Object) error { + objects := getObjects(obj.Pkg()) + gobObj, ok := objects[obj] + if !ok { + path, err := objectpathFor(obj) + if err != nil { + // Capitalized but not exported + // (e.g. local const/var/type). + return err + } + gobObj = &gobObject{Path: path} + objects[obj] = gobObj } - gobObj = &gobObject{Path: path} - objects[obj] = gobObj + + gobObj.GopRefs = append(gobObj.GopRefs, gobRef{ + FileIndex: fileIndex, + Range: nodeRange(n), + }) + return nil } - gobObj.GopRefs = append(gobObj.GopRefs, gobRef{ - FileIndex: fileIndex, - Range: nodeRange(n), - }) + // goxls:overload use,refer its overload decl & overload members + if err := reportRef(obj); err != nil { + return true + } + if odObj, _ := info.OverloadOf(n); odObj != nil { + if err := reportRef(odObj); err != nil { + return true + } + } } //} - case *ast.ImportSpec: // Report a reference from each import path // string to the imported package. diff --git a/gopls/internal/regtest/misc/references_gox_test.go b/gopls/internal/regtest/misc/references_gox_test.go index 33ee86537fa..bb732e68268 100644 --- a/gopls/internal/regtest/misc/references_gox_test.go +++ b/gopls/internal/regtest/misc/references_gox_test.go @@ -196,6 +196,143 @@ func main() { runFindRefTest(t, files, testCases) } +func TestRefOverloadDeclCrossPackage(t *testing.T) { + const files = ` +-- go.mod -- +module mod.com + +go 1.19 +-- lib/lib.gop -- +package lib + +func Add = ( + func(a, b int) int { + return a + b + } + func(a, b string) string { + return a + b + } +) + +func LibAddUse() { + println(Add(1, 2)) +} + +func MulInt(a, b int) int { + return a * b +} + +func MulFloat(a, b float64) float64 { + return a * b +} + +func Mul = ( + MulInt + func(a, b string) string { + return a + b + } + MulFloat +) +-- lib/gop_autogen.go -- +package lib + +import "fmt" + +const GopPackage = true +const _ = true +const Gopo_Mul = "MulInt,,MulFloat" +func Add__0(a int, b int) int { + return a + b +} +func Add__1(a string, b string) string { + return a + b +} +func MulInt(a int, b int) int { + return a * b +} +func Mul__1(a string, b string) string { + return a + b +} +func MulFloat(a float64, b float64) float64 { + return a * b +} +func LibAddUse() { + fmt.Println(Add__0(1, 2)) +} +-- def.gop -- +func Add = ( + func(a, b int) int { + return a + b + } + func(a, b string) string { + return a + b + } +) +-- test.gop -- +import "mod.com/lib" + +println Add(1, 2) +println Add("Hello", "World") + +println lib.Add(1, 2) +println lib.Add("Hello", "World") + +println lib.Mul(1, 2) +println lib.Mul("Hello", "World") +println lib.Mul(200.5, 2.3) +-- gop_autogen.go -- +package main + +import ( + "fmt" + "mod.com/lib" +) + +const _ = true +func Add__0(a int, b int) int { + return a + b +} +func Add__1(a string, b string) string { + return a + b +} +func main() { + fmt.Println(Add__0(1, 2)) + fmt.Println(Add__1("Hello", "World")) + fmt.Println(lib.Add__0(1, 2)) + fmt.Println(lib.Add__1("Hello", "World")) + fmt.Println(lib.MulInt(1, 2)) + fmt.Println(lib.Mul__1("Hello", "World")) + fmt.Println(lib.MulFloat(200.5, 2.3)) +} +` + testCases := []refTest{ + { + "def.gop", `Add`, []string{ + "def.gop 0:5-0:8", // overload decl + "test.gop 2:8-2:11", // overload int call + "test.gop 3:8-3:11", // overload string call + }, + }, + { + "lib/lib.gop", `Add`, []string{ + "lib/lib.gop 2:5-2:8", // overload decl + "lib/lib.gop 12:9-12:12", // same package use + "test.gop 5:12-5:15", // cross package use lib.Add + "test.gop 6:12-6:15", // cross package use lib.Add + }, + }, + { + "lib/lib.gop", `func (Mul) = \(`, []string{ + "lib/lib.gop 23:5-23:8", + "test.gop 8:12-8:15", + "test.gop 9:12-9:15", + "test.gop 10:12-10:15", + }, + }, + } + runFindRefTest(t, files, testCases) +} + type refTest struct { defineFile string defineLocReg string