heuristics updated enum collision

This commit is contained in:
2026-06-25 06:39:31 +02:00
parent 75fd45d983
commit b45513c5fb
4 changed files with 200 additions and 25 deletions

View File

@@ -227,4 +227,89 @@ class HeuristicCallGraphEngineExtendedTest {
.containsExactlyInAnyOrder("TransitionEnum.CHECKOUT_STARTED");
}
@Test
void shouldResolveCorrectEnumWhenNamesCollide() throws IOException {
String source = """
package com.example;
public class OrderService {
private StateMachine machine;
public void processOrder() {
// We use OrderEvent.PROCESS
machine.fire(OrderEvent.PROCESS);
}
}
public class InventoryService {
private StateMachine machine;
public void updateInventory() {
// We use InternalEvent.PROCESS which has same simple name
machine.fireInternal(InternalEvent.PROCESS);
}
public void wrongProcess() {
// This calls fire(OrderEvent) but with InternalEvent.PROCESS
// It should be REJECTED by type-aware heuristic matching if it matches fire(OrderEvent)
machine.fire(InternalEvent.PROCESS);
}
}
class StateMachine {
// Two overloaded methods or methods in different classes (simulated by names)
public void fire(OrderEvent event) {}
public void fireInternal(InternalEvent event) {}
}
enum OrderEvent { PROCESS, CANCEL }
enum InternalEvent { PROCESS, AUDIT }
""";
java.nio.file.Path tempDir = java.nio.file.Files.createTempDirectory("callgraph_test_collision");
java.nio.file.Files.writeString(tempDir.resolve("CollisionConfig.java"), source);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
// Scenario 1: Trace OrderService.processOrder
EntryPoint entryPoint1 = EntryPoint.builder()
.className("com.example.OrderService")
.methodName("processOrder")
.build();
TriggerPoint trigger1 = TriggerPoint.builder()
.className("com.example.StateMachine")
.methodName("fire")
.event("event")
.build();
List<CallChain> chains1 = engine.findChains(List.of(entryPoint1), List.of(trigger1));
assertThat(chains1).hasSize(1);
assertThat(chains1.get(0).getTriggerPoint().getPolymorphicEvents())
.containsExactly("OrderEvent.PROCESS")
.doesNotContain("InternalEvent.PROCESS");
// Scenario 2: Trace InventoryService.updateInventory
EntryPoint entryPoint2 = EntryPoint.builder()
.className("com.example.InventoryService")
.methodName("updateInventory")
.build();
TriggerPoint trigger2 = TriggerPoint.builder()
.className("com.example.StateMachine")
.methodName("fireInternal")
.event("event")
.build();
List<CallChain> chains2 = engine.findChains(List.of(entryPoint2), List.of(trigger2));
assertThat(chains2).hasSize(1);
assertThat(chains2.get(0).getTriggerPoint().getPolymorphicEvents())
.containsExactly("InternalEvent.PROCESS")
.doesNotContain("OrderEvent.PROCESS");
}
}