From 5fbb5a864310ebeab95588161588d1e8cc1c83a6 Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Mon, 21 Oct 2019 12:42:52 +0200
Subject: [PATCH] Remove confusing attribute toTypeDecl.

- Changed error message for invalid redefinition
---
 src/main/jastadd/Analysis.jrag                | 26 ++++----
 src/main/jastadd/Backend.jadd                 | 62 +++++++++----------
 src/main/jastadd/Errors.jrag                  | 13 ++--
 src/test/jastadd/errors/Inheritance.expected  |  4 +-
 src/test/jastadd/errors/Inheritance.relast    |  1 -
 .../jastadd/errors/InheritanceLeft.expected   |  4 +-
 6 files changed, 56 insertions(+), 54 deletions(-)

diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag
index 2ad299a..89d6fb0 100644
--- a/src/main/jastadd/Analysis.jrag
+++ b/src/main/jastadd/Analysis.jrag
@@ -30,12 +30,6 @@ aspect ComponentAnalysis {
   //--- name ---
   syn String Component.name() = getID();
 
-  //--- toTypeDecl ---
-  /** @return enclosing type */
-  syn TypeDecl Component.toTypeDecl() = enclosingTypeDecl();
-  /** @return type of nonterminal relation role is defined for */
-  eq RelationComponent.toTypeDecl() = getTypeUse().decl();
-
   //--- enclosingTypeDecl ---
   inh TypeDecl Component.enclosingTypeDecl();
   eq TypeDecl.getChild().enclosingTypeDecl() = this;
@@ -48,7 +42,7 @@ aspect ComponentAnalysis {
   eq Program.getChild().otherSide() = null;
 
   //--- ofTypeDecl ---
-  syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().toTypeDecl();
+  syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().getTypeUse().decl();
 
   //--- isAlreadyDeclared ---
   /**
@@ -56,8 +50,8 @@ aspect ComponentAnalysis {
    */
   syn boolean RelationComponent.isAlreadyDeclared()
     = !isTargetOfDirectedRelation()                     /* if unnamed in relation, there is no role name, so no error */
-      && toTypeDecl() != null                           /* nonterminal type of role is defined */
-      && findComponent(toTypeDecl(), name()) != this;   /* there is another role defined previously with the same name */
+      && getTypeUse().decl() != null                           /* nonterminal type of role is defined */
+      && findComponent(getTypeUse().decl(), name()) != this;   /* there is another role defined previously with the same name */
 
   //--- findComponent ---
   /** Search for either a component on the RHS of the given type with the given name,
@@ -82,12 +76,16 @@ aspect ComponentAnalysis {
     return null;
   }
 
+  /* Should this better return the component, where it is defined previously defined? */
   //--- isInvalidRedefinition ---
   /**
    * Check, if a component with the same name is already declared in some supertype
    */
-  syn boolean Component.isInvalidRedefinition() {
-    TypeDecl td = toTypeDecl();
+  syn boolean Component.isInvalidRedefinition() = false;
+  eq TokenComponent.isInvalidRedefinition() = hasInvalidRedefinitionOn(enclosingTypeDecl());
+  eq RelationComponent.isInvalidRedefinition() = hasInvalidRedefinitionOn(getTypeUse().decl());
+
+  syn boolean Component.hasInvalidRedefinitionOn(TypeDecl td) {
     if (td == null) return false;
 
     while (td.hasSuper() && td.getSuper().decl() != null) {
@@ -121,16 +119,16 @@ aspect ComponentAnalysis {
    * @return true, if the component has both type and role, its type matches the given typeDecl and its name matches the given name
    */
   syn boolean RelationComponent.matches(TypeDecl td, String name)
-    = !isTargetOfDirectedRelation() && toTypeDecl() == td && name().equals(name);
+    = !isTargetOfDirectedRelation() && getTypeUse().decl() == td && name().equals(name);
 
   //--- relationComponents ---
   coll Set<RelationComponent> TypeDecl.relationComponents()
     [new HashSet<RelationComponent>()]
     root Program;
   RelationComponent contributes this
-    when !isTargetOfDirectedRelation() && toTypeDecl() != null
+    when !isTargetOfDirectedRelation() && getTypeUse().decl() != null
     to TypeDecl.relationComponents()
-    for toTypeDecl();
+    for getTypeUse().decl();
 
   //--- relationComponentsTransitive ---
   syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() {
diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd
index f5d69d3..a3711d3 100644
--- a/src/main/jastadd/Backend.jadd
+++ b/src/main/jastadd/Backend.jadd
@@ -240,7 +240,7 @@ aspect BackendDirectedAPI {
     generateGetOne(sb);
 
     // Set
-    sb.append(ind(1) + "public " + toTypeDecl() + " " + toTypeDecl());
+    sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
     sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
     if (!optional) {
       sb.append(ind(2) + "assertNotNull(o);\n");
@@ -252,7 +252,7 @@ aspect BackendDirectedAPI {
 
   public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) {
     // Get
-    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl() + ".");
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
     if (useJastAddNames) {
       // getXs
       sb.append("get" + nameCapitalized() + "s() {\n");
@@ -260,7 +260,7 @@ aspect BackendDirectedAPI {
       sb.append(ind(1) + "}\n");
 
       // getXList
-      sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+      sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
       sb.append(".get" + nameCapitalized() + "List() {\n");
     } else {
       sb.append(name() + "() {\n");
@@ -287,7 +287,7 @@ aspect BackendDirectedAPI {
     sb.append(ind(1) + "}\n");
 
     // Add
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
     if (!useJastAddNames) {
       sb.append("To");
     }
@@ -302,7 +302,7 @@ aspect BackendDirectedAPI {
     sb.append(ind(1) + "}\n");
 
     // Insert / add at specific position
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
     if (!useJastAddNames) {
       sb.append("To");
     }
@@ -317,7 +317,7 @@ aspect BackendDirectedAPI {
     sb.append(ind(1) + "}\n");
 
     // Remove
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".remove");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
     if (!useJastAddNames) {
       sb.append("From");
     }
@@ -331,7 +331,7 @@ aspect BackendDirectedAPI {
   }
 
   public void RelationComponent.generateGetOne(StringBuilder sb) {
-    sb.append(ind(1) + "public " + ofTypeDecl() + " " + toTypeDecl() + ".");
+    sb.append(ind(1) + "public " + ofTypeDecl() + " " + getTypeUse().decl() + ".");
     if (useJastAddNames) {
       sb.append("get" + nameCapitalized());
     } else {
@@ -353,7 +353,7 @@ aspect BackendDirectedAPI {
 
   public void RelationComponent.generateExtraOptAPI(StringBuilder sb) {
     // has
-    sb.append(ind(1) + "public boolean " + toTypeDecl());
+    sb.append(ind(1) + "public boolean " + getTypeUse().decl());
     sb.append(".has" + nameCapitalized() + "() {\n");
     sb.append(ind(2) + "return ");
     if (useJastAddNames) {
@@ -365,7 +365,7 @@ aspect BackendDirectedAPI {
     sb.append(ind(1) + "}\n");
 
     // clear
-    sb.append(ind(1) + "public void " + toTypeDecl());
+    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");
@@ -418,7 +418,7 @@ aspect BackendBidirectionalAPI {
     generateGetOne(sb);
 
     // Set
-    sb.append(ind(1) + "public " + toTypeDecl() + " " + toTypeDecl());
+    sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl());
     sb.append(".set" + nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
     if (!isOpt) {
       sb.append(ind(2) + "assertNotNull(o);\n");
@@ -465,7 +465,7 @@ aspect BackendBidirectionalAPI {
 
   public void RelationComponent.generateBiManyMany(StringBuilder sb, RelationComponent opposite) {
     // Get
-    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl() + ".");
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
     if (useJastAddNames) {
       // getXs
       sb.append("get" + nameCapitalized() + "s() {\n");
@@ -473,7 +473,7 @@ aspect BackendBidirectionalAPI {
       sb.append(ind(1) + "}\n");
 
       // getXList
-      sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+      sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
       sb.append(".get" + nameCapitalized() + "List() {\n");
     } else {
       sb.append(name() + "() {\n");
@@ -489,7 +489,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 (resolvedElement != null && element.as$Unresolved().getUnresolved$ResolveOpposite()) {\n");
-              sb.append(ind(6) + ASTNode.listClass + "<" + toTypeDecl() + "> otherList = resolvedElement." + opposite.getImplAttributeField() + ";\n");
+              sb.append(ind(6) + ASTNode.listClass + "<" + getTypeUse().decl() + "> otherList = resolvedElement." + opposite.getImplAttributeField() + ";\n");
               sb.append(ind(6) + "if (otherList == null) {\n");
                 sb.append(ind(7) + "otherList = new " + listClass + "<>();\n");
               sb.append(ind(6) + "}\n");
@@ -508,7 +508,7 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(1) + "}\n");
 
     // Add
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
     if (!useJastAddNames) {
       sb.append("To");
     }
@@ -529,7 +529,7 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(1) + "}\n");
 
     // Insert / add at specific position
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
     if (!useJastAddNames) {
       sb.append("To");
     }
@@ -551,7 +551,7 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(1) + "}\n");
 
     // Remove
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".remove");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
     if (!useJastAddNames) {
       sb.append("From");
     }
@@ -571,7 +571,7 @@ aspect BackendBidirectionalAPI {
 
   public void RelationComponent.generateBiManyOne(StringBuilder sb, RelationComponent opposite) {
     // Get
-    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl() + ".");
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl() + ".");
     if (useJastAddNames) {
       // getXs
       sb.append("get" + nameCapitalized() + "s() {\n");
@@ -579,7 +579,7 @@ aspect BackendBidirectionalAPI {
       sb.append(ind(1) + "}\n");
 
       // getXList
-      sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+      sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + getTypeUse().decl());
       sb.append(".get" + nameCapitalized() + "List() {\n");
     } else {
       sb.append(name() + "() {\n");
@@ -595,7 +595,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) + toTypeDecl() + " oldTarget = resolvedElement." + opposite.getImplAttributeField() + ";\n");
+              sb.append(ind(6) + getTypeUse().decl() + " oldTarget = resolvedElement." + opposite.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");
@@ -620,7 +620,7 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(1) + "}\n");
 
     // Add
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
     if (!useJastAddNames) {
       sb.append("To");
     }
@@ -643,7 +643,7 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(1) + "}\n");
 
     // Insert / add at specific position
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".add");
     if (!useJastAddNames) {
       sb.append("To");
     }
@@ -664,7 +664,7 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(1) + "}\n");
 
     // Remove
-    sb.append(ind(1) + "public void " + toTypeDecl() + ".remove");
+    sb.append(ind(1) + "public void " + getTypeUse().decl() + ".remove");
     if (!useJastAddNames) {
       sb.append("From");
     }
@@ -685,13 +685,13 @@ aspect BackendBidirectionalAPI {
     generateGetOne(sb);
 
     // Set
-    sb.append(ind(1) + "public " + toTypeDecl() + " " + toTypeDecl() + ".set" + nameCapitalized()
+    sb.append(ind(1) + "public " + getTypeUse().decl() + " " + getTypeUse().decl() + ".set" + nameCapitalized()
       + "(" + ofTypeDecl() + " o) {\n");
     if (!isOpt) {
       sb.append(ind(2) + "assertNotNull(o);\n");
     }
     sb.append(ind(2) + "if (" + getImplAttributeField() + " != null) {\n");
-    sb.append(ind(3) + ASTNode.listClass + "<" + toTypeDecl() + "> list2 = " + getImplAttributeField()
+    sb.append(ind(3) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list2 = " + getImplAttributeField()
       + "." + otherSide().getImplAttributeField() + ";\n");
     sb.append(ind(3) + "list2.remove(this);\n");
     sb.append(ind(3) + getImplAttributeField() + "." + "set"
@@ -703,7 +703,7 @@ aspect BackendBidirectionalAPI {
     if (isOpt) {
       sb.append(ind(2) + "if (o != null) {\n");
     }
-    sb.append(ind(ind) + ASTNode.listClass + "<" + toTypeDecl() + "> list = o."
+    sb.append(ind(ind) + ASTNode.listClass + "<" + getTypeUse().decl() + "> list = o."
       + otherSide().getImplAttributeField() + ";\n");
     sb.append(ind(ind) + "if (list == null) {\n");
     sb.append(ind(ind+1) + "list = new " + ASTNode.listClass + "<>();\n");
@@ -933,13 +933,13 @@ aspect NameResolutionHelper {
   public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
 
     if (serializer && !resolverHelper) {
-      sb.append(ind(1) + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
+      sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
         sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n");
       sb.append(ind(1) + "}\n");
     } else {
       sb.append(ind(1) + "// context-dependent name resolution\n");
-      sb.append(ind(1) + "uncache " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position);\n");
-      sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
+      sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position);\n");
+      sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
         sb.append(ind(2) + "// default to context-independent name resolution\n");
         sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n");
       sb.append(ind(1) + "}\n");
@@ -948,13 +948,13 @@ aspect NameResolutionHelper {
 
   public void RelationComponent.generateDirectedContextDependentNameResolution(StringBuilder sb) {
     if (serializer && !resolverHelper) {
-      sb.append(ind(1) + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
+      sb.append(ind(1) + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
         sb.append(ind(2) + "return (" + ofTypeDecl() + ") globallyResolveASTNodeByUID(id);\n");
       sb.append(ind(1) + "}\n");
     } else {
       sb.append(ind(1) + "// context-dependent name resolution\n");
-      sb.append(ind(1) + "uncache " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id);\n");
-      sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
+      sb.append(ind(1) + "uncache " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id);\n");
+      sb.append(ind(1) + "syn " + ofTypeDecl() + " " + getTypeUse().decl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
         sb.append(ind(2) + "// default to context-independent name resolution\n");
         sb.append(ind(2) + "return globallyResolve" + ofTypeDecl() + "ByToken(id);\n");
       sb.append(ind(1) + "}\n");
diff --git a/src/main/jastadd/Errors.jrag b/src/main/jastadd/Errors.jrag
index 393c09d..0ff888a 100644
--- a/src/main/jastadd/Errors.jrag
+++ b/src/main/jastadd/Errors.jrag
@@ -16,17 +16,22 @@ aspect Errors {
     to Program.errors();
 
   RelationComponent contributes error("Role '" + name()
-      + "' is already declared for type '" + toTypeDecl() + "'")
+      + "' is already declared for type '" + getTypeUse().decl() + "'")
     when isAlreadyDeclared()
     to Program.errors();
 
-  Component contributes error("Component '" + name()
-    + "' is an invalid redefinition for type '" + toTypeDecl() + "'")
+  RelationComponent contributes error("Role '" + name()
+    + "' is an invalid redefinition for type '" + getTypeUse().decl() + "'")
+    when isInvalidRedefinition()
+    to Program.errors();
+
+  TokenComponent contributes error("Token '" + name()
+    + "' is an invalid redefinition for type '" + enclosingTypeDecl() + "'")
     when isInvalidRedefinition()
     to Program.errors();
 
   RelationComponent contributes
-    error("Role name missing for type '" + toTypeDecl() + "'")
+    error("Role name missing for type '" + getTypeUse().decl() + "'")
     when !isTargetOfDirectedRelation() && name().isEmpty()
     to Program.errors();
 
diff --git a/src/test/jastadd/errors/Inheritance.expected b/src/test/jastadd/errors/Inheritance.expected
index 37beedd..3742ef5 100644
--- a/src/test/jastadd/errors/Inheritance.expected
+++ b/src/test/jastadd/errors/Inheritance.expected
@@ -1,3 +1,3 @@
 Errors:
-$FILENAME Line 4, column 12: Component 'X' is an invalid redefinition for type 'B3'
-$FILENAME Line 7, column 5: Component 'X' is an invalid redefinition for type 'B2'
+$FILENAME Line 4, column 12: Token 'X' is an invalid redefinition for type 'B3'
+$FILENAME Line 7, column 5: Role 'X' is an invalid redefinition for type 'B2'
diff --git a/src/test/jastadd/errors/Inheritance.relast b/src/test/jastadd/errors/Inheritance.relast
index e79e6b3..db746eb 100644
--- a/src/test/jastadd/errors/Inheritance.relast
+++ b/src/test/jastadd/errors/Inheritance.relast
@@ -5,4 +5,3 @@ B3 : A ::= <X:String>;
 X;
 
 rel B2.X -> X;
-rel X.X -> B2;
diff --git a/src/test/jastadd/errors/InheritanceLeft.expected b/src/test/jastadd/errors/InheritanceLeft.expected
index 7dd3b7d..e94e4ef 100644
--- a/src/test/jastadd/errors/InheritanceLeft.expected
+++ b/src/test/jastadd/errors/InheritanceLeft.expected
@@ -1,3 +1,3 @@
 Errors:
-$FILENAME Line 4, column 12: Component 'X' is an invalid redefinition for type 'B3'
-$FILENAME Line 7, column 10: Component 'X' is an invalid redefinition for type 'B2'
+$FILENAME Line 4, column 12: Token 'X' is an invalid redefinition for type 'B3'
+$FILENAME Line 7, column 10: Role 'X' is an invalid redefinition for type 'B2'
-- 
GitLab