Repository navigation
fix(go): resolve methods promoted through embedded types - #814
kunalgoesbyken wants to merge 1 commit into
Conversation
…face
`type Server struct{ Base }` promotes Base's methods to Server, but the
walk never recorded the embedding, so `s.Hello()` found no `Server.Hello`
and had no parent chain to climb. Calls to a promoted method, from outside
or through the receiver, got no edge.
Emit an `extends` edge for each same-package embedded type (`Base`, `*Base`,
`Base[T]`, and an interface embedded in an interface) so the existing
typed-member resolution walks up to it. A package-qualified embed and a
constraint union are not recorded, and the edge only binds to a type in the
embedder's own directory.
The same method promoted from two embedded types at one depth is an
ambiguous selector in Go, so that call resolves to neither.
🌱 graft blast radius1 area changed → 3 areas can be affected. 5 dependent symbols, depth 2. flowchart TB
A0(("Graph Building<br/>3 symbols"))
A1(("Engine<br/>1 symbol"))
A2(("Pull Request Review<br/>1 symbol"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1,A2 reached;
Who knows this code — 2 people across 4 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 5 dependent symbols, grouped by areaGraph Building — 3 symbols in 3 files
Engine — 1 symbol in 1 file
Pull Request Review — 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.
51 test suites also reference this code54 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. |
|
Same as #806: only |
Summary
type Server struct{ Base }promotesBase's methods, but the walk never recorded the embedding, sos.Hello()found noServer.Helloand had no parent chain to climb. Calls to a promoted method got no edge.Changes
extract.ts: a Go struct or interface emits anextendsedge for each unqualified embedded type:Base,*Base,Base[T], and an interface embedded in an interface. A package-qualified embed (sync.Mutex) names another package and is skipped, as are constraint unions and~intelements. A named field (base Base) is not an embed.resolve.ts: for Go,extendsmay target a struct, and the edge only binds to a type in the embedder's own directory. The existing typed-member walk then finds the promoted method, with the embedder's own method winning over the embedded one.resolve.ts,resolveTypedMember: for Go, a method found on two embedded types at the same depth is an ambiguous selector (the compiler rejects the call), so it resolves to neither.When two packages both define
Base.Hello, the owner index is keyed by type name only, so the call drops rather than land on the other package's method. That limit is unchanged.Testing
On Windows 11 with Node 26:
test/graph-go-embedded.test.ts(new): struct, pointer and interface embedding, the outer type's own method winning, a same-namedBasein another package not being linked, the same method promoted from two embedded types resolving to neither, a shallower promotion winning over a deeper one, and a named field andsync.Mutexproducing noextendsedge. Both tests fail on main.test/graph*,blast*,ask*,generic*,depth*,resolve*andcovers*suites: 674 tests, 1 fail. The one failure isdiscoverWorkspaceChildren follows a symlinked child repo, a symlink permission error on Windows that fails the same way on main.tsc --noEmitpasses.On seedfall, 7
callsand 20extendsedges are added and none removed. For examplecmd/seedfall/explore.go#cmdExplore -> cmd/seedfall/configflags.go#configArgs.register, throughexploreArgsembeddingconfigArgs.Fixes #813