From 5188b017947d2cc9675ef88e2df5efea6b0e7a0b Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Tue, 9 Nov 2021 19:05:05 +0100
Subject: [PATCH] begin with removing tree and list

---
 .../src/main/jastadd/NameResolution.jrag      | 58 +++++++++++++--
 .../src/main/jastadd/RagConnect.relast        |  5 ++
 .../main/jastadd/parser/ParserRewrites.jrag   | 74 +++++++++++++++++++
 .../src/main/jastadd/parser/RagConnect.parser | 56 +++++++-------
 .../src/main/jastadd/scanner/Keywords.flex    |  5 +-
 .../src/test/01-input/list/Test.connect       | 12 +--
 .../src/test/01-input/singleList/Test.connect | 16 ++--
 .../01-input/singleListVariant/Test.connect   | 50 ++++++-------
 .../src/test/01-input/tree/Test.connect       |  4 +-
 .../01-input/treeAllowedTokens/Test.connect   |  8 +-
 10 files changed, 206 insertions(+), 82 deletions(-)
 create mode 100644 ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag

diff --git a/ragconnect.base/src/main/jastadd/NameResolution.jrag b/ragconnect.base/src/main/jastadd/NameResolution.jrag
index 3b75bc0..80525b5 100644
--- a/ragconnect.base/src/main/jastadd/NameResolution.jrag
+++ b/ragconnect.base/src/main/jastadd/NameResolution.jrag
@@ -1,18 +1,32 @@
-aspect NameResolution {
+aspect RagConnectNameResolution {
 
+  // rel EndpointDefinition.Mapping* -> MappingDefinition
   refine RefResolverStubs eq EndpointDefinition.resolveMappingByToken(String id, int position) {
-    // return a MappingDefinition
+    MappingDefinition result = tryResolveMappingByToken(id);
+    if (result == null) {
+      System.err.println("Could not resolve MappingDefinition '" + id + "'.");
+    }
+    return result;
+  }
+  syn MappingDefinition EndpointDefinition.tryResolveMappingByToken(String id) {
     for (MappingDefinition mappingDefinition : ragconnect().allMappingDefinitionList()) {
       if (mappingDefinition.getID().equals(id)) {
         return mappingDefinition;
       }
     }
-    System.err.println("Could not resolve MappingDefinition '" + id + "'.");
     return null;
   }
 
+  // rel ___ -> TypeComponent
   refine RefResolverStubs eq ASTNode.globallyResolveTypeComponentByToken(String id) {
-    // return a TypeComponent. id is of the form 'parent_type_name + "." + child_type_name'
+    TypeComponent result = tryGloballyResolveTypeComponentByToken(id);
+    if (result == null) {
+      System.err.println("Could not resolve TypeComponent '" + id + "'.");
+    }
+    return result;
+  }
+  syn TypeComponent ASTNode.tryGloballyResolveTypeComponentByToken(String id) {
+    // id is of the form 'parent_type_name + "." + child_type_name'
     int dotIndex = id.indexOf(".");
     String parentTypeName = id.substring(0, dotIndex);
     String childTypeName = id.substring(dotIndex + 1);
@@ -23,12 +37,19 @@ aspect NameResolution {
         return comp.asTypeComponent();
       }
     }
-    System.err.println("Could not resolve TypeComponent '" + id + "'.");
     return null;
   }
 
+  // rel ___ -> Component
   refine RefResolverStubs eq ASTNode.globallyResolveComponentByToken(String id) {
-    // return a Component. id is of the form 'parent_type_name + "." + child_type_name'
+    Component result = tryGloballyResolveComponentByToken(id);
+    if (result == null) {
+      System.err.println("Could not resolve Component '" + id + "'.");
+    }
+    return result;
+  }
+  syn Component ASTNode.tryGloballyResolveComponentByToken(String id) {
+    // id is of the form 'parent_type_name + "." + child_type_name'
     int dotIndex = id.indexOf(".");
     String parentTypeName = id.substring(0, dotIndex);
     String childTypeName = id.substring(dotIndex + 1);
@@ -39,7 +60,30 @@ aspect NameResolution {
         return comp;
       }
     }
-    System.err.println("Could not resolve Component '" + id + "'.");
+    return null;
+  }
+
+  // rel ___ -> TokenComponent (from relast-preprocessor)
+  // refine here to have an attribute without writing on stderr if not found
+  refine NameResolution eq ASTNode.globallyResolveTokenComponentByToken(String id) {
+    TokenComponent result = tryGloballyResolveTokenComponentByToken(id);
+    if (result == null) {
+      System.err.println("Could not resolve TokenComponent '" + id + "'.");
+    }
+    return result;
+  }
+  syn TokenComponent ASTNode.tryGloballyResolveTokenComponentByToken(String id) {
+    // id is of the form 'type_name + "." + token_name'
+    int dotIndex = id.indexOf(".");
+    String typeName = id.substring(0, dotIndex);
+    String tokenName = id.substring(dotIndex + 1);
+    TypeDecl type = program().resolveTypeDecl(typeName);
+    // iterate over components and find the matching tokenComponent
+    for (Component comp : type.getComponentList()) {
+      if (comp.isTokenComponent() && comp.getName().equals(tokenName)) {
+        return comp.asTokenComponent();
+      }
+    }
     return null;
   }
 
diff --git a/ragconnect.base/src/main/jastadd/RagConnect.relast b/ragconnect.base/src/main/jastadd/RagConnect.relast
index c1cbbb2..3728d41 100644
--- a/ragconnect.base/src/main/jastadd/RagConnect.relast
+++ b/ragconnect.base/src/main/jastadd/RagConnect.relast
@@ -28,3 +28,8 @@ abstract MappingDefinitionType ::= ;
 JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
 JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
 DefaultMappingDefinition : MappingDefinition ;
+
+// only used by parser
+abstract UntypedEndpointDefinition : EndpointDefinition ::= <TokenOrType> <Indexed:boolean> <WithAdd:boolean> ;
+ReceiveUntypedEndpointDefinition : UntypedEndpointDefinition;
+SendUntypedEndpointDefinition : UntypedEndpointDefinition;
diff --git a/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag b/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag
new file mode 100644
index 0000000..214fec4
--- /dev/null
+++ b/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag
@@ -0,0 +1,74 @@
+aspect ParserRewrites {
+  rewrite SendUntypedEndpointDefinition {
+    when (tryGloballyResolveTypeComponentByToken(getTokenOrType()) != null)
+    to SendTypeEndpointDefinition {
+      SendTypeEndpointDefinition result = new SendTypeEndpointDefinition();
+      result.applyFrom(this);
+      if (this.getIndexed()) {
+        result.setUseList(true);
+      }
+      return result;
+    }
+  }
+
+  rewrite ReceiveUntypedEndpointDefinition {
+    when (tryGloballyResolveTypeComponentByToken(getTokenOrType()) != null)
+    to ReceiveTypeEndpointDefinition {
+      ReceiveTypeEndpointDefinition result = new ReceiveTypeEndpointDefinition();
+      result.applyFrom(this);
+      if (this.getWithAdd()) {
+        result.setWithAdd(true);
+      }
+      if (this.getIndexed()) {
+        result.setUseList(true);
+      }
+      return result;
+    }
+  }
+
+  rewrite SendUntypedEndpointDefinition {
+    when (tryGloballyResolveTokenComponentByToken(getTokenOrType()) != null)
+    to SendTokenEndpointDefinition {
+      SendTokenEndpointDefinition result = new SendTokenEndpointDefinition();
+      result.applyFrom(this);
+      return result;
+    }
+  }
+
+  rewrite ReceiveUntypedEndpointDefinition {
+    when (tryGloballyResolveTokenComponentByToken(getTokenOrType()) != null)
+    to ReceiveTokenEndpointDefinition {
+      ReceiveTokenEndpointDefinition result = new ReceiveTokenEndpointDefinition();
+      result.applyFrom(this);
+      return result;
+    }
+  }
+
+  protected void TypeEndpointDefinition.applyFrom(UntypedEndpointDefinition def) {
+    this.setAlwaysApply(def.getAlwaysApply());
+    this.setType(TypeComponent.createRef(def.getTokenOrType()));
+    this.moveMappingsFrom(def);
+  }
+
+  protected void TokenEndpointDefinition.applyFrom(UntypedEndpointDefinition def) {
+    this.setAlwaysApply(def.getAlwaysApply());
+    this.setToken(TokenComponent.createRef(def.getTokenOrType()));
+    this.moveMappingsFrom(def);
+  }
+
+  protected void EndpointDefinition.moveMappingsFrom(UntypedEndpointDefinition def) {
+    // can safely iterate over list as we get an unmodifyable list
+    for (MappingDefinition mapping : def.getMappingList().toArray(new MappingDefinition[0])) {
+      def.removeMapping(mapping);
+      this.addMapping(mapping);
+    }
+  }
+
+  private void UntypedEndpointDefinition.clearMappings() {
+  }
+
+  eq UntypedEndpointDefinition.targetTypeName() = "<unknown>";
+  syn MEndpointDefinition UntypedEndpointDefinition.toMustache() {
+    throw new RuntimeException("UntypedEndpoint can not be transformed using toMustache!");
+  }
+}
diff --git a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
index a7ba289..1088ba5 100644
--- a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
+++ b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
@@ -43,49 +43,49 @@ EndpointDefinition endpoint_definition
 ;
 
 EndpointDefinition endpoint_definition_type
