Home » Modeling » TMF (Xtext) » Parsing in-memory codes with crossrefs between resources in RCP application(I need to parse in-memory pseudocodes split into several chunks using Xtext. The chunks have crossreferences between each other. It works from an RCP application if the content is in files in the work)
Parsing in-memory codes with crossrefs between resources in RCP application [message #1795760] |
Fri, 28 September 2018 02:40  |
Eclipse User |
|
|
|
Hello,
TL;DR: I need to parse in-memory pseudocodes split into several chunks using Xtext. The chunks have crossreferences between each other. It works from an RCP application if the content is in files in the workspace, also from a standalone application for in-memory pseudocodes (using 'createInjectorAndDoEMFRegistration'), but now I need to combine the two approaches, i.e. parsing in-memory pseudocodes in RCP app, but the crossreference resolution between resources do not work.
In my project I am parsing pseudocode split into several files using Xtext.
When executed as Eclipse RCP application, the crossreferences between files in the editor work as expected, this is nice.
When executed as a command line application, I follow the method described in the FAQ (https://wiki.eclipse.org/Xtext/FAQ#How_do_I_load_my_model_in_a_standalone_Java_application.C2.A0.3F): I use new MyLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); to get an injector, then inject a Provider<XtextResourceSet> resourceSetProvider, create an XtextResourceSet, set the OPTION_RESOLVE_ALL to true, then for each chunk of the pseudocode to be parsed I create a new resource in the resource set:
Resource resource = resourceSet.createResource(URI.createURI("dummy:/" + (i++) + ".ext");
InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
resource.load(inputStream, resourceSet.getLoadOptions());
This works well too, the crossreferences between the resources are resolved correctly.
Now I need to combine these two approaches. In my Eclipse RCP application I need to be able to parse files in the workspace, as well as pseudocodes that exist only in memory, i.e., not backed by any file in the workspace. Of course, the second approach described above is not expected to work out of the box, as it uses createInjectorAndDoEMFRegistration(). The parsing of in-memory pseudocodes work with that, but I get exceptions ("Passed org.eclipse.xtext.builder.clustering.CurrentDescriptions is not based on a resource set") and GUI glitches in the editor, as expected.
If instead of creating a new injector I fetch the injector used by the GUI (via the getInjector method of the Activator in my ui project), the crossreference resolution between different dummy:/ resources do not work, and I get "ERROR org.eclipse.xtext.linking.lazy.LazyLinkingResource - resolution of uriFragment '|30' failed." errors. If I use the activator's injector but with platform:/ URIs pointing to existing files, it seems to work.
What is different between the automatically created injector and the one created by createInjectorAndDoEMFRegistration that prevents me from parsing the dummy:/ resources properly, with crossreference resolution between different resources in the same resource set? May I fix it somehow or am I doing something stupid? Unfortunately the nicer, ExecutableExtensionFactory-based solution (as mentioned in http://koehnlein.blogspot.com/2012/11/xtext-tip-how-do-i-get-guice-injector.html) to get the injector is not an option, but I assume it would not make any difference as I'd get the same injector.
You can find an MWE attached. The key part of it is the following code (in org.xtext.example.mydsl.ui.CustomMydslActivator):
Injector injector = MydslActivator.getInstance().getInjector(ORG_XTEXT_EXAMPLE_MYDSL_MYDSL);
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
Resource res1 = resourceSet.createResource(URI.createURI("dummy:/1.mydsl"));
res1.load(new ByteArrayInputStream("person A; Hello A! Hello B!".getBytes(StandardCharsets.UTF_8)), resourceSet.getLoadOptions());
Resource res2 = resourceSet.createResource(URI.createURI("dummy:/2.mydsl"));
res2.load(new ByteArrayInputStream("person B;".getBytes(StandardCharsets.UTF_8)), resourceSet.getLoadOptions());
EcoreUtil.resolveAll(resourceSet); // just in case
Model model1 = (Model)res1.getContents().get(0);
System.out.println(model1.getGreetings().get(1).getPerson()); // Prints: org.xtext.example.mydsl.myDsl.impl.PersonImpl@51038633 (eProxyURI: dummy:/1.mydsl#|1)
System.out.println(model1.getGreetings().get(1).getPerson().eIsProxy()); // Prints: true. Apparently, the proxy cannot be resolved.
Thanks a lot for any suggestion,
Daniel
|
|
| |
Re: Parsing in-memory codes with crossrefs between resources in RCP application [message #1795850 is a reply to message #1795772] |
Mon, 01 October 2018 07:48  |
Eclipse User |
|
|
|
Dear Christian,
Thank you very much for your swift help! I have adapted it to our real code and it seems to work like a charm.
> - i wonder how you managed to create that broken zip file. (some bad mixing of windows paths inside the file nams)
It was created with 7-Zip, sorry for the additional burden.
> - the usecase you describe is non xtext supports out of the box
I thought there were already use cases when some text somehow appearing in memory (e.g. from a SWT textbox or a file not in the workspace) needs to be parsed together with some other resources (e.g. loaded from file). Apparently I was mistaken.
Thanks again!
Cheers,
Daniel
|
|
|
Goto Forum:
Current Time: Sat Jun 14 13:29:01 EDT 2025
Powered by FUDForum. Page generated in 0.04244 seconds
|