Codegenerierung mit Xtend

Transcription

Codegenerierung mit Xtend
Codegenerierung mit Xtend








































Uni Jena, 2013-04-22
© itemis AG


























Code Generator
• DomainmodelGenerator.xtend
• in the package org.eclipse.xtext.example.generator
• in DSL project!
package org.eclipse.xtext.example.generator
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.IGenerator
import org.eclipse.xtext.generator.IFileSystemAccess
class DomainmodelGenerator implements IGenerator {
override void doGenerate(Resource resource, IFileSystemAccess fsa) {
//TODO implement here
}
}








































• override doGenerate method
© itemis AG


























2
Access the Model








































• 




for(e: resource.allContents.toIterable.filter(typeof(Entity))) {

...

}


filter the contents of the resource (model root) down to the defined entities


• iterate a resource with all its deeply nested elements with allContents


(method getAllContents())

• resulting in a TreeIterator


• to iterate in a for loop use extension method toIterable() from library

IteratorExtensions


• filter by type


• lambda expression .filter(): Bedingung wird auf jedes Element der Menge

angewendet

• type expression typeof(Entity)  org.eclipse.xtext.example.domainmodel.Entity



© itemis AG
3
Generierten Code Schreiben
fsa.generateFile(
e.fullyQualifiedName.toString("/") + ".java“,
e.compile)
• File schreiben: generateFile(String
fileName, CharSequence contents)
• Methode im übergebenen Filesystem-Access-Objekt: IFileSystemAccess
fsa
• Service für vollqualifizierten Namen nach Java-Style: IQualifiedNameProvider
• als Extension einbinden
@Inject extension IQualifiedNameProvider
• IQualifiedNameProvider-Extension stellt Methode fullyQualifiedName zur
Verfügung
• Umwandlung in Pfad mit toString("/“)








































• Fileinhalt wird in Methode compile berechnet
© itemis AG


























4
Strukturierung des Generators
• Mit Xtend Klassen und Methoden
• Methodenaufruf mit
compile(e)
• erster Parameter auch mit Punktschreibweise
e.compile()
• unnötige Klammern weg
e.compile
• Methodendefinition
def compile(Entity e) {}
• Methode mit Template Expression (Rich String)
def compile(Entity e) ’’’
package «e.eContainer.fullyQualifiedName»;








































public class «e.name» {
}
’’’
© itemis AG


























5
Template Expressions
• Template Expression bieten
• eingebettete Ausdrücke
• intelligenten Zeilenumbruch, WhiteSpaces und Einrückungen
• eingebettete Kontroll-Ausdrücke
def compile(Entity e) ’’’
«IF e.eContainer != null»
package «e.eContainer.fullyQualifiedName»;
«ENDIF»
public class «e.name» «IF e.superType != null
»extends «e.superType.fullyQualifiedName» «ENDIF»{
«FOR f:e.features»
//...
«ENDFOR»
}
’’’
• eingebettete Methodenaufrufe








































’’’ ... «f.compile» ... ’’’
© itemis AG


























6
Starten der Codegenerierung
• Codegenerator läuft beim Speichern im Editor








































• geht auch headless im Buildprozess
© itemis AG


























7