From 515c1ccbb90dc9850cb3f023e2554b6303f700a7 Mon Sep 17 00:00:00 2001 From: Saurabh Sinha Date: Thu, 29 Oct 2026 14:51:39 -0400 Subject: [PATCH] test(l2): calls at the same line:col in sibling files resolve to their own callees Pins the #32 fix (988581d, a7a103f): the call-site index is keyed on the declaring file. --- internal/semantic_analysis/call_graph_test.go | 30 +++++++++++++++++++ testdata/callsite_collision/go.mod | 3 ++ testdata/callsite_collision/methods.go | 11 +++++++ testdata/callsite_collision/types.go | 11 +++++++ 4 files changed, 55 insertions(+) create mode 100644 testdata/callsite_collision/go.mod create mode 100644 testdata/callsite_collision/methods.go create mode 100644 testdata/callsite_collision/types.go diff --git a/internal/semantic_analysis/call_graph_test.go b/internal/semantic_analysis/call_graph_test.go index 6124394..e234ed7 100644 --- a/internal/semantic_analysis/call_graph_test.go +++ b/internal/semantic_analysis/call_graph_test.go @@ -246,3 +246,33 @@ func TestLibraryByPath(t *testing.T) { } } } + +// TestCallGraph_SamePositionInSiblingFiles: HelpX (types.go) and the method P +// (methods.go, filed under T in types.go) each make one call at the same +// line:col. Each must resolve its own callee; resolving by position over the +// whole package attributed right to HelpX (#32). +func TestCallGraph_SamePositionInSiblingFiles(t *testing.T) { + dir, err := filepath.Abs("../../testdata/callsite_collision") + if err != nil { + t.Fatal(err) + } + b := syntactic_analysis.NewSymbolTableBuilder(dir) + st, err := b.Build(nil, true) + if err != nil { + t.Fatalf("symbol table build failed: %v", err) + } + edges := semantic_analysis.NewCallGraphBuilder(dir, b.Fset(), b.Pkgs()).Build(st) + + got := make([]string, 0, len(edges)) + for _, e := range edges { + got = append(got, e.Source+" -> "+e.Target) + } + sort.Strings(got) + want := []string{ + "example.com/callsitecollision.HelpX -> example.com/callsitecollision.wrong", + "example.com/callsitecollision.T.P -> example.com/callsitecollision.right", + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("edges = %q, want %q", got, want) + } +} diff --git a/testdata/callsite_collision/go.mod b/testdata/callsite_collision/go.mod new file mode 100644 index 0000000..22b5987 --- /dev/null +++ b/testdata/callsite_collision/go.mod @@ -0,0 +1,3 @@ +module example.com/callsitecollision + +go 1.21 diff --git a/testdata/callsite_collision/methods.go b/testdata/callsite_collision/methods.go new file mode 100644 index 0000000..dfdff7a --- /dev/null +++ b/testdata/callsite_collision/methods.go @@ -0,0 +1,11 @@ +package collision + +// P's call is at the same line:col as Hlp's in types.go. + +func right() {} + +func init() {} + +func (T) N() {} + +func (T) P() { right() } diff --git a/testdata/callsite_collision/types.go b/testdata/callsite_collision/types.go new file mode 100644 index 0000000..864cd27 --- /dev/null +++ b/testdata/callsite_collision/types.go @@ -0,0 +1,11 @@ +// Package collision has two calls at the same line:col in sibling files, one in +// a method declared away from its receiver type (#32). +package collision + +type T struct{} + +func (T) M() {} + +func wrong() {} + +func HelpX() { wrong() }