diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicy.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicy.java index 8f9ac49..da207f5 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicy.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicy.java @@ -20,12 +20,19 @@ public final class CallChainLinkPolicy { } public static boolean shouldFailClosedOnAmbiguousCallGraphWiden(TriggerPoint trigger) { - return shouldFailClosedOnAmbiguousCallGraphWiden(trigger, null); + return shouldFailClosedOnAmbiguousCallGraphWiden(trigger, null, null); } public static boolean shouldFailClosedOnAmbiguousCallGraphWiden( TriggerPoint trigger, String machineEventTypeFqn) { + return shouldFailClosedOnAmbiguousCallGraphWiden(trigger, machineEventTypeFqn, null); + } + + public static boolean shouldFailClosedOnAmbiguousCallGraphWiden( + TriggerPoint trigger, + String machineEventTypeFqn, + CodebaseContext context) { if (trigger == null || trigger.isExternal() || !trigger.isAmbiguous()) { return false; } @@ -39,7 +46,7 @@ public final class CallChainLinkPolicy { } if (event != null && event.contains(".valueOf(")) { return MachineEnumCanonicalizer.isDynamicTriggerExpression(event) - && !isTrustedEnumPolymorphicWiden(trigger, machineEventTypeFqn); + && !isTrustedEnumPolymorphicWiden(trigger, machineEventTypeFqn, context); } return MachineEnumCanonicalizer.isDynamicTriggerExpression(event) && event != null; @@ -51,10 +58,17 @@ public final class CallChainLinkPolicy { * cross-package or unqualified widens. */ static boolean isTrustedEnumPolymorphicWiden(TriggerPoint trigger) { - return isTrustedEnumPolymorphicWiden(trigger, null); + return isTrustedEnumPolymorphicWiden(trigger, null, null); } static boolean isTrustedEnumPolymorphicWiden(TriggerPoint trigger, String machineEventTypeFqn) { + return isTrustedEnumPolymorphicWiden(trigger, machineEventTypeFqn, null); + } + + static boolean isTrustedEnumPolymorphicWiden( + TriggerPoint trigger, + String machineEventTypeFqn, + CodebaseContext context) { if (trigger == null) { return false; } @@ -75,7 +89,7 @@ public final class CallChainLinkPolicy { } String enumType = pe.substring(0, pe.lastIndexOf('.')); if (!enumType.contains(".") - || !MachineEnumCanonicalizer.enumTypesMatch(eventTypeFqn, enumType)) { + || !MachineEnumCanonicalizer.enumTypesMatch(eventTypeFqn, enumType, context)) { return false; } } @@ -86,12 +100,29 @@ public final class CallChainLinkPolicy { TriggerPoint trigger, List matched, boolean ambiguousSource) { + return resolveLinkResolution(trigger, matched, ambiguousSource, null, null); + } + + public static LinkResolution resolveLinkResolution( + TriggerPoint trigger, + List matched, + boolean ambiguousSource, + String machineEventTypeFqn) { + return resolveLinkResolution(trigger, matched, ambiguousSource, machineEventTypeFqn, null); + } + + public static LinkResolution resolveLinkResolution( + TriggerPoint trigger, + List matched, + boolean ambiguousSource, + String machineEventTypeFqn, + CodebaseContext context) { if (trigger != null && trigger.isExternal()) { return LinkResolution.UNRESOLVED_EXTERNAL; } if (ambiguousSource || (trigger != null && trigger.isAmbiguous()) - || shouldFailClosedOnAmbiguousCallGraphWiden(trigger)) { + || shouldFailClosedOnAmbiguousCallGraphWiden(trigger, machineEventTypeFqn, context)) { return LinkResolution.AMBIGUOUS_WIDEN; } if (matched != null && !matched.isEmpty()) { diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricher.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricher.java index 05de893..b7c0895 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricher.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricher.java @@ -69,7 +69,9 @@ public class TransitionLinkerEnricher implements AnalysisEnricher { String triggerSource = tp.getSourceState() != null ? simplifySourceState(tp.getSourceState()) : null; if (CallChainLinkPolicy.shouldFailClosedOnAmbiguousCallGraphWiden( - tp, machineTypes != null ? machineTypes.eventTypeFqn() : null)) { + tp, + machineTypes != null ? machineTypes.eventTypeFqn() : null, + context)) { updatedChains.add(chain.toBuilder() .triggerPoint(tp) .matchedTransitions(null) @@ -155,7 +157,12 @@ public class TransitionLinkerEnricher implements AnalysisEnricher { tp = tp.toBuilder().ambiguous(true).build(); } - LinkResolution linkResolution = CallChainLinkPolicy.resolveLinkResolution(tp, matched, ambiguousSource); + LinkResolution linkResolution = CallChainLinkPolicy.resolveLinkResolution( + tp, + matched, + ambiguousSource, + machineTypes != null ? machineTypes.eventTypeFqn() : null, + context); if (!matched.isEmpty()) { CallChain newChain = chain.toBuilder() 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 5fb5f18..6190c88 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 @@ -166,7 +166,7 @@ public final class MachineEnumCanonicalizer { if (context != null && context.isAmbiguousSimpleName(symbolicType)) { continue; } - if (!enumTypesMatch(machineEventTypeFqn, symbolicType)) { + if (!enumTypesMatch(machineEventTypeFqn, symbolicType, context)) { continue; } if (transitionEvents.size() == 1) { diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicyTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicyTest.java index daf9340..1e0866b 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicyTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/CallChainLinkPolicyTest.java @@ -74,6 +74,23 @@ class CallChainLinkPolicyTest { trigger, "com.example.OrderEvent")).isFalse(); } + @Test + void shouldResolveLinkWhenTrustedWidenPassesUsingMachineEventType() { + TriggerPoint trigger = TriggerPoint.builder() + .ambiguous(false) + .event("OrderEvent.valueOf(eventStr)") + .polymorphicEvents(List.of("com.example.OrderEvent.PAY", "com.example.OrderEvent.SHIP")) + .build(); + + assertThat(CallChainLinkPolicy.resolveLinkResolution( + trigger, + List.of(), + false, + "com.example.OrderEvent")).isEqualTo(LinkResolution.NO_MATCH); + assertThat(CallChainLinkPolicy.shouldFailClosedOnAmbiguousCallGraphWiden( + trigger, "com.example.OrderEvent")).isFalse(); + } + @Test void shouldNotTrustImportStylePolymorphicWidenWithoutPackage() { TriggerPoint trigger = TriggerPoint.builder()