Fail closed on ambiguous simple types in implementation widening
Prevent getImplementations("Name") from widening to unrelated classes when multiple types share the same simple name across packages.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -442,6 +442,12 @@ public class CodebaseContext {
|
||||
}
|
||||
if (!visited.add(cleanName)) return;
|
||||
|
||||
// Fail closed on ambiguous simple type names: we must not pick an arbitrary FQN and widen
|
||||
// to unrelated implementations across packages.
|
||||
if (cleanName != null && !cleanName.contains(".") && ambiguousSimpleNames.contains(cleanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try direct match
|
||||
List<String> directImpls = interfaceToImpls.get(cleanName);
|
||||
|
||||
|
||||
@@ -250,6 +250,29 @@ class CodebaseContextTest {
|
||||
assertThat(context.getEnumValues("b.OrderEvent")).containsExactly("b.OrderEvent.SHIP");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImplementationsShouldFailClosedForAmbiguousSimpleTypeName() throws IOException {
|
||||
Files.createDirectories(tempDir.resolve("a"));
|
||||
Files.createDirectories(tempDir.resolve("b"));
|
||||
Files.writeString(tempDir.resolve("a/Service.java"),
|
||||
"package a; public interface Service {}");
|
||||
Files.writeString(tempDir.resolve("a/AServiceImpl.java"),
|
||||
"package a; public class AServiceImpl implements Service {}");
|
||||
Files.writeString(tempDir.resolve("b/Service.java"),
|
||||
"package b; public interface Service {}");
|
||||
Files.writeString(tempDir.resolve("b/BServiceImpl.java"),
|
||||
"package b; public class BServiceImpl implements Service {}");
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.scan(tempDir);
|
||||
|
||||
assertThat(context.getImplementations("Service"))
|
||||
.as("ambiguous simple interface name must not widen to arbitrary impls")
|
||||
.isEmpty();
|
||||
assertThat(context.getImplementations("a.Service")).contains("a.AServiceImpl");
|
||||
assertThat(context.getImplementations("b.Service")).contains("b.BServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindClassWithFullyQualifiedAnnotation() throws IOException {
|
||||
String source = """
|
||||
|
||||
Reference in New Issue
Block a user