|
|
|
|
|
|
|
|
|
|
|
|
Re: Connecting to a non-xtext language from Eclipse: Binding ResourceDescriptionStrategy [message #1778661 is a reply to message #1778346] |
Tue, 19 December 2017 15:07 |
Steffen Zschaler Messages: 266 Registered: July 2009 |
Senior Member |
|
|
OK, so I finally got this to work.
The core of the problem was indeed related to my slightly strange resource description strategy: For some reason, in some cases Xtext seems to bypass the strategy altogether. As a result, my adapters weren't always reliably installed.
To fix this, I have implemented a full implementation of that provides translation services and a new that installs these whenever an appropriate resource is opened or created. This resource set then replaces the SynchronizedXTextResourceSet in my DSLModule.
Interestingly, I had to make sure that I only do this when running in Eclipse. When running standalone, everything seems to work fine without my translating resource set. In fact, adding it in causes errors (I assume, but haven't followed this in detail, because there is now a conflict with how my resource description strategy works). This was easy enough to solve by binding the resource set in the right module, but I remain confused about why this would happen: As far as I can tell, none of my code is dependent on the environment. Yet, Xtext seems to take a substantially different path for parsing and validation depending on whether it's running standalone or in Eclipse.
Out of curiosity: does this ring a bell with anybody?
Many thanks,
Steffen
|
|
|
|
Re: Connecting to a non-xtext language from Eclipse: Binding ResourceDescriptionStrategy [message #1778670 is a reply to message #1778667] |
Tue, 19 December 2017 17:16 |
Steffen Zschaler Messages: 266 Registered: July 2009 |
Senior Member |
|
|
I've not made any changes to how the resource factory is registered. However, my adaptation language probably breaks some assumptions in EMF or Xtext: Essentially, my setup is as follows:
I have three metamodels:
- A: my xtext DSML. This contains references to elements of B.
- B: my adaptation layer language. Instances of this wrap instances of C.
- C: a pre-existing language. This has been developed by a third party and comes with a full plugin registering the metamodel etc.
I have developed B by writing an ecore model and generating java code from it, then manually modifying the implementation to add appropriate forwarding and translation to the adaptation layer (including translation of references, etc.). It's not a hugely complicated language, so this was fairly straightforward.
I now registered a new resource description strategy for ".c" files that would produce EObjectDescriptions with suitable B instances wrapping the C objects. Effectively, I expected this to make it look to my xtext language A as if ".c" files actually contained only B objects.
This was enough for standalone use, but not quite enough for use in Eclipse. Here, I also had to introduce a wrapper for the resource and resource set. Note that C already comes with a fully-defined resource factory and registration set up, which I don't want to touch. I also don't want to have to materialise B files; their purpose is purely as an adaptation layer. As a result, there is no actual physical resource that has the B elements. Instead, I'm now providing an instance of my translating resource that is backed by the original C resource and behaves as if it is inside the same resource set.
To make sure this translating resource is picked up, I introduced the translating resource set. I couldn't think of a meaningful way of doing this otherwise, given that I only want translation to happen when ".c" files are looked at from my xtext DSL A (so I cannot simply replace the resource factory for ".c" files, if I'm not mistaken). This seems to work mostly, though, slightly annoyingly, the original resource still leaks on occasion (in particular, when the automated builders are running).
This felt like the natural way to solve this, but is beginning to increasingly feel like more complicated than it should be. I might be barking up the wrong tree here and there may be a much easier way to get what I want that I'm just not seeing. Any thoughts along those lines would of course be very much appreciated.
|
|
|
Re: Connecting to a non-xtext language from Eclipse: Binding ResourceDescriptionStrategy [message #1778706 is a reply to message #1778670] |
Wed, 20 December 2017 10:57 |
Steffen Zschaler Messages: 266 Registered: July 2009 |
Senior Member |
|
|
Having debugged this a bit more, it seems that what I'm really missing is the right place to inject stuff. At the moment, it seems that my resource description strategy and the translating resource/resource set are correctly picked up when parsing/linking/validating from within an editor, but are not picked up at all when the automated build is running. As a result, all works well in the editor, but I get all kinds of weird and wonderful errors as soon as I save a ".a" file.
Here's what I have done to inject the various bits and pieces. The ResourceDescriptionStrategy is injected via the Activator and ExecutableExtensionFactory (and extension point as per above) of the B plugin (I realise, I will eventually want to separate out the IDE and non-IDE bits here, but haven't done so for now):
public class AdaptationRuntimeModule extends AbstractGenericResourceRuntimeModule {
@Override
protected String getLanguageName() {
return "...BEditorID";
}
@Override
protected String getFileExtensions() {
return "c";
}
public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
return AdaptationResourceDescriptionStrategy.class;
}
...
}
The translating resource set (remember, for some reason this is only needed when running from Eclipse) is injected from A's .ui plugin like this:
/**
* Use this class to register components to be used within the Eclipse IDE.
*/
@FinalFieldsConstructor
class AUiModule extends AbstractAUiModule {
def Class<? extends XtextResourceSet> bindXtextResourceSet() {
TranslatingResourceSet // a sub-class of SynchronizedXtextResourceSet
}
}
When validation etc runs in the editor, it correctly uses my resource description strategy and the new resource set. When the automated builder runs, it uses a normal SynchronizedXtextResourceSet and also doesn't seem to pick up the resource description strategy.
Looks like I need to register things in another way somewhere else. What am I missing?
Steffen
|
|
|
|
|
|
|
|
|
|
|
Re: Connecting to a non-xtext language from Eclipse: Binding ResourceDescriptionStrategy [message #1778737 is a reply to message #1778729] |
Wed, 20 December 2017 15:30 |
Steffen Zschaler Messages: 266 Registered: July 2009 |
Senior Member |
|
|
Thanks, both. Given that I already have the translation stuff in place and it's more a matter of getting it hooked into xtext in the right place, I'm thinking about not using derived state computer. If I understand correctly, it's just a different way of getting the translation done, but I would still be left with the problem of actually hooking things up correctly. (Correct me if I'm wrong).
I suspect that the main problem is that I am doing two things for one resource URI. I don't want to pollute the resource contents with my adapter elements (which is what derived state computation seems to be doing, although there's a fair amount of cleanup going on, too). Importantly, my adapter objects have the same name as the original objects, so that might cause problems down the line if they're both in the same resource, especially as I seem to struggle getting xtext to reliably use my resource-description strategy.
So my plan is to go with something along the lines of what Ed suggests by creating virtual resources with a new ".c.b" suffix, registering my adapter language against "*.b" files. Because these files will never actually exist, I need a way of pretending to xtext that they are there by creating a virtual ".c.b" resource for every ".c" resource xtext considers in scope. I'm thinking that injecting my own version of PersistedStateProvider (via org.eclipse.xtext.ui.shared.overridingGuiceModule) is the way to go here. Then, I can override the load method to add IResourceDescriptions for the ".c.b" resources as needed. Providing a suitably "magic" resource factory for ".b" files (as sketched by Ed above) should then hopefully make sure that the translation magic is put in place as needed.
Does this sound like a sensible path? I'm a little worried about having to use org.eclipse.xtext.ui.shared.overridingGuiceModule as this makes the change global and might lead to conflicts with other xtext languages. But given that PersistedStateProvider is bound in SharedModule, I guess I don't have much choice, do I?
Many thanks,
Steffen
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05144 seconds