Skip to content

fix(resolution): Java/Kotlin imports disambiguate same-name classes (#314)#472

Merged
colbymchenry merged 1 commit into
mainfrom
fix/314-java-import-resolver
May 26, 2026
Merged

fix(resolution): Java/Kotlin imports disambiguate same-name classes (#314)#472
colbymchenry merged 1 commit into
mainfrom
fix/314-java-import-resolver

Conversation

@colbymchenry
Copy link
Copy Markdown
Owner

Summary

A Maven multi-module project where dao/converter/FooConverter and service/converter/FooConverter both expose convert() used to resolve by file-path proximity — picking whichever class was closer to the caller, which is wrong any time the caller lives in an equidistant cross-cutting module. `extractImportMappings` had no Java branch at all, so the FQN signal Java imports carry — `import com.example.dao.converter.FooConverter;` — was thrown away.

What changed

  • `extractJavaImports` — new. Parses regular and `import static` directives. Wildcard imports (`*`) intentionally skipped (would need package-file enumeration).
  • `resolveViaImport` — new Java/Kotlin cross-file branch. Converts the imported FQN to a file-path suffix (`com/example/dao/converter/FooConverter.java` or `.kt`) and resolves against the file whose path matches by suffix. Also handles `import static` member imports.
  • `matchMethodCall` (Java/Kotlin field-receiver path) — now passes the imported FQN to `resolveMethodOnType` so when two `FooConverter::convert` candidates exist, the import — not iteration order — picks the right one.

Validation

Synthetic 3-module repro (the key proof):

Import in caller Resolves to
`import com.example.dao.converter.FooConverter;` `dao/.../FooConverter.java`
`import com.example.service.converter.FooConverter;` `service/.../FooConverter.java`

Same field declaration, same call site, same caller path — swapping only the import line swaps the target. That's import-driven, not path-proximity-driven, which is exactly what #314 demands.

spring-petclinic (47 `.java` files, single-module so no same-name collisions): +15 newly import-resolved Java edges, +2 references, no regression in `calls`/`imports`/`extends`/`instantiates`.

Test plan

  • Unit test: synthetic 3-module Maven layout, asserts import → correct target (NOT path-proximity default)
  • Full suite: 48 files, 1013 tests pass
  • Manual end-to-end verification with both import directions

Closes #314.

🤖 Generated with Claude Code

…314)

A Maven multi-module project where `dao/converter/FooConverter` and
`service/converter/FooConverter` both expose a `convert` method used
to resolve by file-path proximity — picking whichever class was closer
to the caller, which is wrong any time the caller lives in an
equidistant cross-cutting module. `extractImportMappings` had no Java
branch at all, so the FQN signal Java imports carry — `import
com.example.dao.converter.FooConverter;` — was thrown away.

- `extractJavaImports` parses regular and `import static` directives;
  wildcard imports (`*`) are intentionally skipped.
- `resolveViaImport` has a new Java/Kotlin cross-file branch that
  converts the imported FQN to a file-path suffix
  (`com/example/dao/converter/FooConverter.java`, or `.kt`) and
  resolves the symbol against the file whose path matches by suffix.
- For the field-receiver pattern (`@Autowired private FooConverter
  fooConverter; fooConverter.convert(...)` — Spring's typical shape),
  `matchMethodCall` now looks up the receiver's inferred type in the
  caller file's imports and threads the resulting FQN through to
  `resolveMethodOnType`. When two `FooConverter::convert` candidates
  exist, the import — not iteration order — picks the right one.

Validated end-to-end with a synthetic 3-module repro:
  import com.example.dao.converter.FooConverter;     -> dao convert
  import com.example.service.converter.FooConverter; -> service convert
Same field declaration, same call site, swapping only the import
swaps the resolved target.

spring-petclinic (47 .java files, single-module so no same-name
collisions): +15 newly import-resolved edges, +2 references, no
regression in calls / imports / extends / instantiates.

Closes #314.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Add Java import resolution to extractImportMappings for cross-module disambiguation

1 participant