diff --git a/build.gradle b/build.gradle index aa950e4f313455285a629e034648c856b4c90d93..068c1f63ec3bc3e4f09a87e14198f696307c1bf9 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,7 @@ dependencies { testCompile 'org.assertj:assertj-core:3.12.1' compile 'com.fasterxml.jackson.core:jackson-core:2.9.8' compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8' + compile 'org.jastadd:jastadd:2.3.4' runtime 'org.jastadd:jastadd:2.3.4' compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0' @@ -159,7 +160,7 @@ task firstRelationsRun(type: RelastTest) { grammarName = 'src/test/jastadd/relations/Relations' useJastAddNames = true packageName = 'relations.ast' - moreInputFiles 'src/test/jastadd/Utils.jadd' + moreInputFiles 'src/test/jastadd/Utils.jadd', 'src/test/jastadd/relations/Relations.jrag' } task secondRelationsRun(type: RelastTest, dependsOn: firstRelationsRun) { @@ -185,7 +186,7 @@ task compileDefaultNamesTest(type: RelastTest) { relastFiles 'src/test/jastadd/relations/Relations.relast' grammarName = 'src/test/jastadd/relations/Relations3' packageName = 'defaultnames.ast' - moreInputFiles 'src/test/jastadd/Utils.jadd' + moreInputFiles 'src/test/jastadd/Utils.jadd', 'src/test/jastadd/relations/Relations.jrag' } task compileDefaultNamesResolverTest(type: RelastTest) { @@ -253,6 +254,7 @@ task compileListNamesTest(type: RelastTest) { grammarName = 'src/test/jastadd/listnames/ListNames' useJastAddNames = true jastAddList = 'ListyMcListface' + listClass = 'java.util.LinkedList' packageName = 'listnames.ast' moreInputFiles 'src/test/jastadd/Utils.jadd' } diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag index 139bd082748e4407dbdcbf851f54a8147fba7949..21456331346ac897ee8f597c52e93c1ac8edb498 100644 --- a/src/main/jastadd/Analysis.jrag +++ b/src/main/jastadd/Analysis.jrag @@ -36,13 +36,13 @@ aspect ComponentAnalysis { eq Program.getChild().enclosingTypeDecl() = null; //--- otherSide --- - inh RelationComponent RelationComponent.otherSide(); - eq Relation.getLeft().otherSide() = getRight(); - eq Relation.getRight().otherSide() = getLeft(); - eq Program.getChild().otherSide() = null; + inh RelationComponent RelationComponent.opposite(); + eq Relation.getLeft().opposite() = getRight(); + eq Relation.getRight().opposite() = getLeft(); + eq Program.getChild().opposite() = null; //--- ofTypeDecl --- - syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().getTypeUse().decl(); + syn TypeDecl RelationComponent.ofTypeDecl() = opposite().getTypeUse().decl(); //--- isAlreadyDeclared --- /** @@ -141,7 +141,7 @@ aspect ComponentAnalysis { //--- relationComponentsTransitive --- syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() { - ArrayList<RelationComponent> list = new ArrayList<>(); + Collection<RelationComponent> list = new ArrayList<>(); if (hasSuper() && getSuper().decl() != null) { list.addAll(getSuper().decl().relationComponentsTransitive()); } @@ -170,10 +170,14 @@ aspect ComponentAnalysis { //--- isList --- syn boolean Component.isList() = false; eq ListComponent.isList() = true; + eq NTAListComponent.isList() = true; + eq ManyRelationComponent.isList() = true; //--- isOpt --- syn boolean Component.isOpt() = false; eq OptComponent.isOpt() = true; + eq NTAOptComponent.isOpt() = true; + eq OptionalRelationComponent.isOpt() = true; //--- isNullable --- syn boolean Component.isNullable() = false; @@ -188,7 +192,7 @@ aspect InstanceSupplier { //--- subTypeDecls --- syn Collection<TypeDecl> TypeDecl.subTypeDecls() { - java.util.List<TypeDecl> subDecls = new ArrayList(); + Collection<TypeDecl> subDecls = new ArrayList(); for (TypeDecl decl : program().getTypeDeclList()) { if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) { subDecls.add(decl); @@ -248,10 +252,6 @@ aspect Constructors { aspect Utils { - //--- isMany --- - syn boolean RelationComponent.isMany() = false; - eq ManyRelationComponent.isMany() = true; - //--- toString --- public String SimpleTypeUse.toString() { return getID(); diff --git a/src/main/jastadd/DumpTree.jrag b/src/main/jastadd/DumpTree.jrag index 9193b9334fb63901d8dc985b5e5ba091e6a1e710..2d2f3403c7c03738cd6ff6e4351d22dadc440988 100644 --- a/src/main/jastadd/DumpTree.jrag +++ b/src/main/jastadd/DumpTree.jrag @@ -1,25 +1,18 @@ -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; - -// We have been careful to not import many types here because the imports are added for -// _ALL_ AST nodes and can cause collisions in the abstract grammar namespace. - aspect DumpTree { private static final String ASTNode.DUMP_TREE_INDENT = " "; public String ASTNode.dumpTree() { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - dumpTree(new PrintStream(bytes)); + java.io.ByteArrayOutputStream bytes = new java.io.ByteArrayOutputStream(); + dumpTree(new java.io.PrintStream(bytes)); return bytes.toString(); } - public void ASTNode.dumpTree(PrintStream out) { + public void ASTNode.dumpTree(java.io.PrintStream out) { dumpTree(out, ""); out.flush(); } - public void ASTNode.dumpTree(PrintStream out, String indent) { + public void ASTNode.dumpTree(java.io.PrintStream out, String indent) { out.print(indent + getClass().getSimpleName()); out.print(getTokens()); String extra = extraDumpInfo(); @@ -40,26 +33,21 @@ aspect DumpTree { public String ASTNode.extraDumpInfo() { return ""; } public String ASTNode.getTokens() { - java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>( - new java.util.Comparator<java.lang.reflect.Method>() { - public int compare(java.lang.reflect.Method m1, java.lang.reflect.Method m2) { - return m1.getName().compareTo(m2.getName()); - } - }); + java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>(Comparator.comparing(java.lang.reflect.Method::getName)); methods.addAll(java.util.Arrays.asList(getClass().getMethods())); - String result = ""; + StringBuilder result = new StringBuilder(); for (java.lang.reflect.Method method : methods) { ASTNodeAnnotation.Token token = method.getAnnotation(ASTNodeAnnotation.Token.class); if (token != null) { try { - result += String.format(" %s=\"%s\"", token.name(), method.invoke(this)); - } catch (IllegalAccessException ignored) { - } catch (InvocationTargetException ignored) { + result.append(String.format(" %s=\"%s\"", token.name(), method.invoke(this))); + } catch (IllegalAccessException ignored) { + } catch (java.lang.reflect.InvocationTargetException ignored) { } } } - return result; + return result.toString(); } -} \ No newline at end of file +} diff --git a/src/main/jastadd/backend/API.jadd b/src/main/jastadd/backend/API.jadd index 481bc2dbbea2bb55c7d0fd6f0bf350e739fba416..97be8bc90327168fcc71c54b2d99220a280754b5 100644 --- a/src/main/jastadd/backend/API.jadd +++ b/src/main/jastadd/backend/API.jadd @@ -1,16 +1,105 @@ aspect BackendAPI { public void Relation.generateAPI(StringBuilder sb) { - sb.append(ind(1) + "// " + prettyPrint() + "\n"); - getDirection().generateAPI(sb); + sb.append(ind(1) + "// api for " + prettyPrint() + "\n"); + if (getLeft().isNavigable()) { + sb.append(ind(1) + "// left direction for " + prettyPrint() + "\n"); + getLeft().generateAPI(sb); + } + if (getRight().isNavigable()) { + sb.append(ind(1) + "// right direction for " + prettyPrint() + "\n"); + getRight().generateAPI(sb); + } sb.append("\n"); } - public abstract void Direction.generateAPI(StringBuilder sb); + public void RelationComponent.generateAPI(StringBuilder sb) { + if (opposite().isNavigable()) { + if (multiplicityOne() || multiplicityOpt()) { + generateGetOne(sb); + if (opposite().multiplicityOne() || opposite().multiplicityOpt()) { + generateBiOneOne(sb); + } else if (opposite().multiplicityMany()) { + generateBiOneMany(sb); + } + if (isOpt()) { + generateExtraOptAPI(sb); + } + } else if (multiplicityMany()) { + if (opposite().multiplicityOne() || opposite().multiplicityOpt()) { + generateBiManyOne(sb); + } else if (opposite().multiplicityMany()) { + generateBiManyMany(sb); + } + } + } else { + if (multiplicityOne() || multiplicityOpt()) { + generateGetOne(sb); + generateDirectedZeroOneAPI(sb); + if (isOpt()) { + generateExtraOptAPI(sb); + } + } else if (multiplicityMany()) { + generateDirectedManyAPI(sb); + } + } + } + + public void RelationComponent.generateGetOne(StringBuilder sb) { + sb.append(ind(1) + "public " + ofTypeDecl() + " " + getTypeUse().decl() + "."); + if (useJastAddNames) { + sb.append("get" + nameCapitalized()); + } else { + sb.append(name()); + } + sb.append("() {\n"); + if (resolverHelper | serializer) { + sb.append(ind(2) + "if (" + getImplAttributeField() + " != null && " + getImplAttributeField() + "." + isUnresolvedMethod + "()) {\n"); + sb.append(ind(3) + "if (" + getImplAttributeField() + "." + asUnresolvedMethod + "().get" + unresolvedPrefix + "ResolveOpposite()) {\n"); + sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + resolvePostfix + "(" + getImplAttributeField() + "." + asUnresolvedMethod + "().get" + unresolvedPrefix + "Token()));\n"); + sb.append(ind(3) + "} else {\n"); + sb.append(ind(4) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + resolvePostfix + "(" + getImplAttributeField() + "." + asUnresolvedMethod + "().get" + unresolvedPrefix + "Token()));\n"); + sb.append(ind(3) + "}\n"); + sb.append(ind(2) + "}\n"); + } + sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n"); + sb.append(ind(1) + "}\n"); + } + + public void RelationComponent.generateExtraOptAPI(StringBuilder sb) { + // has + sb.append(ind(1) + "public boolean " + getTypeUse().decl()); + sb.append(".has" + nameCapitalized() + "() {\n"); + sb.append(ind(2) + "return "); + if (useJastAddNames) { + sb.append("get" + nameCapitalized()); + } else { + sb.append(name()); + } + sb.append("() != null;\n"); + sb.append(ind(1) + "}\n"); + + // clear + sb.append(ind(1) + "public void " + getTypeUse().decl()); + sb.append(".clear" + nameCapitalized() + "() {\n"); + sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n"); + sb.append(ind(1) + "}\n"); + } inh Relation Direction.relation(); + inh Relation RelationComponent.relation(); eq Relation.getChild().relation() = this; eq Program.getChild().relation() = null; + inh boolean RelationComponent.isNavigable(); + eq Relation.getLeft().isNavigable() = getDirection().isNavigableLeftToRight(); + eq Relation.getRight().isNavigable() = getDirection().isNavigableRightToLeft(); + eq Program.getChild().isNavigable() = false; + + syn boolean Direction.isNavigableRightToLeft() = true; + eq RightDirection.isNavigableRightToLeft() = false; + syn boolean Direction.isNavigableLeftToRight() = true; + eq LeftDirection.isNavigableLeftToRight() = false; + public String RelationComponent.nameCapitalized() { return name().substring(0,1).toUpperCase() + name().substring(1); } diff --git a/src/main/jastadd/backend/AbstractGrammar.jadd b/src/main/jastadd/backend/AbstractGrammar.jadd index a9728d231ef25162218719dc08a47853003abbdb..b067019d21a52f64e9000c1decd9cbf6bcb080aa 100644 --- a/src/main/jastadd/backend/AbstractGrammar.jadd +++ b/src/main/jastadd/backend/AbstractGrammar.jadd @@ -1,7 +1,9 @@ aspect BackendAbstractGrammar { - public static String ASTNode.listClass = "ArrayList"; + public static String ASTNode.listInterface = "java.util.List"; + public static String ASTNode.listClass = "java.util.ArrayList"; public static String ASTNode.jastAddListType = "List"; + public static String ASTNode.jastAddOptType = "Opt"; public static boolean ASTNode.resolverHelper = false; public static boolean ASTNode.serializer = false; @@ -21,47 +23,6 @@ aspect BackendAbstractGrammar { } } - public void TypeDecl.generateUnresolvedClass(StringBuilder sb) { - if (getAbstract()) { - sb.append(ind(1) + "abstract "); - } else { - sb.append(ind(1)); - } - sb.append("class " + "Unresolved$" + getID() + " extends " + getID() + " implements Unresolved$Node {\n"); - - sb.append(ind(2) + "private String unresolved$Token;\n"); - sb.append(ind(2) + "public String getUnresolved$Token() {\n"); - sb.append(ind(3) + "return unresolved$Token;\n"); - sb.append(ind(2) + "}\n"); - sb.append(ind(2) + "void setUnresolved$Token(String token) {\n"); - sb.append(ind(3) + "this.unresolved$Token = token;\n"); - sb.append(ind(2) + "}\n"); - - sb.append(ind(2) + "private boolean unresolved$ResolveOpposite;\n"); - sb.append(ind(2) + "public boolean getUnresolved$ResolveOpposite() {\n"); - sb.append(ind(3) + "return unresolved$ResolveOpposite;\n"); - sb.append(ind(2) + "}\n"); - sb.append(ind(2) + "void setUnresolved$ResolveOpposite(boolean resolveOpposite) {\n"); - sb.append(ind(3) + "this.unresolved$ResolveOpposite = resolveOpposite;\n"); - sb.append(ind(2) + "}\n"); - - sb.append(ind(1) + "}\n"); - - sb.append(ind(1) + "Unresolved$Node " + getID() + ".as$Unresolved() {\n"); - sb.append(ind(2) + "return null;\n"); - sb.append(ind(1) + "}\n"); - sb.append(ind(1) + "Unresolved$Node Unresolved$" + getID() + ".as$Unresolved() {\n"); - sb.append(ind(2) + "return this;\n"); - sb.append(ind(1) + "}\n"); - - sb.append(ind(1) + "boolean " + getID() + ".is$Unresolved() {\n"); - sb.append(ind(2) + "return false;\n"); - sb.append(ind(1) + "}\n"); - sb.append(ind(1) + "boolean Unresolved$" + getID() + ".is$Unresolved() {\n"); - sb.append(ind(2) + "return true;\n"); - sb.append(ind(1) + "}\n"); - } - public void TypeDecl.generateAbstractGrammar(StringBuilder sb) { if (getAbstract()) { sb.append("abstract "); @@ -119,7 +80,7 @@ aspect BackendAbstractGrammar { return "<" + getImplAttributeName() + ":" + ofTypeDecl() + ">"; } public String ManyRelationComponent.generateAbstractGrammar() { - return "<" + getImplAttributeName() + ":" + ASTNode.listClass + "<" + ofTypeDecl() + ">>"; + return "<" + getImplAttributeName() + ":" + ASTNode.listInterface + "<" + ofTypeDecl() + ">>"; } public String RelationComponent.getImplAttributeName() { @@ -128,11 +89,11 @@ aspect BackendAbstractGrammar { public String RelationComponent.getImplAttributeField() { // tt.bind("TypeInSignature", ASTNode.convTypeNameToSignature(type())); - return "token" + ofTypeDecl() + "__impl_" + getID(); + return "token" + org.jastadd.ast.AST.ASTNode.convTypeNameToSignature(ofTypeDecl().toString()) + "__impl_" + getID(); } public String ManyRelationComponent.getImplAttributeField() { // tt.bind("TypeInSignature", ASTNode.convTypeNameToSignature(type())); - return "token" + listClass + "_" + ofTypeDecl() + "___impl_" + getID(); + return "token" + org.jastadd.ast.AST.ASTNode.convTypeNameToSignature(ASTNode.listInterface) + "_" + ofTypeDecl() + "___impl_" + getID(); } } diff --git a/src/main/jastadd/backend/Backend.jadd b/src/main/jastadd/backend/Backend.jadd index c751488eb18df1a1e59b4a93edebf341bcdea0c0..cc4477d91bac5e0fe442be6130c418c7803abdd7 100644 --- a/src/main/jastadd/backend/Backend.jadd +++ b/src/main/jastadd/backend/Backend.jadd @@ -6,10 +6,6 @@ aspect BackendAspect { } public void Program.generateAspect(StringBuilder sb) { - sb.append("import java.util.ArrayList;\n"); - sb.append("import java.util.Collections;\n"); - sb.append("import java.time.Instant;\n"); - sb.append("import java.time.Period;\n"); sb.append("aspect RelAstAPI {\n"); for (TypeDecl td: getTypeDecls()) { @@ -53,7 +49,7 @@ aspect BackendAspect { return ASTNode.jastAddListType + "<" + getTypeUse() + "> " + getID(); } public String OptComponent.constructorParameter() { - return "Opt<" + getTypeUse() + "> " + getID(); + return ASTNode.jastAddOptType + "<" + getTypeUse() + "> " + getID(); } public String Component.constructorSetMethod() { return "set" + getID(); diff --git a/src/main/jastadd/backend/BidirectionalAPI.jadd b/src/main/jastadd/backend/BidirectionalAPI.jadd index 75f28ab40df71d2690208408e6cb314d9107d886..3ee8f6d4fa5588f36949d770aa7a27560811689f 100644 --- a/src/main/jastadd/backend/BidirectionalAPI.jadd +++ b/src/main/jastadd/backend/BidirectionalAPI.jadd @@ -1,349 +1,261 @@ aspect BackendBidirectionalAPI { - public void Bidirectional.generateAPI(StringBuilder sb) { - RelationComponent l = relation().getLeft(); - RelationComponent r = relation().getRight(); - if (l.multiplicityOne()) { - if (r.multiplicityOne()) { - l.generateBiOneOne(sb, false); - r.generateBiOneOne(sb, false); - } else if (r.multiplicityOpt()) { - l.generateBiOneOne(sb, false); - r.generateBiOneOne(sb, true); - } else if (r.multiplicityMany()) { - l.generateBiOneMany(sb, false); - r.generateBiManyOne(sb, l); - } - } else if (l.multiplicityOpt()) { - if (r.multiplicityOne()) { - l.generateBiOneOne(sb, true); - r.generateBiOneOne(sb, false); - } else if (r.multiplicityOpt()) { - l.generateBiOneOne(sb, true); - r.generateBiOneOne(sb, true); - } else if (r.multiplicityMany()) { - l.generateBiOneMany(sb, true); - r.generateBiManyOne(sb, l); - } - } else if (l.multiplicityMany()) { - if (r.multiplicityOne()) { - l.generateBiManyOne(sb, r); - r.generateBiOneMany(sb, false); - } else if (r.multiplicityOpt()) { - l.generateBiManyOne(sb, r); - r.generateBiOneMany(sb, true); - } else if (r.multiplicityMany()) { - l.generateBiManyMany(sb, r); - r.generateBiManyMany(sb, l); - } - } - } - - public void RelationComponent.generateBiOneOne(StringBuilder sb, boolean isOpt) { - // Get - generateGetOne(sb); + public void RelationComponent.generateBiOneOne(StringBuilder sb) { + boolean resolve = resolverHelper || serializer; // Set - sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); - sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); - if (!isOpt) { + String setMethodDecl = getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + setMethodDecl + " {\n"); + if (!isOpt()) { sb.append(ind(2) + "assertNotNull(o);\n"); } // unset the old opposite - sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n"); - sb.append(ind(3) + "" + getImplAttributeField() + ".set" + otherSide().getImplAttributeName() + "(null);\n"); - sb.append(ind(2) + "}\n"); - if (resolverHelper | serializer) { - sb.append(ind(2) + "if (o != null && !o.is$Unresolved() && o." + otherSide().getImplAttributeField() + " != null) {\n"); - } else { - sb.append(ind(2) + "if (o != null && o." + otherSide().getImplAttributeField() + " != null) {\n"); - } - sb.append(ind(3) + "o." + otherSide().getImplAttributeField() + ".set" + getImplAttributeName() + "(null);\n"); + sb.append(ind(2) + "if (" + getImplAttributeField() + " != null)\n"); + sb.append(ind(3) + getImplAttributeField() + ".set" + opposite().getImplAttributeName() + "(null);\n"); + + sb.append(ind(2) + "if (o != null && " + (resolve ? "!o." + isUnresolvedMethod + "() && o." : "o.") + opposite().getImplAttributeField() + " != null) {\n"); + sb.append(ind(3) + "o." + opposite().getImplAttributeField() + ".set" + getImplAttributeName() + "(null);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); - if (resolverHelper | serializer) { - sb.append(ind(2) + "if (o == null || !o.is$Unresolved()) {\n"); - if (isOpt) { - sb.append(ind(3) + "if (o != null) {\n"); - sb.append(ind(4) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); - sb.append(ind(3) + "}\n"); - } else { - sb.append(ind(3) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); - } - sb.append(ind(2) + "}\n"); - } else { - if (isOpt) { - sb.append(ind(2) + "if (o != null) {\n"); - sb.append(ind(3) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); - sb.append(ind(2) + "}\n"); - } else { - sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); - } + if (resolve) { + sb.append(ind(2) + "if (o == null || !o." + isUnresolvedMethod + "())\n"); } + if (isOpt()) { + sb.append(ind(resolve ? 3 : 2) + "if (o != null)\n"); + } + sb.append(ind((isOpt() ? 1 : 0) + (resolve ? 3 : 2)) + "o.set" + opposite().getImplAttributeName() + "(this);\n"); sb.append(ind(2) + "return this;\n"); sb.append(ind(1) + "}\n"); - - if (isOpt) { - generateExtraOptAPI(sb); - } } - public void RelationComponent.generateBiManyMany(StringBuilder sb, RelationComponent opposite) { + public void RelationComponent.generateBiManyMany(StringBuilder sb) { // Get - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "."); if (useJastAddNames) { + String getMethodDecl1 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "s()"; + String getMethodDecl2 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "List()"; + // getXs - sb.append("get" + nameCapitalized() + "s() {\n"); + sb.append("public " + getMethodDecl1 + " {\n"); sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n"); sb.append(ind(1) + "}\n"); // getXList - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl()); - sb.append(".get" + nameCapitalized() + "List() {\n"); + sb.append(ind(1) + "public " + getMethodDecl2 + " {\n"); } else { - sb.append(name() + "() {\n"); + String getMethodDecl = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "." + name() + "()"; + sb.append("public " + getMethodDecl + " {\n"); } - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); // resolve the entire list 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"); - sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); - sb.append(ind(4) + "if (element.is$Unresolved()) {\n"); - sb.append(ind(5) + "changed = true;\n"); - sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); - sb.append(ind(5) + "if (resolvedElement != null && element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); - sb.append(ind(6) + ASTNode.listClass + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + opposite.getImplAttributeField() + ";\n"); - sb.append(ind(6) + "if (otherList == null) {\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"); - sb.append(ind(5) + "}\n"); - sb.append(ind(5) + "l.set(i, resolvedElement);\n"); - sb.append(ind(4) + "}\n"); - sb.append(ind(3) + "}\n"); - sb.append(ind(3) + "if (changed) {\n"); - sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); - sb.append(ind(3) + "}\n"); + sb.append(ind(3) + "boolean changed = false;\n"); + sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); + sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); + sb.append(ind(4) + "if (element." + isUnresolvedMethod + "()) {\n"); + sb.append(ind(5) + "changed = true;\n"); + sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "" + resolvePostfix + "(element." + asUnresolvedMethod + "().get" + unresolvedTokenMethod + "(), i);\n"); + sb.append(ind(5) + "if (resolvedElement != null && element." + asUnresolvedMethod + "().get" + unresolvedResolveOppositeMethod + "()) {\n"); + sb.append(ind(6) + ASTNode.listInterface + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + opposite().getImplAttributeField() + ";\n"); + sb.append(ind(6) + "if (otherList == null) {\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"); + sb.append(ind(5) + "}\n"); + sb.append(ind(5) + "l.set(i, resolvedElement);\n"); + sb.append(ind(4) + "}\n"); + sb.append(ind(3) + "}\n"); + sb.append(ind(3) + "if (changed) {\n"); + sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); + sb.append(ind(3) + "}\n"); sb.append(ind(2) + "}\n"); } - sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); + sb.append(ind(2) + "return l != null ? java.util.Collections.unmodifiableList(l) : java.util.Collections.emptyList();\n"); sb.append(ind(1) + "}\n"); // Add - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); - if (!useJastAddNames) { - sb.append("To"); - } - sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + String addMethodDecl1 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + addMethodDecl1 + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + otherSide().ofTypeDecl() + "> list2 = o." + otherSide().getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + opposite().ofTypeDecl() + "> list2 = o." + opposite().getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list2 == null) {\n"); sb.append(ind(3) + "list2 = new "+ ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "list.add(o);\n"); sb.append(ind(2) + "list2.add(this);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n"); - sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(list2);\n"); + sb.append(ind(2) + "o.set" + opposite().getImplAttributeName() + "(list2);\n"); sb.append(ind(1) + "}\n"); // Insert / add at specific position - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); - if (!useJastAddNames) { - sb.append("To"); - } - sb.append(nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n"); + String addMethodDecl2 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(int index, " + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + addMethodDecl2 + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + otherSide().ofTypeDecl() + "> list2 = o." - + otherSide().getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + opposite().ofTypeDecl() + "> list2 = o." + opposite().getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list2 == null) {\n"); sb.append(ind(3) + "list2 = new "+ ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "list.add(index, o);\n"); sb.append(ind(2) + "list2.add(this);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n"); - sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(list2);\n"); + sb.append(ind(2) + "o.set" + opposite().getImplAttributeName() + "(list2);\n"); sb.append(ind(1) + "}\n"); // Remove - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove"); - if (!useJastAddNames) { - sb.append("From"); - } - sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + String removeMethodDecl = "void " + getTypeUse().decl() + ".remove" + (useJastAddNames ? "" : "From") + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + removeMethodDecl + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list != null && list.remove(o)) {\n"); - sb.append(ind(3) + ASTNode.listClass + "<" + otherSide().ofTypeDecl() + "> list2 = o." - + otherSide().getImplAttributeField() + ";\n"); + sb.append(ind(3) + ASTNode.listInterface + "<" + opposite().ofTypeDecl() + "> list2 = o." + opposite().getImplAttributeField() + ";\n"); sb.append(ind(3) + "if (list2 != null) list2.remove(this);\n"); sb.append(ind(3) + "set" + getImplAttributeName() + "(list);\n"); - sb.append(ind(3) + "o.set" + otherSide().getImplAttributeName() + "(list2);\n"); + sb.append(ind(3) + "o.set" + opposite().getImplAttributeName() + "(list2);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(1) + "}\n"); } - public void RelationComponent.generateBiManyOne(StringBuilder sb, RelationComponent opposite) { + public void RelationComponent.generateBiManyOne(StringBuilder sb) { // Get - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "."); if (useJastAddNames) { + String getMethodDecl1 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "s()"; + String getMethodDecl2 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "List()"; + // getXs - sb.append("get" + nameCapitalized() + "s() {\n"); + sb.append("public " + getMethodDecl1 + " {\n"); sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n"); sb.append(ind(1) + "}\n"); // getXList - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl()); - sb.append(".get" + nameCapitalized() + "List() {\n"); + sb.append(ind(1) + "public " + getMethodDecl2 + " {\n"); } else { - sb.append(name() + "() {\n"); + String getMethodDecl = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "." + name() + "()"; + sb.append("public " + getMethodDecl + " {\n"); } - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); // resolve the entire list 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"); - sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); - sb.append(ind(4) + "if (element.is$Unresolved()) {\n"); - sb.append(ind(5) + "changed = true;\n"); - sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); - sb.append(ind(5) + "if (element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); - sb.append(ind(6) + getTypeUse().decl() + " oldTarget = resolvedElement." + opposite.getImplAttributeField() + ";\n"); - sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n"); - sb.append(ind(7) + "oldTarget." + getImplAttributeField() + ".remove(resolvedElement);\n"); - sb.append(ind(6) + "}\n"); - sb.append(ind(6) + "if (oldTarget == this) {\n"); - sb.append(ind(7) + "l.remove(i);\n"); - sb.append(ind(7) + "i--;\n"); - sb.append(ind(6) + "} else {\n"); - sb.append(ind(7) + "resolvedElement.set" + opposite.getImplAttributeName() + "(this);\n"); - sb.append(ind(7) + "l.set(i, resolvedElement);\n"); - sb.append(ind(6) + "}\n"); - sb.append(ind(5) + "} else {\n"); - sb.append(ind(6) + "l.set(i, resolvedElement);\n"); - sb.append(ind(5) + "}\n"); - sb.append(ind(4) + "}\n"); - sb.append(ind(3) + "}\n"); - sb.append(ind(3) + "if (changed) {\n"); - sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); - sb.append(ind(3) + "}\n"); + sb.append(ind(3) + "boolean changed = false;\n"); + sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); + sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); + sb.append(ind(4) + "if (element." + isUnresolvedMethod + "()) {\n"); + sb.append(ind(5) + "changed = true;\n"); + sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + resolvePostfix + "(element." + asUnresolvedMethod + "().get" + unresolvedTokenMethod + "(), i);\n"); + sb.append(ind(5) + "if (element." + asUnresolvedMethod + "().get" + unresolvedResolveOppositeMethod + "()) {\n"); + sb.append(ind(6) + getTypeUse().decl() + " oldTarget = resolvedElement." + opposite().getImplAttributeField() + ";\n"); + sb.append(ind(6) + "if (oldTarget != null && oldTarget != this) {\n"); + sb.append(ind(7) + "oldTarget." + getImplAttributeField() + ".remove(resolvedElement);\n"); + sb.append(ind(6) + "}\n"); + sb.append(ind(6) + "if (oldTarget == this) {\n"); + sb.append(ind(7) + "l.remove(i);\n"); + sb.append(ind(7) + "i--;\n"); + sb.append(ind(6) + "} else {\n"); + sb.append(ind(7) + "resolvedElement.set" + opposite().getImplAttributeName() + "(this);\n"); + sb.append(ind(7) + "l.set(i, resolvedElement);\n"); + sb.append(ind(6) + "}\n"); + sb.append(ind(5) + "} else {\n"); + sb.append(ind(6) + "l.set(i, resolvedElement);\n"); + sb.append(ind(5) + "}\n"); + sb.append(ind(4) + "}\n"); + sb.append(ind(3) + "}\n"); + sb.append(ind(3) + "if (changed) {\n"); + sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); + sb.append(ind(3) + "}\n"); sb.append(ind(2) + "}\n"); } - sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); + sb.append(ind(2) + "return l != null ? java.util.Collections.unmodifiableList(l) : java.util.Collections.emptyList();\n"); sb.append(ind(1) + "}\n"); // Add - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); - if (!useJastAddNames) { - sb.append("To"); - } - sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + String addMethodDecl1 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + addMethodDecl1 + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + "if (o != null && o." + otherSide().getImplAttributeField() + " != null) {\n"); - sb.append(ind(3) + ASTNode.listClass + "<" + ofTypeDecl() + "> list2 = o." - + otherSide().getImplAttributeField() + "." + getImplAttributeField() + ";\n"); + sb.append(ind(2) + "if (o != null && o." + opposite().getImplAttributeField() + " != null) {\n"); + sb.append(ind(3) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list2 = o." + opposite().getImplAttributeField() + "." + getImplAttributeField() + ";\n"); sb.append(ind(3) + "if (list2.remove(o))\n"); - sb.append(ind(4) + "o." + otherSide().getImplAttributeField() - + ".set" + getImplAttributeName() + "(list2);\n"); + sb.append(ind(4) + "o." + opposite().getImplAttributeField() + ".set" + getImplAttributeName() + "(list2);\n"); sb.append(ind(2) + "}\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "list.add(o);\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n"); - sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); + sb.append(ind(2) + "o.set" + opposite().getImplAttributeName() + "(this);\n"); sb.append(ind(1) + "}\n"); // Insert / add at specific position - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); - if (!useJastAddNames) { - sb.append("To"); - } - sb.append(nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n"); - sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + "if (o != null && o." + otherSide().getImplAttributeField() + " != null) {\n"); - sb.append(ind(3) + ASTNode.listClass + "<" + ofTypeDecl() + "> list2 = o." + otherSide().getImplAttributeField() + "." + getImplAttributeField() + ";\n"); - sb.append(ind(3) + "if (list2.remove(o))\n"); - sb.append(ind(4) + "o." + otherSide().getImplAttributeField() + ".set" + getImplAttributeName() + "(list2);\n"); - sb.append(ind(2) + "}\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); - sb.append(ind(2) + "if (list == null) {\n"); - sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); - sb.append(ind(2) + "}\n"); - sb.append(ind(2) + "list.add(index, o);\n"); - sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n"); - sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(this);\n"); + String addMethodDecl2 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(int index, " + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + addMethodDecl2 + " {\n"); + sb.append(ind(2) + "assertNotNull(o);\n"); + sb.append(ind(2) + "if (o != null && o." + opposite().getImplAttributeField() + " != null) {\n"); + sb.append(ind(3) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list2 = o." + opposite().getImplAttributeField() + "." + getImplAttributeField() + ";\n"); + sb.append(ind(3) + "if (list2.remove(o))\n"); + sb.append(ind(4) + "o." + opposite().getImplAttributeField() + ".set" + getImplAttributeName() + "(list2);\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + "if (list == null) {\n"); + sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "list.add(index, o);\n"); + sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n"); + sb.append(ind(2) + "o.set" + opposite().getImplAttributeName() + "(this);\n"); sb.append(ind(1) + "}\n"); // Remove - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove"); - if (!useJastAddNames) { - sb.append("From"); - } - sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + String removeMethodDecl = "void " + getTypeUse().decl() + ".remove" + (useJastAddNames ? "" : "From") + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + removeMethodDecl + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list != null && list.remove(o)) {\n"); sb.append(ind(3) + "set" + getImplAttributeName() + "(list);\n"); - sb.append(ind(3) + "if (o." + otherSide().getImplAttributeField() + " == this) {\n"); - sb.append(ind(4) + "o.set" + otherSide().getImplAttributeName() + "(null);\n"); + sb.append(ind(3) + "if (o." + opposite().getImplAttributeField() + " == this) {\n"); + sb.append(ind(4) + "o.set" + opposite().getImplAttributeName() + "(null);\n"); sb.append(ind(3) + "}\n"); sb.append(ind(2) + "}\n"); sb.append(ind(1) + "}\n"); } - public void RelationComponent.generateBiOneMany(StringBuilder sb, boolean isOpt) { - // Get - generateGetOne(sb); - + public void RelationComponent.generateBiOneMany(StringBuilder sb) { // Set - sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() - + "(" + ofTypeDecl() + " o) {\n"); - if (!isOpt) { + String setMethodDecl = getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + setMethodDecl + " {\n"); + if (!isOpt()) { sb.append(ind(2) + "assertNotNull(o);\n"); } sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n"); - sb.append(ind(3) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list2 = " + getImplAttributeField() - + "." + otherSide().getImplAttributeField() + ";\n"); + sb.append(ind(3) + ASTNode.listInterface + "<" + getTypeUse().decl() + "> list2 = " + getImplAttributeField() + "." + opposite().getImplAttributeField() + ";\n"); sb.append(ind(3) + "list2.remove(this);\n"); - sb.append(ind(3) + getImplAttributeField() + "." + "set" - + otherSide().getImplAttributeName() + "(list2);\n"); + sb.append(ind(3) + getImplAttributeField() + "." + "set" + opposite().getImplAttributeName() + "(list2);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); - int ind = isOpt ? 3 : 2; - if (isOpt) { + int ind = isOpt() ? 3 : 2; + if (isOpt()) { sb.append(ind(2) + "if (o != null) {\n"); } - sb.append(ind(ind) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list = o." - + otherSide().getImplAttributeField() + ";\n"); + sb.append(ind(ind) + ASTNode.listInterface + "<" + getTypeUse().decl() + "> list = o." + opposite().getImplAttributeField() + ";\n"); sb.append(ind(ind) + "if (list == null) {\n"); sb.append(ind(ind+1) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(ind) + "}\n"); sb.append(ind(ind) + "list.add(this);\n"); - sb.append(ind(ind) + "o.set" + otherSide().getImplAttributeName() + "(list);\n"); - if (isOpt) { + sb.append(ind(ind) + "o.set" + opposite().getImplAttributeName() + "(list);\n"); + if (isOpt()) { sb.append(ind(2) + "}\n"); } sb.append(ind(2) + "return this;\n"); sb.append(ind(1) + "}\n"); - - if (isOpt) { - generateExtraOptAPI(sb); - } } } diff --git a/src/main/jastadd/backend/DirectedAPI.jadd b/src/main/jastadd/backend/DirectedAPI.jadd index 000c47614ec48abbf110f18090a1d08ec55eb758..3cbc9f0985fec33ccd79b36eb6831af1a6b4fce7 100644 --- a/src/main/jastadd/backend/DirectedAPI.jadd +++ b/src/main/jastadd/backend/DirectedAPI.jadd @@ -1,28 +1,11 @@ aspect BackendDirectedAPI { - public void RightDirection.generateAPI(StringBuilder sb) { - relation().getLeft().generateDirectedAPI(sb); - } - public void LeftDirection.generateAPI(StringBuilder sb) { - relation().getRight().generateDirectedAPI(sb); - } - public abstract void RelationComponent.generateDirectedAPI(StringBuilder sb); - public void OneRelationComponent.generateDirectedAPI(StringBuilder sb) { - generateDirectedZeroOneAPI(sb, false); - } - public void OptionalRelationComponent.generateDirectedAPI(StringBuilder sb) { - generateDirectedZeroOneAPI(sb, true); - - generateExtraOptAPI(sb); - } - public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb, boolean optional) { - // Get - generateGetOne(sb); + public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb) { + String setMethodDecl = getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o)"; // Set - sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); - sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); - if (!optional) { + sb.append(ind(1) + "public " + setMethodDecl + " {\n"); + if (!isOpt()) { sb.append(ind(2) + "assertNotNull(o);\n"); } sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); @@ -30,50 +13,49 @@ aspect BackendDirectedAPI { sb.append(ind(1) + "}\n"); } - public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { + public void RelationComponent.generateDirectedManyAPI(StringBuilder sb) { + // Get - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "."); if (useJastAddNames) { + String getMethodDecl1 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "s()"; + String getMethodDecl2 = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".get" + nameCapitalized() + "List()"; // getXs - sb.append("get" + nameCapitalized() + "s() {\n"); + sb.append(ind(1) + "public " + getMethodDecl1 + " {\n"); sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n"); sb.append(ind(1) + "}\n"); // getXList - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl()); - sb.append(".get" + nameCapitalized() + "List() {\n"); + sb.append(ind(1) + "public " + getMethodDecl2 + " {\n"); } else { - sb.append(name() + "() {\n"); + String getMethodDecl = "java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + "." + name() + "()"; + sb.append("public " + getMethodDecl + " {\n"); } - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); // resolve the entire list 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"); - sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); - sb.append(ind(4) + "if (element.is$Unresolved()) {\n"); - sb.append(ind(5) + "changed = true;\n"); - sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.as$Unresolved().getUnresolved$Token(), i);\n"); - sb.append(ind(5) + "l.set(i, resolvedElement);\n"); - sb.append(ind(4) + "}\n"); - sb.append(ind(3) + "}\n"); - sb.append(ind(3) + "if (changed) {\n"); - sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); - sb.append(ind(3) + "}\n"); + sb.append(ind(3) + "boolean changed = false;\n"); + sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n"); + sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n"); + sb.append(ind(4) + "if (element." + isUnresolvedMethod + "()) {\n"); + sb.append(ind(5) + "changed = true;\n"); + sb.append(ind(5) + ofTypeDecl() + " resolvedElement = " + resolvePrefix + "" + nameCapitalized() + "" + resolvePostfix + "(element." + asUnresolvedMethod + "().get" + unresolvedTokenMethod + "(), i);\n"); + sb.append(ind(5) + "l.set(i, resolvedElement);\n"); + sb.append(ind(4) + "}\n"); + sb.append(ind(3) + "}\n"); + sb.append(ind(3) + "if (changed) {\n"); + sb.append(ind(4) + "set" + getImplAttributeName() + "(l);\n"); + sb.append(ind(3) + "}\n"); sb.append(ind(2) + "}\n"); } - sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); + sb.append(ind(2) + "return l != null ? java.util.Collections.unmodifiableList(l) : java.util.Collections.emptyList();\n"); sb.append(ind(1) + "}\n"); // Add - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); - if (!useJastAddNames) { - sb.append("To"); - } - sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + String addMethodDecl1 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + addMethodDecl1 + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); @@ -82,13 +64,10 @@ aspect BackendDirectedAPI { sb.append(ind(1) + "}\n"); // Insert / add at specific position - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add"); - if (!useJastAddNames) { - sb.append("To"); - } - sb.append(nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n"); + String addMethodDecl2 = "void " + getTypeUse().decl() + ".add" + (useJastAddNames ? "" : "To") + nameCapitalized() + "(int index, " + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + addMethodDecl2 + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list == null) {\n"); sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "}\n"); @@ -97,57 +76,13 @@ aspect BackendDirectedAPI { sb.append(ind(1) + "}\n"); // Remove - sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove"); - if (!useJastAddNames) { - sb.append("From"); - } - sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + String removeMethodDecl = "void " + getTypeUse().decl() + ".remove" + (useJastAddNames ? "" : "From") + nameCapitalized() + "(" + ofTypeDecl() + " o)"; + sb.append(ind(1) + "public " + removeMethodDecl + " {\n"); sb.append(ind(2) + "assertNotNull(o);\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); + sb.append(ind(2) + ASTNode.listInterface + "<" + ofTypeDecl() + "> list = " + getImplAttributeField() + ";\n"); sb.append(ind(2) + "if (list != null && list.remove(o)) {\n"); sb.append(ind(3) + "set" + getImplAttributeName() + "(list);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(1) + "}\n"); } - - public void RelationComponent.generateGetOne(StringBuilder sb) { - sb.append(ind(1) + "public " + ofTypeDecl() + " " + getTypeUse().decl() + "."); - if (useJastAddNames) { - sb.append("get" + nameCapitalized()); - } else { - sb.append(name()); - } - sb.append("() {\n"); - if (resolverHelper | serializer) { - sb.append(ind(2) + "if (" + getImplAttributeField() + " != null && " + getImplAttributeField() + ".is$Unresolved()) {\n"); - sb.append(ind(3) + "if (" + getImplAttributeField() + ".as$Unresolved().getUnresolved$ResolveOpposite()) {\n"); - sb.append(ind(4) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(" + getImplAttributeField() + ".as$Unresolved().getUnresolved$Token()));\n"); - sb.append(ind(3) + "} else {\n"); - sb.append(ind(4) + "set" + getImplAttributeName() + "(resolve" + nameCapitalized() + "ByToken(" + getImplAttributeField() + ".as$Unresolved().getUnresolved$Token()));\n"); - sb.append(ind(3) + "}\n"); - sb.append(ind(2) + "}\n"); - } - sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n"); - sb.append(ind(1) + "}\n"); - } - - public void RelationComponent.generateExtraOptAPI(StringBuilder sb) { - // has - sb.append(ind(1) + "public boolean " + getTypeUse().decl()); - sb.append(".has" + nameCapitalized() + "() {\n"); - sb.append(ind(2) + "return "); - if (useJastAddNames) { - sb.append("get" + nameCapitalized()); - } else { - sb.append(name()); - } - sb.append("() != null;\n"); - sb.append(ind(1) + "}\n"); - - // clear - sb.append(ind(1) + "public void " + getTypeUse().decl()); - sb.append(".clear" + nameCapitalized() + "() {\n"); - sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n"); - sb.append(ind(1) + "}\n"); - } } diff --git a/src/main/jastadd/backend/LowerBoundCheck.jadd b/src/main/jastadd/backend/LowerBoundCheck.jadd index e7690cacca84527435dc09e7e6a1ff6991089795..12c57b676dccb4b706c2e0b694407f3844a26479 100644 --- a/src/main/jastadd/backend/LowerBoundCheck.jadd +++ b/src/main/jastadd/backend/LowerBoundCheck.jadd @@ -6,7 +6,7 @@ aspect LowerBoundCheck { sb.append(ind(1) + "public java.util.List<Pair<ASTNode, String>> " + "ASTNode.getLowerBoundsViolations() {\n"); - sb.append(ind(2) + "ArrayList<Pair<ASTNode, String>> list = new ArrayList<>();\n"); + sb.append(ind(2) + "" + ASTNode.listInterface + "<Pair<ASTNode, String>> list = new " + ASTNode.listClass + "<>();\n"); sb.append(ind(2) + "computeLowerBoundsViolations(list);\n"); sb.append(ind(2) + "return list;\n"); sb.append(ind(1) + "}\n"); diff --git a/src/main/jastadd/backend/NameResolution.jadd b/src/main/jastadd/backend/NameResolution.jadd index 1d373e9e4b4c224bf5c65227182e0c2493197737..9b47dc1cee3a14f4ad114c8028b0f446392ad064 100644 --- a/src/main/jastadd/backend/NameResolution.jadd +++ b/src/main/jastadd/backend/NameResolution.jadd @@ -1,5 +1,61 @@ aspect NameResolutionHelper { + protected static final String ASTNode.unresolvedPrefix = "Unresolved$"; + protected static final String ASTNode.isUnresolvedMethod = "is$Unresolved"; + protected static final String ASTNode.asUnresolvedMethod = "as$Unresolved"; + protected static final String ASTNode.unresolvedTokenMethod = unresolvedPrefix + "Token"; + protected static final String ASTNode.unresolvedResolveOppositeMethod = unresolvedPrefix + "ResolveOpposite"; + protected static final String ASTNode.createReferenceMethod = "createReference"; + protected static final String ASTNode.createRefMethod = "createRef"; + protected static final String ASTNode.createRefDirectionMethod = "createRefDirection"; + protected static final String ASTNode.resolvePrefix = "resolve"; + protected static final String ASTNode.globallyResolvePrefix = "globallyResolve"; + protected static final String ASTNode.resolvePostfix = "ByToken"; + protected static final String ASTNode.resolveAllMethod = "resolveAll"; + protected static final String ASTNode.treeResolveAllMethod = "treeResolveAll"; + protected static final String ASTNode.unresolvedNodeInterface = unresolvedPrefix + "Node$Interface"; + + public void TypeDecl.generateUnresolvedClass(StringBuilder sb) { + if (getAbstract()) { + sb.append(ind(1) + "abstract "); + } else { + sb.append(ind(1)); + } + sb.append("class " + unresolvedPrefix + getID() + " extends " + getID() + " implements " + unresolvedNodeInterface + " {\n"); + + sb.append(ind(2) + "private String unresolved$Token;\n"); + sb.append(ind(2) + "public String get" + unresolvedTokenMethod + "() {\n"); + sb.append(ind(3) + "return unresolved$Token;\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "void set" + unresolvedTokenMethod + "(String token) {\n"); + sb.append(ind(3) + "this.unresolved$Token = token;\n"); + sb.append(ind(2) + "}\n"); + + sb.append(ind(2) + "private boolean unresolved$ResolveOpposite;\n"); + sb.append(ind(2) + "public boolean get" + unresolvedResolveOppositeMethod + "() {\n"); + sb.append(ind(3) + "return unresolved$ResolveOpposite;\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "void set" + unresolvedResolveOppositeMethod + "(boolean resolveOpposite) {\n"); + sb.append(ind(3) + "this.unresolved$ResolveOpposite = resolveOpposite;\n"); + sb.append(ind(2) + "}\n"); + + sb.append(ind(1) + "}\n"); + + sb.append(ind(1) + unresolvedNodeInterface + " " + getID() + "." + asUnresolvedMethod + "() {\n"); + sb.append(ind(2) + "return null;\n"); + sb.append(ind(1) + "}\n"); + sb.append(ind(1) + unresolvedNodeInterface + " " + unresolvedPrefix + getID() + "." + asUnresolvedMethod + "() {\n"); + sb.append(ind(2) + "return this;\n"); + sb.append(ind(1) + "}\n"); + + sb.append(ind(1) + "boolean " + getID() + "." + isUnresolvedMethod + "() {\n"); + sb.append(ind(2) + "return false;\n"); + sb.append(ind(1) + "}\n"); + sb.append(ind(1) + "boolean " + unresolvedPrefix + getID() + "." + isUnresolvedMethod + "() {\n"); + sb.append(ind(2) + "return true;\n"); + sb.append(ind(1) + "}\n"); + } + public String Program.generateRewriteToSuperTypeStub() { StringBuilder sb = new StringBuilder(); generateRewriteToSuperTypeStub(sb); @@ -48,8 +104,8 @@ aspect NameResolutionHelper { public void Program.generateGenericRefCreation(StringBuilder sb) { sb.append(ind(1) + "// generic reference creation\n"); - sb.append(ind(1) + "syn String ASTNode.createReference();\n"); - sb.append(ind(1) + "eq ASTNode.createReference() {\n"); + sb.append(ind(1) + "syn String ASTNode." + createReferenceMethod + "();\n"); + sb.append(ind(1) + "eq ASTNode." + createReferenceMethod + "() {\n"); sb.append(ind(2) + "throw new RuntimeException(\"Generic reference creation not implemented.\");\n"); sb.append(ind(1) + "}\n"); } @@ -74,17 +130,17 @@ aspect NameResolutionHelper { public void RelationComponent.generateContextDependentRefCreation(StringBuilder sb) { sb.append(ind(1) + "// context-dependent reference creation\n"); - sb.append(ind(1) + "syn String " + getTypeUse().decl() + ".createRefTo" + nameCapitalized() + "(" + ofTypeDecl() + " target) {\n"); + sb.append(ind(1) + "syn String " + getTypeUse().decl() + "." + createRefMethod + "To" + nameCapitalized() + "(" + ofTypeDecl() + " target) {\n"); sb.append(ind(2) + "// default to context-independent reference creation\n"); - sb.append(ind(2) + "return target.createReference();\n"); + sb.append(ind(2) + "return target." + createReferenceMethod + "();\n"); sb.append(ind(1) + "}\n"); } public void TypeDecl.generateContextIndependentRefCreation(StringBuilder sb) { sb.append(ind(1) + "// context-independent reference creation\n"); - sb.append(ind(1) + "eq " + getID() + ".createReference() {\n"); + sb.append(ind(1) + "eq " + getID() + "." + createReferenceMethod + "() {\n"); sb.append(ind(2) + "// default to generic reference creation\n"); - sb.append(ind(2) + "return super.createReference();\n"); + sb.append(ind(2) + "return super." + createReferenceMethod + "();\n"); sb.append(ind(1) + "}\n"); } @@ -110,9 +166,9 @@ aspect NameResolutionHelper { sb.append("aspect RefResolverHelpers {\n\n"); - sb.append(ind(1) + "interface Unresolved$Node {\n"); - sb.append(ind(2) + "String getUnresolved$Token();\n"); - sb.append(ind(2) + "boolean getUnresolved$ResolveOpposite();\n"); + sb.append(ind(1) + "interface " + unresolvedNodeInterface + " {\n"); + sb.append(ind(2) + "String get" + unresolvedTokenMethod + "();\n"); + sb.append(ind(2) + "boolean get" + unresolvedResolveOppositeMethod + "();\n"); sb.append(ind(1) + "}\n\n"); for (TypeDecl td: getTypeDecls()) { @@ -131,30 +187,30 @@ aspect NameResolutionHelper { throw new RuntimeException("unable to find instantiable subtype for " + getID()); } - sb.append(ind(1) + "public static " + getID() + " " + getID() + ".createRef(String ref) {\n"); - sb.append(ind(2) + "Unresolved$" + instantiableSubType.getID() + " unresolvedNode = new Unresolved$" + instantiableSubType.getID() + "();\n"); - sb.append(ind(2) + "unresolvedNode.setUnresolved$Token(ref);\n"); - sb.append(ind(2) + "unresolvedNode.setUnresolved$ResolveOpposite(true);\n"); + sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefMethod + "(String ref) {\n"); + sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n"); + sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n"); + sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(true);\n"); sb.append(ind(2) + "return unresolvedNode;\n"); sb.append(ind(1) + "}\n"); - sb.append(ind(1) + "public static " + getID() + " " + getID() + ".createRefDirection(String ref) {\n"); - sb.append(ind(2) + "Unresolved$" + instantiableSubType.getID() + " unresolvedNode = new Unresolved$" + instantiableSubType.getID() + "();\n"); - sb.append(ind(2) + "unresolvedNode.setUnresolved$Token(ref);\n"); - sb.append(ind(2) + "unresolvedNode.setUnresolved$ResolveOpposite(false);\n"); + sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefDirectionMethod + "(String ref) {\n"); + sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n"); + sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n"); + sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(false);\n"); sb.append(ind(2) + "return unresolvedNode;\n"); sb.append(ind(1) + "}\n"); } public void TypeDecl.generateContextIndependentNameResolution(StringBuilder sb) { sb.append(ind(1) + "// context-independent name resolution\n"); - sb.append(ind(1) + "uncache ASTNode.globallyResolve" + getID() + "ByToken(String id);\n"); - sb.append(ind(1) + "syn " + getID() + " ASTNode.globallyResolve" + getID() + "ByToken(String id) {\n"); + sb.append(ind(1) + "uncache ASTNode." + globallyResolvePrefix + getID() + resolvePostfix + "(String id);\n"); + sb.append(ind(1) + "syn " + getID() + " ASTNode." + globallyResolvePrefix + getID() + resolvePostfix + "(String id) {\n"); if (serializer && !manualReferences) { if (jsonPointer) { sb.append(ind(2) + "return (" + getID() + ") resolveJsonPointer(id);\n"); } else { - sb.append(ind(2) + "return (" + getID() + ") globallyResolveASTNodeByUID(id);\n"); + sb.append(ind(2) + "return (" + getID() + ") " + globallyResolvePrefix + "ASTNodeByUID(id);\n"); } } else { sb.append(ind(2) + "// perform context independent name resolution here using the id\n"); @@ -193,56 +249,56 @@ aspect NameResolutionHelper { public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) { if (serializer && !resolverHelper) { - sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n"); - sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n"); + sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id, int position) {\n"); + sb.append(ind(2) + "return (" + ofTypeDecl() + ") " + globallyResolvePrefix + "ASTNodeByUID(id);\n"); sb.append(ind(1) + "}\n"); } else { sb.append(ind(1) + "// context-dependent name resolution\n"); - sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position);\n"); - sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n"); + sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id, int position);\n"); + sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id, int position) {\n"); sb.append(ind(2) + "// default to context-independent name resolution\n"); - sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n"); + sb.append(ind(2) + "return " + globallyResolvePrefix + ofTypeDecl() + resolvePostfix + "(id);\n"); sb.append(ind(1) + "}\n"); } } public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) { if (serializer && !resolverHelper) { - sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n"); - sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n"); + sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id) {\n"); + sb.append(ind(2) + "return (" + ofTypeDecl() + ") " + globallyResolvePrefix + "ASTNodeByUID(id);\n"); sb.append(ind(1) + "}\n"); } else { sb.append(ind(1) + "// context-dependent name resolution\n"); - sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id);\n"); - sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n"); + sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id);\n"); + sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + resolvePostfix + "(String id) {\n"); sb.append(ind(2) + "// default to context-independent name resolution\n"); - sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n"); + sb.append(ind(2) + "return " + globallyResolvePrefix + ofTypeDecl() + resolvePostfix + "(id);\n"); sb.append(ind(1) + "}\n"); } } public void Program.resolveAll(StringBuilder sb) { sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n"); - sb.append(ind(1) + "public void ASTNode.resolveAll() {\n"); + sb.append(ind(1) + "public void ASTNode." + resolveAllMethod + "() {\n"); sb.append(ind(1) + "}\n\n"); sb.append(ind(1) + "// enforce resolving in the entire subtree\n"); - sb.append(ind(1) + "public void ASTNode.treeResolveAll() {\n"); + sb.append(ind(1) + "public void ASTNode." + treeResolveAllMethod + "() {\n"); sb.append(ind(2) + "if (children != null) {\n"); sb.append(ind(3) + "for (int i = 0; i < numChildren; ++i) {\n"); sb.append(ind(4) + "ASTNode child = children[i];\n"); sb.append(ind(4) + "if (child != null) {\n"); - sb.append(ind(5) + "child.treeResolveAll();\n"); + sb.append(ind(5) + "child." + treeResolveAllMethod + "();\n"); sb.append(ind(4) + "}\n"); sb.append(ind(3) + "}\n"); sb.append(ind(2) + "}\n"); - sb.append(ind(2) + "resolveAll();\n"); + sb.append(ind(2) + resolveAllMethod + "();\n"); sb.append(ind(1) + "}\n"); } public void TypeDecl.resolveAll(StringBuilder sb) { sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n"); - sb.append(ind(1) + "public void " + getID() + ".resolveAll() {\n"); + sb.append(ind(1) + "public void " + getID() + "." + resolveAllMethod + "() {\n"); for (RelationComponent relationComponent : relationComponents()) { sb.append(ind(2)); if (useJastAddNames) { @@ -250,9 +306,9 @@ aspect NameResolutionHelper { } else { sb.append(relationComponent.name()); } - sb.append(relationComponent.isMany() && useJastAddNames ? "List" : "").append("();\n"); + sb.append(relationComponent.isList() && useJastAddNames ? "List" : "").append("();\n"); } - sb.append(ind(2) + "super.resolveAll();\n"); + sb.append(ind(2) + "super." + resolveAllMethod + "();\n"); sb.append(ind(1) + "}\n"); } } diff --git a/src/main/jastadd/backend/PrettyPrinting.jadd b/src/main/jastadd/backend/PrettyPrinting.jadd index 49d33b9997f4840e54afe7de2f7dd4ba786bb45d..63c5344546c84ce11800d0171d0bb236b4da9c32 100644 --- a/src/main/jastadd/backend/PrettyPrinting.jadd +++ b/src/main/jastadd/backend/PrettyPrinting.jadd @@ -33,10 +33,10 @@ aspect PrettyPrinting { aspect Utils { public String ASTNode.ind(int n) { - String s = ""; + StringBuilder s = new StringBuilder(); for (int i = 0; i < n; i++) { - s += " "; + s.append(" "); } - return s; + return s.toString(); } } diff --git a/src/main/jastadd/backend/Serializer.jadd b/src/main/jastadd/backend/Serializer.jadd index 90ba24e30df96ba67eb8d3bec543347648d58879..21db37f69f93f2c852528ab334245ce5f3e3d9e0 100644 --- a/src/main/jastadd/backend/Serializer.jadd +++ b/src/main/jastadd/backend/Serializer.jadd @@ -169,10 +169,10 @@ aspect Serializer { case "String": sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "());\n"); break; - case "Instant": + case "java.time.Instant": sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().toString());\n"); break; - case "Period": + case "java.time.Period": sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().toString());\n"); break; default: @@ -209,7 +209,7 @@ aspect Serializer { if (jsonPointer) { sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().jsonPointer());\n"); } else if (manualReferences) { - sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", createRefTo" + getID() + "(" + getID() + "()));\n"); + sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + createRefMethod + "To" + getID() + "(" + getID() + "()));\n"); } else { sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", get" + getID() + "().unique$Id());\n"); } @@ -217,7 +217,7 @@ aspect Serializer { if (jsonPointer) { sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().jsonPointer());\n"); } else if (manualReferences) { - sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", createRefTo" + getID() + "(" + getID() + "()));\n"); + sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + createRefMethod + "To" + getID() + "(" + getID() + "()));\n"); } else { sb.append(ind(indent) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().unique$Id());\n"); } @@ -238,7 +238,7 @@ aspect Serializer { if (jsonPointer) { sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().jsonPointer());\n"); } else if (manualReferences) { - sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + "createRefTo" + getID() + "(" + getID() + "()));\n"); + sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + "" + createRefMethod + "To" + getID() + "(" + getID() + "()));\n"); } else { sb.append(ind(indent + 1) + "g.writeStringField(\"" + getID() + "\", " + getID() + "().unique$Id());\n"); } @@ -256,7 +256,7 @@ aspect Serializer { if (jsonPointer) { sb.append(ind(indent + 1) + "g.writeString(child.jsonPointer());\n"); } else if (manualReferences) { - sb.append(ind(indent + 1) + "g.writeString(createRefTo" + getID() + "(child));\n"); + sb.append(ind(indent + 1) + "g.writeString(" + createRefMethod + "To" + getID() + "(child));\n"); }else { sb.append(ind(indent + 1) + "g.writeString(child.unique$Id());\n"); } @@ -390,11 +390,11 @@ aspect Serializer { case "String": sb.append(ind(indent) + "element.set" + getID() + "(children.get(\"" + getID() + "\").asText());\n"); break; - case "Instant": - sb.append(ind(indent) + "element.set" + getID() + "(Instant.parse(children.get(\"" + getID() + "\").asText()));\n"); + case "java.time.Instant": + sb.append(ind(indent) + "element.set" + getID() + "(java.time.Instant.parse(children.get(\"" + getID() + "\").asText()));\n"); break; - case "Period": - sb.append(ind(indent) + "element.set" + getID() + "(Period.parse(children.get(\"" + getID() + "\").asText()));\n"); + case "java.time.Period": + sb.append(ind(indent) + "element.set" + getID() + "(java.time.Period.parse(children.get(\"" + getID() + "\").asText()));\n"); break; default: // assume that the type is an enum. there is no way of checking this here @@ -565,11 +565,11 @@ aspect Serializer { sb.append(ind(1) + " return null;\n"); sb.append(ind(1) + "}\n"); sb.append("\n"); - sb.append(ind(1) + "ASTNode ASTNode.globallyResolveASTNodeByUID(String uid) {\n"); + sb.append(ind(1) + "ASTNode ASTNode." + globallyResolvePrefix + "ASTNodeByUID(String uid) {\n"); sb.append(ind(2) + "if (getParent() == null) {\n"); sb.append(ind(3) + "return uid$Map().get(uid).get();\n"); sb.append(ind(2) + "} else {\n"); - sb.append(ind(3) + "return getParent().globallyResolveASTNodeByUID(uid);\n"); + sb.append(ind(3) + "return getParent()." + globallyResolvePrefix + "ASTNodeByUID(uid);\n"); sb.append(ind(2) + "}\n"); sb.append(ind(1) + "}\n"); sb.append("\n"); @@ -616,18 +616,18 @@ aspect Serializer { } public void OneRelationComponent.deserialize(StringBuilder sb, int indent) { - sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n"); + sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + "." + createRefMethod + "Direction(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" + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(relations.get(\"" + getID() + "\").asText()));\n"); + sb.append(ind(indent) + "element.set" + nameCapitalized() + "(" + ofTypeDecl().getID() + "." + createRefMethod + "Direction(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" + (useJastAddNames?"":"To") + nameCapitalized() + "(" + ofTypeDecl().getID() + ".createRefDirection(child.asText()));\n"); + sb.append(ind(indent + 1) + "element.add" + (useJastAddNames?"":"To") + nameCapitalized() + "(" + ofTypeDecl().getID() + "." + createRefMethod + "Direction(child.asText()));\n"); sb.append(ind(indent) + "}\n"); } } diff --git a/src/test/jastadd/Utils.jadd b/src/test/jastadd/Utils.jadd index e0e012f21e6b83feffb271ea33b71d83a77e5843..bc836ea2e12f6cbd4e1ff7195039f9e1124c2d07 100644 --- a/src/test/jastadd/Utils.jadd +++ b/src/test/jastadd/Utils.jadd @@ -10,4 +10,4 @@ aspect Utils { public enum Weekday { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } -} \ No newline at end of file +} diff --git a/src/test/jastadd/relations/Relations.jrag b/src/test/jastadd/relations/Relations.jrag new file mode 100644 index 0000000000000000000000000000000000000000..69766fef8f5b5374fce094db182a99ef871c95e5 --- /dev/null +++ b/src/test/jastadd/relations/Relations.jrag @@ -0,0 +1,38 @@ +import java.util.ArrayList; + +aspect NTA { + + // E ::= ... /<NT1>/ ... ; + syn String E.getNT1() = ""; + + // E ::= ... /<NT2:String>/ ... ; + syn String E.getNT2() = ""; + + // E ::= ... /<NT3:boolean>/ ... ; + syn boolean E.getNT3() = false; + + // E ::= ... /<NT4:int>/ ... ; + syn int E.getNT4() = 1; + + // E ::= ... /<NT5:float>/ ... ; + syn float E.getNT5() = 1.0f; + + // E ::= ... /<NT6:double>/ ... ; + syn double E.getNT6() = 1.0d; + + // E ::= ... /<NT7:long>/ ... ; + syn long E.getNT7() = 1l; + + // E ::= ... /[NT8:A]/ ... ; + syn Opt<A> E.getNT8Opt() = new Opt<A>(); + + // E ::= ... /[A]/ ... ; + syn Opt<A> E.getAOpt() = new Opt<A>(); + + // E ::= ... /NT10:A*/ ... ; + syn List<A> E.getNT10List() = new List<A>(); + + // E ::= ... /B*/ ... ; + syn List<B> E.getBList() = new List<B>(); + +} diff --git a/src/test/jastadd/relations/Relations.relast b/src/test/jastadd/relations/Relations.relast index 12f132e5e58968baff38120d79fde1090151acf8..b519a442e963f8fbdd184cec3b006a67e8228f68 100644 --- a/src/test/jastadd/relations/Relations.relast +++ b/src/test/jastadd/relations/Relations.relast @@ -51,9 +51,10 @@ D ::= SingleA:A ListOfA:A* [OptionalA:A] /NTAA:A/ ; // production with tokens, nonterminal-tokens, multi-line E ::= <T1> <T2:String> <T3:boolean> <T4:int> <T5:float> <T6:double> <T7:long> <T8:java.lang.Object> <T9:ArrayList<String>> <T10:java.util.ArrayList<java.lang.String>> - /<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/ ; + /<NT1>/ /<NT2:String>/ /<NT3:boolean>/ /<NT4:int>/ /<NT5:float>/ /<NT6:double>/ /<NT7:long>/ + /[NT8:A]/ /[A]/ /NT10:A*/ /B*/; -rel E.NT1 -> A ; +rel E.R1 -> A ; // inheritance and empty F : A ; diff --git a/src/test/jastadd/serializer-names/Serializer.relast b/src/test/jastadd/serializer-names/Serializer.relast index 6bbd44b8a4ace22be14d9c37b328d903cccda143..9106765c6ee6b8016de898c75efa2f3c38903050 100644 --- a/src/test/jastadd/serializer-names/Serializer.relast +++ b/src/test/jastadd/serializer-names/Serializer.relast @@ -13,8 +13,8 @@ C:NamedElement ::= D1:D [D2:D] D3:D* <C1:char> <C2:Character> <T1:String> <T2> - <N:Instant> - <P:Period> + <N:java.time.Instant> + <P:java.time.Period> <Day:Weekday>; D:NamedElement; diff --git a/src/test/jastadd/serializer/Serializer.relast b/src/test/jastadd/serializer/Serializer.relast index 6bbd44b8a4ace22be14d9c37b328d903cccda143..9106765c6ee6b8016de898c75efa2f3c38903050 100644 --- a/src/test/jastadd/serializer/Serializer.relast +++ b/src/test/jastadd/serializer/Serializer.relast @@ -13,8 +13,8 @@ C:NamedElement ::= D1:D [D2:D] D3:D* <C1:char> <C2:Character> <T1:String> <T2> - <N:Instant> - <P:Period> + <N:java.time.Instant> + <P:java.time.Period> <Day:Weekday>; D:NamedElement;