How to substitute XXX.class.getName() in generation when class is returned by concept behavior?
I have a concept behavior method with java.lang.Class return type.
What is the way to generate XXX.class.getName() when doing "to baseLanguage" generation?
If I try ReferenceMacro over Object: ->$[ Object ] .class.getName() I get "type java.lang.Class is not subtype of node<Classifier>" error (reference target is implemented by mere "node.getOutputClass()")
...
After a bit of reflection I realized "concept behaviours should not be used to return java objects". Am I right?
So, instead of returning java objects like "java.util.Map" from concept behaviours and trying to convert it back to template form in generator, either relevant node<...> should be returned from behaviour or template switch should be used.
Is it the case?
PS. It looks like ClassifierResolveUtils.resolveSpecialSyntax could be used to convert from "class name as string to node<Classifier> form", however it looks to be much easier to avoid that and use node<Classifier> in behaviour return type.
What is the way to generate XXX.class.getName() when doing "to baseLanguage" generation?
If I try ReferenceMacro over Object: ->$[ Object ] .class.getName() I get "type java.lang.Class is not subtype of node<Classifier>" error (reference target is implemented by mere "node.getOutputClass()")
...
After a bit of reflection I realized "concept behaviours should not be used to return java objects". Am I right?
So, instead of returning java objects like "java.util.Map" from concept behaviours and trying to convert it back to template form in generator, either relevant node<...> should be returned from behaviour or template switch should be used.
Is it the case?
PS. It looks like ClassifierResolveUtils.resolveSpecialSyntax could be used to convert from "class name as string to node<Classifier> form", however it looks to be much easier to avoid that and use node<Classifier> in behaviour return type.
Please sign in to leave a comment.
I've attached my current code.
I'm trying to create a DSL for Apache JMeter (jmeter.apache.org/index.html).
I want sharing generator logic (just to avoid repeated code for each and every type of test element), so I created "AbstractTestElement_generator" that does the following:
1. Creates java object with specific class name, relevant for the concrete implementation of the concept.
2. Attaches current element to its parent tree
3. Applies COPY_SRC to children
The specific element calls $INCLUDE$AbstractTestElement_generator and does some concept-specific stuff.
So, my key problem is
P1) "how AbstractTestElement_generator would know the proper node < Classifier > to use when creating element"
P2) The one I listed at stackoverflow: "how could I attach metadata to concept properties, so I can move generic setProperty loop right into AbstractTestElement_generator".
Concepts
AbstractTestElement_concept.png (65KB)
Controller_concept.png (62KB)
ThreadGroup_concept.png (74KB)
Behaviors
ThreadGroup_generator.png (204KB)
Generators
AbstractTestElement_generator.png (209KB)
ThreadGroup_generator.png (204KB)
I've attached current code to both original question and the reply, however it does not appear in forum UI when browsing.
First or all, I propose to NOT use behaviour methods for parameterising generation process here.
I think, it's better to use template fragments for specifying exact JMeter (runtime) class representing specific concept (sub-concept of AbstractTestElement). If you'd like to keep single template for AbstractTestElement & instantiate specific classes for each sub-concept of AbstractTestElement concept, you can:
See StyleAttribute template switch doing something similar in MPS.
Similar approach can be used to instantiate proper runtime class for properties: (String/LongProperty), but instead of template switch this time you have to use reference macro with java switch inside. If you prefer to reuse corresponding code across different reference macros - you can extract it into a java class inside generator and call corresponding class from the reference macros.
In general, my suggestions would be:
In MPS you can find similar "properties" inside editor language, see StyleClassItem concept. Our decision was to create exact sub-concept for each property "kind" and keep them all in the same plain list of properties (single containment role). The benefit here is: in this case you can create single template for each "property" generating complete code line like:
Thank you for the suggestion.
I wonder how that could be extended by "inherited languages".
As far as I can understand, a set of $SWITCH$ statements would be hard-coded in the language itself.
I wonder how that would be extendable.
When using behaviors, just adding more "AbstractTestElement subconcepts" makes thing work with core generator.
How a derived language would stuff it's own test element concepts into my $SWITCH$?
I do not quite get which mapping configuration would be used in presence of multiple derived languages.
I want to factor "new ThreadGroup" to the Abstract... generator since I need to associate a mapping label with that newly created item (see AbstractTestElement_generator.png above)
I just do not want copy&paste all those mapping code around, so I tried to factor that out.
That works, however, can you please shed some light on my P2 question?
Basically, if I could associate "AbstractThreadGroup.NUM_THREADS" with given concept property, I could move as much "boilerplate generation" as it is possible to the Abstract.. generator, so some of the components would be just "do Abstract.. generation".
Just a small little annotation over LinkDeclaration.
How that "extended switch" would sneak into logic of my AbstractTestElement generator?