Repository navigation
fix(java): resolve static calls made through the class name - #806
kunalgoesbyken wants to merge 1 commit into
Conversation
`Strings.trim(s)` names the class as the receiver, but a Java receiver with no local binding gave no type, so the call was dropped and `callers Strings.trim` found nothing. Instance, field and implicit-this calls resolved; the static utility calls that carry most of a Java codebase's shared code did not. Python and Swift already read an UpperCamelCase receiver with no binding as the type; do the same here. A constant (`LOG.info()`) or JDK type (`Math.max`) owns no in-repo method of that name and still drops, and a typed parameter or field wins over the class name. A receiver imported by name from a class outside the repo (`import com.google.common.base.Strings`) drops too, even when the repo has its own `Strings`.
🌱 graft blast radius1 area changed → 4 areas can be affected. 8 dependent symbols, depth 2. flowchart TB
A0(("Dependency Graph Building<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 Building — 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.
54 test suites also reference this code64 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. |
|
The only red check is |
Summary
Strings.trim(s)names the class as the receiver, but a Java receiver with no local binding got no type, so the call was dropped andcallers Strings.trimfound nothing. Python and Swift already read an UpperCamelCase receiver with no binding as the type; this does the same for Java.Changes
bindings.ts:resolveRecvTypereturns an UpperCamelCase Java receiver as its own type when no binding matched. A typed parameter, field or local of that name is found first and wins. A constant (LOG.info()) or a JDK type (Math.max,List.of()) owns no in-repo method of that name, so it finds no owner-qualified match and still drops.extract.ts,resolve.ts: a receiver that is a single-type import carries the import's name as the call'sspecifier, andresolveEdgesdrops the call when that name is not a file in the repo. Without this,import com.google.common.base.Strings; Strings.trim(s)linked to an in-repoStrings. Wildcard and static imports are not recorded.Testing
On Windows 11 with Node 26:
test/graph-java.test.ts: the first test covers a static call resolving to its class, two classes with the same method name resolving to their own, and a constant, a JDK type and a parameter named like the class. The second covers an in-repoStringsimported by name resolving, and the same call under an external import of that name dropping. Both 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.Fixes #805