Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden

Die Seite wird erstellt Finja Junker
 
WEITER LESEN
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Software Factories

   8 Xtend

SS 2018

Prof. Dr. Dirk Müller
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Übersicht
    ●     Motivation: pro und contra Java
    ●     Hello-World-Beispiel
    ●     Sichtweisen, Einordnung und Geschichte
    ●     Beispiel „Liste von Strings in Großbuchstaben“
    ●     wichtige Schlüsselwörter
    ●     Active Annotations
    ●     Operator-Überladung
    ●     Template Expressions
    ●     Codegenerierung für das HelloDSL-Beispiel
    ●     Codegenerierung für einen Prolog-zu-Scheme-Transpiler
    ●     Zusammenfassung
                           Dirk Müller: Software Factories
SS 2018                                                           2/37
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Java
    ●   Vorteile
        –   plattformunabhängig durch Bytecode-Ansatz, Ausführung auf JVM
        –   objektorientierte und imperative Paradigmen kombiniert
        –   mächtige Bibliotheken
        –   sehr gute integrierte Entwicklungsumgebungen (frei) verfügbar
    ●   Nachteile                                     Umwandlung einer Liste von
        – Redundanz im Quellcode mit Typangaben      Strings in die zugehörige Liste
                                                     von Strings in Großbuchstaben
        – funktionales Paradigma kaum umgesetzt
        – keine Operatorüberladung
       public ArrayList toUpperCase(final List strings) {
           final ArrayList result = new ArrayList();
           for (final String string : strings) {
             String _upperCase = string.toUpperCase();
             result.add(_upperCase);
           }
           return result;
         }
                            Dirk Müller: Software Factories
             Quelle: [2]
SS 2018                                                                          3/37
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Hello World!
    package example1
    class HelloWorld {
        def static void main(String[] args) {
             println('Hello World!')
                                      package example1;
        }
                                      import org.eclipse.xtext.xbase.lib.InputOutput;
    }
                                      @SuppressWarnings("all")
                                      public class HelloWorld {
                                        public static void main(final String[] args) {
                                          InputOutput.println("Hello World!");
                                        }
                                      }

      ●   Xtend-Code wird beim Speichern automatisch (on-the-
          fly) in korrespondierenden Java-Code übersetzt und im
          Ordner xtend-gen (anpassbar) abgelegt
      ●   auffällige Einsparungen
          – Semikolons als Trenner zwischen Anweisungen
          – Rückgabetypen

                              Dirk Müller: Software Factories
SS 2018                                                                                  4/37
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Am 20.03.2018
          erschienen!
                          Java 10 bereits heute
     ●   flexibler und ausdrucksstarker
         Java-Dialekt
         – keine Interoperabilitätsprobleme mit Java
     ●   wird zu gut lesbarem Java-5-kompatiblen
         (anpassbar) Code kompiliert
     ●   nahtlose Nutzung bestehender
         Java-Bibliotheken
     ●   Ausführung (fast) so schnell wie bei Handcodierung
     ●   Paradigmen: objektorientiert, imperativ und funktional
     ●   Typ-Inferenz, Makros (Active Annotations), Lambda-
         Ausdrücke und Operatorüberladung als einige Highlights
     ●   statische Typisierung
        – gut für Fehlersuche und IDE-Integration
                           Dirk Müller: Software Factories
          Quelle: [5]
SS 2018                                                           5/37
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Android-GUI-Programmierung mit Xtend
    ●     nur von Mini-Laufzeitbibliothek org.eclipse.xtend.lib
          abhängig, die hauptsächlich aus Google Guava besteht
          – Google Guava sollte sowieso genutzt werden

            Quelle: [7]     Dirk Müller: Software Factories
SS 2018                                                           6/37
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Sichtweisen auf Xtend

    ●     abgespecktes Java
    ●     ideale Ergänzung zu einer mit Xtext spezifizierten DSL, um
          einen Übersetzer (Transpiler) oder einen Compiler selbst
          zu schreiben
    ●     „Xtend ist ein Java-Dialekt, der mir weniger Geschwätz
          und mehr Funktionalität bietet“ [4]
    ●     „Java + Xtend == Better Java“ [2]
    ●     ein integrierender Java-Transpiler
    ●     ein typsicherer Ersatz für Java Server Pages (JSP) [6]

                           Dirk Müller: Software Factories
