diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java index a66a435..e8e6bd2 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java @@ -404,7 +404,7 @@ public final class MachineEnumCanonicalizer { } if (!transitionEvents.isEmpty()) { - result = capToConfiguredTransitionEvents(result, transitionEvents); + result = capToConfiguredTransitionEvents(result, transitionEvents, eventTypeFqn); } return result; } @@ -414,7 +414,8 @@ public final class MachineEnumCanonicalizer { */ static List capToConfiguredTransitionEvents( List candidates, - List transitionEvents) { + List transitionEvents, + String eventTypeFqn) { if (transitionEvents == null || transitionEvents.isEmpty()) { return candidates == null ? List.of() : candidates; } @@ -430,9 +431,21 @@ public final class MachineEnumCanonicalizer { capped.add(candidate); continue; } + String candidateType = enumTypeFromRef(candidate); String constant = constantName(candidate); for (String transitionEvent : transitionEvents) { - if (constantName(transitionEvent).equals(constant)) { + if (!constantName(transitionEvent).equals(constant)) { + continue; + } + String transitionType = enumTypeFromRef(transitionEvent); + if (candidate.contains(".") && transitionEvent.contains(".")) { + if (candidateType != null && transitionType != null + && enumTypesMatch(candidateType, transitionType)) { + capped.add(transitionEvent); + break; + } + } else if (eventTypeFqn != null && transitionType != null + && enumTypesMatch(eventTypeFqn, transitionType)) { capped.add(transitionEvent); break; } diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContext.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContext.java index 3edc9fd..6869e00 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContext.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContext.java @@ -460,9 +460,23 @@ public class CodebaseContext { } // Try simple name match if input was FQN - if (directImpls == null && typeName.contains(".")) { - String simpleName = typeName.substring(typeName.lastIndexOf('.') + 1); - directImpls = interfaceToImpls.get(simpleName); + if (directImpls == null && cleanName.contains(".")) { + String simpleName = cleanName.substring(cleanName.lastIndexOf('.') + 1); + List simpleImpls = interfaceToImpls.get(simpleName); + if (simpleImpls != null) { + if (ambiguousSimpleNames.contains(simpleName)) { + String pkg = cleanName.substring(0, cleanName.lastIndexOf('.')); + List pkgScoped = new ArrayList<>(); + for (String impl : simpleImpls) { + if (impl.startsWith(pkg + ".")) { + pkgScoped.add(impl); + } + } + directImpls = pkgScoped.isEmpty() ? null : pkgScoped; + } else { + directImpls = simpleImpls; + } + } } if (directImpls != null) { diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java index 794ace5..68bd636 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java @@ -263,6 +263,16 @@ class MachineEnumCanonicalizerTest { assertThat(enriched.getPolymorphicEvents()).isNullOrEmpty(); } + @Test + void shouldNotCapForeignPackageEnumConstantToMachineTransition() { + List capped = MachineEnumCanonicalizer.capToConfiguredTransitionEvents( + List.of("b.OrderEvent.PAY"), + List.of("a.OrderEvent.PAY"), + "a.OrderEvent"); + + assertThat(capped).isEmpty(); + } + @Test void shouldValidateRawNameConsistencyForCanonicalHelpers() { assertThat(MachineEnumCanonicalizer.isRawNameConsistentWithFullIdentifier( diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContextTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContextTest.java index 863040a..1e5c336 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContextTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/ast/common/CodebaseContextTest.java @@ -271,8 +271,8 @@ class CodebaseContextTest { 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"); + assertThat(context.getImplementations("a.Service")).containsExactly("a.AServiceImpl"); + assertThat(context.getImplementations("b.Service")).containsExactly("b.BServiceImpl"); } @Test