From 8098b81cee96f86fbd9708ce57e91b35d25bcc4d Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Tue, 14 Jan 2020 19:38:09 +0100 Subject: [PATCH] improve generation of relation interface --- src/main/jastadd/Analysis.jrag | 8 +- src/main/jastadd/backend/API.jadd | 65 ++++++++++++++++- .../jastadd/backend/BidirectionalAPI.jadd | 73 +++++-------------- src/main/jastadd/backend/DirectedAPI.jadd | 45 ++---------- src/main/jastadd/backend/NameResolution.jadd | 2 +- 5 files changed, 91 insertions(+), 102 deletions(-) diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag index 139bd08..c73a8ca 100644 --- a/src/main/jastadd/Analysis.jrag +++ b/src/main/jastadd/Analysis.jrag @@ -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; @@ -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/backend/API.jadd b/src/main/jastadd/backend/API.jadd index 481bc2d..9476a47 100644 --- a/src/main/jastadd/backend/API.jadd +++ b/src/main/jastadd/backend/API.jadd @@ -1,16 +1,75 @@ 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 (otherSide().isNavigable()) { + if (multiplicityOne() || multiplicityOpt()) { + if (otherSide().multiplicityOne() || otherSide().multiplicityOpt()) { + generateBiOneOne(sb); + } else if (otherSide().multiplicityMany()) { + generateBiOneMany(sb); + } + } else if (multiplicityMany()) { + if (otherSide().multiplicityOne() || otherSide().multiplicityOpt()) { + generateBiManyOne(sb); + } else if (otherSide().multiplicityMany()) { + generateBiManyMany(sb); + } + } + } else { + if (multiplicityOne() || multiplicityOpt()) { + generateDirectedZeroOneAPI(sb); + } else if (multiplicityMany()) { + generateDirectedManyAPI(sb); + } + } + } + + 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(); + + 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/BidirectionalAPI.jadd b/src/main/jastadd/backend/BidirectionalAPI.jadd index 75f28ab..2056683 100644 --- a/src/main/jastadd/backend/BidirectionalAPI.jadd +++ b/src/main/jastadd/backend/BidirectionalAPI.jadd @@ -1,52 +1,13 @@ 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) { + public void RelationComponent.generateBiOneOne(StringBuilder sb) { // Get generateGetOne(sb); // Set sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); - if (!isOpt) { + if (!isOpt()) { sb.append(ind(2) + "assertNotNull(o);\n"); } // unset the old opposite @@ -63,7 +24,7 @@ aspect BackendBidirectionalAPI { sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); if (resolverHelper | serializer) { sb.append(ind(2) + "if (o == null || !o.is$Unresolved()) {\n"); - if (isOpt) { + 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"); @@ -72,7 +33,7 @@ aspect BackendBidirectionalAPI { } sb.append(ind(2) + "}\n"); } else { - if (isOpt) { + 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"); @@ -84,12 +45,12 @@ aspect BackendBidirectionalAPI { sb.append(ind(2) + "return this;\n"); sb.append(ind(1) + "}\n"); - if (isOpt) { + 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) { @@ -115,12 +76,12 @@ aspect BackendBidirectionalAPI { 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) + ASTNode.listClass + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + otherSide().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(6) + "resolvedElement.set" + otherSide().getImplAttributeName() + "(otherList);\n"); sb.append(ind(5) + "}\n"); sb.append(ind(5) + "l.set(i, resolvedElement);\n"); sb.append(ind(4) + "}\n"); @@ -195,7 +156,7 @@ aspect BackendBidirectionalAPI { } - 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) { @@ -221,7 +182,7 @@ aspect BackendBidirectionalAPI { 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) + getTypeUse().decl() + " oldTarget = resolvedElement." + otherSide().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"); @@ -229,7 +190,7 @@ aspect BackendBidirectionalAPI { 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) + "resolvedElement.set" + otherSide().getImplAttributeName() + "(this);\n"); sb.append(ind(7) + "l.set(i, resolvedElement);\n"); sb.append(ind(6) + "}\n"); sb.append(ind(5) + "} else {\n"); @@ -306,14 +267,14 @@ aspect BackendBidirectionalAPI { sb.append(ind(1) + "}\n"); } - public void RelationComponent.generateBiOneMany(StringBuilder sb, boolean isOpt) { + public void RelationComponent.generateBiOneMany(StringBuilder sb) { // Get generateGetOne(sb); // Set sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); - if (!isOpt) { + if (!isOpt()) { sb.append(ind(2) + "assertNotNull(o);\n"); } sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n"); @@ -325,8 +286,8 @@ aspect BackendBidirectionalAPI { 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." @@ -336,13 +297,13 @@ aspect BackendBidirectionalAPI { 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) { + if (isOpt()) { sb.append(ind(2) + "}\n"); } sb.append(ind(2) + "return this;\n"); sb.append(ind(1) + "}\n"); - if (isOpt) { + if (isOpt()) { generateExtraOptAPI(sb); } } diff --git a/src/main/jastadd/backend/DirectedAPI.jadd b/src/main/jastadd/backend/DirectedAPI.jadd index 000c476..9bece4a 100644 --- a/src/main/jastadd/backend/DirectedAPI.jadd +++ b/src/main/jastadd/backend/DirectedAPI.jadd @@ -1,36 +1,25 @@ 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) { + public void RelationComponent.generateDirectedZeroOneAPI(StringBuilder sb) { // Get generateGetOne(sb); // Set sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl()); sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n"); - if (!optional) { + if (!isOpt()) { sb.append(ind(2) + "assertNotNull(o);\n"); } sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n"); sb.append(ind(2) + "return this;\n"); sb.append(ind(1) + "}\n"); + + if (isOpt()) { + generateExtraOptAPI(sb); + } } - 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) { @@ -130,24 +119,4 @@ aspect BackendDirectedAPI { 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/NameResolution.jadd b/src/main/jastadd/backend/NameResolution.jadd index 1d373e9..5819466 100644 --- a/src/main/jastadd/backend/NameResolution.jadd +++ b/src/main/jastadd/backend/NameResolution.jadd @@ -250,7 +250,7 @@ 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(1) + "}\n"); -- GitLab