Vous êtes sur la page 1sur 18

17/03/2020

Xtend
Programming Language
Ayoub SABRAOUI

Master SID BIG-DATA

Année universitaire 2019/2020

Eclipse Project
• Part of Eclipse Modeling

Part of a family of languages


• Xtext, Xtend, Xbase , Xpand, Xcore 2

1
17/03/2020

Introduction

Xtend et son IDE sont développés en


tant que projet de la fondation Eclipse.

Le projet se présente modestement comme un ensemble de


plug-ins qui viennent se greffer à une installation existante de
l'IDE Eclipse.

Date de sa première version : 2011

Le code est open source sous la licence Eclipse Public


License.

Xtend est livré avec une documentation, accessible sur son site
web: https://www.eclipse.org/xtend/documentation
3

Introduction

Xtend est un langage généraliste, complet, polyvalent et totalement


interopérable avec Java.
Vous pouvez réutiliser toutes les bibliothèques Java.

Il a une syntaxe plus concise que Java et fournit de puissantes


fonctionnalités telles que:
• L’inférence de type,
• Les méthodes d’extension,
• Les méthodes de dispatch
• Les expressions lambda,
• Les expressions Template multi-lignes

Xtend est couplé avec Xtext.


L'un des buts principaux de Xtend est la génération de code, à base
d’un DSL 4

2
17/03/2020

Xtend - un meilleur Java avec moins de "rigueur"

Xtend est un langage typé utilisant le système de typage Java,


les notions de généricité et les annotations Java.
Xtend et Java sont complètement interopérables.

La plupart des concepts linguistiques d’Xtend sont similaires à


Java, ex.: classes, interfaces, méthodes,…etc.
Un des buts principaux d’Xtend est de proposer une version moins
explicite et moins rigoureuse de Java.

Création d’un projet Xtend

Vous pouvez utiliser Xtend dans vos projets Java


Eclipse (projets Java simple et plug-in).

Les étapes à suivre pour créer un projet Xtend:


1. Démarrer Eclipse, aller à File | New | Project…, puis
sélectionner Java Project.
2. Saisir un nom pour votre projet: org.xtend.exemple et
appuyer sur terminer.

Pour créer un nouveau fichier Xtend, par exemple une classe Xtend, cliquez avec le
bouton droit de la souris sur votre dossier source et sélectionnez Nouveau | Classe
Xtend.

Un nouveau dossier source xtend-gen sera créé dans votre projet, contenant le code
java correspondant à votre code Xtend.
6

3
17/03/2020

Premier programme Xtend

Similaire à Java, bien que Les ; sont optionnelles

Toutes les déclarations de méthodes commencent par def ou override


(seront expliqués plus loin dans ce cours).

Les méthodes sont publiques par défaut.

Le code Java généré

Le répertoire xtend-gen contient les fichiers


Classe Java générés, correspondant aux classes Xtend.
Java
générée

La vue Xtend Generated Code permet d’afficher le code Java généré correspondant au
code Xtend sélectionné. Mise à jour à chaque nouvel enregistrement du fichier Xtend.

L’exécution du fichier Xtend se fait en cliquant sur le bouton droit de la souris, puis sur:
Run As | Java Application
8

4
17/03/2020

Les types

Dans Xtend, La déclaration des classes et des interfaces est


similaire à celle de Java, mais tous les types Xtend sont publics
par défaut. En outre, on peut déclarer plusieurs types publics dans
un même fichier, et ils seront compilés dans des fichiers Java
séparés.

Comme dans Java, toutes les classes Xtend héritent implicitement


de la classe java.lang.Object

La déclaration de paquetages dans Xtend fonctionne comme dans


Java.

Les types
Dans une classe Xtend, on peut définir autant de constructeurs
que l'on veut, en utilisant le mot-clé new, sans utiliser le nom de
la classe.

Les constructeurs sont


publics par défaut.

On peut aussi définir les classes internes et anonymes.

Xtend prend en charge la déclaration des annotations et des


enum. 10

5
17/03/2020

Les méthodes
Une méthode Xtend est déclarée en commençant par def ou override,
elle est publique par défaut.

Le concept des modificateurs d'accès est le même qu’en Java.

Pour redéfinir une méthode d’un SuperType (classe ou interface), il


faut obligatoirement utiliser le mot clé override au lieu de def.

Exemples:
i. La méthode suivante déclenchera une erreur de compilation, puisque nous
aurions dû utiliser override au lieu de def :

11
ii. Il est impossible de redéfinir une méthode finale.

Les méthodes
Dans Xtend, il n’y a pas d’instructions, tout est expression.

La dernière expression d’une méthode étant la valeur


de retour  l’utilisation de l’instruction return est
optionnelle.
Le type de retour d’une méthode peut être omis s’il peut être déduit du
corps de la méthode.
Exemples: les déclarations suivantes
Remarques: sur les paramètres de méthodes
sont valides def String meth1() {
return "" i. Il faut toujours spécifier les types de
}
paramètres, Xtend ne peut pas les
def String meth2() { inférer automatiquement.
""
} ii. Les paramètres sont toujours considérés
def meth3() { comme final.
return ""
} 12
def meth4() {
""
}

6
17/03/2020

Les méthodes

Xtend prend en charge le modificateur static pour les méthodes et peut


inférer le type de retour s'il n'est pas explicitement indiqué:
def static createInstance() {
new MyClass('obj')
}

Comme dans Java, les paramètres vararg sont autorisés et accessibles sous
forme de tableaux dans le corps de la méthode:

def printAll(String... strings) {


strings.forEach[ s | println(s) ]
}

Il est possible de déduire le type de retour d'une méthode à partir de son corps. Les
méthodes récursives et les méthodes abstraites doivent explicitement déclarer un
type de retour.
13

Les méthodes

Méthodes abstraites
Une méthode abstraite ne définit pas de corps et doit être déclarée dans
une classe abstraite ou une interface. Il est également obligatoire de
spécifier le type de retour, car il ne peut pas être inféré.

abstract class AbstractClass() {


def String abstractMethod() // no body
}

Méthodes génériques
Xtend introduit les types paramétrés (generic) sur les méthodes.

def <T> second(List<T> elements) {


elements.get(1)
}

14

7
17/03/2020

Les méthodes

Surcharge des opérateurs


Xtend supporte la surcharge des opérateurs. Pour déclarer un opérateur,
on peut soit déclarer une méthode simple en utilisant le nom de
l'opérateur, soit en utilisant directement l'opérateur comme dans les cas
suivants:

class Money {
def + (Money other) { ... }
def - (Money other) { ... }
def * (BigDecimal times) { ... }
...
}

15

Les attributs et les variables

Les attributs et les variables sont déclarés à l’aide de :


i. val : pour les attributs et variables finaux
ii. var : pour les attributs et variables non-finaux

Les attributs sont privés par défaut.

Le type d’(attribut/variable) peut être omis, il peut être inféré du contexte


ou de l’expression d’initialisation.

Quelques exemples de déclaration de variables:

8
17/03/2020

Les opérateurs

La sémantique des opérateurs Xtend diffère légèrement de Java. En


particulier, == compare deux objets en valeur en mappant l’opérateur
vers la méthode equals().

Pour comparer deux objets en référence, il faut utiliser l’opérateur


triple égal ===

Les opérateurs arithmétiques sont étendus aux listes. Par exemple, lors
de l’exécution du code suivant :

On obtient

17

Le nouveau sucre syntaxique

En Xtend, la manipulation des getters et setters se fait par une syntaxe


plus allégée.

Par exemple:

Au lieu d’écrire... On peut écrire...


o.getName() o.name
o.setName("...") o.name = "..."

De même, si une méthode


n’a pas de paramètres, on
peut l’appeler sans utilisation Appel de la fonction
int mSpar()
de parenthèses.

18

9
17/03/2020

Accès aux membres statiques

Tout comme dans Java, l’accès aux membres des types se fait en
utilisant l’opérateur point (.)

• Utilisation de l’opérateur :: dans les anciennes versions d’Xtend

To Java

19

Accès aux types internes

Il en va de même pour les types internes (classes et interfaces).

