Commit a4c49252 authored by Niklas Fors's avatar Niklas Fors
Browse files

Add part implementation of bidirectional and add test case

parent 019406f5
.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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment