Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Dokumentation for Formatter2 API(How to implement formatter2 in Xtext ?)
Dokumentation for Formatter2 API [message #1837158] Fri, 22 January 2021 23:19 Go to next message
Olaf Bigalk is currently offline Olaf BigalkFriend
Messages: 155
Registered: July 2009
Location: Berlin
Senior Member
The dokumentation of the formatter2 API is for me very incomplete.
Is there any document discribing in detail how to write a formmatter2.
Re: Dokumentation for Formatter2 API [message #1837162 is a reply to message #1837158] Sat, 23 January 2021 05:19 Go to previous messageGo to next message
Tamas Miklossy is currently offline Tamas MiklossyFriend
Messages: 134
Registered: February 2016
Senior Member
Hello Olaf,

you can find more information about the Xtext formatter2 API under:

https://de.slideshare.net/meysholdt/xtexts-new-formatter-api
https://blogs.itemis.com/en/tabular-formatting-with-the-new-formatter-api
https://www.eclipse.org/forums/index.php?SQ=f1aaa0dbbe18f2d2d4155d24b42a5430&t=search&srch=formatter2&btn_submit=Search&field=all&forum_limiter=27&attach=0&search_logic=AND&sort_order=DESC&author=
take a look at the Xtext Examples shipped with the Xtext Framework, the also demonstrate the usage of the formatter2 API

If you have any particular problem, just ask a little bit more concrete question, then we were able to help you more.

Hope that helps,
Tamás

[Updated on: Sat, 23 January 2021 05:20]

Report message to a moderator

Re: Dokumentation for Formatter2 API [message #1837167 is a reply to message #1837162] Sat, 23 January 2021 08:24 Go to previous messageGo to next message
Olaf Bigalk is currently offline Olaf BigalkFriend
Messages: 155
Registered: July 2009
Location: Berlin
Senior Member
Thanx a lot I'l take a look and be eventually back with more concrete questions
Thanx a lot
Re: Dokumentation for Formatter2 API [message #1837168 is a reply to message #1837167] Sat, 23 January 2021 08:54 Go to previous messageGo to next message
Olaf Bigalk is currently offline Olaf BigalkFriend
Messages: 155
Registered: July 2009
Location: Berlin
Senior Member
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 Go to previous message
Tamas Miklossy is currently offline Tamas MiklossyFriend
Messages: 134
Registered: February 2016
Senior Member
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
Previous Topic:Strange Error Message - no clue what is wrong
Next Topic:Defining variable inside your language document?
Goto Forum:
  


Current Time: Wed Aug 04 10:03:40 GMT 2021

Powered by FUDForum. Page generated in 0.01857 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top