L’accès à l’interface interne se fait selon la syntaxe suivante:

20

10
17/03/2020

Les expressions littérales


Une expression littérale est une valeur fixe et immuable, écrite
directement dans le code.

Les littérales sont spécifiés dans Xtend comme dans Java mais avec
quelques exceptions.
• String littérale: ,
• Booléen littérale: true et false
• Null littérale: même sémantique que dans Java
• Collection et tableau littérale:

//Crée un tableau de String

//Crée une liste de String

//Crée une liste de String

//Crée une Map<String, Integer> 21

Les méthodes d'extension


Les méthodes d’extension permettent d’ajouter de nouvelles méthodes
aux types existants sans les modifier.
• Ex1: si m(Entity) est une méthode d’extension, et e est de type Entity, on
Ex1
peut écrire e.m() au lieu de m(e), même si m n’est pas une méthode définie
dans Entity.
• Ex22: soit la méthode suivante:
Ex

En Xtend on peut l’appeler soit comme en Java:


Soit comme une méthode d’extension de type String :

De même, on peut utiliser certaines méthodes utilitaires des collections:

22

11
17/03/2020

Les méthodes d'extension

On peut aussi utiliser les méthodes statiques des classes


java.util.Collections comme des méthodes d’extension, en
utilisant import static extension dans le fichier source.
• La déclaration suivante:

• Nous permet d’utiliser la méthode statique singletonList comme suit:

23

Les méthodes d'extension

Enfin, en ajoutant le mot clé extension à un attribut, une


variable locale, ou un paramètre, ses méthodes deviennent des
méthodes d’extension dans cette classe, bloc de code, ou corps de
méthode, respectivement. Par exemple, supposons la classe
suivante :

24

12
17/03/2020

Les méthodes d'extension


Maintenant, si on veut utiliser ces méthodes comme des méthodes d’extension dans une
autre classe C, il faut juste utiliser le mot clé extension pour déclarer un attribut de type
MyListExtensions

On peut atteindre le même


objectif en ajoutant le mot
clé extension à une
variable locale :

De même pour la déclaration d’un


paramètre :
25

La variable implicite - it

Comme dans Java, l’instance


courante est liée au mot clé this.
Cependant, Xtend introduit une
autre variable spéciale it, pour
obtenir le même comportement
pour n’importe quelle variable ou
paramètre.

26

13
17/03/2020

Les constructeurs

L’appel d’un constructeur a la même syntaxe qu’en Java. La


seule différence est que les parenthèses vides sont
optionnelles :

R.: Si les types d’arguments sont omis, ils seront inférés du


contexte.

27

Condition if
Une structure if est utilisée pour choisir entre deux valeurs différentes
basées sur un prédicat.

L’expression:
if (p) e1 else e2

se traduit soit par la valeur e1 ou e2 selon que p soit vrai ou faux.

La partie else est optionnelle ce qui est un raccourci pour une branche else qui
retourne la valeur par défaut du type courant.
if (p) e1 Est un raccourci de: if (p) e1 else null

La structure if est une expression qui retourne une valeur. Par conséquent,
on peut l’utiliser comme expression imbriquée dans d’autres expressions :
val nom = if (prenom != null) prenom + ' ' + nom else nom

28

14
17/03/2020

La structure Switch

L’utilisation de la structure switch en Xtend est très


différente de celle de Java. Son utilisation n’est pas limitée à
certaines valeurs, mais peut être utilisée pour n’importe quel
objet.
• Seul le case sélectionné est exécuté, vous n'avez pas besoin
d'insérer une instruction de rupture explicite (ex. break en Java).
En effet, Xtend ne prend pas en charge l’instruction break.

• Object.equals(Object) est utilisé pour comparer la valeur


dans le case avec celui sur lequel on switch.

29

La structure Switch

Exemple:
def String switchExample(Entity e, Entity specialEntity) {
switch e {
case e.name.length > 0 : "a un nom"
case e.superType != null : "a un super type"
case specialEntity : "est un type special"
default: ""
}
}

L’expression e est évaluée en premier puis comparée à chaque case


