From 1ef3b087daac423ff19d795274171964e3c0fb08 Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Wed, 13 Mar 2019 08:27:50 +0100
Subject: [PATCH] fix relast for the original names and for inherited relations

---
 src/main/jastadd/Analysis.jrag |  9 ++++++
 src/main/jastadd/Backend.jadd  | 53 ++++++++++++++++++++++++----------
 2 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag
index 93573c9..d96c5db 100644
--- a/src/main/jastadd/Analysis.jrag
+++ b/src/main/jastadd/Analysis.jrag
@@ -94,6 +94,15 @@ aspect ComponentAnalysis {
     to TypeDecl.relationComponents()
     for toTypeDecl();
 
+  syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() {
+    ArrayList<RelationComponent> list = new ArrayList<>();
+    if (hasSuper() && getSuper().decl() != null) {
+      list.addAll(getSuper().decl().relationComponentsTransitive());
+    }
+    list.addAll(relationComponents());
+    return list;
+  }
+
   syn Set<OneRelationComponent> TypeDecl.oneRelationComponents() {
     Set<OneRelationComponent> set = new HashSet<>();
     for (RelationComponent rc: relationComponents()) {
diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd
index 7fb0cd2..5439024 100644
--- a/src/main/jastadd/Backend.jadd
+++ b/src/main/jastadd/Backend.jadd
@@ -431,7 +431,7 @@ aspect BackendBidirectionalAPI {
             sb.append(ind(5) + "if (resolvedElement != null && element.asUnresolved().get__resolve_opposite()) {\n");
               sb.append(ind(6) + ASTNode.listClass + "<" + toTypeDecl() + "> otherList = resolvedElement.get" + opposite.getImplAttributeName() + "();\n");
               sb.append(ind(6) + "if (otherList == null) {\n");
-                sb.append(ind(7) + "otherList = new ArrayList<>();\n");
+                sb.append(ind(7) + "otherList = new " + listClass + "<>();\n");
               sb.append(ind(6) + "}\n");
               sb.append(ind(6) + "otherList.add(this);\n");
               sb.append(ind(6) + "resolvedElement.set" + opposite.getImplAttributeName() + "(otherList);\n");
@@ -986,11 +986,18 @@ aspect Serializer {
     sb.append(ind(2) + "throw new SerializationException(\"unable to serialize class \" + this.getClass().getSimpleName());\n");
     sb.append(ind(1) + "}\n");
 
+
     sb.append(ind(1) + "public void ASTNode.serialize(java.io.File file) throws SerializationException {\n");
+    sb.append(ind(2) + "serialize(file, false);\n");
+    sb.append(ind(1) + "}\n");
+
+    sb.append(ind(1) + "public void ASTNode.serialize(java.io.File file, boolean humanReadable) throws SerializationException {\n");
     sb.append(ind(2) + "try {\n");
     sb.append(ind(3) + "com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();\n");
     sb.append(ind(3) + "com.fasterxml.jackson.core.JsonGenerator generator = factory.createGenerator(file, com.fasterxml.jackson.core.JsonEncoding.UTF8);\n");
-    sb.append(ind(3) + "generator.setPrettyPrinter(new com.fasterxml.jackson.core.util.DefaultPrettyPrinter());\n");
+    sb.append(ind(3) + "if (humanReadable) {\n");
+    sb.append(ind(4) + "generator.setPrettyPrinter(new com.fasterxml.jackson.core.util.DefaultPrettyPrinter());\n");
+    sb.append(ind(3) + "}\n");
     sb.append(ind(3) + "serialize(generator);\n");
     sb.append(ind(3) + "generator.close();\n");
     sb.append(ind(2) + "} catch (java.io.IOException e) {\n");
@@ -1045,9 +1052,9 @@ aspect Serializer {
       }
       sb.append(ind(3) + "g.writeEndObject(); // children\n");
     }
-    if (relationComponents().size() > 0) {
+    if (relationComponentsTransitive().size() > 0) {
       sb.append(ind(3) + "g.writeObjectFieldStart(\"relations\");\n");
-      for (RelationComponent relation : relationComponents()) {
+      for (RelationComponent relation : relationComponentsTransitive()) {
         relation.serialize(sb, 3);
       }
       sb.append(ind(3) + "g.writeEndObject(); // relations\n");
@@ -1130,18 +1137,30 @@ aspect Serializer {
   }
 
   public void OneRelationComponent.serialize(StringBuilder sb, int indent) {
-    sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().__uid());\n");
+    if (useJastAddNames){
+      sb.append(ind(indent) + "g.writeStringField(\""+getID()+"\", get" + getID() + "().__uid());\n");
+    } else {
+      sb.append(ind(indent) + "g.writeStringField(\""+getID()+"\", " + getID() + "().__uid());\n");
+    }
   }
 
   public void OptionalRelationComponent.serialize(StringBuilder sb, int indent) {
-    sb.append(ind(indent) + "if (has" + getID() + "()) {\n");
-    sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().__uid());\n");
+    sb.append(ind(indent) + "if (has" + nameCapitalized() + "()) {\n");
+    if (useJastAddNames){
+      sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().__uid());\n");
+    } else {
+      sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().__uid());\n");
+    }
     sb.append(ind(indent) + "}\n");
   }
 
   public void ManyRelationComponent.serialize(StringBuilder sb, int indent) {
     sb.append(ind(indent) + "g.writeArrayFieldStart(\"" + getID() + "\");\n");
-    sb.append(ind(indent) + "for (" + ofTypeDecl().getID() + " child : get" + getID() + "List()) {\n");
+    if (useJastAddNames) {
+      sb.append(ind(indent) + "for (" + ofTypeDecl().getID() + " child : get" + getID() + "List()) {\n");
+    } else {
+      sb.append(ind(indent) + "for (" + ofTypeDecl().getID() + " child : " + getID() + "()) {\n");
+    }
     sb.append(ind(indent + 1) + "g.writeString(child.__uid());\n");
     sb.append(ind(indent) + "}\n");
     sb.append(ind(indent) + "g.writeEndArray();\n");
@@ -1322,10 +1341,14 @@ aspect Serializer {
     sb.append(ind(1) + "}\n");
 
     sb.append(ind(1) + "protected java.util.Map<String, ASTNode> ASTNode.__uidMap(java.util.Map<String, ASTNode> map) {\n");
-    sb.append(ind(2) + "if (map.keySet().contains(__uid())) {\n");
-    sb.append(ind(3) + "throw new RuntimeException(new SerializationException(\"UID \" + this.__uid + \" is not unique\"));\n");
-    sb.append(ind(2) + "} else {\n");
-    sb.append(ind(3) + "map.put(this.__uid, this);\n");
+    sb.append(ind(2) + "if (!(this instanceof " + jastAddListType + " || this instanceof Opt)) {\n");
+    sb.append(ind(3) + "if (map.keySet().contains(__uid())) {\n");
+    sb.append(ind(4) + "throw new RuntimeException(new SerializationException(\"UID \" + this.__uid() + \" is assigned to both " +
+      "\" + this.getClass().getSimpleName() + \":\" + this.hashCode() + \" and " +
+      "\" + map.get(__uid()).getClass().getSimpleName() + \":\" + map.get(__uid()).hashCode()));\n");
+    sb.append(ind(3) + "} else {\n");
+    sb.append(ind(4) + "map.put(this.__uid, this);\n");
+    sb.append(ind(3) + "}\n");
     sb.append(ind(2) + "}\n");
     sb.append(ind(2) + "for (ASTNode child : astChildren()) {\n");
     sb.append(ind(3) + "child.__uidMap(map);\n");
@@ -1348,18 +1371,18 @@ aspect Serializer {
   }
 
   public void OneRelationComponent.deserialize(StringBuilder sb, int indent) {
-    sb.append(ind(indent) + "element.set" + getID() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n");
+    sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n");
     sb.append(ind(indent - 1) + "} else {\n");
     sb.append(ind(indent) + "throw new DeserializationException(\"deserializer of missing mandatory relation child " + getID() + "\");\n");
   }
 
   public void OptionalRelationComponent.deserialize(StringBuilder sb, int indent) {
-    sb.append(ind(indent) + "element.set" + getID() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n");
+    sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n");
   }
 
   public void ManyRelationComponent.deserialize(StringBuilder sb, int indent) {
     sb.append(ind(indent) + "for (" + jsonNodeType + " child : relations.get(\"" + getID() + "\")) {\n");
-    sb.append(ind(indent + 1) + "element.add" + getID() + "(" + ofTypeDecl().getID() + ".createRefDirection(child.asText()));\n");
+    sb.append(ind(indent + 1) + "element.add" + (useJastAddNames?"":"To") + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(child.asText()));\n");
     sb.append(ind(indent) + "}\n");
   }
 }
-- 
GitLab