diff --git a/spec/jastadd/Analysis.jrag b/spec/jastadd/Analysis.jrag index 646474700f49de5cc97bbff6ecdcb4920894756b..79439576fcb4bbe0a40dc8f97fe9396629c9676d 100644 --- a/spec/jastadd/Analysis.jrag +++ b/spec/jastadd/Analysis.jrag @@ -18,29 +18,14 @@ aspect TypeAnalysis { } aspect ComponentAnalysis { - syn boolean Component.isDeclaringName() = true; - eq RelationComponent.isDeclaringName() = !isTargetOfRightDirection(); + syn boolean Component.isTargetOfDirectedRelation() = false; + eq RelationComponent.isTargetOfDirectedRelation() = isTargetOfRightDirection(); inh boolean RelationComponent.isTargetOfRightDirection(); eq Relation.getRight().isTargetOfRightDirection() = getDirection() instanceof RightDirection; eq Program.getChild().isTargetOfRightDirection() = false; - syn String Component.name() { - if (!isDeclaringName()) { - return ""; - } - if (!getID().isEmpty()) { - return getID(); - } - return otherRelationSideName(); - } - inh String Component.otherRelationSideName(); - eq Relation.getLeft().otherRelationSideName() - = getRight().getTypeUse().getID(); - eq Relation.getRight().otherRelationSideName() - = getLeft().getTypeUse().getID(); - eq Program.getChild().otherRelationSideName() - = ""; + syn String Component.name() = getID(); syn TypeDecl Component.toTypeDecl() = enclosingTypeDecl(); eq RelationComponent.toTypeDecl() = getTypeUse().decl(); @@ -53,7 +38,8 @@ aspect ComponentAnalysis { eq Program.getChild().ofTypeDecl() = null; syn boolean Component.isAlreadyDeclared() - = isDeclaringName() && lookupComponent(toTypeDecl(), name()) != this; + = !isTargetOfDirectedRelation() + && lookupComponent(toTypeDecl(), name()) != this; inh Component Component.lookupComponent(TypeDecl td, String name); eq Program.getChild().lookupComponent(TypeDecl td, String name) { if (td != null) { @@ -73,7 +59,7 @@ aspect ComponentAnalysis { } syn RelationComponent RelationComponent.lookup(TypeDecl td, String name) - = isDeclaringName() && toTypeDecl() == td && name().equals(name) + = !isTargetOfDirectedRelation() && toTypeDecl() == td && name().equals(name) ? this : null; @@ -82,7 +68,7 @@ aspect ComponentAnalysis { [new HashSet<RelationComponent>()] root Program; RelationComponent contributes this - when isDeclaringName() && toTypeDecl() != null + when !isTargetOfDirectedRelation() && toTypeDecl() != null to TypeDecl.relationComponents() for toTypeDecl(); } diff --git a/spec/jastadd/Backend.jadd b/spec/jastadd/Backend.jadd index e12ba7fc394edf078904aca8f12b40c688f22c3d..b7a4b101064bb652fcaf77bfeacecb9b777588fe 100644 --- a/spec/jastadd/Backend.jadd +++ b/spec/jastadd/Backend.jadd @@ -128,7 +128,7 @@ aspect PrettyPrint { } } public String OptionalRelationComponent.prettyPrint() { - return "[" + super.prettyPrint() + "]"; + return super.prettyPrint() + "?"; } public String ManyRelationComponent.prettyPrint() { return super.prettyPrint() + "*"; diff --git a/spec/jastadd/DumpTree.jrag b/spec/jastadd/DumpTree.jrag index 897b8d2bc68534469d6b5f18c947296d13d245bf..f49741e6fe607365f323846828b6735e4034d913 100644 --- a/spec/jastadd/DumpTree.jrag +++ b/spec/jastadd/DumpTree.jrag @@ -21,7 +21,12 @@ aspect DumpTree { public void ASTNode.dumpTree(PrintStream out, String indent) { out.print(indent + getClass().getSimpleName()); - out.println(getTokens()); + out.print(getTokens()); + String extra = extraDumpInfo(); + if (!extra.isEmpty()) { + out.print(" " + extra); + } + out.println(); String childIndent = indent + DUMP_TREE_INDENT; for (ASTNode child : astChildren()) { if (child == null) { @@ -32,6 +37,8 @@ aspect DumpTree { } } + public String ASTNode.extraDumpInfo() { return ""; } + public String ASTNode.getTokens() { java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>( new java.util.Comparator<java.lang.reflect.Method>() { diff --git a/spec/jastadd/Errors.jrag b/spec/jastadd/Errors.jrag index 3aa6ff27a17bd45fd367ee44925005347b165e14..b97c8252e95eb2f7bca97c863c5c544cef859c71 100644 --- a/spec/jastadd/Errors.jrag +++ b/spec/jastadd/Errors.jrag @@ -19,6 +19,21 @@ aspect Errors { + "' is already declared for type '" + toTypeDecl() + "'") when isAlreadyDeclared() to Program.errors(); + + RelationComponent contributes + error("Role name missing for type '" + toTypeDecl() + "'") + when !isTargetOfDirectedRelation() && name().isEmpty() + to Program.errors(); + + RelationComponent contributes + error("The target of a directed relation cannot have a role name") + when isTargetOfDirectedRelation() && !getID().isEmpty() + to Program.errors(); + + RelationComponent contributes + error("The target of a directed relation may only have multiplicity 1") + when isTargetOfDirectedRelation() && !hasMultiplicityOne() + to Program.errors(); } aspect HelpAttributes { @@ -28,6 +43,9 @@ aspect HelpAttributes { inh boolean TypeUse.isToken(); eq Program.getChild().isToken() = false; eq TokenComponent.getTypeUse().isToken() = true; + + syn boolean RelationComponent.hasMultiplicityOne() = false; + eq OneRelationComponent.hasMultiplicityOne() = true; } aspect ErrorMessage { diff --git a/src/java/org/jastadd/relast/compiler/Compiler.java b/src/java/org/jastadd/relast/compiler/Compiler.java index eeaeacfbde606bbbe41f3b0476be7d639797188b..0a0cf2a9f3280612b8b76f7b0ba62ec53b6e0b6b 100644 --- a/src/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/java/org/jastadd/relast/compiler/Compiler.java @@ -34,6 +34,7 @@ public class Compiler { Program p = parseProgram(commandLine.getArguments().get(0)); if (!p.errors().isEmpty()) { + System.out.println(p.dumpTree()); System.err.println("Errors:"); for (ErrorMessage e: p.errors()) { System.err.println(e);