Repository navigation
fix(go): resolve package-qualified calls into the imported package - #764
kunalgoesbyken wants to merge 1 commit into
Conversation
🌱 graft blast radius1 area changed → 4 areas can be affected. 8 dependent symbols, depth 2. flowchart TB
A0(("Dependency Graph Construction<br/>5 symbols"))
A1(("Graph Engine<br/>1 symbol"))
A2(("Pull Request Review<br/>1 symbol"))
A3(("Symbol Overlap Detection<br/>1 symbol"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1,A2,A3 reached;
Who knows this code — 3 people across 5 areas
Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no All 8 dependent symbols, grouped by areaDependency Graph Construction — 5 symbols in 5 files
Graph Engine — 1 symbol in 1 file
Pull Request Review — 1 symbol in 1 file
Symbol Overlap Detection — 1 symbol in 1 file
Test signal per changed area — 1 ⚠Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.
48 test suites also reference this code58 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.
Open the interactive graph → — click an area to see its dependent symbols at file:line. |
|
Thanks, this works: |
A Go call into another package is always `pkg.Fn()`. It was read as a member call on a receiver named `pkg`, which has no type, so resolve dropped it and no cross-package call ever got an edge. Map each import's local name to its path, carry that path on the call, and resolve the name among the non-test functions in the package's directory. A parameter, `:=`, `var`, range or type-switch binding that shadows the import name is not the package once it is in scope, so calls on it take no package edge. The right side of `user, err := user.Load()` still does.
52ceafd to
6b97f00
Compare
|
Thanks for catching that. Fixed: the package lookup now skips any name declared locally in the function (params, |
Summary
Fixes #763
In Go, a call into another package is always written
pkg.Fn().calleeNamereads it as a member call on a receiver namedpkg.resolveRecvTypefinds no type for a package name, andresolveEdgesdrops member calls that have norecvType. So no call between packages ever got acallsedge, andgraft callers/blaststopped at the package boundary.Changes
extract.ts: collect each Go file's imports as local name → import path. The local name is the alias, or else the last path segment. When a selector call's receiver has no resolved type and matches one of those names, the call edge carries the import path as itsspecifier. Gleam module calls already work this way.resolve.ts: a Go call with aspecifiermaps the import path to its in-repo package directory, using the module lookup thatresolveGoImportalready did, now split out asgoImportDir. It then looks for the name among the functions in that directory's non-_test.gofiles. Exactly one match gives anextractededge. Anything else drops: stdlib or third-party packages, no match, or several matches.Receivers that already resolve to a type (receiver var, bound local, struct field) are untouched, because the package lookup only runs when
resolveRecvTypereturns nothing. Lookup is limited to the imported package's directory, so a function with the same name in another package can't be picked.With the issue's reproducer:
Out of scope
import . "pkg") and calls through package-level function variables still get no edge.Testing
On Windows 11 with Node 26:
test/graph-go.test.ts. A module withpkg/util/{helper,format}.go, pluspkg/other/other.gothat defines the same names.main.gocallsutil.Helper()(next tofmt.Println), andalt.gocallsut.Format()through an aliased import. It asserts thatruncalls exactlypkg/util/helper.go#Helperandaltcalls exactlypkg/util/format.go#Format.actual: [],expected: ['pkg/util/helper.go#Helper'].test/graph-go.test.tspasses 7/7.tsc -p tsconfig.json --noEmitis clean.test/graph-*.test.ts,test/blast*.test.tsandtest/graphrank.test.tspass (424 pass, 0 fail).