SS 2018                                                                7/37
Software Factories SS 2018 - Prof. Dr. Dirk Müller - HTW Dresden
Einordnung
    ●     JVM-Sprachen nutzen die hochoptimierte Java Virtual
          Machine zur Ausführung von Bytecode

                                                                    org.eclipse.xtend.lib
                                                                                            On-the-fly-Transpiler
    ●     z. B. Scala, Groovy, Clojure, JRuby
        Scala-Quellcode                 Java-Quellcode                                       Xtend-Quellcode
            (.scala)                        (.java)                                              (.xtend)

     Groovy-Quellcode
         (.groovy)                           javac

     Clojure-Quellcode                                              Vorteile
     (.clj,cljs,.cljc,.edn)                                       ● Performanz
                                     Java-Bytecode (.class)       ● einfache Integration
        JRuby-Quellcode
                                                                  ● einfache Fehlerbehe-
             (.rb)
                                                                    bung via Java-Debugger
                               JVM           JVM              JVM
                              Windows        Linux            Mac

             Quelle: [6]
                                Dirk Müller: Software Factories
SS 2018                                                                                                             8/37
Geschichte
    ●     Ursprünge in openArchitectureWare (2006-2011)             JAX Innovation
          – Xpand als statisch typisierte Templatesprache für       Award 2007:
                                                                     1. Groovy
            M2C-Transformationen                                     3. oAW
          – Xtend als funktionale Sprache, um das Metamodell mit
            zusätzlicher Logik erweitern zu können (M2M-Transformationen)
    ●     2011 Xtend2 (Suffix .xtend) als Ersatz für Xpand (.xpt)
          und Xtend (.exp), später Namensvereinfachung zu Xtend
    ●     Version 2.7.0 vom 2.9.2014
          – reife Makros via Active Annotations, z. B. @Accessors
    ●     Version 2.8.0 vom 11.3.2015
          – Reverse Engineering von Java zu Xtend incl. Warnungen bei
            unübersetzbarem Code (FixMe-Tags) unterstützt
    ●     Version 2.9.0 vom 1.12.2015
          – Unterstützung von IntelliJ IDEA und Android Studio
    ●     aktuelle Version 2.11.0 vom 01.02.2017
            Quellen: [5][6]   Dirk Müller: Software Factories
SS 2018                                                                         9/37
Beispiel Liste von Strings in Großbuchstaben
    public ArrayList toUpperCase(final List strings) {
        final ArrayList result = new ArrayList();
        for (final String string : strings) {
          String _upperCase = string.toUpperCase();
          result.add(_upperCase);
        }                                var list = new ArrayList();
        return result;                            in Java 10 [9] möglich
      }
    Java            def toUpperCase(List strings) {       10 Auftreten von
                          val result = new ArrayList()    String/string
                          for (string : strings) {
                            result += string.toUpperCase         sehr ausdrucksstark
                          }
                          return result                            3 Auftreten von
                        }                                          String/string
  Xtend imperativ
                      def toUpperCase(List strings) {
                            strings.map( string | string.toUpperCase )
   Xtend funktional       }

   Xtend funktional      def toUpperCase(List strings) {
                               strings.map[toUpperCase]
   mit Lambda-Ausdrücken
                                  }
   Quelle: [2]
                            Dirk Müller: Software Factories
SS 2018                                                                        10/37
Wichtige Schlüsselwörter
    ●     class zur Deklaration einer Klasse
          – Standardsichtbarkeit ist public
          – package zu package private übersetzt (Standard in Java)
          – mehrere Public-Klassen in einer Datei erlaubt
          – Konstruktoren mit new statt des Klassennamens, public als Std.
    ●     Deklaration von Klassenvariablen
          – Standardsichtbarkeit ist private
          – val zur Deklaration einer Wert-Variable (final)
          – var zur Deklaration einer (echten) Variable, Weglassung möglich
          – Weglassung des Typs erlaubt, falls Ableitung aus Initialisierung
    ●     def zur Deklaration einer Methode
          – Standardsichtbarkeit ist public
          – Rückgabetyp kann aus dem Methodenrumpf abgeleitet werden,
            außer bei abstrakten und rekursiven Methoden
            Quelle: [5]       Dirk Müller: Software Factories
SS 2018                                                                        11/37
Makros via Active Annotations
    ●     schematische wiederkehrender Code (Boilerplate-Code)
          – Assistenten (Wizards) in IDEs               Klicken
          – Sammlung von Code-Generatoren
                                                              unübersichtlich
          – wie individueller Code auch handgeschrieben
                                                                  aufwendig
    ●     Active Annotations als ein modernes Mittel zur
          Codegenerierung
          – einfache Integration in existierende Projekte
          – kürzere Durchlaufzeiten z. B. zur Erstellung von Prototypen
    ●     Grundidee: Übersetzung von Xtend-Code in Java-Code
          unter Nutzung einer Bibliothek
    ●     können nicht im selben Projekt genutzt werden, nur in
          einem vorgeschalteten oder kompiliert in einer JAR-Datei
    ●     Schnittstellen im Teil org.eclipse.xtend.lib.macro
          der Laufzeitbibliothek definiert
            Quelle: [5]      Dirk Müller: Software Factories
SS 2018                                                                         12/37
Grundlegende Idee hinter MDSD

  Code einer Referenz-                             Anwendungs-
  Anwendung                                        Modell

             Analyse

                                                                  individueller

                                     Separierung
    individueller   generischer                                   Code
    Code            Code

    schematisch                                     schematisch
    wiederkehrender Code                            wiederkeh-    Plattform
                                                    render Code

                       Dirk Müller: Software Factories
SS 2018                                                                       13/37
Vorgefertigte Active Annotations
    ●     org.eclipse.xtend.lib.annotations als Plug-in / JAR
    ●     Entwurfsmuster in Bibliothek abgelegt
          – aktive Weiterentwicklung (z. T. Beta-Versionen)
    ●     @Accessors dient dem Anlegen von Gettern und Settern
          für den gekapselten Zugriff auf eine Klassenvariable
    ●     @Data dient der Konvertierung einer Klasse in eine
          Wertobjekt-Klasse (z. B. Geldbetrag, Datum)
          – keine Identität, nicht veränderbar, Erzeugung in gültigen Zustand
          – alles final
          – Getter-Methoden werden generiert, Setter-Methoden nicht
          – Konstruktor mit Parametern für alle nicht-initialisierten Felder
          – equals(Object)- / hashCode()-Methoden werden generiert
          – toString()-Methode wird generiert
    ●     @Delegate dient der automatischen Implementierung von
          Delegierungsmethoden für Schnittstellen
              Quelle: [5]    Dirk Müller: Software Factories
SS 2018                                                                         14/37
package example1;
     Generierung von                            import org.eclipse.xtend.lib.annotations.AccessorType;
                                                import org.eclipse.xtend.lib.annotations.Accessors;

    Gettern und Settern                         import org.eclipse.xtext.xbase.lib.Pure;
                                                @Accessors
                                                @SuppressWarnings("all")
                                                public class Person {
                                                  private String name;
                                                  private String firstName;
                                                  @Accessors({ AccessorType.PUBLIC_GETTER,
                                                               AccessorType.PROTECTED_SETTER })
                                                  private int age;
  package example1                                @Accessors(AccessorType.NONE)
  import                                          private String internalField;
                                                  @Pure                          keine Seiteneffekte
  org.eclipse.xtend.lib.annotations.Accessors
                                                  public String getName() {
  @Accessors class Person {                         return this.name;
       String name                                }
       String firstName                           public void setName(final String name) {
       @Accessors(PUBLIC_GETTER,                    this.name = name;
                   PROTECTED_SETTER) int age      }
       @Accessors(NONE) String internalField      @Pure
  }                                               public String getFirstName() {
                                                    return this.firstName;
                                                  }
                                                  public void setFirstName(final String firstName) {
                                                    this.firstName = firstName;
               klassenspezifische                 }
                Angaben werden                    @Pure
                  überschrieben                   public int getAge() {
                                                    return this.age;
                                                  }
                                                  protected void setAge(final int age) {
                                                    this.age = age;
                                                  }}

            Quelle: [5]           Dirk Müller: Software Factories
SS 2018                                                                                             15/37
Operator-Überladung
    ●     Ziel: besser lesbarer Code, Idee von C++ übernommen
    ●     näher an der fachlichen Domäne (typisch: Mathematik),
          aber Ausdrucksstärke nicht verbessert (syntactic sugar)
    package example1
    import org.eclipse.xtend.lib.annotations.Data
                                                        public Complex(final    double re,
    @Data                   u.a. Konstruktor generiert                  final   double im) {
    class Complex {                                          super();
        val double re            Real- und                   this.re = re;
        val double im                                        this.im = im;
                                Imaginärteil            }
        def +(Complex other) {
            new Complex(re + other.re, im + other.im)
        }                                Addition
        def -() {
            new Complex(-re, -im)          entgegengesetzte
        }                                Zahl (unärer Operator)
        def -(Complex other) {
            this + -other             Subtraktion als Addition
        }                             der entgegengesetzten
    }                                           Zahl
                               Dirk Müller: Software Factories
SS 2018                                                                                    16/37
Test der Operatoren für komplexe Zahlen
    class ComplexExample {                       package example1;
         def static void main(String[] args) {   import example1.Complex;
              val x = new Complex(1, 2)          import org.eclipse.xtext.xbase.lib.InputOutput;
              val y = new Complex(-3, 5)         @SuppressWarnings("all")
              val z = new Complex(0, 3)          public class ComplexExample {
alle Typen var result = -x + y                     public static void main(final String[] args)
abgeleitet result    += z
              println(result.toString())
                                                   {
                                                     final Complex x = new Complex(1, 2);
         }                                           final Complex y = new Complex((-3), 5);
    }                                                final Complex z = new Complex(0, 3);
                                                     Complex _minus = x.operator_minus();
                         wegen @Data mit             Complex result = _minus.operator_plus(y);
   automatisch                                       Complex _result = result;
                        generiert, hier über
   mit verfügbar                                     result = _result.operator_plus(z);
                       Xbase-I/O-Bibliothek          String _string = result.toString();
                          aber auch als              InputOutput.println(_string);
                        println(result)            }
                             möglich             }

                                   Dirk Müller: Software Factories
SS 2018                                                                                        17/37
Template Expressions

    ●     Ziel: gut lesbare String-Verkettung
          – wichtig für Compiler/Transpiler
    ●     von Paar dreifacher Anführungszeichen (''') abgegrenzt
    ●     interpolierte Ausdrücke von französischen
          Anführungszeichen («Guillemets») umschlossen
          –   Zeichensatz sollte UTF-8 sein
          –   weniger Probleme mit Escape-Konflikten
          –   über Syntax-Vervollständigung angeboten
          –   explizit (unter Windows) mit CTRL+< bzw. CTRL+>
    ●     können überall stehen (alles ist ein Ausdruck)
    ●     Typ ist CharSequence, wird ggf. in String umgewandelt

                             Dirk Müller: Software Factories
SS 2018                                                            18/37
FOR-Schleifen in Templates
          – BEFORE fügt Vorspann-Text ein
          – AFTER fügt Abspann-Text ein
          – SEPARATOR fügt Text zwischen zwei aufeinanderfolgenden
            Iterationen ein (Trenner)
          – BEFORE und AFTER nur ausgeführt, wenn min. 1 Iteration
          – SEPARATOR nur ausgeführt, wenn min. 2 Iterationen

                            Dirk Müller: Software Factories
SS 2018                                                              19/37
Whitespace-Behandlung in Xtend-Templates
                                                        
                                                                Traffic light colors:
                                                                
                                                                     red
                                                                     yellow
                                                                     green
                                                                
    println(new HelloWorld().html)

    ●     Formatierung bei Templatesprachen klassisch über
          Nachschaltung eines Formatter bzw. Pretty Printer gelöst
    ●     Code des Generators und des gen. Codes übersichtlich
    ●     Xtend-Ansatz: Unterscheidung, welche Einrückungen für
          Ausgabe gedacht sind und welche nicht (Kontrollstrukturen
          wie z. B. FOR oder IF), sichtbar per Syntax-Hervorhebung
                           Dirk Müller: Software Factories
SS 2018                                                                            20/37
Einhaken in den Generator-Mechanismus
                                                              Datei anlegen und
                                                               ersten Text dort
                                                                  eintragen

                                                        funktional: filtern,
                         liefert einen Baum-           Namen extrahieren,
                         Iterator             mit Kommas trennen
                          als Sicht auf diese
                              Ressource

                     Dirk Müller: Software Factories
SS 2018                                                                        21/37
Codegenerierung in Java übersetzt

                                                    Quelldatei in der
                                                    Sprache Xtend

                                                    generierte Zieldatei
                                                          in Java

                  Dirk Müller: Software Factories
SS 2018                                                                 22/37
Test der Codegenerierung

                                            Test in zweiter
                                            Eclipse-Instanz

              Speichern als
              Trigger für die
             Codegenerierung

              Dirk Müller: Software Factories
SS 2018                                                       23/37
Zielcode generiert

          Zieldatei

               Dirk Müller: Software Factories
SS 2018                                          24/37
Neuer Eintrag im Quellcode

               Dirk Müller: Software Factories
SS 2018                                          25/37
Konsistente Änderung im Zielcode

                  Dirk Müller: Software Factories
SS 2018                                             26/37
Liste zu grüßender Personen mit Templates
          override void doGenerate(Resource resource,
              IFileSystemAccess2 fsa, IGeneratorContext context)
          {
              fsa.generateFile('greetings.txt', 'People to greet: ' +
                  resource.allContents
                      .filter(typeof(Greeting))
                      .map[name]
                      .join(', '))                              ohne Templates
          }

          override void doGenerate(Resource resource,
                                                                          mit Templates
              IFileSystemAccess2 fsa, IGeneratorContext context)
          {
              fsa.generateFile('greetings.txt', 'People to greet: ' + '''
                   «FOR greeting : resource.allContents
                                      .filter(Greeting)
                                      .toIterable
                                      SEPARATOR ', '»«greeting.name»«ENDFOR»
               ''')
          }                  wichtig, dass in 1 Zeile, sonst Umbrüche in der Liste

                                Dirk Müller: Software Factories
SS 2018                                                                                   27/37
Einstellungen für den Xtend-Transpiler

                                              Java-Version für Zielcode

                                                   Warnungen unterdrückt

                                              Zielverzeichnis

                                                    Nachfrage beim Versuch,
                                                  generierte Dateien zu editieren

                     Dirk Müller: Software Factories
SS 2018                                                                         28/37
Beispiel: Lied „99 Bottles of Beer“
    99 Bottles of Beer

    99 bottles of beer on the wall, 99 bottles of beer.
    Take one down and pass it around, 98 bottles of beer on the wall.

    98 bottles of beer on the wall, 98 bottles of beer.
    Take one down and pass it around, 97 bottles of beer on the wall.

    [..]

    2 bottles of beer on the wall, 2 bottles of beer.
    Take one down and pass it around, 1 bottle of beer on the wall.
           „One“ als Variante            „one“           „one“ als Variante
    1 bottle of beer on the wall, 1 bottle of beer.
    Take one down and pass it around, no more bottles of beer on the wall.

    No more bottles of beer on the wall, no more bottles of beer.
    Go to the store and buy some more, 99 bottles of beer on the wall.
              Quelle: [8]       Dirk Müller: Software Factories
SS 2018                                                                       29/37
Bottles-Song in BASIC
    10    REM BASIC Version of 99 Bottles of beer
    20    FOR X=100 TO 1 STEP -1
    30    PRINT X;"Bottle(s) of beer on the wall,";X;"bottle(s) of beer"
    40    PRINT "Take one down and pass it around,"        Singular/Plural unsauber
    50    PRINT X-1;"bottle(s) of beer on the wall"
    60    NEXT                                             Endvers nicht abgebildet
    10 REM Basic version of 99 bottles of beer
    20 REM Modified by M. Eric Carr (eric@carrnet.net)
    30 REM from prior version found on this site.
    40 REM (Modified to correct "1 bottle" grammar)
    50 FOR X=99 TO 1 STEP -1
    60 PRINT X;"bottle";                               GOSUB-Unterprogramm
    70 IF X1 THEN PRINT "s";                              nicht genutzt
    80 PRINT " of beer on the wall,";X;"bottle";
    90 IF X1 THEN PRINT "s";
    100 PRINT " of beer"
    110 PRINT "Take one down and pass it around,"
    120 PRINT X-1;"bottle";
    130 IF X1 THEN PRINT "s";
    140 PRINT " of beer on the wall"
    150 NEXT                                        Endvers nicht abgebildet

              Quelle: [8]      Dirk Müller: Software Factories
SS 2018                                                                          30/37
Bottles-Song in Java
 class Bottle {
   public static void main(String args[]) {
       singTheSong(99);
   }
   private static void singTheSong(int all) {
       for (int i=all; i>0; i--) {
           System.out.println(Bottles(i) + " of beer on the wall, " + bottles(i)
                                            + " of beer.");
           System.out.println("Take one down and pass it around, " + bottles(i-1)
                                  + " of beer on the wall.");
           System.out.println();
       }
       println("No more bottles of beer on the wall, no more bottles of beer.");
       System.out.println("Go to the store and buy some more, " + bottles(all)
                             + "of beer on the wall.");
   }
   private static String bottles(int i) {
       switch(i) {
         case 0: return "no more bottles";
         case 1: return "one bottle";
         default: return i + " bottles";
       }
   }
   private static String Bottles(int i) {
       return bottles(i).substring(0,1).toUpperCase() + bottles(i).substring(1);
   }
 }                             Dirk Müller: Software Factories
SS 2018                                                                             31/37
Bottles-Song in Xtend
  class BottlesSong {
      def static void main(String[] args) {
          println(new BottlesSong().singTheSong(99))
      }                                                         Template Expression
      def singTheSong(int all) '''
          «FOR i : all .. 1»
              «i.Bottles» of beer on the wall, «i.bottles» of beer.
              Take one down and pass it around, «(i - 1).bottles» of beer on the wall.

          «ENDFOR»
          No more bottles of beer on the wall, no more bottles of beer.
          Go to the store and buy some more, «all.bottles» of beer on the wall.
      '''
      def static bottles(int i) {                               Powerful Switch Expression
          switch i {
    1 als     case 0 : 'no more bottles'
              case 1 : 'one bottle'                                   Template Expression
   Zahlwort
              default : '''«i» bottles'''
          }.toString                                            Extension method
      }
      def static Bottles(int i) {
          bottles(i).toFirstUpper                         Everything is an expression.
      }
  }
                              Dirk Müller: Software Factories
SS 2018                                                                                  32/37
Codegenerierung für einen
                      Prolog-zu-Scheme-Transpiler
 /*
  * generated by Xtext 2.9.2
  */
 package de.htwdd.sf.beleg.muellerd.generator       Xtext generiert eine Schablone

 import   org.eclipse.emf.ecore.resource.Resource
 import   org.eclipse.xtext.generator.AbstractGenerator
 import   org.eclipse.xtext.generator.IFileSystemAccess2
 import   org.eclipse.xtext.generator.IGeneratorContext

 /**
  * Generates code from your model files on save.
  *
  * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
  */
 class PrologDslGenerator extends AbstractGenerator { Callback-Routine, die beim Speichern
                                                            des Quelltextes aufgerufen wird
     override void doGenerate(
         Resource resource,                         AST vom Parsen mittels Xtext geliefert
         IFileSystemAccess2 fsa,
         IGeneratorContext context)
     {                                                 Zugriff aufs Dateisystem
     }                 muss noch gefüllt   werden
 }
                                  Dirk Müller: Software Factories
SS 2018                                                                                       33/37
Implementierung von doGenerate
  class PrologDslGenerator extends AbstractGenerator {

      String code      // zur Konstruktion des auszugebenden Textes

      override void doGenerate(Resource resource,
                                 IFileSystemAccess2 fsa,           Filtern des passenden
                                 IGeneratorContext context)          Typs und iterierbar
      {              notwendige Initialisierung zum leeren String          machen
          code = ""
          for (e : resource.allContents.filter(PrologDsl).toIterable)
          {
              System.out.println("Start Transformieren")                Kontrollausgabe
              e.traversiere     Methode, die noch für alle            in der Konsole der
          }                      Typen implementiert wird           ersten Eclipse-Instanz
          fsa.generateFile("PrologDsl.lsp", code)
                                                                  Herausschreiben des
      }
                                                                     Endergebnisses
      def conc(String str) {       // zum Anfügen neuer Programmteile
          code = code + str;
      }
                                       Hilfsmethode
  }
                               Dirk Müller: Software Factories
SS 2018                                                                                 34/37
Implementierung einer Regel in Xtend

       → ( prolog (quote ) (quote  ))
    def traversiere(PrologDsl k) {
           conc("(prolog (quote")       noch zu implementieren
           k.program.traversiere
           conc(")\r\n(quote")    Zeilenumbruch zur besseren Lesbarkeit
           k.query.traversiere         noch zu implementieren
           conc("))")
        }

             Besser lesbare Lösung mittels Templates möglich?
                             Dirk Müller: Software Factories
SS 2018                                                                   35/37
Zusammenfassung
    ●     Xtend als statisch typisierte, auf Java aufbauende Sprache
          – Typen können oft abgeleitet werden
          – funktionales Paradigma neben dem objektorientierten und
            imperativen unterstützt
          – alles ist ein Ausdruck => flexible Komponierbarkeit
          – sehr kompakter und ausdrucksstarker Code
    ●     gute Eignung zur Code-Generierung
          – Implementierung der Methode doGenerate
    ●     gute Template-Unterstützung
          – flexible Kontrollstrukturen
          – besonders gut gelungen: Behandlung von Whitespaces mit guter
            Lesbarkeit im Code-Generator und im generierten Code
    ●     Makros für schematisch wiederkehrenden Code via Active
          Annotations und Operatorüberladung als Highlights
                             Dirk Müller: Software Factories
SS 2018                                                                    36/37
Literatur
   [1]    Hartmut Fritzsche, „Software Factories – Skript zur Lehrveranstaltung“, 11.01.2016,
          Download am 6.4.2016,
          http://www2.htw-dresden.de/~fritzsch/SF/Software_Factories_Skript.pdf
   [2]    Sven Efftinge, Sebastian Zarnekow: „Extending Java“, in: Pragmatic Programmer
          Magazine, Dezember 2011, Download am 30.04.2016,
          https://pragprog.com/magazines/2011-12/extending-java
   [3]    Alex Blewitt: „Xtend Extends Java“, in: InfoQ, Juni 2012; (Interview mit Sven Efftinge),
          Download am 30.04.2016, http://www.infoq.com/news/2012/06/xtend-release-10
   [4]    Jan Koehnlein auf Twitter, 21.04.2016, Download am 30.04.2016,
          https://twitter.com/JAXenter/status/723098924114833408
   [5]    Xtend-Dokumentation, https://eclipse.org/xtend/index.html
   [6]    Meinte Boersma: „Meinte's DSL-Blog: Using Xtext’s Xtend(2) language“, 19.09.2011,
          Download am 3.5.2016,
          https://dslmeinte.wordpress.com/2011/09/19/using-xtexts-xtend2-language/
   [7]    Sven Efftinge: „sven eftinge's blog: Writing Android UIs with Xtend“, 12.12.2011,
          Download am 6.5.2016,
          http://blog.efftinge.de/2011/12/writing-android-uis-with-xtend.html
   [8]    Oliver Schade: „99 Bottles of Beer“, 2016, Download am 01.03.2018
          http://99-bottles-of-beer.net
   [9]    Oracle: „JEP 286: Local-Variable Type Inference“, 6.3.2018, Download am 21.3.2018,
          http://openjdk.java.net/jeps/286
                                   Dirk Müller: Software Factories
SS 2018                                                                                         37/37
Sie können auch lesen