From db3908ff2e3c568e1e73c7b78de933fe39b5548e Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Tue, 1 Oct 2019 15:28:51 +0200 Subject: [PATCH] Add LeftDirection ('<-') for relations. - Also add some tests for left direction --- src/main/jastadd/Analysis.jrag | 6 +- src/main/jastadd/Backend.jadd | 9 ++ src/main/jastadd/RelAst.ast | 1 + src/main/jastadd/RelAst.flex | 1 + src/main/jastadd/RelAst.parser | 1 + .../org/jastadd/relast/compiler/Compiler.java | 2 +- src/test/jastadd/errors/ErrorsLeft.expected | 5 + src/test/jastadd/errors/ErrorsLeft.relast | 8 ++ .../jastadd/errors/InheritanceLeft.expected | 3 + .../jastadd/errors/InheritanceLeft.relast | 6 ++ src/test/jastadd/errors/MultipleLeft.expected | 5 + src/test/jastadd/errors/MultipleLeft_1.relast | 6 ++ src/test/jastadd/errors/MultipleLeft_2.relast | 2 + src/test/jastadd/relations/Relations.relast | 5 + .../java/org/jastadd/relast/tests/Errors.java | 15 +++ .../org/jastadd/relast/tests/Relations.java | 94 +++++++++++++++++++ 16 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 src/test/jastadd/errors/ErrorsLeft.expected create mode 100644 src/test/jastadd/errors/ErrorsLeft.relast create mode 100644 src/test/jastadd/errors/InheritanceLeft.expected create mode 100644 src/test/jastadd/errors/InheritanceLeft.relast create mode 100644 src/test/jastadd/errors/MultipleLeft.expected create mode 100644 src/test/jastadd/errors/MultipleLeft_1.relast create mode 100644 src/test/jastadd/errors/MultipleLeft_2.relast diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag index 8f586ce..8959b7b 100644 --- a/src/main/jastadd/Analysis.jrag +++ b/src/main/jastadd/Analysis.jrag @@ -29,11 +29,15 @@ aspect TypeAnalysis { aspect ComponentAnalysis { syn boolean Component.isTargetOfDirectedRelation() = false; - eq RelationComponent.isTargetOfDirectedRelation() = isTargetOfRightDirection(); + eq RelationComponent.isTargetOfDirectedRelation() = isTargetOfRightDirection() | isTargetOfLeftDirection(); inh boolean RelationComponent.isTargetOfRightDirection(); eq Relation.getRight().isTargetOfRightDirection() = getDirection() instanceof RightDirection; eq Program.getChild().isTargetOfRightDirection() = false; + inh boolean RelationComponent.isTargetOfLeftDirection(); + eq Relation.getLeft().isTargetOfLeftDirection() + = getDirection() instanceof LeftDirection; + eq Program.getChild().isTargetOfLeftDirection() = false; syn String Component.name() = getID(); diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd index 5401260..cde27fe 100644 --- a/src/main/jastadd/Backend.jadd +++ b/src/main/jastadd/Backend.jadd @@ -216,6 +216,9 @@ 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) { @@ -904,6 +907,9 @@ aspect NameResolutionHelper { public void RightDirection.generateContextDependentNameResolution(StringBuilder sb) { relation().getLeft().generateContextDependentNameResolution(sb); } + public void LeftDirection.generateContextDependentNameResolution(StringBuilder sb) { + relation().getRight().generateContextDependentNameResolution(sb); + } public void Bidirectional.generateContextDependentNameResolution(StringBuilder sb) { relation().getLeft().generateContextDependentNameResolution(sb); relation().getRight().generateContextDependentNameResolution(sb); @@ -1451,6 +1457,9 @@ aspect PrettyPrint { public String RightDirection.prettyPrint() { return "->"; } + public String LeftDirection.prettyPrint() { + return "<-"; + } public String Bidirectional.prettyPrint() { return "<->"; } diff --git a/src/main/jastadd/RelAst.ast b/src/main/jastadd/RelAst.ast index 2b468e9..9b29df1 100644 --- a/src/main/jastadd/RelAst.ast +++ b/src/main/jastadd/RelAst.ast @@ -21,4 +21,5 @@ OptionalRelationComponent : RelationComponent; ManyRelationComponent : RelationComponent; abstract Direction; RightDirection : Direction; +LeftDirection : Direction; Bidirectional : Direction; diff --git a/src/main/jastadd/RelAst.flex b/src/main/jastadd/RelAst.flex index 68b2ebf..7cccbe3 100644 --- a/src/main/jastadd/RelAst.flex +++ b/src/main/jastadd/RelAst.flex @@ -62,6 +62,7 @@ ID = [a-zA-Z$_][a-zA-Z0-9$_]* "/" { return sym(Terminals.SLASH); } "?" { return sym(Terminals.QUESTION_MARK); } "->" { return sym(Terminals.RIGHT); } +"<-" { return sym(Terminals.LEFT); } "<->" { return sym(Terminals.BIDIRECTIONAL); } // ID diff --git a/src/main/jastadd/RelAst.parser b/src/main/jastadd/RelAst.parser index 24fb22b..0a09739 100644 --- a/src/main/jastadd/RelAst.parser +++ b/src/main/jastadd/RelAst.parser @@ -101,5 +101,6 @@ RelationComponent relation_comp = Direction direction = RIGHT {: return new RightDirection(); :} + | LEFT {: return new LeftDirection(); :} | BIDIRECTIONAL {: return new Bidirectional(); :} ; diff --git a/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/Compiler.java index 1a2605f..22b6168 100644 --- a/src/main/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/main/java/org/jastadd/relast/compiler/Compiler.java @@ -14,7 +14,7 @@ import java.util.List; public class Compiler { - private static final String VERSION = "0.2.2"; + private static final String VERSION = "0.2.3"; private ArrayList<Option<?>> options; private FlagOption optionWriteToFile; diff --git a/src/test/jastadd/errors/ErrorsLeft.expected b/src/test/jastadd/errors/ErrorsLeft.expected new file mode 100644 index 0000000..155d0ec --- /dev/null +++ b/src/test/jastadd/errors/ErrorsLeft.expected @@ -0,0 +1,5 @@ +Errors: +$FILENAME Line 5, column 10: Role name missing for type 'A' +$FILENAME Line 6, column 15: Role name missing for type 'B' +$FILENAME Line 7, column 5: The target of a directed relation cannot have a role name +$FILENAME Line 8, column 5: The target of a directed relation may only have multiplicity 1 diff --git a/src/test/jastadd/errors/ErrorsLeft.relast b/src/test/jastadd/errors/ErrorsLeft.relast new file mode 100644 index 0000000..e381449 --- /dev/null +++ b/src/test/jastadd/errors/ErrorsLeft.relast @@ -0,0 +1,8 @@ +Program ::= A* B*; +A; +B; + +rel B <- A; +rel A.bs* <-> B*; +rel B.b <- A.b; +rel B* <- A.b2; diff --git a/src/test/jastadd/errors/InheritanceLeft.expected b/src/test/jastadd/errors/InheritanceLeft.expected new file mode 100644 index 0000000..ef568b5 --- /dev/null +++ b/src/test/jastadd/errors/InheritanceLeft.expected @@ -0,0 +1,3 @@ +Errors: +$FILENAME Line 2, column 12: Component 'X' is already declared for type 'B1' +$FILENAME Line 6, column 10: Component 'X' is already declared for type 'B2' diff --git a/src/test/jastadd/errors/InheritanceLeft.relast b/src/test/jastadd/errors/InheritanceLeft.relast new file mode 100644 index 0000000..a63c266 --- /dev/null +++ b/src/test/jastadd/errors/InheritanceLeft.relast @@ -0,0 +1,6 @@ +A ::= X; +B1 : A ::= X; +B2 : A; +X; + +rel X <- B2.X; diff --git a/src/test/jastadd/errors/MultipleLeft.expected b/src/test/jastadd/errors/MultipleLeft.expected new file mode 100644 index 0000000..4c2b802 --- /dev/null +++ b/src/test/jastadd/errors/MultipleLeft.expected @@ -0,0 +1,5 @@ +Errors: +$FILENAME1 Line 5, column 10: Role name missing for type 'A' +$FILENAME1 Line 6, column 15: Role name missing for type 'B' +$FILENAME2 Line 1, column 5: The target of a directed relation cannot have a role name +$FILENAME2 Line 2, column 5: The target of a directed relation may only have multiplicity 1 diff --git a/src/test/jastadd/errors/MultipleLeft_1.relast b/src/test/jastadd/errors/MultipleLeft_1.relast new file mode 100644 index 0000000..c0ac803 --- /dev/null +++ b/src/test/jastadd/errors/MultipleLeft_1.relast @@ -0,0 +1,6 @@ +Program ::= A* B*; +A; +B; + +rel B <- A; +rel A.bs* <-> B*; diff --git a/src/test/jastadd/errors/MultipleLeft_2.relast b/src/test/jastadd/errors/MultipleLeft_2.relast new file mode 100644 index 0000000..9ee5922 --- /dev/null +++ b/src/test/jastadd/errors/MultipleLeft_2.relast @@ -0,0 +1,2 @@ +rel B.b <- A.b; +rel B* <- A.b2; diff --git a/src/test/jastadd/relations/Relations.relast b/src/test/jastadd/relations/Relations.relast index 6a56229..892ad39 100644 --- a/src/test/jastadd/relations/Relations.relast +++ b/src/test/jastadd/relations/Relations.relast @@ -17,3 +17,8 @@ rel A.Bi6? <-> B.Bi6*; rel A.Bi7* <-> B.Bi7; rel A.Bi8* <-> B.Bi8?; rel A.Bi9* <-> B.Bi9*; + +rel A <- Root.AaLeft?; +rel B <- A.Di1Left ; +rel B <- A.Di2Left?; +rel B <- A.Di3Left*; diff --git a/src/test/java/org/jastadd/relast/tests/Errors.java b/src/test/java/org/jastadd/relast/tests/Errors.java index 8154c19..718c049 100644 --- a/src/test/java/org/jastadd/relast/tests/Errors.java +++ b/src/test/java/org/jastadd/relast/tests/Errors.java @@ -27,16 +27,31 @@ class Errors { test("Errors"); } + @Test + void test1Left() throws IOException { + test("ErrorsLeft"); + } + @Test void test2() throws IOException { test("Inheritance"); } + @Test + void test2Left() throws IOException { + test("InheritanceLeft"); + } + @Test void test3() throws IOException { test("Multiple", "Multiple_1", "Multiple_2"); } + @Test + void test3Left() throws IOException { + test("MultipleLeft", "MultipleLeft_1", "MultipleLeft_2"); + } + private void test(String name, String... inFilenames) throws IOException { List<String> inFiles = Arrays.stream(inFilenames.length > 0 ? inFilenames : new String[]{name}) .map(f -> "./src/test/jastadd/errors/" + f + ".relast") diff --git a/src/test/java/org/jastadd/relast/tests/Relations.java b/src/test/java/org/jastadd/relast/tests/Relations.java index a23d998..4ad3a15 100644 --- a/src/test/java/org/jastadd/relast/tests/Relations.java +++ b/src/test/java/org/jastadd/relast/tests/Relations.java @@ -132,6 +132,100 @@ class Relations { assertEquals(a3.getDi3List(), Arrays.asList()); } + /** + * rel A.Di1 -> B; + */ + @Test + void testDi1Left() { + setup(); + a1.setDi1Left(b2); + a2.setDi1Left(b1); + + assertSame(a1.getDi1Left(), b2); + assertSame(a2.getDi1Left(), b1); + + a2.setDi1Left(b2); + + assertSame(a1.getDi1Left(), b2); + assertSame(a2.getDi1Left(), b2); + + try { + a3.setDi1Left(null); + fail("should throw an exception"); + } catch (Exception e) { + // OK + } + } + + + /** + * rel A.Di2? -> B; + */ + @Test + void testDi2Left() { + setup(); + a1.setDi2Left(b2); + a2.setDi2Left(b1); + + assertSame(a1.getDi2Left(), b2); + assertSame(a2.getDi2Left(), b1); + + a2.setDi2Left(b2); + + assertSame(a1.getDi2Left(), b2); + assertSame(a2.getDi2Left(), b2); + + a2.clearDi2Left(); + + assertSame(a1.getDi2Left(), b2); + assertNull(a2.getDi2Left()); + + assertTrue(a1.hasDi2Left()); + assertFalse(a2.hasDi2Left()); + assertFalse(a3.hasDi2Left()); + } + + + /** + * rel A.Di3* -> B; + */ + @Test + void testDi3Left() { + setup(); + a1.addDi3Left(b1); + a1.addDi3Left(b2); + a1.addDi3Left(b3); + a2.addDi3Left(b2); + + assertEquals(a1.getDi3Lefts(), Arrays.asList(b1, b2, b3)); + assertEquals(a1.getDi3LeftList(), Arrays.asList(b1, b2, b3)); + assertEquals(a2.getDi3Lefts(), Arrays.asList(b2)); + assertEquals(a2.getDi3LeftList(), Arrays.asList(b2)); + assertEquals(a3.getDi3Lefts(), Arrays.asList()); + assertEquals(a3.getDi3LeftList(), Arrays.asList()); + + a1.addDi3Left(b1); + a2.addDi3Left(b1); + a2.addDi3Left(b2); + + assertEquals(a1.getDi3Lefts(), Arrays.asList(b1, b2, b3, b1)); + assertEquals(a1.getDi3LeftList(), Arrays.asList(b1, b2, b3, b1)); + assertEquals(a2.getDi3Lefts(), Arrays.asList(b2, b1, b2)); + assertEquals(a2.getDi3LeftList(), Arrays.asList(b2, b1, b2)); + assertEquals(a3.getDi3Lefts(), Arrays.asList()); + assertEquals(a3.getDi3LeftList(), Arrays.asList()); + + a1.removeDi3Left(b1); + a2.removeDi3Left(b2); + + assertEquals(a1.getDi3Lefts(), Arrays.asList(b2, b3, b1)); + assertEquals(a1.getDi3LeftList(), Arrays.asList(b2, b3, b1)); + assertEquals(a2.getDi3Lefts(), Arrays.asList(b1, b2)); + assertEquals(a2.getDi3LeftList(), Arrays.asList(b1, b2)); + assertEquals(a3.getDi3Lefts(), Arrays.asList()); + assertEquals(a3.getDi3LeftList(), Arrays.asList()); + } + /** * rel A.Bi1 <-> B.Bi1; -- GitLab