Skip to content
Snippets Groups Projects
Commit a4c49252 authored by Niklas Fors's avatar Niklas Fors
Browse files

Add part implementation of bidirectional and add test case

parent 019406f5
No related branches found
No related tags found
No related merge requests found
.DS_Store
.class
*.class
.vimrc
.*.swp
*.relast
/*.relast
/.settings
/bin/
......
......@@ -32,10 +32,13 @@ aspect ComponentAnalysis {
inh TypeDecl Component.enclosingTypeDecl();
eq TypeDecl.getChild().enclosingTypeDecl() = this;
eq Program.getChild().enclosingTypeDecl() = null;
inh TypeDecl RelationComponent.ofTypeDecl();
eq Relation.getLeft().ofTypeDecl() = getRight().toTypeDecl();
eq Relation.getRight().ofTypeDecl() = getLeft().toTypeDecl();
eq Program.getChild().ofTypeDecl() = null;
inh RelationComponent RelationComponent.otherSide();
eq Relation.getLeft().otherSide() = getRight();
eq Relation.getRight().otherSide() = getLeft();
eq Program.getChild().otherSide() = null;
syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().toTypeDecl();
syn boolean Component.isAlreadyDeclared()
= !isTargetOfDirectedRelation()
......
......@@ -112,13 +112,23 @@ aspect BackendAPI {
public void Relation.generateAPI(StringBuilder sb) {
sb.append(ind(1) + "// " + prettyPrint() + "\n");
getDirection().generateAPI(sb);
sb.append("\n");
}
public abstract void Direction.generateAPI(StringBuilder sb);
public void RightDirection.generateAPI(StringBuilder sb) {
relation().getLeft().generateDirectedAPI(sb);
inh Relation Direction.relation();
eq Relation.getChild().relation() = this;
eq Program.getChild().relation() = null;
public String RelationComponent.nameCapitalized() {
return name().substring(0,1).toUpperCase() + name().substring(1);
}
}
public void Bidirectional.generateAPI(StringBuilder sb) {
aspect BackendDirectedAPI {
public void RightDirection.generateAPI(StringBuilder sb) {
relation().getLeft().generateDirectedAPI(sb);
}
public abstract void RelationComponent.generateDirectedAPI(StringBuilder sb);
......@@ -180,16 +190,84 @@ aspect BackendAPI {
sb.append(ind(2) + "}\n");
sb.append(ind(1) + "}\n");
}
}
inh Relation Direction.relation();
eq Relation.getChild().relation() = this;
eq Program.getChild().relation() = null;
aspect BackendBidirectionalAPI {
public void Bidirectional.generateAPI(StringBuilder sb) {
RelationComponent l = relation().getLeft();
RelationComponent r = relation().getRight();
public String RelationComponent.nameCapitalized() {
return name().substring(0,1).toUpperCase() + name().substring(1);
if (l.multiplicityOne()) {
if (r.multiplicityOne()) {
l.generateBiOne(sb, false);
r.generateBiOne(sb, false);
} else if (r.multiplicityOpt()) {
l.generateBiOne(sb, false);
r.generateBiOne(sb, true);
} else if (r.multiplicityMany()) {
}
} else if (l.multiplicityOpt()) {
if (r.multiplicityOne()) {
l.generateBiOne(sb, true);
r.generateBiOne(sb, false);
} else if (r.multiplicityOpt()) {
l.generateBiOne(sb, true);
r.generateBiOne(sb, true);
} else if (r.multiplicityMany()) {
}
} else if (l.multiplicityMany()) {
if (r.multiplicityOne()) {
} else if (r.multiplicityOpt()) {
} else if (r.multiplicityMany()) {
}
}
}
public void RelationComponent.generateBiOne(StringBuilder sb, boolean isOpt) {
// Get
sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl());
sb.append("." + name() + "() {\n");
sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n");
sb.append(ind(1) + "}\n");
// Set
sb.append(ind(1) + "public void " + toTypeDecl());
sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
if (!isOpt) {
sb.append(ind(2) + "assertNotNull(o);\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");
sb.append(ind(2) + "if (o != null && o.get" + otherSide().getImplAttributeName() + "() != null) {\n");
sb.append(ind(3) + "o.get" + otherSide().getImplAttributeName() + "().set" + getImplAttributeName() + "(null);\n");
sb.append(ind(2) + "}\n");
sb.append(ind(2) + "set" + getImplAttributeName() + "(o);\n");
if (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");
}
sb.append(ind(1) + "}\n");
if (isOpt) {
// has
sb.append(ind(1) + "public boolean " + toTypeDecl());
sb.append(".has" + nameCapitalized() + "() {\n");
sb.append(ind(2) + "return " + name() + "() != null;\n");
sb.append(ind(1) + "}\n");
}
}
}
aspect PrettyPrint {
public String Relation.prettyPrint() {
return "rel "
......
......@@ -32,7 +32,7 @@ aspect Errors {
RelationComponent contributes
error("The target of a directed relation may only have multiplicity 1")
when isTargetOfDirectedRelation() && !hasMultiplicityOne()
when isTargetOfDirectedRelation() && !multiplicityOne()
to Program.errors();
}
......@@ -44,8 +44,12 @@ aspect HelpAttributes {
eq Program.getChild().isToken() = false;
eq TokenComponent.getTypeUse().isToken() = true;
syn boolean RelationComponent.hasMultiplicityOne() = false;
eq OneRelationComponent.hasMultiplicityOne() = true;
syn boolean RelationComponent.multiplicityOne() = false;
eq OneRelationComponent.multiplicityOne() = true;
syn boolean RelationComponent.multiplicityOpt() = false;
eq OptionalRelationComponent.multiplicityOpt() = true;
syn boolean RelationComponent.multiplicityMany() = false;
eq ManyRelationComponent.multiplicityMany() = true;
}
aspect ErrorMessage {
......
/AST/*
/AllBiGen.ast
/AllBiGen.jadd
Root ::= A* B*;
A ::= <Name>;
B ::= <Name>;
rel A.b1 <-> B.a1;
rel A.b2 <-> B.a2?;
rel A.b3 <-> B.a3*;
rel A.b4? <-> B.a4;
rel A.b5? <-> B.a5?;
rel A.b6? <-> B.a6*;
rel A.b7* <-> B.a7;
rel A.b8* <-> B.a8?;
rel A.b9* <-> B.a9*;
all: compile run
compile:
(cd .. && ant jar)
java -jar ../compiler.jar AllBi.relast --file
java -jar ../tools/jastadd2.jar --package=AST AllBiGen.ast AllBiGen.jadd Utils.jadd
run:
javac AST/*.java Test.java
java Test
\ No newline at end of file
import AST.*;
public class Test {
private Root r;
private A a1;
private A a2;
private A a3;
private B b1;
private B b2;
private B b3;
public static void main(String args[]) {
new Test().test();
}
public void test() {
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
}
/**
* rel A.b1 <-> B.a1;
*/
private void test1() {
test11();
test12();
}
private void test11() {
// Init
setup();
a1.setB1(b1);
a2.setB1(b2);
// Change
a2.setB1(b1);
assertNull(a1.b1());
assertSame(a2.b1(), b1);
assertSame(b1.a1(), a2);
assertNull(b2.a1());
}
private void test12() {
// Init
setup();
a1.setB1(b2);
// Change
a2.setB1(b2);
assertNull(a1.b1());
assertSame(a2.b1(), b2);
assertNull(b1.a1());
assertSame(b2.a1(), a2);
}
/**
* rel A.b2 <-> B.a2?;
*/
private void test2() {
test21();
test22();
}
private void test21() {
// Init
setup();
a1.setB2(b1);
a2.setB2(b2);
// Change
a2.setB2(b1);
assertNull(a1.b2());
assertSame(a2.b2(), b1);
assertSame(b1.a2(), a2);
assertNull(b2.a2());
}
private void test22() {
// Init
setup();
a1.setB2(b2);
// Change
a2.setB2(b2);
assertNull(a1.b2());
assertSame(a2.b2(), b2);
assertNull(b1.a2());
assertSame(b2.a2(), a2);
}
/**
* rel A.b3 <-> B.a3*;
*/
private void test3() {
}
/**
* rel A.b4? <-> B.a4;
*/
private void test4() {
test41();
test42();
}
private void test41() {
// Init
setup();
a1.setB4(b1);
a2.setB4(b2);
// Change
a2.setB4(b1);
assertNull(a1.b4());
assertSame(a2.b4(), b1);
assertSame(b1.a4(), a2);
assertNull(b2.a4());
}
private void test42() {
// Init
setup();
a1.setB4(b2);
// Change
a2.setB4(b2);
assertNull(a1.b4());
assertSame(a2.b4(), b2);
assertNull(b1.a4());
assertSame(b2.a4(), a2);
}
/**
* rel A.b5? <-> B.a5?;
*/
private void test5() {
test51();
test52();
}
private void test51() {
// Init
setup();
a1.setB5(b1);
a2.setB5(b2);
// Change
a2.setB5(b1);
assertNull(a1.b5());
assertSame(a2.b5(), b1);
assertSame(b1.a5(), a2);
assertNull(b2.a5());
}
private void test52() {
// Init
setup();
a1.setB5(b2);
// Change
a2.setB5(b2);
assertNull(a1.b5());
assertSame(a2.b5(), b2);
assertNull(b1.a5());
assertSame(b2.a5(), a2);
}
/**
* rel A.b6? <-> B.a6*;
*/
private void test6() {
}
/**
* rel A.b7* <-> B.a7;
*/
private void test7() {
}
/**
* rel A.b8* <-> B.a8?;
*/
private void test8() {
}
/**
* rel A.b9* <-> B.a9*;
*/
private void test9() {
}
private void setup() {
r = new Root();
a1 = new A("a1");
a2 = new A("a2");
a3 = new A("a3");
b1 = new B("b1");
b2 = new B("b2");
b3 = new B("b3");
r.addA(a1);
r.addA(a2);
r.addA(a3);
r.addB(b1);
r.addB(b2);
r.addB(b3);
}
private void assertNull(Object obj) {
check(obj == null);
}
private void assertSame(Object o1, Object o2) {
check(o1 == o2);
}
private void check(boolean b) {
if (!b) {
throw new RuntimeException();
}
}
}
\ No newline at end of file
aspect Utils {
public String A.toString() {
return getName();
}
public String B.toString() {
return getName();
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment