How to add content to a TemplateFragment via Open API?

I am able to create and add a TemplateDeclaration to the generators. I also figured to place my actual content in the context of a TemplateFragment . Basically I tried to reproduce the following outcome (see image "desired outcome").
My question is: What is the right approach to reproduce the result shown in the following image?

(Image: desired outcome)
mpsJA1.png


My code so far creates another outcome (see image at the bottom):
  ⋮
// create template declaration 
node<TemplateDeclaration> jaTemplate = new node<TemplateDeclaration>(); 
jaTemplate.name = "reduce_JointAngles"; 
jaTemplate.applicableConcept.set(stub);

// create the template fragment TF 
node<TemplateFragment> tf = new node<TemplateFragment>(); 

// create inner element 
node<XmlElement> element = new node<XmlElement>(); 
element.tagName = "data";

// add element to TF
tf.contextNodeQuery.set(element);
  ⋮
prettyPrint();
(Image: actual outcome)
mpsJA2.png


Thanks in advance!

Cheers,
Dennis
8 comments
I guess you'll need to do something like this:
jaTemplate.contentNode = element;
jaTemplate.contentNode.@templateFragment = new node<TemplateFragment>();
prettyPrint();
TemplateFragment is a node attribute (annotation) and so is added though the .@ syntax to decorate other nodes. Generator macros are also macros and you will need to handle them in a similar way.

You can read more on handling attributes at https://confluence.jetbrains.com/display/MPSD32/Commenting+out and https://confluence.jetbrains.com/display/MPSD32/Documentation+comments
0
Thx very much, that helped me alot!

So in addition to that I would like to create a $LOOP$ macro. I get stuck while creating the mapped nodes part (as seen in the following image):
loopTest.png

Now my problem is to create the DotExpression . How do I access the node parameter and angles variable, which is a child of the associated Concept :
conceptTest.png

My code so far:
// create the source node query
node<SourceSubstituteMacro_SourceNodesQuery> loopQuery = new node<SourceSubstituteMacro_SourceNodesQuery>();
  ⋮
// create statements and stuff
  ⋮
// create the DotExpression
node<DotExpression> dotExp = new node<DotExpression>();
// trying to access the node operand and operation???
dotExp.operand.set(loopQuery.getParameters()
    .findFirst({~it => it.name.equalsIgnoreCase("TemplateFunctionParameter_sourceNode"); })); ???
dotExp.operation ???
prettyPrint();

What do I have to do, in order to make it work, and what would be the right way to do it properly?


Cheers,
Dennis
0
The operation must be some of the SNodeOperations sub-concepts, perhaps one of SPropertyAccess, SLinkAccess or SLinkListAccess.
You can find out the actual concept by looking at the "node.angles" expression in your first screen-shot and observe the concept in the Inspector window or highlight the line and opening it in Node Explorer (Alt + F12).

Also, you may use quotations to build parts of AST in a more convenient way.

Vaclav
0
This is the node-structure of what I'd like to achieve:
dotExpressionNodes.png

But I'm still not quite sure how to create the operation and operand for this specific DotExpression ...
// this is the angles field of the concept that needs to be referenced as operation...
node<LinkDeclaration> link1 = new node<LinkDeclaration>(); 
link1.role.set("angles"); 
link1.metaClass.set(enum member value/LinkMetaclass : aggregation/); 
link1.target.set(concept/FloatingPointConstant/); 
link1.sourceCardinality.set(enum member value/Cardinality : 0..n/);

  ⋮

// query
node<SourceSubstituteMacro_SourceNodesQuery> loopQuery = new node<SourceSubstituteMacro_SourceNodesQuery>();
// body
node<StatementList> loopBodyStatementList = new node<StatementList>();
// statement
node<ExpressionStatement> expStatement = new node<ExpressionStatement>();
// expression
node<DotExpression> dotExp = new node<DotExpression>();

//  (node.angles) operation (would be angles); set the link from above ???
node<SLinkListAccess> lla = new node<SLinkListAccess>();
lla.link.set(link1); ???
dotExp.operation.set(lla);

// (node.angles) operand (would be node)???
dotExp.operand.set(loopQuery.getParameters()
   .findFirst({~it => it.name.equalsIgnoreCase("TemplateFunctionParameter_sourceNode"); })); ???
prettyPrint();
This is not really working, because the DotExpression is not being shown in the inspector after executing this code. So there seems to be something wrong, but I can't figure what? And how to do it right...
0
I can't see in the snippets of your code adding the DotExpression to the ExpressionStatement neither adding the ExpressionStatement to the loopBodyStatementList, but maybe you just omitted that from the listing:
loopBodyStatementList.statement.add(expStatement)
expStatement.expression = dotExp
prettyPrint();
0
Thanks! Actually for some reasons I did add it the wrong way... Now it's showing up, but the operand is still wrong.
I would like to access the the node parameter from the (genContext, node, operationContext)->sequence<node<>> function.
As you can see in the image below, the operation works properly (see the .angles; on the top right). Only the operand is actually referring to the concept of TemplateFunctionParameter_sourceNode itself.
TemplateFunctionParameter_sourceNode.png

So my approach seems to be wrong for the operand :
dotExp.operand.set(loopQuery.getParameters()
    .findFirst({~it => it.name.equalsIgnoreCase("TemplateFunctionParameter_sourceNode"); }));
prettyPrint();
How can I reference the node parameter of the SourceSubstituteMacro_SourceNodesQuery -context as operand ?
0
I wound try creating the operand this way:
dot.operand = new node<TemplateFunctionParameter_sourceNode>();
prettyPrint();
0

Please sign in to leave a comment.