Fail closed on ambiguous simple enum names
Track enum name collisions during scan and refuse to resolve enum values by simple name when multiple enums share the same identifier across packages. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -482,7 +482,12 @@ public class CodebaseContext {
|
||||
}
|
||||
}
|
||||
enumValues.put(fqn, values);
|
||||
if (!simpleNameToFqn.containsKey(simpleName)) {
|
||||
if (simpleNameToFqn.containsKey(simpleName)) {
|
||||
String existingFqn = simpleNameToFqn.get(simpleName);
|
||||
if (existingFqn != null && !existingFqn.equals(fqn)) {
|
||||
ambiguousSimpleNames.add(simpleName);
|
||||
}
|
||||
} else {
|
||||
simpleNameToFqn.put(simpleName, fqn);
|
||||
}
|
||||
|
||||
@@ -516,6 +521,9 @@ public class CodebaseContext {
|
||||
|
||||
List<String> values = enumValues.get(cleanName);
|
||||
if (values == null) {
|
||||
if (!cleanName.contains(".") && ambiguousSimpleNames.contains(cleanName)) {
|
||||
return null;
|
||||
}
|
||||
String fqn = simpleNameToFqn.get(cleanName);
|
||||
if (fqn != null) values = enumValues.get(fqn);
|
||||
}
|
||||
|
||||
@@ -231,6 +231,25 @@ class CodebaseContextTest {
|
||||
assertThat(context.findEntryPointClasses(List.of("EnableStateMachine"))).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getEnumValuesShouldFailClosedForAmbiguousSimpleEnumName() throws IOException {
|
||||
Files.createDirectories(tempDir.resolve("a"));
|
||||
Files.createDirectories(tempDir.resolve("b"));
|
||||
Files.writeString(tempDir.resolve("a/OrderEvent.java"),
|
||||
"package a; public enum OrderEvent { PAY }");
|
||||
Files.writeString(tempDir.resolve("b/OrderEvent.java"),
|
||||
"package b; public enum OrderEvent { SHIP }");
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.scan(tempDir);
|
||||
|
||||
assertThat(context.getEnumValues("OrderEvent"))
|
||||
.as("ambiguous simple enum name must not resolve to arbitrary package")
|
||||
.isNull();
|
||||
assertThat(context.getEnumValues("a.OrderEvent")).containsExactly("a.OrderEvent.PAY");
|
||||
assertThat(context.getEnumValues("b.OrderEvent")).containsExactly("b.OrderEvent.SHIP");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindClassWithFullyQualifiedAnnotation() throws IOException {
|
||||
String source = """
|
||||
|
||||
Reference in New Issue
Block a user