Using NodeModelUtils on cloned EObjects #3357
-
|
Hi, A bit of context: in my project I am developing an editor that offers some extra functionality to the user. The user can trigger this functionality from a dedicated entry in the context menu that shows up when right-clicking on the editor view. This functionality performs some computation, possibly modifying the parse tree Xtext created when parsing the file(s). Thus, after the computation has finished and the result has been presented to the user, there are discrepancies between the parse tree residing in memory and the content of the file(s). As a consequence, if the user triggers this functionality again, a failure happens, as the functionality now operates on a tainted parse tree. To work around this problem, I wrote some code to duplicate the entire ResourceSet (because in our DSL, model files can import other model files) containing the Resource corresponding to the file the user right-clicked on when they triggered the functionality. This way, the functionality operates on a clean parse tree that matches the textual models each time it is invoked. Preliminary question: is this a clever idea, or are there better ways to achieve this? Assuming it is a clever idea, let's move on to the real problem. The code for my extra functionality exploits FYI, the code I'm using to duplicate the ResourceSet is: xtextResource = ... // the resource corresponding to the file on which the extra functionality has been called
ResourceSet originalResourceSet = xtextResource.getResourceSet();
XtextResourceSet newResourceSet = new XtextResourceSet();
originalResourceSet.getLoadOptions().forEach(newResourceSet::addLoadOption); // not sure this is needed
EcoreUtil2.clone(newResourceSet, originalResourceSet);
EcoreUtil2.resolveAll(newResourceSet); // not sure this is needed eitherMany thanks in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Hi, final ResourceSet newResourceSet = new XtextResourceSet();
resourceSet.getResources().forEach(originalResource -> {
final EObject rootEObject = originalResource.getContents().get(0);
final String originalResourceText = NodeModelUtils.getNode(rootEObject).getText();
final XtextResource newResource = (XtextResource) newResourceSet.createResource(originalResource.getURI());
try {
newResource.reparse(originalResourceText);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
resourceSet.getResources().forEach(resource -> ((XtextResource) resource).relink());I am not sure the final calls to |
Beta Was this translation helpful? Give feedback.
Hi,
I'm coming back to this post to report that after doing some research I understood that there is no easy way to duplicate the node model associated with a Resource/EObject. For reference, see https://www.eclipse.org/forums/index.php/t/489882/ and https://www.eclipse.org/forums/index.php/t/1095332/
The standard approach to overcome this limitation is to create a new Resource and reparse the content of the Resource to be cloned into it. This means that one has to work at the level of the Resources and not of the single EObjects. For example, this is what I am doing in my project: