diff --git a/ragconnect.base/src/main/jastadd/NameResolution.jrag b/ragconnect.base/src/main/jastadd/NameResolution.jrag index 3b75bc0eb633830cb0e63c80d5d51e7d04e1b4f0..80525b590d886af4db3c0dd1916a73d356df2244 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 c1cbbb2445e55956f41ee780eab2e216175b6b6f..3728d411587de9d543fce2e8b71b37083d0e68b4 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 0000000000000000000000000000000000000000..214fec41df4de5a2bcf56288b892cda8d7aea068 --- /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 a7ba289535a01938c1284ad67f46b2a9e81b9fb5..1088ba51ac2de82cc2baaa7b618b0b05d84da4cb 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 69830108bfb0644cd75008b47b58ee149dc3b2ad..11f73da45e957a008b32fbddc050bb619f58f100 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 c0efaea9d5ad307c0c43b7d577b1cff5884c0d8b..7720e95233ef2eec1073d60cb6936205c8b1410c 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 21b2796544ae65e96da5b03f088e5f7966620a7f..8876730fda2ae27dc8fb886dec2bdba08a6ecf31 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 23365109901425e8a6060c3ef3c2d8fe4cfc7656..6a33afea9cd1c56604dbe0b6bffc180bd1c8cb63 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 857f6297f12249451b026051201ebfc004c2f6a6..3fc8564ee5c8f53076d8e27ef29c590885205a58 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 d872ce56c59097e678e6cff0b25ec422130b6129..c17a58e7d9798217c582ac5e65492ba25bcb7ea2 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();