Nachtrag zu XtendFlow

Im letzte Artikel hatte ich erwähnt, dass eine angezeigte Warnung für die bind Methode der integrierenden Funktionseinheit Normalize eine Unzulänglichkeit des Xtend-Compilers sei und diese in der nächsten Version Xtext/Xtend behoben sein wird. Leider erwies sich die Korrektur in Xtend als schwieriger als gedacht, da eine Lösung die Komponierbarkeit von Xtend-Ausdrücken erfordert, was eine signifikante mit nicht geringem Aufwand verbundene Erweiterung von Xtend's Active-Annotation-Framework bedeutet.

Das Xtext/Xtend-Team wusste noch nicht, wann sie das angehen werden. Deshalb habe ich mir noch mal Gedanken gemacht, wie man dieses Problem anders umgehen kann und habe eine Lösung gefunden, die mir im Nachhinein auch noch wesentlich besser gefällt, als die ursprüngliche.

Anstelle, als Anwender, in einer integrierenden Funktionseinheit eine expliziten Konstruktor definieren zu müssen, der die Methode aufruft, die die Ports der integrierten Funktionseinheiten miteinander verbindet, wird dieses Methode einfach per zusätzlicher Annotation @Wiring markiert. Der Annotationsprozessor ruft diese markierte Methode dann im generierten Code automatisch am Ende des generierten Konstruktors auf. Hier der alternative, neue Code der Funktionseinheit:

	@FunctionUnit(...)
	class Normalize {   
	    val toLower = new ToLower
	    val toUpper = new ToUpper
	    
	    @Wiring
	    private def void wiring() {
	        toLower.output -> [msg | lower.forward(msg)]
	        toUpper.output -> [msg | upper.forward(msg)]
	    }
	    ...
	}

Damit gibt es erst einmal keine unbegründeten Warnungen mehr für XtendFlow-annotierten Funktionseinheiten.

Ein Problem bleibt leider: Fügt der Anwender einen Konstruktor hinzu, so muss dieser Java-Code enthalten (insbesondere Semikola), da der Annotationsprozessor im Falle von integrierenden Funktionseinheiten einen Aufruf der mit @Wiring markierten Methode hinzufügt. Weil Xtend aber das Komponieren von Xtend-Ausdrücken, wie oben gesagt, noch nicht unterstützt, kann der Code des anwender-spezifizierten Konstruktors nur textuell in den des generierten Konstruktors eingefügt werden. Der generierte Konstruktor ist jedoch Java-Code, deswegen muss leider auch der anwender-spezifizierte Konstruktor Java-Code enthalten.
Dies ist jetzt nicht all zu tragisch, da Konstruktorcode in integrierenden Funktionseinheiten zumeist nur Feld-Initialisierungen und Methodenaufruf enthält, was bedeutet, das lediglich darauf zu achten ist, jedes Statement mit einen Semikolon abzuschließen.

Bleibt zu hoffen, dass das Xtext/Xtend-Team die Möglichkeit, Xtend-Ausdrücke in Annotationsprozessoren zu komponieren, alsbald dem schon so sehr beachtlichen Funktionsumfang von Xtend hinzufügt.