-  = RECEIVE token_ref           {: return new ReceiveTokenEndpointDefinition().setToken(token_ref); :}
-  | SEND token_ref              {: return new SendTokenEndpointDefinition().setToken(token_ref); :}
-  | RECEIVE TREE type_ref       {: return new ReceiveTypeEndpointDefinition().setType(type_ref); :}
-  | RECEIVE TREE WITH ADD type_ref
+  = SEND ID.type_name DOT ID.child_name
     {:
-      ReceiveTypeEndpointDefinition result = new ReceiveTypeEndpointDefinition();
-      result.setType(type_ref);
-      result.setWithAdd(true);
+      SendUntypedEndpointDefinition result = new SendUntypedEndpointDefinition();
+      result.setTokenOrType(type_name + "." + child_name);
+      return result;
+    :}
+  | SEND INDEXED ID.type_name DOT ID.child_name
+    {:
+      SendUntypedEndpointDefinition result = new SendUntypedEndpointDefinition();
+      result.setTokenOrType(type_name + "." + child_name);
+      result.setIndexed(true);
+      return result;
+    :}
+  | RECEIVE ID.type_name DOT ID.child_name
+    {:
+      ReceiveUntypedEndpointDefinition result = new ReceiveUntypedEndpointDefinition();
+      result.setTokenOrType(type_name + "." + child_name);
       return result;
     :}
-  | SEND TREE type_ref          {: return new SendTypeEndpointDefinition().setType(type_ref); :}
-  | RECEIVE LIST type_ref
+  | RECEIVE INDEXED ID.type_name DOT ID.child_name
     {:
-      ReceiveTypeEndpointDefinition result = new ReceiveTypeEndpointDefinition();
-      result.setType(type_ref);
-      result.setUseList(true);
+      ReceiveUntypedEndpointDefinition result = new ReceiveUntypedEndpointDefinition();
+      result.setTokenOrType(type_name + "." + child_name);
+      result.setIndexed(true);
       return result;
     :}
-  | RECEIVE LIST WITH ADD type_ref
+  | RECEIVE WITH ADD ID.type_name DOT ID.child_name
     {:
-      ReceiveTypeEndpointDefinition result = new ReceiveTypeEndpointDefinition();
-      result.setType(type_ref);
+      ReceiveUntypedEndpointDefinition result = new ReceiveUntypedEndpointDefinition();
+      result.setTokenOrType(type_name + "." + child_name);
       result.setWithAdd(true);
-      result.setUseList(true);
       return result;
     :}
-  | SEND LIST type_ref
+  | RECEIVE INDEXED WITH ADD ID.type_name DOT ID.child_name
     {:
-      SendTypeEndpointDefinition result = new SendTypeEndpointDefinition();
-      result.setType(type_ref);
-      result.setUseList(true);
+      ReceiveUntypedEndpointDefinition result = new ReceiveUntypedEndpointDefinition();
+      result.setTokenOrType(type_name + "." + child_name);
+      result.setIndexed(true);
+      result.setWithAdd(true);
       return result;
     :}
 ;
 
-TokenComponent token_ref
-  = ID.type_name DOT ID.token_name  {: return TokenComponent.createRef(type_name + "." + token_name); :}
-;
-
-TypeComponent type_ref
-  = ID.parent_type_name DOT ID.child_type_name  {: return TypeComponent.createRef(parent_type_name + "." + child_type_name); :}
-;
-
 ArrayList string_list
   = ID
   | string_list COMMA ID
