|
|
|
Re: Dokumentation for Formatter2 API [message #1837168 is a reply to message #1837167] |
Sat, 23 January 2021 08:54   |
|
I have the following formatter code:
def dispatch void format(GeneratorModel m, extension IFormattableDocument document) {
// TODO: format HiddenRegions around keywords, attributes, cross references, etc.
// model.region
val model = m.regionFor
model.keyword("generator").prepend[newLine]
interior(
m.regionFor.keyword('{').append[newLine],
m.regionFor.keyword('}'),
[indent]
)
for (sub : m.templateList) {
sub.format
}
}
def dispatch void format(TemplateDescriptor m, extension IFormattableDocument document) {
interior(
m.regionFor.keyword('{').append[newLine],
m.regionFor.keyword('}'),
[indent]
)
for (sub : m.sectionOrder) {
sub.format
}
// td.append[setNewLines(1, 1, 2)]
}
def dispatch void format(Section m, extension IFormattableDocument document) {
// TODO: format HiddenRegions around keywords, attributes, cross references, etc.
interior(
m.regionFor.keyword('{').append[newLine],
m.regionFor.keyword('}'),
[indent]
)
for (sub : m.mapping) {
sub.format
}
}
the coresponding grammar looks like this (terminal rule FQN ommitted)
GeneratorModel:
"generator" "model" name=FQN "for" model=[ecore::EPackage]
("template" templateList+=TemplateDescriptor)*;
TemplateDescriptor:
name=ID sectionMarker=STRING variableMarker=STRING "{"
sectionOrder+=Section*
"}"
;
Section:
name=ID "{"
mapping+=SectionVarMapping
"}"
;
SectionVarMapping:
name=ID feature=[ecore::EStructuralFeature|FQN]
;
the coresponding grammar looks like this (terminal rule FQN ommitted)
GeneratorModel:
"generator" "model" name=FQN "for" model=[ecore::EPackage]
("template" templateList+=TemplateDescriptor)*;
TemplateDescriptor:
name=ID sectionMarker=STRING variableMarker=STRING "{"
sectionOrder+=Section*
"}"
;
Section:
name=ID "{"
mapping+=SectionVarMapping
"}"
;
SectionVarMapping:
name=ID feature=[ecore::EStructuralFeature|FQN]
;
And the following model text
template ClassTemplate "//XXXXX" "_X_" {
package {
packageName GeneratorModel.name
}
classheader {
className GeneratorModel.name
}
}
I expected the first '}' to be indented with the "package" subsequent line should be as well indented this way except the last '}'.
What is missing in my formatter code?
|
|
|
Re: Dokumentation for Formatter2 API [message #1837254 is a reply to message #1837168] |
Tue, 26 January 2021 10:10  |
|
Hello Olaf,
In order to indent the closing '}' with the "package" keyword, you have to append a newline to the beginning and to the end of the interior.
The following formatter implementation works for me:
/*
* generated by Xtext 2.25.0-SNAPSHOT
*/
package org.xtext.example.mydsl.formatting2
import org.eclipse.xtext.formatting2.AbstractFormatter2
import org.eclipse.xtext.formatting2.IFormattableDocument
import org.xtext.example.mydsl.myDsl.GeneratorModel
import org.xtext.example.mydsl.myDsl.Section
import org.xtext.example.mydsl.myDsl.SectionVarMapping
import org.xtext.example.mydsl.myDsl.TemplateDescriptor
class MyDslFormatter extends AbstractFormatter2 {
def dispatch void format(GeneratorModel m, extension IFormattableDocument document) {
for (sub : m.templateList) {
sub.format
}
}
def dispatch void format(TemplateDescriptor m, extension IFormattableDocument document) {
val begin = m.regionFor.keyword("{")
val end = m.regionFor.keyword("}")
begin.append[newLine]
interior(begin, end)[indent]
for (sub : m.sectionOrder) {
sub.format
}
}
def dispatch void format(Section m, extension IFormattableDocument document) {
val begin = m.regionFor.keyword("{")
val end = m.regionFor.keyword("}")
begin.append[newLine]
interior(begin, end)[indent]
for (sub : m.mapping) {
sub.format
}
end.append[newLine]
}
def dispatch void format(SectionVarMapping m, extension IFormattableDocument document) {
m.append[newLine]
}
}
The corresponding JUnit test cases:
package org.xtext.example.mydsl.tests
import com.google.inject.Inject
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.formatter.FormatterTestHelper
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(XtextRunner)
@InjectWith(MyDslInjectorProvider)
class MyDslFormatterTest {
@Inject extension FormatterTestHelper
@Test def test001() {
assertFormatted[
toBeFormatted = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {}
'''
expectation = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
}
'''
]
}
@Test def test002() {
assertFormatted[
toBeFormatted = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
package {
}
}
'''
expectation = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
package {
}
}
'''
]
}
@Test def test003() {
assertFormatted[
toBeFormatted = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
package {
packageName GeneratorModel.name
}
}
'''
expectation = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
package {
packageName GeneratorModel.name
}
}
'''
]
}
@Test def test004() {
assertFormatted[
toBeFormatted = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
package {
packageName GeneratorModel.name
}
classheader {
className GeneratorModel.name
}
}
'''
expectation = '''
generator model foo for bar
template ClassTemplate "//XXXXX" "_X_" {
package {
packageName GeneratorModel.name
}
classheader {
className GeneratorModel.name
}
}
'''
]
}
}
Hope that helps,
Tamás
|
|
|
Powered by
FUDForum. Page generated in 0.02232 seconds