diff --git a/spec/jastadd/Backend.jadd b/spec/jastadd/Backend.jadd index 2171c5dc13cbf785a49a40a960c13f87853985d7..bcc9c37ab7ff60f4a39664ba0d5c137cb265dd78 100644 --- a/spec/jastadd/Backend.jadd +++ b/spec/jastadd/Backend.jadd @@ -163,9 +163,10 @@ aspect BackendDirectedAPI { public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) { // Get - sb.append(ind(1) + "public Collection<" + ofTypeDecl() + "> " + toTypeDecl()); + sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); sb.append("." + name() + "() {\n"); - sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "ArrayList<List> l = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "return l != null ? l : Collections.emptyList();\n"); sb.append(ind(1) + "}\n"); // Add @@ -223,7 +224,8 @@ aspect BackendBidirectionalAPI { } else if (r.multiplicityOpt()) { } else if (r.multiplicityMany()) { - + l.generateBiMany(sb); + r.generateBiMany(sb); } } } @@ -265,6 +267,49 @@ aspect BackendBidirectionalAPI { sb.append(ind(1) + "}\n"); } } + + public void RelationComponent.generateBiMany(StringBuilder sb) { + // Get + sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl()); + sb.append("." + name() + "() {\n"); + sb.append(ind(2) + "ArrayList<" + ofTypeDecl() + "> l = get" + + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "return l != null ? l : Collections.emptyList();\n"); + sb.append(ind(1) + "}\n"); + + // Add + sb.append(ind(1) + "public void " + toTypeDecl() + ".addTo"); + sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + sb.append(ind(2) + "assertNotNull(o);\n"); + sb.append(ind(2) + "ArrayList<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "if (list == null) {\n"); + sb.append(ind(3) + "list = new ArrayList<>();\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "ArrayList<" + otherSide().ofTypeDecl() + "> list2 = o.get" + + otherSide().getImplAttributeName() + "();\n"); + sb.append(ind(2) + "if (list2 == null) {\n"); + sb.append(ind(3) + "list2 = new ArrayList<>();\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(1) + "}\n"); + + // Remove + sb.append(ind(1) + "public void " + toTypeDecl() + ".removeFrom"); + sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); + sb.append(ind(2) + "assertNotNull(o);\n"); + sb.append(ind(2) + "ArrayList<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n"); + sb.append(ind(2) + "if (list != null && list.remove(o)) {\n"); + sb.append(ind(3) + "ArrayList<" + otherSide().ofTypeDecl() + "> list2 = o.get" + + otherSide().getImplAttributeName() + "();\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(2) + "}\n"); + sb.append(ind(1) + "}\n"); + } } diff --git a/test/Test.java b/test/Test.java index 38ae7956f7e0c4828775a2754fb6698add244c8e..5a1b321240e91ddc55cc7cd40fbe449f665c5314 100644 --- a/test/Test.java +++ b/test/Test.java @@ -1,4 +1,5 @@ import AST.*; +import java.util.*; public class Test { private Root r; @@ -211,6 +212,36 @@ public class Test { * rel A.b9* <-> B.a9*; */ private void test9() { + setup(); + a1.addToB9(b1); + a1.addToB9(b2); + + assertEquals(a1.b9(), Arrays.asList(b1, b2)); + assertEquals(a2.b9(), Arrays.asList()); + assertEquals(a3.b9(), Arrays.asList()); + assertEquals(b1.a9(), Arrays.asList(a1)); + assertEquals(b2.a9(), Arrays.asList(a1)); + assertEquals(b3.a9(), Arrays.asList()); + + b3.addToA9(a1); + b3.addToA9(a3); + b3.addToA9(a1); + + assertEquals(a1.b9(), Arrays.asList(b1, b2, b3, b3)); + assertEquals(a2.b9(), Arrays.asList()); + assertEquals(a3.b9(), Arrays.asList(b3)); + assertEquals(b1.a9(), Arrays.asList(a1)); + assertEquals(b2.a9(), Arrays.asList(a1)); + assertEquals(b3.a9(), Arrays.asList(a1, a3, a1)); + + b3.removeFromA9(a1); + + assertEquals(a1.b9(), Arrays.asList(b1, b2, b3)); + assertEquals(a2.b9(), Arrays.asList()); + assertEquals(a3.b9(), Arrays.asList(b3)); + assertEquals(b1.a9(), Arrays.asList(a1)); + assertEquals(b2.a9(), Arrays.asList(a1)); + assertEquals(b3.a9(), Arrays.asList(a3, a1)); } @@ -233,15 +264,17 @@ public class Test { } private void assertNull(Object obj) { - check(obj == null); + check(obj == null, "Object not null: " + obj); } private void assertSame(Object o1, Object o2) { - check(o1 == o2); + check(o1 == o2, "Objects not same: " + o1 + ", " + o2); } - - private void check(boolean b) { + private void assertEquals(Object o1, Object o2) { + check(o1.equals(o2), "Objects not equals: " + o1 + ", " + o2); + } + private void check(boolean b, String message) { if (!b) { - throw new RuntimeException(); + throw new RuntimeException(message); } }