Documentation and merge behaviour for state files

This commit is contained in:
Johan Maasing 2025-04-19 19:24:45 +02:00
parent a546d257f3
commit cf3ff3f982
6 changed files with 193 additions and 32 deletions

View file

@ -62,23 +62,49 @@ public class StatesVisitorTransformer extends StatesBaseVisitor<StatesParser.Doc
}
public Set<TypeNode> getTypes() {
// TODO calculate data types from NodeTypes and MessageTypes with duplicate check.
HashMap<String, TypeNode> typeNodes = new HashMap<>();
final HashMap<String, TypeNode> stateTypeNodes = new HashMap<>();
this.nodeTypes.forEach(typeNode -> {
if (typeNodes.containsKey(typeNode.name())) {
throw new RuntimeException("Duplicate type name: " + typeNode.name());
if (stateTypeNodes.containsKey(typeNode.name())) {
TypeNode mergedNode = mergeTypeFields(typeNode, stateTypeNodes.get(typeNode.name()));
stateTypeNodes.put(typeNode.name(), mergedNode);
} else {
typeNodes.put(typeNode.name(), typeNode);
stateTypeNodes.put(typeNode.name(), typeNode);
}
}) ;
final HashMap<String, TypeNode> messageTypeNodes = new HashMap<>();
this.messageTypes.forEach(typeNode -> {
if (typeNodes.containsKey(typeNode.name())) {
throw new RuntimeException("Duplicate type name: " + typeNode.name());
if (stateTypeNodes.containsKey(typeNode.name())) {
throw new ParseException("Message " + typeNode.name() + " conflicts with state with the same type name");
}
if (messageTypeNodes.containsKey(typeNode.name())) {
TypeNode mergedNode = mergeTypeFields(typeNode, messageTypeNodes.get(typeNode.name()));
messageTypeNodes.put(typeNode.name(), mergedNode);
} else {
typeNodes.put(typeNode.name(), typeNode);
messageTypeNodes.put(typeNode.name(), typeNode);
}
}) ;
return Set.of(typeNodes.values().toArray(new TypeNode[0])) ;
HashSet<TypeNode> allTypeNodes = new HashSet<>(stateTypeNodes.values());
allTypeNodes.addAll(messageTypeNodes.values());
return allTypeNodes ;
}
private TypeNode mergeTypeFields(TypeNode t1, TypeNode t2) {
List<FieldNode> t1Fields = (t1 != null) ? t1.fields() : List.of() ;
List<FieldNode> t2Fields = (t2 != null) ? t2.fields() : List.of() ;
HashMap<String, FieldNode> mergedFields = new HashMap<>();
t1Fields.forEach(field -> {
if (mergedFields.containsKey(field.name())) {
throw new ParseException("Duplicate field name: " + field.name());
}
mergedFields.put(field.name(), field);
});
t2Fields.forEach(field -> {
if (mergedFields.containsKey(field.name())) {
throw new ParseException("Duplicate field name: " + field.name());
}
mergedFields.put(field.name(), field);
});
return new TypeNode(t1.name(), mergedFields.values().stream().toList()) ;
}
private List<FieldNode> extractFields(StatesParser.TypeDeclarationContext declaration) {

View file

@ -43,12 +43,12 @@ public class EndpointsCLI implements Callable<Integer> {
private Path file;
@SuppressWarnings("CanBeFinal")
@Option(names = {"-t", "--template"}, description = "The template directory. Default is ~/endpoints-templates")
private Path templateDir = Paths.get(System.getProperty("user.dir"), "endpoints-templates");
@Option(names = {"-t", "--template"}, defaultValue = "endpoints-template", description = "The template directory. Default is ${DEFAULT-VALUE}")
private Path templateDir ;
@SuppressWarnings("CanBeFinal")
@Option(names = {"-o", "--output"}, description = "The directory to write the generated code to. Default is ~/endpoints-output")
private Path outputDir = Paths.get(System.getProperty("user.dir"), "endpoints-output");
@Option(names = {"-o", "--output"}, defaultValue = "endpoints-output", description = "The directory to write the generated code to. Default is ${DEFAULT-VALUE}")
private Path outputDir ;
@SuppressWarnings("unused")
@Option(names = {"-v", "--verbose"}, description = "Print verbose debug messages.")