Thread CodebaseContext through canonical form validator
requireCanonical and event matching now use context-aware enum checks so ambiguous import-style identifiers are not falsely rewritten during export validation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -50,7 +50,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateFields(result, machineTypes, violations);
|
validateFields(result, machineTypes, violations, context);
|
||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateFields(result, machineTypes, violations);
|
validateFields(result, machineTypes, violations, null);
|
||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,17 +89,18 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
private static void validateFields(
|
private static void validateFields(
|
||||||
AnalysisResult result,
|
AnalysisResult result,
|
||||||
StateMachineTypeResolver.MachineTypes machineTypes,
|
StateMachineTypeResolver.MachineTypes machineTypes,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
validateTransitions(result.getTransitions(), machineTypes, violations);
|
CodebaseContext context) {
|
||||||
validateStateCollection(result.getStates(), machineTypes.stateTypeFqn(), "states", violations);
|
validateTransitions(result.getTransitions(), machineTypes, violations, context);
|
||||||
|
validateStateCollection(result.getStates(), machineTypes.stateTypeFqn(), "states", violations, context);
|
||||||
validateStateRawNameSync(result.getStates(), machineTypes.stateTypeFqn(), "states", violations);
|
validateStateRawNameSync(result.getStates(), machineTypes.stateTypeFqn(), "states", violations);
|
||||||
validateStateLabels(result.getStartStates(), machineTypes.stateTypeFqn(), "startStates", violations);
|
validateStateLabels(result.getStartStates(), machineTypes.stateTypeFqn(), "startStates", violations, context);
|
||||||
validateStateLabels(result.getEndStates(), machineTypes.stateTypeFqn(), "endStates", violations);
|
validateStateLabels(result.getEndStates(), machineTypes.stateTypeFqn(), "endStates", violations, context);
|
||||||
|
|
||||||
if (result.getMetadata() != null) {
|
if (result.getMetadata() != null) {
|
||||||
validateTriggers(result.getMetadata().getTriggers(), machineTypes, violations);
|
validateTriggers(result.getMetadata().getTriggers(), machineTypes, violations, context);
|
||||||
validateCallChains(
|
validateCallChains(
|
||||||
result.getMetadata().getCallChains(), result.getTransitions(), machineTypes, violations);
|
result.getMetadata().getCallChains(), result.getTransitions(), machineTypes, violations, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +115,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
private static void validateTransitions(
|
private static void validateTransitions(
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
StateMachineTypeResolver.MachineTypes machineTypes,
|
StateMachineTypeResolver.MachineTypes machineTypes,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (transitions == null) {
|
if (transitions == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
prefix + ".event.fullIdentifier",
|
prefix + ".event.fullIdentifier",
|
||||||
transition.getEvent().fullIdentifier(),
|
transition.getEvent().fullIdentifier(),
|
||||||
machineTypes.eventTypeFqn(),
|
machineTypes.eventTypeFqn(),
|
||||||
violations);
|
violations,
|
||||||
|
context);
|
||||||
requireRawNameSync(
|
requireRawNameSync(
|
||||||
prefix + ".event.rawName",
|
prefix + ".event.rawName",
|
||||||
transition.getEvent().rawName(),
|
transition.getEvent().rawName(),
|
||||||
@@ -135,9 +138,9 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
violations);
|
violations);
|
||||||
}
|
}
|
||||||
validateStateListWithRawSync(
|
validateStateListWithRawSync(
|
||||||
transition.getSourceStates(), machineTypes.stateTypeFqn(), prefix + ".sourceStates", violations);
|
transition.getSourceStates(), machineTypes.stateTypeFqn(), prefix + ".sourceStates", violations, context);
|
||||||
validateStateListWithRawSync(
|
validateStateListWithRawSync(
|
||||||
transition.getTargetStates(), machineTypes.stateTypeFqn(), prefix + ".targetStates", violations);
|
transition.getTargetStates(), machineTypes.stateTypeFqn(), prefix + ".targetStates", violations, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,13 +148,14 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
List<State> states,
|
List<State> states,
|
||||||
String stateTypeFqn,
|
String stateTypeFqn,
|
||||||
String pathPrefix,
|
String pathPrefix,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (states == null) {
|
if (states == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < states.size(); i++) {
|
for (int i = 0; i < states.size(); i++) {
|
||||||
State state = states.get(i);
|
State state = states.get(i);
|
||||||
requireCanonical(pathPrefix + "[" + i + "].fullIdentifier", state.fullIdentifier(), stateTypeFqn, violations);
|
requireCanonical(pathPrefix + "[" + i + "].fullIdentifier", state.fullIdentifier(), stateTypeFqn, violations, context);
|
||||||
requireRawNameSync(
|
requireRawNameSync(
|
||||||
pathPrefix + "[" + i + "].rawName",
|
pathPrefix + "[" + i + "].rawName",
|
||||||
state.rawName(),
|
state.rawName(),
|
||||||
@@ -183,13 +187,14 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
Set<State> states,
|
Set<State> states,
|
||||||
String stateTypeFqn,
|
String stateTypeFqn,
|
||||||
String pathPrefix,
|
String pathPrefix,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (states == null) {
|
if (states == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (State state : states) {
|
for (State state : states) {
|
||||||
requireCanonical(pathPrefix + "[" + i++ + "].fullIdentifier", state.fullIdentifier(), stateTypeFqn, violations);
|
requireCanonical(pathPrefix + "[" + i++ + "].fullIdentifier", state.fullIdentifier(), stateTypeFqn, violations, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,20 +202,22 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
Set<String> labels,
|
Set<String> labels,
|
||||||
String stateTypeFqn,
|
String stateTypeFqn,
|
||||||
String pathPrefix,
|
String pathPrefix,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (labels == null) {
|
if (labels == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String label : labels) {
|
for (String label : labels) {
|
||||||
requireCanonical(pathPrefix + "[" + i++ + "]", label, stateTypeFqn, violations);
|
requireCanonical(pathPrefix + "[" + i++ + "]", label, stateTypeFqn, violations, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateTriggers(
|
private static void validateTriggers(
|
||||||
List<TriggerPoint> triggers,
|
List<TriggerPoint> triggers,
|
||||||
StateMachineTypeResolver.MachineTypes machineTypes,
|
StateMachineTypeResolver.MachineTypes machineTypes,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (triggers == null) {
|
if (triggers == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -220,16 +227,16 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
String eventTypeFqn = preferTypeFqn(trigger.getEventTypeFqn(), machineTypes.eventTypeFqn());
|
String eventTypeFqn = preferTypeFqn(trigger.getEventTypeFqn(), machineTypes.eventTypeFqn());
|
||||||
String stateTypeFqn = preferTypeFqn(trigger.getStateTypeFqn(), machineTypes.stateTypeFqn());
|
String stateTypeFqn = preferTypeFqn(trigger.getStateTypeFqn(), machineTypes.stateTypeFqn());
|
||||||
|
|
||||||
requireCanonical(prefix + ".event", trigger.getEvent(), eventTypeFqn, violations);
|
requireCanonical(prefix + ".event", trigger.getEvent(), eventTypeFqn, violations, context);
|
||||||
validateTriggerEventForm(prefix + ".event", trigger.getEvent(), violations);
|
validateTriggerEventForm(prefix + ".event", trigger.getEvent(), violations);
|
||||||
requireCanonical(prefix + ".sourceState", trigger.getSourceState(), stateTypeFqn, violations);
|
requireCanonical(prefix + ".sourceState", trigger.getSourceState(), stateTypeFqn, violations, context);
|
||||||
validateDynamicIdentifierForm(prefix + ".sourceState", trigger.getSourceState(), violations);
|
validateDynamicIdentifierForm(prefix + ".sourceState", trigger.getSourceState(), violations);
|
||||||
|
|
||||||
if (trigger.getPolymorphicEvents() != null) {
|
if (trigger.getPolymorphicEvents() != null) {
|
||||||
for (int j = 0; j < trigger.getPolymorphicEvents().size(); j++) {
|
for (int j = 0; j < trigger.getPolymorphicEvents().size(); j++) {
|
||||||
String polyPath = prefix + ".polymorphicEvents[" + j + "]";
|
String polyPath = prefix + ".polymorphicEvents[" + j + "]";
|
||||||
String polyEvent = trigger.getPolymorphicEvents().get(j);
|
String polyEvent = trigger.getPolymorphicEvents().get(j);
|
||||||
requireCanonical(polyPath, polyEvent, eventTypeFqn, violations);
|
requireCanonical(polyPath, polyEvent, eventTypeFqn, violations, context);
|
||||||
validatePolymorphicEventForm(polyPath, polyEvent, violations);
|
validatePolymorphicEventForm(polyPath, polyEvent, violations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,7 +247,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
List<CallChain> callChains,
|
List<CallChain> callChains,
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
StateMachineTypeResolver.MachineTypes machineTypes,
|
StateMachineTypeResolver.MachineTypes machineTypes,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (callChains == null) {
|
if (callChains == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -252,30 +260,30 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
String triggerPrefix = prefix + ".triggerPoint";
|
String triggerPrefix = prefix + ".triggerPoint";
|
||||||
String eventTypeFqn = preferTypeFqn(trigger.getEventTypeFqn(), machineTypes.eventTypeFqn());
|
String eventTypeFqn = preferTypeFqn(trigger.getEventTypeFqn(), machineTypes.eventTypeFqn());
|
||||||
String stateTypeFqn = preferTypeFqn(trigger.getStateTypeFqn(), machineTypes.stateTypeFqn());
|
String stateTypeFqn = preferTypeFqn(trigger.getStateTypeFqn(), machineTypes.stateTypeFqn());
|
||||||
requireCanonical(triggerPrefix + ".event", trigger.getEvent(), eventTypeFqn, violations);
|
requireCanonical(triggerPrefix + ".event", trigger.getEvent(), eventTypeFqn, violations, context);
|
||||||
validateTriggerEventForm(triggerPrefix + ".event", trigger.getEvent(), violations);
|
validateTriggerEventForm(triggerPrefix + ".event", trigger.getEvent(), violations);
|
||||||
requireCanonical(triggerPrefix + ".sourceState", trigger.getSourceState(), stateTypeFqn, violations);
|
requireCanonical(triggerPrefix + ".sourceState", trigger.getSourceState(), stateTypeFqn, violations, context);
|
||||||
validateDynamicIdentifierForm(triggerPrefix + ".sourceState", trigger.getSourceState(), violations);
|
validateDynamicIdentifierForm(triggerPrefix + ".sourceState", trigger.getSourceState(), violations);
|
||||||
if (trigger.getPolymorphicEvents() != null) {
|
if (trigger.getPolymorphicEvents() != null) {
|
||||||
for (int j = 0; j < trigger.getPolymorphicEvents().size(); j++) {
|
for (int j = 0; j < trigger.getPolymorphicEvents().size(); j++) {
|
||||||
String polyPath = triggerPrefix + ".polymorphicEvents[" + j + "]";
|
String polyPath = triggerPrefix + ".polymorphicEvents[" + j + "]";
|
||||||
String polyEvent = trigger.getPolymorphicEvents().get(j);
|
String polyEvent = trigger.getPolymorphicEvents().get(j);
|
||||||
requireCanonical(polyPath, polyEvent, eventTypeFqn, violations);
|
requireCanonical(polyPath, polyEvent, eventTypeFqn, violations, context);
|
||||||
validatePolymorphicEventForm(polyPath, polyEvent, violations);
|
validatePolymorphicEventForm(polyPath, polyEvent, violations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validateMatchedTransitionsWhenResolvable(
|
validateMatchedTransitionsWhenResolvable(
|
||||||
prefix, chain, trigger, transitions, machineTypes.eventTypeFqn(), violations);
|
prefix, chain, trigger, transitions, machineTypes.eventTypeFqn(), violations, context);
|
||||||
validateOverLinkedPolymorphicEvents(
|
validateOverLinkedPolymorphicEvents(
|
||||||
prefix, chain, trigger, transitions, machineTypes.eventTypeFqn(), violations);
|
prefix, chain, trigger, transitions, machineTypes.eventTypeFqn(), violations, context);
|
||||||
}
|
}
|
||||||
if (chain.getMatchedTransitions() != null) {
|
if (chain.getMatchedTransitions() != null) {
|
||||||
for (int j = 0; j < chain.getMatchedTransitions().size(); j++) {
|
for (int j = 0; j < chain.getMatchedTransitions().size(); j++) {
|
||||||
MatchedTransition matched = chain.getMatchedTransitions().get(j);
|
MatchedTransition matched = chain.getMatchedTransitions().get(j);
|
||||||
String matchedPrefix = prefix + ".matchedTransitions[" + j + "]";
|
String matchedPrefix = prefix + ".matchedTransitions[" + j + "]";
|
||||||
requireCanonical(matchedPrefix + ".event", matched.getEvent(), machineTypes.eventTypeFqn(), violations);
|
requireCanonical(matchedPrefix + ".event", matched.getEvent(), machineTypes.eventTypeFqn(), violations, context);
|
||||||
requireCanonical(matchedPrefix + ".sourceState", matched.getSourceState(), machineTypes.stateTypeFqn(), violations);
|
requireCanonical(matchedPrefix + ".sourceState", matched.getSourceState(), machineTypes.stateTypeFqn(), violations, context);
|
||||||
requireCanonical(matchedPrefix + ".targetState", matched.getTargetState(), machineTypes.stateTypeFqn(), violations);
|
requireCanonical(matchedPrefix + ".targetState", matched.getTargetState(), machineTypes.stateTypeFqn(), violations, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,11 +300,12 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
String path,
|
String path,
|
||||||
String value,
|
String value,
|
||||||
String enumTypeFqn,
|
String enumTypeFqn,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
if (!MachineEnumCanonicalizer.isMachineEnumReference(value, enumTypeFqn)) {
|
CodebaseContext context) {
|
||||||
|
if (!MachineEnumCanonicalizer.isMachineEnumReference(value, enumTypeFqn, context)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String expected = MachineEnumCanonicalizer.canonicalizeLabel(value, enumTypeFqn);
|
String expected = MachineEnumCanonicalizer.canonicalizeLabel(value, enumTypeFqn, context);
|
||||||
if (!expected.equals(value)) {
|
if (!expected.equals(value)) {
|
||||||
violations.add(new Violation(path, value, expected));
|
violations.add(new Violation(path, value, expected));
|
||||||
}
|
}
|
||||||
@@ -347,7 +356,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
TriggerPoint trigger,
|
TriggerPoint trigger,
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
String eventTypeFqn,
|
String eventTypeFqn,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (trigger.getPolymorphicEvents() == null || trigger.getPolymorphicEvents().isEmpty()) {
|
if (trigger.getPolymorphicEvents() == null || trigger.getPolymorphicEvents().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -373,7 +383,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int matchingTransitionCount = countMatchingConfiguredTransitions(
|
int matchingTransitionCount = countMatchingConfiguredTransitions(
|
||||||
transitions, trigger.getPolymorphicEvents(), eventTypeFqn);
|
transitions, trigger.getPolymorphicEvents(), eventTypeFqn, context);
|
||||||
if (matchingTransitionCount > 0
|
if (matchingTransitionCount > 0
|
||||||
&& chain.getMatchedTransitions() != null
|
&& chain.getMatchedTransitions() != null
|
||||||
&& chain.getMatchedTransitions().size() > matchingTransitionCount) {
|
&& chain.getMatchedTransitions().size() > matchingTransitionCount) {
|
||||||
@@ -387,7 +397,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
private static int countMatchingConfiguredTransitions(
|
private static int countMatchingConfiguredTransitions(
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
List<String> polymorphicEvents,
|
List<String> polymorphicEvents,
|
||||||
String eventTypeFqn) {
|
String eventTypeFqn,
|
||||||
|
CodebaseContext context) {
|
||||||
if (transitions == null || transitions.isEmpty() || polymorphicEvents == null) {
|
if (transitions == null || transitions.isEmpty() || polymorphicEvents == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -400,7 +411,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
? transition.getEvent().fullIdentifier()
|
? transition.getEvent().fullIdentifier()
|
||||||
: transition.getEvent().rawName();
|
: transition.getEvent().rawName();
|
||||||
for (String polyEvent : polymorphicEvents) {
|
for (String polyEvent : polymorphicEvents) {
|
||||||
if (eventsMatch(polyEvent, smEvent, eventTypeFqn)) {
|
if (eventsMatch(polyEvent, smEvent, eventTypeFqn, context)) {
|
||||||
count++;
|
count++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -415,7 +426,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
TriggerPoint trigger,
|
TriggerPoint trigger,
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
String eventTypeFqn,
|
String eventTypeFqn,
|
||||||
List<Violation> violations) {
|
List<Violation> violations,
|
||||||
|
CodebaseContext context) {
|
||||||
if (LifecycleTriggerMarkers.isLifecycle(trigger.getEvent())) {
|
if (LifecycleTriggerMarkers.isLifecycle(trigger.getEvent())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -429,7 +441,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
MachineEnumCanonicalizer.TriggerEventKind eventKind =
|
MachineEnumCanonicalizer.TriggerEventKind eventKind =
|
||||||
MachineEnumCanonicalizer.classifyTriggerEvent(trigger.getEvent());
|
MachineEnumCanonicalizer.classifyTriggerEvent(trigger.getEvent());
|
||||||
if (eventKind == MachineEnumCanonicalizer.TriggerEventKind.CANONICAL_ENUM) {
|
if (eventKind == MachineEnumCanonicalizer.TriggerEventKind.CANONICAL_ENUM) {
|
||||||
if (eventMatchesAnyTransition(trigger.getEvent(), transitions, eventTypeFqn)) {
|
if (eventMatchesAnyTransition(trigger.getEvent(), transitions, eventTypeFqn, context)) {
|
||||||
violations.add(new Violation(
|
violations.add(new Violation(
|
||||||
chainPrefix + ".matchedTransitions",
|
chainPrefix + ".matchedTransitions",
|
||||||
"empty",
|
"empty",
|
||||||
@@ -444,7 +456,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
if (eventKind != MachineEnumCanonicalizer.TriggerEventKind.DYNAMIC_EXPRESSION) {
|
if (eventKind != MachineEnumCanonicalizer.TriggerEventKind.DYNAMIC_EXPRESSION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!polymorphicEventsMatchAnyTransition(trigger.getPolymorphicEvents(), transitions, eventTypeFqn)) {
|
if (!polymorphicEventsMatchAnyTransition(trigger.getPolymorphicEvents(), transitions, eventTypeFqn, context)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
violations.add(new Violation(
|
violations.add(new Violation(
|
||||||
@@ -476,7 +488,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
private static boolean eventMatchesAnyTransition(
|
private static boolean eventMatchesAnyTransition(
|
||||||
String triggerEvent,
|
String triggerEvent,
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
String eventTypeFqn) {
|
String eventTypeFqn,
|
||||||
|
CodebaseContext context) {
|
||||||
if (transitions == null || transitions.isEmpty() || triggerEvent == null) {
|
if (transitions == null || transitions.isEmpty() || triggerEvent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -487,7 +500,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
String smEvent = transition.getEvent().fullIdentifier() != null
|
String smEvent = transition.getEvent().fullIdentifier() != null
|
||||||
? transition.getEvent().fullIdentifier()
|
? transition.getEvent().fullIdentifier()
|
||||||
: transition.getEvent().rawName();
|
: transition.getEvent().rawName();
|
||||||
if (eventsMatch(triggerEvent, smEvent, eventTypeFqn)) {
|
if (eventsMatch(triggerEvent, smEvent, eventTypeFqn, context)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,7 +510,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
private static boolean polymorphicEventsMatchAnyTransition(
|
private static boolean polymorphicEventsMatchAnyTransition(
|
||||||
List<String> polymorphicEvents,
|
List<String> polymorphicEvents,
|
||||||
List<Transition> transitions,
|
List<Transition> transitions,
|
||||||
String eventTypeFqn) {
|
String eventTypeFqn,
|
||||||
|
CodebaseContext context) {
|
||||||
if (transitions == null || transitions.isEmpty()) {
|
if (transitions == null || transitions.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -509,7 +523,7 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
String smEvent = transition.getEvent().fullIdentifier() != null
|
String smEvent = transition.getEvent().fullIdentifier() != null
|
||||||
? transition.getEvent().fullIdentifier()
|
? transition.getEvent().fullIdentifier()
|
||||||
: transition.getEvent().rawName();
|
: transition.getEvent().rawName();
|
||||||
if (eventsMatch(polyEvent, smEvent, eventTypeFqn)) {
|
if (eventsMatch(polyEvent, smEvent, eventTypeFqn, context)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -517,7 +531,11 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean eventsMatch(String triggerEvent, String smEvent, String eventTypeFqn) {
|
private static boolean eventsMatch(
|
||||||
|
String triggerEvent,
|
||||||
|
String smEvent,
|
||||||
|
String eventTypeFqn,
|
||||||
|
CodebaseContext context) {
|
||||||
if (triggerEvent == null || smEvent == null) {
|
if (triggerEvent == null || smEvent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -529,8 +547,8 @@ public final class AnalysisCanonicalFormValidator {
|
|||||||
if (!triggerConst.equals(smConst)) {
|
if (!triggerConst.equals(smConst)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (MachineEnumCanonicalizer.isMachineEnumReference(triggerEvent, eventTypeFqn)
|
if (MachineEnumCanonicalizer.isMachineEnumReference(triggerEvent, eventTypeFqn, context)
|
||||||
&& MachineEnumCanonicalizer.isMachineEnumReference(smEvent, eventTypeFqn)) {
|
&& MachineEnumCanonicalizer.isMachineEnumReference(smEvent, eventTypeFqn, context)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -392,6 +392,47 @@ class AnalysisCanonicalFormValidatorTest {
|
|||||||
.noneMatch(v -> v.path().contains("matchedTransitions"));
|
.noneMatch(v -> v.path().contains("matchedTransitions"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldSkipImportStyleCanonicalCheckWhenSimpleNameIsAmbiguous(@TempDir Path tempDir) throws IOException {
|
||||||
|
Files.createDirectories(tempDir.resolve("a"));
|
||||||
|
Files.createDirectories(tempDir.resolve("b"));
|
||||||
|
Files.createDirectories(tempDir.resolve("com/example/config"));
|
||||||
|
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 { CANCEL }");
|
||||||
|
Files.writeString(tempDir.resolve("a/OrderState.java"), "package a; public enum OrderState { NEW, PAID }");
|
||||||
|
Files.writeString(tempDir.resolve("com/example/config/OrderStateMachineConfiguration.java"),
|
||||||
|
"""
|
||||||
|
package com.example.config;
|
||||||
|
import a.OrderEvent;
|
||||||
|
import a.OrderState;
|
||||||
|
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
|
||||||
|
public class OrderStateMachineConfiguration
|
||||||
|
extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
CodebaseContext context = new CodebaseContext();
|
||||||
|
context.scan(tempDir);
|
||||||
|
|
||||||
|
AnalysisResult result = AnalysisResult.builder()
|
||||||
|
.name("com.example.config.OrderStateMachineConfiguration")
|
||||||
|
.transitions(List.of(transition(
|
||||||
|
"a.OrderEvent.PAY",
|
||||||
|
"a.OrderState.NEW",
|
||||||
|
"a.OrderState.PAID")))
|
||||||
|
.metadata(CodebaseMetadata.builder()
|
||||||
|
.triggers(List.of(TriggerPoint.builder()
|
||||||
|
.event("OrderEvent.PAY")
|
||||||
|
.className("com.example.web.Controller")
|
||||||
|
.methodName("pay")
|
||||||
|
.sourceFile("Controller.java")
|
||||||
|
.build()))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(AnalysisCanonicalFormValidator.validate(result, context)).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldSkipValidationForStringStateMachines(@TempDir Path tempDir) throws IOException {
|
void shouldSkipValidationForStringStateMachines(@TempDir Path tempDir) throws IOException {
|
||||||
Path configPkg = tempDir.resolve("com/example/config");
|
Path configPkg = tempDir.resolve("com/example/config");
|
||||||
|
|||||||
Reference in New Issue
Block a user