Cause: `buildJavaPackageIndex` kept the first file declaring each
package+type. One repository can hold several build modules or sample
projects that each declare `models.User`, so every `import models.User;`
bound whichever copy was parsed first, a wrong IMPORTS edge at full
confidence that carries the receiver types behind it. In the combined
lang-resolution corpus 24 fixtures declare `models.User`, and e.g.
`java-heritage` UserService.processUser called
`java-assignment-chain/models/User.save`.
Fix: the index keeps every declaring file in a sparse `duplicateTypes` map
(only colliding pairs, so a normal workspace pays nothing), and a type import
resolves to the declaring file sharing the longest leading path with the
importer (its own module or source root). A tie, or an unknown importer,
refuses rather than guessing. Wildcard imports are unchanged.
Corpus A/B (previous commit vs this, same corpus): 40 CALLS edges that
crossed into another fixture's User/Repo/Address/UserService are gone, 55
CALLS/ACCESSES edges now land in their own fixture (0 cross-fixture), and
`java-parent-resolution` User IMPLEMENTS Serializable moves off
`java-heritage` onto its own interface. Receiver-unresolved drops unchanged;
import-target and receiver benches pass. Scope-capture java fingerprint
re-baselined for the added fixture only (parked, --check passes on the old
one).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve Java imports against parsed package declarations, expand package wildcards deterministically, and keep external imports unresolved when no in-repo package declares them.
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>