Access to current Node during code generation

Hello!

I want to create some utility method like this:

class Utility {

public static Something perform( node<SomeConcept> arg) {...return new Something();}


}

And I want to invoke this method from some template

<F  Utility.perform() F>

But how can I to get access to current Node inside a template ?

7 comments

Out of the top of my head, I don't know what you're indicating with <F ... F>, but if this is a template fragment, you need to understand that this contributes to a template.

A template tells the generator what the output should be when it runs. Using so-called macros, you can annotate nodes inside of your template which will allow you to bring dynamic elements into your template: https://confluence.jetbrains.com/display/MPSD20182/Generator#Generator-Macro

So, the answer to your question depends of what that "Something" is your utility is returning.

For example, if you want to build a utility that does some calculation on your input node and returns a sequence so that you can instruct your template to LOOP over this sequence, you need to use $LOOP$ macro. A property macro, for example, just allows you to dynamically replace a primitive, static property in your template with one from your model.

A COPY-SRC macro allows you to copy the node your utility returns ("Something") into the template, maybe that's what you need? 

The hook, where you can call your utility, is shown in the inspector view when your select the corresponding macro annotation in the main template editor.

Does this help?

1

Robert, thank you for your answer! I think LOOP and COPY-SRC are not only what I need. Or probably I am not so experiense in MACROs.

I will try describe problem in general. May be you can give me an advice :)

I have Expression concept that can be like this:   var exp = (A or B) and (not(C and D or E))

where A B C D E - variables names

So, I want to build Java tree for this Expression like this:

 

                                                  AND (Java ANDoperation class)

                                               /           \

(Java ORoperation class)  OR          NOT (Java NOToperation class)

                                         /         \            \

(Java VAR class)           _A_   _B_           (....)

 

for this reason I need to generate for var exp = (A or B) and (not(C and D or E)) a Java container class and a method adding Expression to it

something like this:



and later I create a variable

But I dont understand how to perform Expression because that can be AND or boolean or something else. How can I build Java tree for Expression (suppose Value Java class) and add it to "Variable var" object  (suppose var.setValue(new Value(...))?

 

0

Given the expression

var exp = (A or B) and (not(C and D or E))

how exactly does the Java code that you want to generate look like?

0

There are can be different implementtions.

For example: for plain

var exp = A and B


Variable v = new Variable()

v.setName("exp")

ANDop and = new ANDop(new VarRef("A"), new VarRef("B"))

v.setValue(and)

0

So, for the LHS of your output assignment you need to create a static type declaration based on the root node of your RHS of your input expression, to infer the type so to speak.

For the RHS of your output, you need to create a nested expression that calls the constructors of your Java types that represent the node types of your input. So, you need templates for all of your possible node types (AND, OR, NOT, leafs) in a template switch which is called recursively.

Something roughly along the lines of this (not tested!):

template switch ExpressionSwitch extends <none> 

parameters
value : node<Expression>

null-input message: <none>

cases:

concept AndConcept --> <T new ANDOp($SWITCH$ ExpressionSwitch[new leftChild()], $SWITCH$ ExpressionSwitch[new rightChild()]) T>
inheritors true
condition always

concept OrConcept --> <T new OROp($SWITCH$ ExpressionSwitch[new leftChild()], $SWITCH$ ExpressionSwitch[new rightChild()]) T>
inheritors true
condition always

concept NotConcept --> <T new NOTOp($SWITCH$ ExpressionSwitch[new onlyChild()]) T>
inheritors true
condition always

concept VarRef --> <T new VarRef("$[Name]") T>
inheritors true
condition always


 

Call this template switch in the context of your "getVariable template fragment".

Hope this helps!

2

Robert, thank you. Looks interesting. I'll try this.

1

Robert, that works for my small piece of variations. So thanks again :)



2

Please sign in to leave a comment.