diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd index 569d61b473639b9ef0ad2146b96543ab66109d5a..b285919da1c5cdb9a04de7ec16863e06c330c861 100644 --- a/src/main/jastadd/Backend.jadd +++ b/src/main/jastadd/Backend.jadd @@ -187,7 +187,31 @@ aspect BackendDirectedAPI { public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { // Get - generateGetMany(sb); + // getXs + sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); + sb.append(".get" + nameCapitalized() + "s() {\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() + "> " + toTypeDecl()); + sb.append(".get" + nameCapitalized() + "List() {\n"); + sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); + // resolve the entire list + if (resolverHelper) { + sb.append(ind(2) + "if (l != null) {\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.unresolved()) {\n"); + sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__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) + "set" + getImplAttributeName() + "(l);\n"); + sb.append(ind(2) + "}\n"); + } + sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); + sb.append(ind(1) + "}\n"); // Add sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); @@ -237,36 +261,6 @@ aspect BackendDirectedAPI { sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n"); sb.append(ind(1) + "}\n"); } - - public void RelationComponent.generateGetMany(StringBuilder sb) { - // getXs - sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); - sb.append(".get" + nameCapitalized() + "s() {\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() + "> " + toTypeDecl()); - sb.append(".get" + nameCapitalized() + "List() {\n"); - sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" - + getImplAttributeName() + "();\n"); - // resolve the entire list - if (resolverHelper) { - sb.append(ind(2) + "int removedElements = 0;\n"); - sb.append(ind(2) + "if (l != null) {\n"); - sb.append(ind(3) + "for (int i = 0; i < l.size() - removedElements; i++) {\n"); - sb.append(ind(4) + "if (get" + getImplAttributeName() + "().get(i) != null && get" + getImplAttributeName() + "().get(i).unresolved()) {\n"); - sb.append(ind(5) + ofTypeDecl() + " element = l.remove(i);\n"); - sb.append(ind(5) + "add" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i));\n"); - sb.append(ind(5) + "i--; // go back an index, because we removed an element\n"); - sb.append(ind(5) + "removedElements++; // no need to iterate over the removed elements again\n"); - sb.append(ind(4) + "}\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(1) + "}\n"); - } } aspect BackendBidirectionalAPI { @@ -321,11 +315,7 @@ aspect BackendBidirectionalAPI { sb.append(ind(2) + "assertNotNull(o);\n"); } // unset the old opposite -// if (resolverHelper) { -// sb.append(ind(2) + "if (!o.unresolved() && get" + getImplAttributeName() + "() != null) {\n"); -// } else { - sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null) {\n"); -// } + 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) { @@ -365,7 +355,39 @@ aspect BackendBidirectionalAPI { public void RelationComponent.generateBiManyMany(StringBuilder sb) { // Get - generateGetMany(sb); + // getXs + sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); + sb.append(".get" + nameCapitalized() + "s() {\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() + "> " + toTypeDecl()); + sb.append(".get" + nameCapitalized() + "List() {\n"); + sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); + // resolve the entire list + if (resolverHelper) { + sb.append(ind(2) + "if (l != null) {\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.unresolved()) {\n"); + sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n"); + sb.append(ind(5) + "if (resolvedElement != null) {\n"); + sb.append(ind(6) + ASTNode.listClass + "<" + toTypeDecl() + "> otherList = resolvedElement.get" + getImplAttributeName() + "();\n"); + sb.append(ind(6) + "if (otherList == null) {\n"); + sb.append(ind(7) + "otherList = new ArrayList<>();\n"); + sb.append(ind(6) + "}\n"); + sb.append(ind(6) + "otherList.add(this);\n"); + sb.append(ind(6) + "resolvedElement.set" + 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) + "set" + getImplAttributeName() + "(l);\n"); + sb.append(ind(2) + "}\n"); + } + sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); + sb.append(ind(1) + "}\n"); // Add sb.append(ind(1) + "public void " + toTypeDecl() + ".add"); @@ -404,7 +426,41 @@ aspect BackendBidirectionalAPI { public void RelationComponent.generateBiManyOne(StringBuilder sb) { // Get - generateGetMany(sb); + // getXs + sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); + sb.append(".get" + nameCapitalized() + "s() {\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() + "> " + toTypeDecl()); + sb.append(".get" + nameCapitalized() + "List() {\n"); + sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n"); + // resolve the entire list + if (resolverHelper) { + sb.append(ind(2) + "if (l != null) {\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.unresolved()) {\n"); + sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n"); + sb.append(ind(5) + toTypeDecl() + " oldTarget = resolvedElement.get" + getImplAttributeName() + "();\n"); + sb.append(ind(5) + "if (oldTarget != null && oldTarget != this) {\n"); + sb.append(ind(6) + "oldTarget.get" + getImplAttributeName() + "().remove(resolvedElement);\n"); + sb.append(ind(5) + "}\n"); + sb.append(ind(5) + "if (oldTarget == this) {\n"); + sb.append(ind(6) + "l.remove(i);\n"); + sb.append(ind(6) + "i--;\n"); + sb.append(ind(5) + "} else {\n"); + sb.append(ind(6) + "resolvedElement.set" + getImplAttributeName() + "(this);\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) + "set" + getImplAttributeName() + "(l);\n"); + sb.append(ind(2) + "}\n"); + } + sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n"); + sb.append(ind(1) + "}\n"); // Add sb.append(ind(1) + "public void " + toTypeDecl() + ".add");