diff --git a/.gitignore b/.gitignore index d84ffeed9a4cc08ae800a42ddd2d9d446b11e678..febce236986fe6c4520d73c3aef799915ca9be2e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ src/test/jastadd/serializer/Serializer.ast src/test/jastadd/serializer/Serializer.jadd src/test/jastadd/serializer/SerializerSerializer.jadd src/test/jastadd/serializer/SerializerRefResolver.jadd +src/test/jastadd/serializer/SerializerResolverStubs.jrag diff --git a/build.gradle b/build.gradle index be8ffdec62de203a3abb621cbb96a04ce61f7b36..020c1756b4c385a85a4c1c9916e79b658edb6775 100644 --- a/build.gradle +++ b/build.gradle @@ -294,7 +294,9 @@ task preprocessSerializerTest(type: JavaExec, group: 'verification') { delete 'src/test/jastadd/serializer/Serializer.ast', 'src/test/jastadd/serializer/Serializer.jadd', 'src/test/jastadd/serializer/SerializerRefResolver.jadd', - 'src/test/jastadd/serializer/SerializerSerializer.jadd' + 'src/test/jastadd/serializer/SerializerSerializer.jadd', + 'src/test/jastadd/serializer/SerializerRefResolver.jadd', + 'src/test/jastadd/serializer/SerializerResolverStubs.jrag' } classpath = sourceSets.main.runtimeClasspath @@ -317,6 +319,7 @@ task compileSerializerTest(type: JavaExec, group: 'verification') { 'src/test/jastadd/serializer/Serializer.jadd', 'src/test/jastadd/serializer/SerializerRefResolver.jadd', 'src/test/jastadd/serializer/SerializerSerializer.jadd', + 'src/test/jastadd/serializer/SerializerResolverStubs.jrag', 'src/test/jastadd/Utils.jadd' } diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd index c33893c3aec0ba7c50e507c6d544016880560779..9b0fce85551bc2895b89c6f07f915a92dfeccee1 100644 --- a/src/main/jastadd/Backend.jadd +++ b/src/main/jastadd/Backend.jadd @@ -200,7 +200,7 @@ aspect BackendDirectedAPI { sb.append(".get" + nameCapitalized() + "List() {\n"); sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); // resolve the entire list - if (resolverHelper) { + if (resolverHelper | serializer) { sb.append(ind(2) + "if (l != null) {\n"); sb.append(ind(3) + "boolean changed = false;\n"); sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); @@ -256,7 +256,7 @@ aspect BackendDirectedAPI { public void RelationComponent.generateGetOne(StringBuilder sb) { sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl()); sb.append(".get" + nameCapitalized() + "() {\n"); - if (resolverHelper) { + if (resolverHelper | serializer) { sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null && get" + getImplAttributeName() + "().unresolved()) {\n"); sb.append(ind(3) + "if (get" + getImplAttributeName() + "().asUnresolved().get__resolve_opposite()) {\n"); sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(get" + getImplAttributeName() + "().asUnresolved().get__token()));\n"); @@ -339,7 +339,7 @@ aspect BackendBidirectionalAPI { sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null) {\n"); sb.append(ind(3) + "get" + getImplAttributeName() + "().set" + otherSide().getImplAttributeName() + "(null);\n"); sb.append(ind(2) + "}\n"); - if (resolverHelper) { + if (resolverHelper | serializer) { sb.append(ind(2) + "if (!o.unresolved() && o != null && o.get" + otherSide().getImplAttributeName() + "() != null) {\n"); } else { sb.append(ind(2) + "if (o != null && o.get" + otherSide().getImplAttributeName() + "() != null) {\n"); @@ -347,7 +347,7 @@ aspect BackendBidirectionalAPI { sb.append(ind(3) + "o.get" + otherSide().getImplAttributeName() + "().set" + getImplAttributeName() + "(null);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); - if (resolverHelper) { + if (resolverHelper | serializer) { sb.append(ind(2) + "if (!o.unresolved()) {\n"); if (isOpt) { sb.append(ind(3) + "if (o != null) {\n"); @@ -388,7 +388,7 @@ aspect BackendBidirectionalAPI { sb.append(".get" + nameCapitalized() + "List() {\n"); sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); // resolve the entire list - if (resolverHelper) { + if (resolverHelper | serializer) { sb.append(ind(2) + "if (l != null) {\n"); sb.append(ind(3) + "boolean changed = false;\n"); sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); @@ -481,7 +481,7 @@ aspect BackendBidirectionalAPI { sb.append(".get" + nameCapitalized() + "List() {\n"); sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); // resolve the entire list - if (resolverHelper) { + if (resolverHelper | serializer) { sb.append(ind(2) + "if (l != null) {\n"); sb.append(ind(3) + "boolean changed = false;\n"); sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); @@ -801,8 +801,12 @@ aspect NameResolutionHelper { sb.append(ind(1) + "// context-independent name resolution\n"); sb.append(ind(1) + "syn " + superType + " ASTNode.globallyResolve" + superType + "ByToken(String id) {\n"); + if (serializer) { + sb.append(ind(2) + "return (" + superType + ") globallyResolveASTNodeByUID(id);\n"); + } else { sb.append(ind(2) + "// perform context independent name resolution here using the id\n"); - sb.append(ind(2) + "throw new RuntimeException(\"Context-independent name resolution for "+ superType + " not implemented.\");\n"); + sb.append(ind(2) + "throw new RuntimeException(\"Context-independent name resolution for " + superType + " not implemented.\");\n"); + } sb.append(ind(1) + "}\n"); } @@ -1236,6 +1240,28 @@ aspect Serializer { sb.append(ind(1) + "protected String ASTNode.serializationID() {\n"); sb.append(ind(2) + "return null;\n"); sb.append(ind(1) + "}\n"); + + sb.append(ind(1) + "syn ASTNode ASTNode.globallyResolveASTNodeByUID(String uid) {\n"); + sb.append(ind(2) + "if (getParent() == null) {\n"); + sb.append(ind(3) + "return __uidMap().get(uid);\n"); + sb.append(ind(2) + "} else {\n"); + sb.append(ind(3) + "return getParent().globallyResolveASTNodeByUID(uid);\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(1) + "}\n"); + + sb.append(ind(1) + "syn java.util.Map<String, ASTNode> ASTNode.__uidMap() {\n"); + sb.append(ind(2) + "return(__uidMap(new java.util.HashMap()));\n"); + 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) + "map.put(this.__uid, this);\n"); + sb.append(ind(2) + "for (ASTNode child : astChildren()) {\n"); + sb.append(ind(3) + "child.__uidMap(map);\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "return map;\n"); + sb.append(ind(1) + "}\n"); + + sb.append("}\n"); } diff --git a/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/Compiler.java index 9c6c23bc753d3516e2a639d9e9beb2e51c2e2eb5..533b30d02bcffc1949207d4e24fc19a1ac925189 100644 --- a/src/main/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/main/java/org/jastadd/relast/compiler/Compiler.java @@ -96,7 +96,7 @@ public class Compiler { } } - if (optionResolverHelper.isSet()) { + if (optionResolverHelper.isSet() || optionSerializer.isSet()) { ASTNode.resolverHelper = true; writeToFile(grammarName + "ResolverStubs.jrag", p.generateResolverStubs()); }