Referencing to a class generated in another language/generator
My scenario:
I have a "Document" concept. I defined a generator, which generates classes with names in this form: "class Document{ID}DAO".
In another language, in which I need to have Document{ID}Model which should have "static Document{ID}Model getModel(Document{ID}DAO dao)"
How can I do that? It seems that I have to use some kind of mapping label, but I can't find how to put one on generated class. Besides, it seems that labes are not exported from one generator to another.
Please sign in to leave a comment.
How do I reference from one generator to classes generated in another generator?
i think http://code.google.com/p/mps-lwc11/downloads/detail?name=LWC11-MPS-Docs.pdf&can=2&q=
Page 36ff will help you ...
Best,
Dan
Wowzers on the solution though :p
CrossModuleReferenceTest.zip (74KB)
i m using the 1.5 version of mps. There i can set the mps.internal=true and i can select the generate stup for solution checkbox. Like described in the lwc11 guide, i can reference generated classes from other models then ...
Dan
If you generate one model, referenced models could be not generated yet. So you cannot rely on their output or intermediate models. Instead you should produce output given the very first existing input models.
There are many ways to achieve that goal in your own language. But the idea is still the same. The number of external nodes you need to generate a model is quite few. You probably don't need every existing model, but only ones you refer to. Besides, you don't need every node from that models except the "exported" or "public" ones. Talking about java, the only data you need about existing classes is their methods, fields and inner classifiers, i.e. an interface, not the implementation. The solution is to import this external APIs into our model in the beginning and process them along with the current model.
Let's consider an example. We have two models X and Y. The first one contains higher-level abstraction of classifier (like state machine). The later one refers to the first one.
Here is the reduction sequence:
X: ConceptA -> ConceptB -> Classifier -> java class
Y: ConceptARef -> ConceptBRef -> ClassifierType -> ref to class in .java file
If ConceptA and ConceptARef live in the same model, everything is clear. When they are separated there is a problem: we cannot refer to ConceptB from ConceptBRef. The target doesn't exist while we generate Y. It only appears in intermediate models of X. OK, we need to make this reference internal.
The obvious ways are:
1. Whenever you need to refer to ConceptB, copy it into the current transient model, as a root, but mark it somehow to delete at the last step (to avoid text generation). That is exactly what Java compiler does when you import external classes: it reads them (without method bodies, of course), stores their interface in the memory and probably processes them.
2. Create an internal reference concept, containing all required information about the target (method call can contain types for all parameters for example). For baseLanguage we created such internal concepts in generator-specific baseLanguageInternal language.
Ideally could you demonstrate using the simple example I posted in this thread the supported way(s) of doing this?
Can you think of any reason they would have been working for the past week or so?
The thing I was missing was I needed to add a separate mapping configuration for the preprocessing script that imports the externals that happens before the main mapping configuration.
I've attached it for anyone interested: CrossModuleReferenceTest-importExternals.zip (171KB)
At the moment I just use string reference macros. So I can succeed generation but java compilation fails because of missing references.
in a pre-process mapping script, but I only see nodes from the current model and none from the imported ones.
Is there any other way to ask question like the above?
But as far as I understand this forum, you get notifications for threads you have posted something or marked as favorite. Ok, there is also a rss feed to read new threads, but in my rss reader the newest entry for this url http://forum.jetbrains.com/_rss/forum?forum=Meta-Programming-System is from the 9th of May. So there is seems to be some problem... perhaps just with my reader (Opera). If the important users here don't use the forum directly, its advanced features like voting and read count make not so much sense.
Since my problem has been discussed here before, I really can't imagine that no one can or want to give me a small hint.
What's wrong with my approach? Is there any documentation to the IScope and all this model/module dependencies stuff???
1) import generated classes as JavaStubs. You can refer to them by qualified class names (for example from reference macro). Usually these classes are a part of runtime of your language.
2) use baseLanguageInternal, which allows to convert references to text as early as possible. The main disadvantage is that subsequent generator has no access to reference target, which often requires wrapping your expression into TypeHintExpression.
GlobalScope/ProjectScope should be used only in dialogs allowing to add new dependency or to define scope for Find Usages tool.
Thank you very much for your answer! Both approaches seems to make lots of overhead for me. I just want to supply some common root nodes, which could be used and should be available if the accessories model is imported. And I don't want to create a special generator for imported roots.
So I guess copying imported models to my current model will be the best way for me. But therefor I must solve the problem with the nodesIncludingImported operation, I mentioned here. Do you have any idea how I can access imported nodes from within the generator?
But wouldn't it be a nice feature if you could access output nodes of an accessories model from your sandbox model. Because accessories models are part of the language they must be build before you create your normal models.
Many thanks! But this is not very intuitive.
I haven't thought that the input model for the first generator is already a transient one and also I don't know that imports are removed in transient models. There should be a warning if you use nodesIncludingImported with a normal model you get in every generator method.