|
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746670 is a reply to message #1710808] |
Wed, 02 November 2016 17:53 |
Daniel Ford Messages: 148 Registered: July 2009 Location: New York |
Senior Member |
|
|
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 #1746790 is a reply to message #1746677] |
Fri, 04 November 2016 15:42 |
Daniel Ford Messages: 148 Registered: July 2009 Location: New York |
Senior Member |
|
|
Here's the relevant part of the wf
language = XtextGeneratorLanguage {
name = "com.foo.bar"
fileExtensions = "zipzap"
resourceSet = theResourceSet
fragment = grammarAccess.GrammarAccessFragment2 {}
fragment = ecore.EMFGeneratorFragment2 {}
fragment = serializer.SerializerFragment2 {}
fragment = resourceFactory.ResourceFactoryFragment2 {}
fragment = parser.antlr.XtextAntlrGeneratorFragment2 {}
fragment = validation.ValidatorFragment2 {}
fragment = scoping.ImportNamespacesScopingFragment2 {}
//fragment = exporting.QualifiedNamesFragment2 {}
fragment = builder.BuilderIntegrationFragment2 {}
//fragment = generator.GeneratorFragment2 {}
fragment = formatting.Formatter2Fragment2 {
generateStub=true
generateXtendStub=true
}
//fragment = ui.labeling.LabelProviderFragment2 {}
//fragment = ui.outline.QuickOutlineFragment2 {}
//fragment = ui.outline.OutlineTreeProviderFragment2 {}
//fragment = ui.quickfix.QuickfixProviderFragment2 {}
//fragment = ui.contentAssist.ContentAssistFragment2 {}
fragment = junit.Junit4Fragment2 {}
//fragment = ui.refactoring.RefactorElementNameFragment2 {}
fragment = types.TypesGeneratorFragment2 {}
//fragment = xbase.XtypeGeneratorFragment2 {}
//fragment = xbase.XbaseGeneratorFragment2 {}
//fragment = ui.templates.CodetemplatesGeneratorFragment2 {}
//fragment = ui.compare.CompareFragment2 {}
//fragment = idea.parser.antlr.XtextAntlrIDEAGeneratorFragment {}
//fragment = idea.IdeaPluginGenerator {}
//fragment = web.WebIntegrationFragment {
// framework = "Ace"
//}
}
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)
}
Something I didn't mention, but could be important, is that formatting wasn't originally enabled when the workflow was first run to generate the project's artifacts. It was enabled later.
Maybe I need to delete some artifacts and have the workflow generate new versions that do enable formatting2?
Is that what' you're looking for?
Dan
[Updated on: Fri, 04 November 2016 15:51] Report message to a moderator
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746794 is a reply to message #1746790] |
Fri, 04 November 2016 16:04 |
|
no you dont. but i dont get why you have all these fragments in the workflow
if you create a new project it looks like
language = StandardLanguage {
name = "org.xtext.example.mydsl2.MyDsl"
fileExtensions = "mydsl2"
serializer = {
generateStub = false
}
validator = {
// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
}
}
here you can simply add this
formatter { generateStub = true }
i dont know what your pile of customizations may have as a side effect.
thus i recommend this with a new project and a new workflow first.
and you should consider to use FormatterTester for such tests
if i enable formatter fragment i get following bindings
(check this with your in (abstract)yourdslruntimemodule
// contributed by org.eclipse.xtext.xtext.generator.formatting.Formatter2Fragment2
public Class<? extends IFormatter2> bindIFormatter2() {
return MyDslFormatter.class;
}
// contributed by org.eclipse.xtext.xtext.generator.formatting.Formatter2Fragment2
public void configureFormatterPreferences(Binder binder) {
binder.bind(IPreferenceValuesProvider.class).annotatedWith(FormatterPreferences.class).to(FormatterPreferenceValuesProvider.class);
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
|
|
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746813 is a reply to message #1746811] |
Fri, 04 November 2016 21:50 |
Daniel Ford Messages: 148 Registered: July 2009 Location: New York |
Senior Member |
|
|
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 09:20 |
|
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
HOME: http://www.lorenzobettini.it
TDD Book: https://leanpub.com/tdd-buildautomation-ci
Xtext Book: https://www.packtpub.com/application-development/implementing-domain-specific-languages-xtext-and-xtend-second-edition
|
|
|
Re: [Xtext] Formatter2 usage when programmatically save Xtext resource [message #1746899 is a reply to message #1746827] |
Mon, 07 November 2016 13:25 |
Daniel Ford Messages: 148 Registered: July 2009 Location: New York |
Senior Member |
|
|
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.06340 seconds