séquentiellement.
• Si l'expression du case est une expression booléenne (les deux premiers cas de cet
exemple), le case correspond est choisi si l'expression est vraie.
• Si l'expression du case n'est pas de type booléen, elle est comparée à la valeur de
l'expression principale à l'aide de la méthode equals (le troisième cas dans cet
exemple: e.equals(specialEntity)).
30

15
17/03/2020

La structure Switch

Une autre caractéristique intéressante de la structure switch est le garde-


type. Avec cette fonctionnalité, on peut spécifier un type comme
condition du case et la correspondance se fait si la valeur du switch est une
instance de ce type (si elle est conforme à ce type).

def toString(AttributeType attributeType) {


val elementType = attributeType.elementType
switch elementType { ElementType
BasicType: // ici elementType est un BasicType
elementType.typeName
BasicType
EntityType: // ici elementType est un EntityType
elementType.entity.name EntityType
}
}

Ici entityType est automatiquement casté au type correspondant dans le corps du


case. 31

La structure Switch
Autre utilisation du switch: combiner deux conditions, une du case et
l’autre sur le type utilisé.
def length (Object x) {
switch x {
String case x.length > 0 : x.length //length est défini pour String
List<?> : x.size // size est défini pour List
default : -1
}
}

On peut avoir plusieurs valeurs du case, séparées par une virgule.


def isMale(String sal) {
switch sal {
case "Mr",
case "Mr." : true
default : false
}
}
32

16
17/03/2020

La boucle for
for est utilisé pour exécuter une certaine expression pour chaque élément
d’un tableau ou d’une instance de Iterable. La variable locale est finale,
donc ne peut pas être mise à jour.
for (T variable : tableauOuIterable) expression

Le type de for est void. Le type de la variable locale peut être inféré à partir
du tableau ou de iterable.
for (String s : myChaine) {
faireQlqChose(s)
}

for (s : maChaine)
faireQlqChose(s)

La boucle for basique:


for (var i = 0 ; i < s.length ; i++) {
println(s.subString(0,i)
}
33

while et do-while

La boucle while
while (predicate) expression

Exemple:
while (true) {
uneFonction("string")
}

La boucle do-while
do expression while (predicate)

Exemple:
do
uneFonction("string")
while ((i=i+1)<max)
34

17
17/03/2020

Autres opérateurs
L’opérateur (" ?. ")
Très souvent, vous devrez vérifier si un objet n’est pas nul avant d’invoquer une
méthode; autrement, vous pouvez vouloir retourner null ou tout simplement
n’exécuter pas l’opération.
Xtend fournit l’opérateur "?." qui est une version sûre de l’opérateur de sélection (.)
Écrire o?.m correspond à if(o!=null) o.m
Ceci est particulièrement utile lorsque vous avez des sélections en cascade, par
exemple: o?.f?.m

L’opérateur Elvis (" ? : ")


L’opérateur Elvis (" ? : ") est un autre opérateur pratique pour faire face aux valeurs
par défaut en cas d’instances nulles. Il a la sémantique suivante :
x ?: y retourne x si elle n’est pas nulle et y sinon.
La combinaison des deux opérateurs vous permet de configurer facilement les
valeurs par défaut, par exemple :
// équivalent à: if (o != null) o.toString else 'par défaut'
result = o?.toString ?: 'par défaut' 35

Autres opérateurs
L’opérateur de cast: as
Le transtypage (ou cast) en Xtend est fait en utilisant l’opérateur as. Ainsi,
l’expression Xtend: e as T est équivalente à l’expression Java: (T)e

L’opérateur instanceof
Lorsqu’on utilise instanceof comme condition d’une expression if, Xtend effectue
automatiquement une conversion vers le type correspondant dans le corps de la
branche if. Ceci est illustré dans l'exemple suivant, où les transtypages sont implicites
et ne sont pas nécessaires:

def toString(AttributeType attributeType) {


val elementType = attributeType.elementType
if (elementType instanceof BasicType)
elementType.typeName // elementType is a BasicType here
else if (elementType instanceof EntityType)
elementType.entity.name // elementType is an EntityType here
} 36

18

Vous aimerez peut-être aussi