Align enum rawName with fn-form labels during canonicalization.
Derive transition and state rawName from package-canonical fullIdentifier so JSON exports stay consistent when bare constants or mismatched short forms appear in source. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -180,10 +180,14 @@ public final class MachineEnumCanonicalizer {
|
|||||||
String canonical = canonicalizeLabel(
|
String canonical = canonicalizeLabel(
|
||||||
event.fullIdentifier() != null ? event.fullIdentifier() : event.rawName(),
|
event.fullIdentifier() != null ? event.fullIdentifier() : event.rawName(),
|
||||||
enumTypeFqn);
|
enumTypeFqn);
|
||||||
if (canonical.equals(event.fullIdentifier())) {
|
String fnRaw = toFnForm(canonical, enumTypeFqn);
|
||||||
|
if (fnRaw == null) {
|
||||||
|
fnRaw = event.rawName();
|
||||||
|
}
|
||||||
|
if (canonical.equals(event.fullIdentifier()) && fnRaw.equals(event.rawName())) {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
return Event.of(event.rawName(), canonical);
|
return Event.of(fnRaw, canonical);
|
||||||
}
|
}
|
||||||
|
|
||||||
static State canonicalizeState(State state, String enumTypeFqn) {
|
static State canonicalizeState(State state, String enumTypeFqn) {
|
||||||
@@ -200,6 +204,11 @@ public final class MachineEnumCanonicalizer {
|
|||||||
if (isStringOrPrimitiveType(enumTypeFqn) && canonical.startsWith(enumTypeFqn + ".")) {
|
if (isStringOrPrimitiveType(enumTypeFqn) && canonical.startsWith(enumTypeFqn + ".")) {
|
||||||
String constant = canonical.substring(enumTypeFqn.length() + 1);
|
String constant = canonical.substring(enumTypeFqn.length() + 1);
|
||||||
raw = "\"" + constant + "\"";
|
raw = "\"" + constant + "\"";
|
||||||
|
} else {
|
||||||
|
String fnRaw = toFnForm(canonical, enumTypeFqn);
|
||||||
|
if (fnRaw != null) {
|
||||||
|
raw = fnRaw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return State.of(raw, canonical);
|
return State.of(raw, canonical);
|
||||||
}
|
}
|
||||||
@@ -315,4 +324,25 @@ public final class MachineEnumCanonicalizer {
|
|||||||
private static String simpleName(String fqn) {
|
private static String simpleName(String fqn) {
|
||||||
return fqn.contains(".") ? fqn.substring(fqn.lastIndexOf('.') + 1) : fqn;
|
return fqn.contains(".") ? fqn.substring(fqn.lastIndexOf('.') + 1) : fqn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derives {@code EnumFormat.fn} display form ({@code OrderEvent.PAY}) from a package-canonical identifier.
|
||||||
|
*/
|
||||||
|
static String toFnForm(String canonicalFqn, String enumTypeFqn) {
|
||||||
|
if (canonicalFqn == null || canonicalFqn.isBlank() || isStringOrPrimitiveType(enumTypeFqn)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (canonicalFqn.startsWith("<") || canonicalFqn.startsWith("\"")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!canonicalFqn.contains(".")) {
|
||||||
|
return canonicalFqn;
|
||||||
|
}
|
||||||
|
int lastDot = canonicalFqn.lastIndexOf('.');
|
||||||
|
int prevDot = canonicalFqn.lastIndexOf('.', lastDot - 1);
|
||||||
|
if (prevDot > 0) {
|
||||||
|
return canonicalFqn.substring(prevDot + 1);
|
||||||
|
}
|
||||||
|
return simpleName(enumTypeFqn) + "." + canonicalFqn.substring(lastDot + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,10 +51,33 @@ class MachineEnumCanonicalizerTest {
|
|||||||
|
|
||||||
assertThat(transition.getEvent().fullIdentifier())
|
assertThat(transition.getEvent().fullIdentifier())
|
||||||
.isEqualTo("com.example.order.OrderEvent.PAY");
|
.isEqualTo("com.example.order.OrderEvent.PAY");
|
||||||
|
assertThat(transition.getEvent().rawName()).isEqualTo("OrderEvent.PAY");
|
||||||
assertThat(transition.getSourceStates().get(0).fullIdentifier())
|
assertThat(transition.getSourceStates().get(0).fullIdentifier())
|
||||||
.isEqualTo("com.example.order.OrderState.NEW");
|
.isEqualTo("com.example.order.OrderState.NEW");
|
||||||
|
assertThat(transition.getSourceStates().get(0).rawName()).isEqualTo("OrderState.NEW");
|
||||||
assertThat(transition.getTargetStates().get(0).fullIdentifier())
|
assertThat(transition.getTargetStates().get(0).fullIdentifier())
|
||||||
.isEqualTo("com.example.order.OrderState.PAID");
|
.isEqualTo("com.example.order.OrderState.PAID");
|
||||||
|
assertThat(transition.getTargetStates().get(0).rawName()).isEqualTo("OrderState.PAID");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldAlignBareRawNameToFnForm(@TempDir Path tempDir) throws IOException {
|
||||||
|
writeSampleConfig(tempDir);
|
||||||
|
|
||||||
|
CodebaseContext context = new CodebaseContext();
|
||||||
|
context.scan(tempDir);
|
||||||
|
|
||||||
|
StateMachineTypeResolver.MachineTypes types = StateMachineTypeResolver.resolveTypes(
|
||||||
|
"com.example.config.OrderStateMachineConfiguration", context);
|
||||||
|
|
||||||
|
Transition transition = new Transition();
|
||||||
|
transition.setEvent(Event.of("PAY", "PAY"));
|
||||||
|
transition.setSourceStates(List.of(State.of("NEW", "NEW")));
|
||||||
|
|
||||||
|
MachineEnumCanonicalizer.canonicalizeTransitions(List.of(transition), types);
|
||||||
|
|
||||||
|
assertThat(transition.getEvent().rawName()).isEqualTo("OrderEvent.PAY");
|
||||||
|
assertThat(transition.getSourceStates().get(0).rawName()).isEqualTo("OrderState.NEW");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user