New File Wizard – einfach mit Xtext 2.14 generieren

Dass Xtext 2.14 in der Lage ist, einen New Project Wizard zu generieren, wurde bereits im Blog berichtet. Aber auch ein vergleichbarer, ebenfalls auf Templates basierender Wizard, um DSL-Dateien in bestehenden Projekten zu erzeugen, ist nun neu dazu gekommen.

Dieser Wizard wird mit Eclipse Photon im Juni 2018 erscheinen – hier aber schon mal eine kurze Vorschau.

Erzeugen des New File Wizards

Der Wizard für neue Dateien wird nahezu genauso erzeugt wie der Wizard für neue Projekte. In der mwe2-Datei, die definiert, was generiert wird, muss folgender Abschnitt eingefügt werden:

language = StandardLanguage {
   name = "org.xtext.example.mydsl.MyDsl"
   fileExtensions = "mydsl"
   serializer = {
       generateStub = false
   }
   fileWizard = {
       generate = true
   }
}


Die Generierung mittels
Run As -> MWE2 Workflow generiert nun den Wizard und ein beispielhaftes Template.

Im UI-Projekt der Sprache wird ein Package wizard generiert, das vor allem eine Datei MyDslFileTemplateProvider.xtend enthält (wobei der Name der Datei von dem Namen der Sprache abhängt). In dieser Datei wird der Inhalt des Wizards definiert. Weitere Konfigurationen sind normalerweise nicht nötig.

Wenn lediglich ein einzelnes Template für eine Sprache generiert wird, dann hat der Wizard nur eine Seite. Auf ihr werden neben dem Verzeichnis und einem Namen alle Parameter des Templates angegeben.

Xtext-214-new-file-wizard


Gibt es mehrere Templates, wird auf der ersten Seite eine Combo-Box zur Auswahl des Templates angezeigt. Die Parameter werden dann auf der optionalen, zweiten Seite konfiguriert.

Definieren eigener Templates

Um das “Hello World” an die eigene Sprache anzupassen oder weitere Templates hinzuzufügen, muss der TemplateProvider – eine Klasse, die IFileTemplateProvider implementiert – angepasst werden. Dieser liefert mit der Methode getFileTemplates eine Liste mit allen verfügbaren Templates für die Sprache zurück. Standardmäßig sieht die Implementierung wie folgt aus:

class MyDslFileTemplateProvider implements IFileTemplateProvider {
   override getFileTemplates() {
       #[new HelloWorldFile]
   }
}


Das Hinzufügen eines weiteren Templates ist also das Hinzufügen einer neuen Instanz zu dieser Liste – zum Beispiel:

Das neue Template muss eine Subklasse von AbstractFileTemplate sein. Am einfachsten lässt sich eine solche durch die Nutzung der Active Annotation FileTemplate erzeugen. Diese Annotation bietet die Möglichkeit, den Namen, ein Icon sowie einen Beschreibungstext für das Template festzulegen. Diese regeln die Darstellung des Templates in der Liste der verfügbaren Templates im Wizard.

Man würde also in etwa so beginnen:

@FileTemplate(label="Test", icon="file_template.png",
   description="This creates a new hello world file.")
final class HelloWorldFile {
}


Hier ist zumindest die Methode
generateFile(IFileGenerator) zu implementieren. Der übergebene IFileGenerator enthält dabei eine einzelne Methode generate(CharSequence, CharSequence)die man nun beliebig oft aufrufen kann, um beim Beenden des Wizards Dateien anzulegen.

Ein Aufruf, um ein einfaches “Hello World” zu erzeugen, kann dann zum Beispiel so aussehen:

override generateFiles(IFileGenerator generator) {
generator.generate('''«folder»/«name».mydsl''', '''
Hello «helloName»!
    ''')
}


Zusätzliche Aufrufe von
generate erzeugt weitere Dateien. Die Parameter für die Templates werden mit derselben API definiert, wie die Project Templates. Das vollständige “Hello World” sieht dann so aus:

class MyDslFileTemplateProvider implements IFileTemplateProvider {
override getFileTemplates() {
#[new HelloWorldFile]
}
}

@FileTemplate(label="Hello World", icon="file_template.png",
description="Create a hello world for MyDsl.")
final class HelloWorldFile {
val helloName = combo("Hello Name:",
#["Xtext", "World", "Foo", "Bar"],
"The name to say 'Hello' to")

override generateFiles(IFileGenerator generator) {
generator.generate('''«folder»/«name».mydsl''', '''
Hello «helloName»!
''')
}
}


Auch das Beisteuern weiterer Templates funktioniert analog zu den Projekt Templates über einen Extension Point. In diesem Fall über "org.eclipse.xtext.ui.fileTemplate".

Da Eclipse Photon noch in etwa zwei Monaten Entfernung liegt, kommt hier schon einmal der Link zur nächtlichen Update Site:

http://download.eclipse.org/modeling/tmf/xtext/updates/composite/latest/

Über Arne Deutsch

Arne Deutsch arbeitet als IT-Berater bei der itemis AG in Bonn. Seine Schwerpunkte sind Language Engineering, Xtext und die Entwicklung von Tools für Eclipse.