[Xtext] Formatter2 usage when programmatically save Xtext resource [message #1710808] |
Fri, 09 October 2015 08:47  |
Eclipse User |
|
|
|
Hi there,
I implemented a Formatter2, which works nicely in the IDE when hitting
Strg-Shift-F. However, when I programmatically save a resource, the
serializer of the Xtext Resource is always the OneSpaceFormatter and not
my formatter 2.
My Code to save is
public static void writeXtextResource(Path target, EObject object)
throws IOException{
new org.eclipse.emf.mwe.utils.StandaloneSetup().setPlatformUri("../");
Injector injector = new
PkpConfigStandaloneSetup().createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet =
injector.getInstance(XtextResourceSet.class);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
URI fileURI = URI.createFileURI(target.toAbsolutePath().toString());
Resource resource = resourceSet.createResource(fileURI);
resource.getContents().clear();
resource.getContents().add(object);
resource.save(SaveOptions.newBuilder().format().getOptions().toOptionsMap());
}
I debugged the Injector which actually has my formatter options taken
from the Module.
I enabled the Formatter2 in the mwe file
// formatter API
//fragment = formatting.FormatterFragment auto-inject {}
fragment = formatting2.Formatter2Fragment auto-inject {}
This leads to the corresponding binding in the abstract RuntimeModule
generated for my language:
// contributed by org.eclipse.xtext.generator.formatting2.Formatter2Fragment
public Class<? extends org.eclipse.xtext.formatting2.IFormatter2>
bindIFormatter2() {
return
de.scheidtbachmann.pkp.config.text.formatting2.PkpConfigFormatter.class;
}
// contributed by org.eclipse.xtext.generator.formatting2.Formatter2Fragment
public void configureFormatterPreferences(com.google.inject.Binder
binder) {
binder.bind(org.eclipse.xtext.preferences.IPreferenceValuesProvider.class).annotatedWith(org.eclipse.xtext.formatting2.FormatterPreferences.class).to(org.eclipse.xtext.formatting2.FormatterPreferenceValuesProvider.class);
}
Still, the formatter in the serializer of the XtextResource is the
OneSpaceFormatter...
How to change that?
Cheers,
Hauke
|
|
|
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746670 is a reply to message #1710808] |
Wed, 02 November 2016 13:53   |
Eclipse User |
|
|
|
Xtext Version 2.10.0
I have the same issue as the OP, basically that when programmatically trying to format using just the runtime project, not the UI, then the formatter that is used is always OneWhitespaceFormatter, even when an alternate Formatter2 is available.
More specifically, I have a single Xtext runtime project with Maven structure. The workflow is configured to generate Formatter2, and it does. I've implemented my Formatter2 formatter, and have implemented a unit test (in the same project under src/test/java) to test it. The test runs fine, but my Formatter2 implementation is never invoked. Using the debugger, I note that when I "format" DefaultNodeModelFormatter.format() is called, which then uses a dependency injected IFormatter (i.e., a OneWhitespaceFormatter instance). An instance of my Formatter2 implementation is created by the injection framework and available.
I dug around in some other Xtext projects that I have that do have UI's, some with Formatter2 implementations, and some without. The ones that do have this:
// contributed by org.eclipse.xtext.xtext.generator.formatting.Formatter2Fragment2
public Class<? extends IContentFormatterFactory> bindIContentFormatterFactory() {
return ContentFormatterFactory.class;
}
in their Abstract<MYDSL>UiModule, which would explain why it works in the UI.
I suspect that Formatter2 "handling" in just the runtime project is not implemented yet. One way forward would be for me to override bindINodeModelFormatter() in my DSL's RuntimeModule and return a custom implementation of INodeModelFromatter to support Formatter2.
Am I missing something?
Would this create problems if/when I do develop a UI?
Has this already been addressed in a new version?
Thanks
Dan
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746813 is a reply to message #1746811] |
Fri, 04 November 2016 17:50   |
Eclipse User |
|
|
|
I've been going through the Xtext code looking for where the runtime guice bindings are produced, etc.
I see that the method org.eclipse.xtext.generator.formatting2.Formatter2Fragment.getGuiceBindingsRt() produces the bindings provided above for the Abstract RuntimeModule.
i.e.,:
// contributed by org.eclipse.xtext.xtext.generator.formatting.Formatter2Fragment2
public void configureFormatterPreferences(Binder binder) {
binder.bind(IPreferenceValuesProvider.class).annotatedWith(FormatterPreferences.class).to(FormatterPreferenceValuesProvider.class);
}
But, not surprisingly, I put some breakpoints in, and it never gets called. I dug around trying to find how the workflow would be configured to get it into the mix, but didn't find anything.
So, I started at StandardLanguage and looked around for how it might be configured and would eventually trigger the call to getGuiceBindingsRt() and couldn't find a path from there either.
In the right configuration, it obviously gets called, but I can't see how to conjure that up.
Any hints? Is there some obvious documentation that I've overlooked?
Thanks
Dan
|
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746827 is a reply to message #1746790] |
Sat, 05 November 2016 05:20   |
Eclipse User |
|
|
|
Daniel Ford wrote on Fri, 04 November 2016 15:42
In code, the unit test I'm using to test formatting uses this utility method to perform the formatting and test that the result is as expected:
def void assertFormattedAs(CharSequence input, CharSequence expected) {
expected.toString.assertEquals(
(input.parse.eResource as XtextResource).parseResult.rootNode.format(0, input.length).formattedText)
}
Daniel, this looks like the code snippet in the first edition of the Xtext book, and it is based on the old formatter, you can't use that with the new formatter. The second edition of the book deals with the new formatter, which is also much easier to test, as Christian showed.
Lorenzo
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746899 is a reply to message #1746827] |
Mon, 07 November 2016 08:25   |
Eclipse User |
|
|
|
Lorenzo,
thanks for the tip. BTW, I enjoyed your book, thought it was well written; better yet, I've ordered the second edition, it should be here this week.
The reason I'm using XtextGeneratorLanguage instead of StandardLanguage is because the documentation here: https://www.eclipse.org/Xtext/documentation/302_configuration.html#short-intro-to-mwe
says that it "is not possible to remove fragments from the StandardLanguage." At the moment, I'm generating the runtime project from an external ecore file, and am only interested in generating as little as possible.
From the documentation, it would seem that "fragment = formatting.Formatter2Fragment2()" would do the trick to produce Formatter2 support using XtextGeneratorLanguage in the runtime project, but I haven't found that to be the case. So, it would seem like there's either a bug in the code, or a bug in the documentation.
The guice bindings for the runtime project are produced in org.eclipse.xtext.generator.formatting2.Formatter2Fragment.getGuiceBindingsRt(), but it's never called during the XtextGeneratorLanguage workflow.
Dan
|
|
|
|
Powered by
FUDForum. Page generated in 0.06634 seconds