diff --git a/ragconnect.base/src/main/jastadd/scanner/Keywords.flex b/ragconnect.base/src/main/jastadd/scanner/Keywords.flex
index 6983010..11f73da 100644
--- a/ragconnect.base/src/main/jastadd/scanner/Keywords.flex
+++ b/ragconnect.base/src/main/jastadd/scanner/Keywords.flex
@@ -5,7 +5,8 @@
 "maps"       { return sym(Terminals.MAPS); }
 "to"         { return sym(Terminals.TO); }
 "as"         { return sym(Terminals.AS); }
-"tree"       { return sym(Terminals.TREE); }
-"list"       { return sym(Terminals.LIST); }
+//"tree"       { return sym(Terminals.TREE); }
+//"list"       { return sym(Terminals.LIST); }
 "with"       { return sym(Terminals.WITH); }
+"indexed"    { return sym(Terminals.INDEXED); }
 "add"        { return sym(Terminals.ADD); }
diff --git a/ragconnect.tests/src/test/01-input/list/Test.connect b/ragconnect.tests/src/test/01-input/list/Test.connect
index c0efaea..7720e95 100644
--- a/ragconnect.tests/src/test/01-input/list/Test.connect
+++ b/ragconnect.tests/src/test/01-input/list/Test.connect
@@ -1,6 +1,6 @@
-send list SenderRoot.A ;
-send list SenderRoot.SingleA ;
-receive list ReceiverRoot.A ;
-receive list ReceiverRoot.FromSingleA ;
-receive list with add ReceiverRoot.WithAddFromA ;
-receive list with add ReceiverRoot.WithAddFromSingleA ;
+send indexed SenderRoot.A ;
+send indexed SenderRoot.SingleA ;
+receive indexed ReceiverRoot.A ;
+receive indexed ReceiverRoot.FromSingleA ;
+receive indexed with add ReceiverRoot.WithAddFromA ;
+receive indexed with add ReceiverRoot.WithAddFromSingleA ;
diff --git a/ragconnect.tests/src/test/01-input/singleList/Test.connect b/ragconnect.tests/src/test/01-input/singleList/Test.connect
index 21b2796..8876730 100644
--- a/ragconnect.tests/src/test/01-input/singleList/Test.connect
+++ b/ragconnect.tests/src/test/01-input/singleList/Test.connect
@@ -1,13 +1,13 @@
-send tree SenderRoot.A1 ;
-send tree SenderRoot.A2 ;
-send tree SenderRoot.A3 ;
-send tree SenderRoot.A4 ;
+send SenderRoot.A1 ;
+send SenderRoot.A2 ;
+send SenderRoot.A3 ;
+send SenderRoot.A4 ;
 send SenderRoot.InOutput using IntToA ;
 
-receive tree ReceiverRoot.A ;
-receive tree ReceiverRoot.UsingWildcardA ;
-receive tree with add ReceiverRoot.WithAddA ;
-receive tree with add ReceiverRoot.UsingWildcardWithAddA ;
+receive ReceiverRoot.A ;
+receive ReceiverRoot.UsingWildcardA ;
+receive with add ReceiverRoot.WithAddA ;
+receive with add ReceiverRoot.UsingWildcardWithAddA ;
 
 IntToA maps int i to A {:
     return new A().setID(i);
diff --git a/ragconnect.tests/src/test/01-input/singleListVariant/Test.connect b/ragconnect.tests/src/test/01-input/singleListVariant/Test.connect
index 2336510..6a33afe 100644
--- a/ragconnect.tests/src/test/01-input/singleListVariant/Test.connect
+++ b/ragconnect.tests/src/test/01-input/singleListVariant/Test.connect
@@ -1,28 +1,28 @@
-send tree SenderRoot.T_Empty ;
-send tree SenderRoot.T_Token ;
-send tree SenderRoot.T_OneChild ;
-send tree SenderRoot.T_OneOpt ;
-send tree SenderRoot.T_OneList ;
-send tree SenderRoot.T_TwoChildren ;
-send tree SenderRoot.T_OneOfEach ;
-send tree SenderRoot.T_Abstract ;
+send SenderRoot.T_Empty ;
+send SenderRoot.T_Token ;
+send SenderRoot.T_OneChild ;
+send SenderRoot.T_OneOpt ;
+send SenderRoot.T_OneList ;
+send SenderRoot.T_TwoChildren ;
+send SenderRoot.T_OneOfEach ;
+send SenderRoot.T_Abstract ;
 
-receive tree ReceiverRoot.T_Empty ;
-receive tree ReceiverRoot.T_Token ;
-receive tree ReceiverRoot.T_OneChild ;
-receive tree ReceiverRoot.T_OneOpt ;
-receive tree ReceiverRoot.T_OneList ;
-receive tree ReceiverRoot.T_TwoChildren ;
-receive tree ReceiverRoot.T_OneOfEach ;
-receive tree ReceiverRoot.T_Abstract ;
+receive ReceiverRoot.T_Empty ;
+receive ReceiverRoot.T_Token ;
+receive ReceiverRoot.T_OneChild ;
+receive ReceiverRoot.T_OneOpt ;
+receive ReceiverRoot.T_OneList ;
+receive ReceiverRoot.T_TwoChildren ;
+receive ReceiverRoot.T_OneOfEach ;
+receive ReceiverRoot.T_Abstract ;
 
-receive tree ReceiverRoot.MyEmpty ;
+receive ReceiverRoot.MyEmpty ;
 
-receive tree with add ReceiverRoot.EmptyWithAdd ;
-receive tree with add ReceiverRoot.TokenWithAdd ;
-receive tree with add ReceiverRoot.OneChildWithAdd ;
-receive tree with add ReceiverRoot.OneOptWithAdd ;
-receive tree with add ReceiverRoot.OneListWithAdd ;
-receive tree with add ReceiverRoot.TwoChildrenWithAdd ;
-receive tree with add ReceiverRoot.OneOfEachWithAdd ;
-receive tree with add ReceiverRoot.AbstractWithAdd ;
+receive with add ReceiverRoot.EmptyWithAdd ;
+receive with add ReceiverRoot.TokenWithAdd ;
+receive with add ReceiverRoot.OneChildWithAdd ;
+receive with add ReceiverRoot.OneOptWithAdd ;
+receive with add ReceiverRoot.OneListWithAdd ;
+receive with add ReceiverRoot.TwoChildrenWithAdd ;
+receive with add ReceiverRoot.OneOfEachWithAdd ;
+receive with add ReceiverRoot.AbstractWithAdd ;
diff --git a/ragconnect.tests/src/test/01-input/tree/Test.connect b/ragconnect.tests/src/test/01-input/tree/Test.connect
index 857f629..3fc8564 100644
--- a/ragconnect.tests/src/test/01-input/tree/Test.connect
+++ b/ragconnect.tests/src/test/01-input/tree/Test.connect
@@ -1,2 +1,2 @@
-send tree SenderRoot.Alfa ;
-receive tree ReceiverRoot.Alfa ;
+send SenderRoot.Alfa ;
+receive ReceiverRoot.Alfa ;
diff --git a/ragconnect.tests/src/test/01-input/treeAllowedTokens/Test.connect b/ragconnect.tests/src/test/01-input/treeAllowedTokens/Test.connect
index d872ce5..c17a58e 100644
--- a/ragconnect.tests/src/test/01-input/treeAllowedTokens/Test.connect
+++ b/ragconnect.tests/src/test/01-input/treeAllowedTokens/Test.connect
@@ -1,13 +1,13 @@
-send tree SenderRoot.Alfa ;
-receive tree ReceiverRoot.Alfa ;
+send SenderRoot.Alfa ;
+receive ReceiverRoot.Alfa ;
 
 receive SenderRoot.Input1WhenFlagIsTrue ;
 receive SenderRoot.Input1WhenFlagIsFalse ;
 receive SenderRoot.Input2 ;
 receive SenderRoot.Input3 ;
 
-send tree SenderRoot.AlfaPrimitive using Alfa2String ;
-receive tree ReceiverRoot.AlfaPrimitive using String2Alfa ;
+send SenderRoot.AlfaPrimitive using Alfa2String ;
+receive ReceiverRoot.AlfaPrimitive using String2Alfa ;
 
 Alfa2String maps Alfa alfa to String {:
   StringBuilder sb = new StringBuilder();
-- 
GitLab