% vim:spell spelllang=fr
\chapter{Outils pour exprimer une transformation de modèles en Tom}
\label{ch:outils}
%15p

Dans ce chapitre, nous traitons de notre contribution au langage {\tom} et de
la manière dont notre approche de transformation de modèles par réécriture est
implémentée. Dans un premier temps, nous donnons le mode opératoire concret
pour utiliser nos outils en nous appuyant sur l'exemple de transformation vu
précédemment. Nous présentons ensuite l'extension du langage {\tom} dédiée aux
transformations de modèles, puis nous expliquons son implémentation technique
au sein du compilateur, ainsi que l'implémentation du générateur d'ancrages
formels.

%%Réorganisation du chapitre :
% 1. Exemple pratique super concret (ex 3)
% 2. Extension du langage mais en présentant resolve+tracelink ensemble (ex1)
% 3. Implémentation (ex2)
% 4. Synthèse 

\section{Exemple d'utilisation des outils}

%\todo{ici : j'écris une version pour l'exemple en couleurs ? Je me suis appuyé
%dessus avant, cette section a-t-elle du sens ? ou alors c'est avant que je
%n'aurais pas dû parler des constructions ?\\
%Non, en fait ici on parle d'utilisation concrète, le déroulé d'une
%implémentation vient dans le chapitre suivant sur le cas d'étude SimplePDL, etc.}

Cette section présente l'utilisation de nos outils d'un point de vue concret.
Nous expliquons le processus d'écriture d'une transformation de modèles avec
eux. Pour cela, nous proposons de nous appuyer sur la transformation de texte
en formes géométriques colorées présentée dans un chapitre précédent et que
nous rappelons dans la section~\ref{ch:outils:subsec:ex} ci-après. L'objectif
de cette transformation est purement pédagogique et sert uniquement à illustrer
l'utilisation de nos outils pour ensuite introduire notre extension du langage.
Nous ne nous intéressons donc pas à sa pertinence ni à son utilité dans le
cadre d'un développement en contexte industriel.

\subsection{Exemple support}
\label{ch:outils:subsec:ex}

Le principe général de cette transformation de modèle est de transformer un
modèle sous forme de texte en une représentation graphique, comme l'illustre la
figure~\ref{fig:rappelSimpleTransfo}.

\begin{figure}[h]
  \begin{center}
   \input{figures/simpleApproachExample}
   \caption{Exemple de transformation de texte en formes géométriques colorées.}
    \label{fig:rappelSimpleTransfo}
  \end{center}
\end{figure}

Les figures~\ref{fig:textmmodel} et~\ref{fig:picturemmodel} sont deux
métamodèles que nous proposons et auxquels les modèles source et cible de la
figure~\ref{fig:rappelSimpleTransfo} se conforment respectivement.

\begin{figure}[h]
  \begin{center}
    \input{figures/textmmodel}
    \caption{Un métamodèle pouvant décrire le formalisme textuel (source)
    utilisé dans l'exemple support.}
    \label{fig:textmmodel}
  \end{center}
\end{figure}

Un texte (\emph{Text}) est composé de lettres (\emph{Letter}) et de symboles
(\emph{Symbol}). Dans notre exemple, les lettres peuvent être soit des A
(\emph{AText}), soit des B (\emph{BText}) ; tandis que les symboles sont des
points-virgules (\emph{SemiColon}).

\begin{figure}[h]
  \begin{center}
    \input{figures/picturemmodel}
    \caption{Un métamodèle pouvant décrire le formalisme graphique (cible)
    utilisé dans l'exemple support.}
    \label{fig:picturemmodel}
  \end{center}
\end{figure}

Une image \emph{GeoPicture} est composée de formes (\emph{Shape}) caractérisées
par une couleur (\emph{Color}, pouvant prendre les valeurs \emph{red},
\emph{green} et \emph{blue}). \emph{Shape} est abstraite, et plusieurs formes
concrètes en héritent (\emph{Triangle}, \emph{Pentagon}, \emph{Hexagon},
\emph{Square}, \emph{Circle}). Les formes géométriques sont reliées entre elles
par des segments (\emph{Segmen}).


\FloatBarrier

\subsection{Mode opératoire}

Concrètement, un utilisateur souhaitant implémenter une transformation de
modèle devra opérer par étapes, obtenues en fonction de l'outil principal à
utiliser :
\begin{enumerate}

  \item {\eclipse} : modélisation et génération des structures de données
    {\java-\emf} ;

  \item {\tomemf} : génération des ancrages formels pour représenter les
    modèles comme des termes (passerelle opérant le changement d'espace
    technologique) ;

  \item {\tomjava} : écriture effective de la transformation.

\end{enumerate}

\paragraph{Étape 1 :} La première étape consiste à modéliser le problème,
c'est-à-dire à définir les métamodèles source et cible, en utilisant {\eclipse}
ou tout autre outil capable de générer un métamodèle au format \texttt{.ecore}.
Supposons que ces métamodèles source et cible s'appellent respectivement
\texttt{text.ecore} et \texttt{picture.ecore}.

Depuis ces métamodèles, le générateur de code de {\emf} (\emph{GenModel})
permet de générer les structures de données {\java} correspondantes qui
permettent d'instancier et de manipuler les modèles. L'utilisateur souhaitant
implémenter la transformation n'a pas forcément besoin de se plonger dans ce
code, étant donné que par la suite il ne manipulera pas directement les
modèles en {\java+\emf}, mais plutôt des termes algébriques. Une fois le
code des métamodèles source et cible généré, il suffit de l'exporter sous la
forme d'archives \texttt{.jar} (par exemple \texttt{text.jar} et
\texttt{picture.jar} dans notre cas). Une fois cette opération accomplie,
{\eclipse} n'est plus nécessaire.

\paragraph{Étape 2 :} La seconde étape de la mise en œuvre d'une transformation
consiste à générer les ancrages algébriques à partir de la représentation
{\emf} des métamodèles. Cette étape est réalisée en utilisant un outil nommé
{\tomemf}.  L'utilisateur applique {\tomemf} sur l'archive (ou les archives) en
spécifiant le nom complet de l'\emph{EPackage} (ou des \emph{EPackages})
concerné(s). 

Concrètement, la commande suivante permet d'effectuer l'opération (nous
supposons que les archives \texttt{.jar} sont dans le répertoire courant noté
\texttt{.} et nous ne les nommons donc pas explicitement :

\begin{verbatim}
$> emf-generate-mappings -cp . text.TextEPackage picture.PictureEPackage
\end{verbatim}

Un mécanisme de préfixe a aussi été prévu pour résoudre les conflits de noms.
Nous supposons dans notre exemple qu'il n'y en a pas et que l'utilisateur n'a
pas à spécifier des préfixes. 
%
%Pour éviter les conflits de noms, l'utilisateur peut définir un préfixe à
%utiliser lors d'une application de {\tomemf}. Concrètement, avec les noms de
%fichiers de notre exemple, les commandes suivantes conviendraient :
%
%\begin{verbatim}
%$> emf-generate-mappings -cp ./text.jar -prefix Text_ text.TextPackage
%
%$> emf-generate-mappings -cp ./picture.jar -prefix Pic_ picture.PicturePackage
%\end{verbatim}
%
%Dans les deux cas, les commandes précédentes entraînent la génération de deux
La commande précédente entraîne la génération de deux fichiers d'ancrages
---~un par \emph{EPackage} spécifié~--- nommés respectivement
\texttt{text.TextEPackage.tom} et \texttt{picture.PictureEPackage.tom}. %Dans le
%premier cas, les types et opérateurs ne sont pas préfixés, dans le second,
%chaque \emph{mapping} a un préfixe (les types primitifs et {\ecore} sont
%exclus).
Dans notre exemple, les types et opérateurs ne sont pas préfixés. Si
l'utilisateur avait choisi de spécifier un préfixe, chaque \emph{mapping}
aurait eu un préfixe (les types primitifs et {\ecore} sont exclus).

%Il est aussi possible d'intégrer le sous-typage au moment de la génération des
%ancrages algébriques

La passerelle permettant d'opérer le changement d'espace technologique étant
générée, l'outil {\tomemf} n'est plus utile pour le reste du développement.


\paragraph{Étape 3 :} Il s'agit de l'écriture en {\tomjava} de la
transformation à proprement parler. Cette étape consiste en un développement
{\java} classique intégrant des constructions {\tom} en son sein, notamment
\lex{\%transformation} pour spécifier la transformation. Pour pouvoir manipuler
les modèles comme des termes algébriques, il est nécessaire d'inclure les
fichiers d'ancrages que nous venons de générer avec {\tomemf}. Dans notre
exemple, les inclusions (îlot formel \texttt{\%include}) et la transformation
(îlot formel \texttt{\%transformation}) apparaissent comme illustré dans le
listing~\ref{code:exInclude}.

\begin{figure}[H]
  \centering
  \input{code/exInclude}
%  \caption{<+caption text+>}
%  \label{fig:<+label+>}
\end{figure}

Dans ce programme, un modèle peut être soit chargé en utilisant les services
{\emf} (chargement d'un modèle sérialisé dans un fichier \texttt{.xmi}), soit
créé avec la construction \emph{backquote} de {\tom} (\lex{`}), comme tout
autre terme. Quelle que soit la méthode choisie, le modèle peut ensuite être
manipulé en tant que terme. À ce titre, il est possible de filtrer des motifs
et d'appliquer des stratégies de réécriture (donc des transformations {\tom}).

Une fois le développement terminé, le programme doit être compilé en deux
temps. Il faut procéder à une compilation {\tom} pour \emph{dissoudre} les
îlots formels {\tom} dans le langage hôte, puis compiler normalement le code
{\java} généré en intégrant les bibliothèques générées par {\emf}. L'exécution
du programme est identique à toute exécution de programme {\java}.

\begin{verbatim}
$> tom TestText2Picture.t
$> javac -cp ./text.jar:./picture.jar:${CLASSPATH} TestText2Picture.java
$> java -cp ./text.jar:./picture.jar:${CLASSPATH} TestText2Picture
\end{verbatim}


%%%%%%%

\section{Extension du langage}

Nous avons vu le mode opératoire pour écrire une transformation de modèles avec
nos outils dans la section précédente, sans détailler le langage lui-même. Nous
décrivons nos constructions dans cette section. Nous avons vu dans le
chapitre~\ref{ch:approach} que nous décomposons les transformations de modèles
en transformations élémentaires (\emph{Letter2Shape} par exemple), encodées par
des stratégies de réécriture.  Nous formons ensuite une stratégie en les
composant avec d'autres combinateurs élémentaires tels que \texttt{Sequence} ou
\texttt{TopDown}. Nous avons aussi vu que cela constitue la première phase
d'une transformation suivant notre approche et qu'il faut procéder à une
seconde phase ---~\emph{résolution}~---, elle aussi encodée par une stratégie
de réécriture.

Pour mettre en œuvre la méthode générale de transformation que nous
proposons~\cite{Bach2012}, nous avons ajouté trois constructions principales au
langage {\tom} :

%\begin{itemize}
%  \item exprimer une transformation ;
%  \item intégrer et créer les éléments \emph{resolve} ;
%  \item assurer la traçabilité de la transformation.
%\end{itemize}
%
\begin{itemize}

  \item \lex{\%transformation} pour exprimer une transformation
    (listing~\ref{transformationConstructSyntax}) ;

  \item \lex{\%resolve} pour intégrer et créer les éléments \emph{resolve}
    (listing~\ref{resolveConstructSyntax}) ;

  \item \lex{\%tracelink} pour assurer la résolution des liens ainsi que la
    traçabilité de la transformation (listing~\ref{tracelinkConstructSyntax}).

\end{itemize}

\begin{figure}[H]
  \centering
  \input{code/transformationSyntax}
%  \caption{Syntaxe concrète de la construction \%transformation}
%  \label{transformationConstructSyntax}
\end{figure}

\begin{figure}[H]
  \begin{center}
    \input{code/resolveSyntax}
  \end{center}
  %\caption{Syntaxe concrète de la construction \%resolve}
  %\label{resolveConstructSyntax}
\end{figure}

\begin{figure}[H]
  \begin{center}
    \input{code/tracelinkSyntax}
  \end{center}
  %\caption{Syntaxe concrète de la construction \%tracelink}
  %\label{tracelinkConstructSyntax}
\end{figure}


Ces constructions nous permettent d'implémenter des transformations avec les
caractéristiques suivantes, selon des critères proposés par
Czarnecki~\cite{Czarnecki2003,ibm06} :
%portée de la transformation
%\ttodo{reprendre les critères de Czarnecki~\cite{Czarnecki2003,ibm06} et les
%mettre en relation avec ce que je fais ? :
\begin{itemize}

  \item \textbf{règles de transformation :} une règle contient des
    \emph{patterns} et des variables, et bénéficie de typage. L'application
    des règles peut être contrôlée par le paramétrage des transformations
    élémentaires que l'utilisateur averti peut faire varier ;

  \item \textbf{ordonnancement des règles :} nos règles ne sont pas ordonnées
    ni interactives. Par défaut, et si le flot d'exécution n'est pas interrompu
    (par des instructions du type \texttt{break} ou \texttt{return}), les règles
    sont appliquées sur tous les motifs filtrés du modèle source. Ce
    comportement peut toutefois être modifié par le paramétrage de la
    \emph{définition} en cours {\via} une stratégie {\adhoc}. L'ordre
    d'écriture des \emph{définitions} et des règles n'a pas d'impact sur le
    résultat final ;

  \item \textbf{découpage en phases :} nos transformations sont constituées de
    deux phases, l'une pour transformer, l'autre pour \emph{résoudre} les
    liens ;

  \item \textbf{sens des règles et des transformations :} nos règles sont
    unidirectionnelles, nos transformations ne sont pas naturellement
    bidirectionnelles ;

  \item \textbf{modularité et mécanismes de réutilisation :} nos
    transformations reposent sur le langage de stratégies de réécriture de
    {\tom} dont l'une des caractéristiques est la modularité. Si une règle ne
    peut être directement réutilisée ailleurs, une \emph{définition} (un
    ensemble de règles) peut en revanche l'être ;

  \item \textbf{relation entre l'entrée et la sortie :} le modèle cible est
    différent du modèle source, même dans le cas d'une transformation endogène
    (transformation \emph{out-place}) ;
  
  \item \textbf{portée de la transformation :} tout ou partie du modèle peut
    être transformé, en fonction des \emph{patterns} dans les règles définies
    par l'utilisateur ;

  \item \textbf{traçabilité :} durant une transformation, nous maintenons des
    liens entre les éléments sources et cibles.

\end{itemize}%}

La syntaxe des nouvelles constructions du langage ainsi que les
caractéristiques des transformations de notre approche étant établies,
détaillons précisément ces constructions. Pour illustrer notre propos, nous
nous appuierons sur la transformation proposée en exemple précédemment. Cette
transformation consiste à transformer le modèle texte \texttt{A;B} en une
figure constituée de formes géométriques
(figure~\ref{fig:rappelSimpleTransfo}). 

Afin d'illustrer concrètement l'extension du langage, nous nous appuierons sur
l'extrait de code donné par le listing~\ref{code:transformationText2Picture}.
Les points de suspension dénotent le fait qu'il est parcellaire dans le but de
mettre en avant les nouvelles constructions du langage et de rendre plus
lisible l'extrait de code ainsi que son explication. Nous adoptons en outre le
code visuel suivant : les nouvelles constructions du langage apparaissent en
\colcode{blue}{bleu } tandis que le texte souligné et coloré marque les
correspondances dans la transformation entre les éléments des constructions. Ce
code visuel permet de comprendre clairement les relations entre les termes
créés par les nouvelles constructions du langage.

%et  \myul{magenta}{pour} \myul{black}{les} nouvelles constructions du langage.
%Nous adoptons aussi le code visuel bleu pour les nouvelles constructions du langage.

\begin{figure}[h]
  \begin{center}
    \input{code/transformationText2Picture}
  \end{center}
%  \caption{Extrait de code de la transformation \emph{Text2Picture} illustrant les nouvelles constructions {\tom} dédiées aux transformations de modèles}
%  \label{code:transformationText2Picture}
\end{figure}

\FloatBarrier

\subsection{Expression d'une transformation}

Une transformation prend un modèle source en paramètre et renvoie un modèle
cible. L'encodant sous la forme d'une stratégie de réécriture composée, nous
proposons une construction haut niveau gérant automatiquement sa combinaison.
Elle est composée de transformations élémentaires ---~\emph{définitions}~---,
représentées par des blocs \texttt{definition}. Une \emph{définition} opère une
transformation sur des éléments d'un type unique : deux
éléments ayant des types différents (et sans surtype commun) ne peuvent être
transformés dans une même \emph{définition}. Une transformation comporte donc
au moins autant de \emph{définitions} qu'il y a de types d'éléments que
l'utilisateur souhaite transformer. Chaque \emph{définition} est constituée
d'un ensemble de règles de réécriture composées d'un \emph{pattern} (membre
gauche) ainsi que d'une action (membre droit). Une action est un bloc pouvant
contenir du code hôte et du code {\tom}. De plus, chaque \emph{définition}
---~encodée par une stratégie~--- est nommée et paramétrée par une stratégie de
parcours que l'utilisateur averti peut faire varier.

Chacune de ces \emph{définitions} est écrite sans notion d'ordre par rapport
aux autres \emph{définitions} et elles n'entretiennent aucune dépendance dans
le sens où l'entrée de l'une n'est pas la sortie d'une autre. La transformation
est de type \emph{out-place} (la source n'est jamais modifiée) et la source de
chaque \emph{définition} est le modèle source. Le résultat de la
transformation ne dépend donc pas de l'ordre d'écriture des \emph{définitions}
adopté par l'utilisateur. La transformation finale est encodée par une
stratégie qui est une séquence de ces \emph{définitions}.

%Le
%listing~\ref{code:formeSyntaxeTransfo} illustre la forme générale d'une
%transformation de modèle écrite selon notre approche.
%
%\begin{figure}[H]
%  \begin{center}
%    \input{code/formeSyntaxeTransfo}
%  \end{center}
%  %\caption{Schéma global d'une transformation de modèle avec {\tom}}
%  %\label{code:formeSyntaxeTransfo}
%\end{figure}
%
%Cette transformation \texttt{MyTransfo} donnera lieu à une stratégie $MyTransfo
%= Sequence(TopDown(Nom1),TopDown(Nom2))$.


Dans l'exemple, la transformation nommée \texttt{Text2Picture} est introduite
par le lexème \lex{\%transformation} (ligne 1). Elle sert à transformer un
modèle conforme au métamodèle \texttt{text.ecore} en un modèle conforme au
métamodèle \texttt{picture.ecore}, ce qui est symbolisé par les noms de
fichiers des deux métamodèles de part et d'autre du lexème \lex{\texttt{->}}
(ligne 2). %On peut donner des chemins absolus ou relatifs,
%mais en l'absence de tout élément de chemin, seul le répertoire courant est
%considéré. 
Cette transformation prend deux arguments : \texttt{link} qui est le
modèle de lien qui sera peuplé durant la transformation, et \texttt{gp} qui est
le modèle cible qui sera construit au fur et à mesure de l'avancée des pas
d'exécution.

Cette transformation est constituée d'au moins deux \emph{définitions} nommées
\texttt{Letter2Shape} (ligne 4) et \texttt{Symbol2Shape} (ligne 20). Elles sont
toutes deux paramétrées par une stratégie introduite par le mot-clef
\texttt{traversal} pouvant être différente pour chaque définition (bien que
cela n'ait pas d'impact dans cet exemple, nous avons utilisé deux stratégies
différentes ---~\texttt{TopDown} et \texttt{BottomUp}~--- pour illustrer cette
possibilité). C'est cette stratégie qui est utilisée pour appliquer les
transformations élémentaires. Il est à noter que les paramètres de la
transformation sont aussi les paramètres de ces stratégies. Les
\emph{définitions} sont constituées de règles de réécriture à l'image des
stratégies {\tom}. Le fait que la \emph{définition} qui traduit les lettres en
formes géométriques soit écrite avant ou après celle qui transforme les
symboles n'a aucune importance. La \emph{définition} \texttt{Letter2Shape}
comprend deux règles : l'une pour transformer les éléments de type \emph{BText}
(lignes 5 à 10) et l'autre pour transformer les éléments de type \emph{AText}
(lignes 11 à 16). La \emph{définition} \texttt{Symbol2Shape} est quant à elle
constituée d'une seule règle qui transforme les éléments de type
\emph{SemiColon} (lignes 21 à 28). Une fois définie, une transformation peut
être utilisée (appelée) comme toute autre stratégie {\tom} {\via} la fonction
\texttt{visit()}.

Seule, la construction \lex{\%transformation} permet d'exprimer la première
phase de la transformation en générant une stratégie composée.


\subsection{Résolution}

La seconde phase de la transformation (résolution) est exprimée grâce à deux
autres constructions. 

Pour intégrer et créer des éléments intermédiaires \emph{resolve}, nous avons
introduit une nouvelle construction : \lex{\%resolve} (syntaxe donnée dans le
listing~\ref{resolveConstructSyntax}). Elle permet de créer les termes
intermédiaires pour représenter les éléments censés être créés dans une autre
\emph{définition}. Cette construction correspond à une spécialisation de la
construction \emph{backquote} (\lex{`}), en ce sens qu'elle crée un terme tout
en déclenchant un autre traitement, à savoir la génération d'un \emph{mapping}
dédié.

%\begin{figure}[h]
%  \begin{center}
%    \input{code/resolveSyntax}
%  \end{center}
%  %\caption{Syntaxe de la construction \%resolve}
%  %\label{resolveConstructSyntax}
%\end{figure}

La construction \lex{\%resolve} prend deux paramètres : l'élément source en
cours de transformation et le nom de l'élément de l'image d'un élément
transformé dans une autre définition que ce terme est censé représenter.
%\ttodo{$\leftarrow$ incompréhensible en français, faire un schéma / dessin pour
%expliquer qqch du genre : $r_1 = Img(Source_1).x$ insert schéma.} C'est ce
%mécanisme qu'illustre la figure\needcite.

Cet élément transformé dans une autre \emph{définition} est quant à lui marqué
comme pouvant être résolu {\via} la construction \lex{\%tracelink} (syntaxe
donnée dans le listing~\ref{tracelinkConstructSyntax}). Elle est le pendant de
\lex{\%resolve} et apparaît obligatoirement dans le code si l'utilisation
d'éléments intermédiaires est nécessaire. Elle correspond elle aussi à une
spécialisation de la construction \emph{backquote} : elle permet de créer un
terme tout en mettant à jour la structure de données qui maintient les liens de
traçabilité \emph{interne} (pour la résolution).

%elle permet de créer un terme tout en mettant à jour une structure qui rend la
%résolution possible.

La construction \lex{\%tracelink} prend deux paramètres : le nom du terme
marqué (accompagné de son type) ainsi que le terme lui-même (\emph{terme
backquote}). 

%Si l'on considère deux \emph{définitions} $d_1$ et $d_2$, et deux sources
%$s_{i_1}$ et $s_{i_2}$
%
%Soient $s_i$ les $i$ éléments du modèle source à transformer. Soit $t_i =
%Img(s_i)$ l'image de $s_i$ par la transformation. $t_i$ est un ensemble de $j$
%éléments cibles : $t_i = Img(s_i) = \{ t_{i,j} \}$. Si une règle de cette
%\emph{définition} nécessite un élément temporaire, un élément \emph{resolve}
%$r_{i,j}$ doit être créé. Il représente un élément $t_{i',j'}$ obtenu lors de
%la transformation d'un autre élément source $s_{i'}$. L'image d'une source
%$s_i$ est donc un ensemble d'éléments cibles $t_{i,j}$ dont certains sont des
%éléments intermédiaires $r_{i,j}$ jouant le rôle d'éléments $t_{i',j'} \in
%Img(s_{i'})$.

Dans notre exemple support, la transformation d'un élément \textsf{B} en la
forme constituée d'un pentagone bleu et d'un connecteur nécessite
l'introduction d'un élément \emph{resolve}. En effet, le connecteur carré est
créé dans une autre \emph{définition} ---~\texttt{Symbol2Shape}~--- et nous
devons utiliser le mécanisme de création d'éléments intermédiaires
\emph{resolve}. À la ligne 6, nous instancions donc un terme \emph{resolve} qui
remplacera temporairement l'élément \texttt{target\_right} de l'image de la
transformation du symbole \emph{SemiColon} (\texttt{;}). Outre le fait de jouer
le rôle de \emph{placeholder} et de pouvoir être manipulé comme s'il s'agissait
d'un élément classique du modèle cible, l'élément \emph{resolve} maintient aussi
un lien entre l'élément source (\texttt{b}, de type \texttt{BText}) qui a
provoqué sa création et la cible représentée.

Dans notre exemple, ce mécanisme est réitéré dans la \emph{définition}
suivante (ligne 25) et peut être utilisé autant de fois que nécessaire dans la
transformation.

%%\ttodo{+ bloc de code pour expliquer ?, reprendre l'exemple graphique, par
%%exemple resolveB2Forme -> nope, on réutilise le bloc de code d'avant où on met
%%tout, sinon c'est incompréhensible}
%%\input{code/resolveB2Forme}

%\ttodo{déplacer DISCUSSION / Nous remarquons que la phase de résolution n'apparaît pas dans l'extrait de
%code présenté, ce qui est tout à fait normal. En effet, elle est entièrement
%générée, en fonction de l'utilisation des constructions \lex{\%resolve} au sein
%de la transformation. Ainsi, une transformation ne nécessitant pas d'éléments
%\emph{resolve} (donc sans utilisation du lexème \lex{\%resolve}) n'a pas de
%phase de résolution.} 
%
%\ttodo{ déplacer UTILISATION / À l'inverse, l'utilisation de la construction provoque la
%génération du bloc de résolution dédié au type traité. Dans la version
%actuellement publiée de l'outil ({\tom-2.10}), cette phase est encodée par une
%unique stratégie que l'utilisateur n'écrit qu'indirectement par l'usage
%judicieux des constructions de résolution. L'application de la stratégie de
%résolution est néanmoins à la charge de l'utilisateur au sein de son programme.
%Il doit appeler la stratégie en l'appliquant sur le modèle intermédiaire créé
%lors de la première phase.}
%
%\ttodo{déplacer EXPÉRIMENTATION / Nous avons aussi expérimenté une version modulaire de la phase de résolution.
%Plutôt que de générer une stratégie monolithique effectuant toute la
%résolution, nous avons écrit une solution alternative générant plusieurs
%stratégies de résolution partielle, chacune de ces stratégies n'effectuant la
%réconciliation que sur un type de termes donné. Dans notre exemple, cette
%alternative générerait deux stratégies distinctes, ainsi qu'une stratégie
%combinant les deux. L'inconvénient de cette solution est qu'elle est plus
%complexe à prendre en main pour l'utilisateur. Cependant, elle a l'avantage
%d'offrir un plus grande modularité en décomposant la seconde phase. Ainsi, le
%code généré pour une \emph{définition} peut être réutilisé dans une autre
%transformation, et l'utilisateur averti prendra soin d'accompagner la
%définition de la (ou des) stratégie(s) de résolution correspondante(s).
%Pour des raisons d'utilisabilité de nos outils , nous avons fait le choix de
%diffuser la version du générateur de phase de résolution monolithique dans la
%version stable de {\tom}.}

\subsection{Traçabilité}
\label{ch:outils:trace}
%\ttodo{traçabilité on demand}

Nous avons également étendu le langage afin d'ajouter la traçabilité aux
transformations. Une possibilité eût été de tracer systématiquement les termes
créés, puis de mettre en œuvre un mécanisme de requête pour retrouver les
informations intéressantes. Cependant, cette approche aurait donnée des traces
extrêmement verbeuses et donc peu exploitables. Pour éviter cet écueil, nous
avons fait le choix d'une \emph{traçabilité à la demande}, implémentée par la
construction \lex{\%tracelink} dont la syntaxe a été donnée en début de section
dans le listing~\ref{tracelinkConstructSyntax}.

%\begin{figure}[h]
%  \begin{center}
%    \input{code/tracelinkSyntax}
%  \end{center}
%  %\caption{Syntaxe concrète de la construction \%tracelink}
%  %\label{tracelinkConstructSyntax}
%\end{figure}

Bien que techniquement implémentée par un unique lexème, la notion de
traçabilité est double. Ce lexème a donc actuellement deux usages ---~pour deux
types de traçabilité~--- à savoir :
\begin{itemize}

  \item assurer la traçabilité \emph{interne} (ou \emph{technique}) : pour
    spécifier les éléments correspondant aux éléments \emph{resolve} créés lors
    de la transformation, afin que la phase de résolution puisse effectuer le
    traitement (nous pouvons parler de \emph{resolveLink}) ;

  \item assurer la traçabilité au sens de la qualification logicielle :
    construire d'une part le métamodèle de lien à la compilation de la
    transformation, et d'autre part peupler la trace à l'exécution (nous
    parlons dans ce cas de \emph{trace}).

\end{itemize}

Quelle que soit la traçabilité voulue, nous souhaitons spécifier à la demande
quels sont les éléments que nous créons que nous souhaitons tracer.
L'utilisateur doit donc explicitement désigner les termes {\tom} à tracer.
Chaque terme traçable appartenant à une \emph{définition} de la transformation,
l'élément du modèle source dont il est issu est implicite. Du point de vue de
l'utilisateur, tracer un terme revient simplement à utiliser la construction
dédiée en spécifiant son nom, son type et en écrivant le terme {\via} la
construction \emph{backquote}.

Dans le cadre d'une traçabilité \emph{interne}, la construction correspond au
pendant des éléments \emph{resolve} (\emph{resolveLink}). La création
d'éléments \emph{resolve} dans la transformation implique alors l'utilisation
d'au moins un marquage de ce type. Cette utilisation est celle présentée dans
la section précédente.

Dans le cadre d'une traçabilité de transformation au sens de la qualification
logicielle, la construction de trace peut être utilisée de manière indépendante
de la construction pour la résolution. Une transformation peut donc comporter
des constructions de trace sans qu'aucune construction de résolution ne soit
utilisée. Dans notre approche, l'utilisateur ne fournit pas de métamodèle de
lien \emph{a priori}. La construction de trace permet de générer le métamodèle
de lien de la transformation lors de la compilation, c'est-à-dire de générer
les structures liant sources et cibles en fonction des termes tracés. À
l'exécution, ces structures sont peuplées pour maintenir les relations entre
les sources et les cibles de la transformation. La construction de trace lie un
élément cible créé à la source en cours de transformation, ce qui permet
d'établir un ensemble de relations \texttt{1..N} (une source associée à
plusieurs cibles).

Dans notre exemple support, l'utilisateur a décidé d'opérer une trace minimale,
c'est-à-dire que les éléments tracés sont ceux qui doivent impérativement être
tracés pour que la résolution s'opère correctement. C'est donc la traçabilité
technique qui est essentiellement utilisée ici. Les traces sont activées par
les lexèmes \lex{\%tracelink} (lignes 12 et 23). Celui de la ligne 23
correspond à l'élément \emph{resolve} de la ligne 6 (souligné en magenta),
tandis que celui de la ligne 12 à celui de la ligne 25 (souligné en noir).
L'utilisateur aurait bien évidemment pu tracer les autres éléments créés (par
exemple \texttt{bluePentagon} à ligne 7). Même si l'usage de \lex{\%tracelink}
dans cet exemple fait transparaître la volonté de l'utilisateur d'avoir
uniquement une traçabilité \emph{technique}, un modèle de lien minimal de la
transformation est néanmoins créé. La transformation spécifie un modèle de lien
(\texttt{link} dans notre cas) dans lequel nous stockons les associations
établies entre les éléments sources et les éléments cibles tracés tout au long
de la transformation. En fin de transformation, cette trace peut être
sérialisée pour un usage ultérieur.

En expérimentant nos outils, nous nous sommes aperçus que l'utilisation d'une
construction unique pour deux usages distincts pouvait perturber l'utilisateur.
Nous projetons donc à terme de séparer cette construction en deux constructions
distinctes, chacune adaptée à une des traçabilités.


\section{Travaux d'implémentation}

% rappel
%\usepackage{float}
%...
%\begin{figure}[H]
% ou
%\begin{figure}[!htbp]
% ou
%\usepackage{placeins}
%...
%\FloatBarrier
%\begin{figure}[H]

%\todo{utile ? vient de la réorganisation du premier jet ; refaire, le projet a
%un peu évolué\\}
%D'un point de vue plus macroscopique, le projet {\tom} compte environ 60000
%lignes de code, réparties dans les sous-projets suivants : le compilateur
%{\tom} lui-même (\texttt{engine}), le générateur d'ancrages algébriques et de
%structures de données {\java} à partir d'une signature (\texttt{gom}), les
%bibliothèques (\texttt{library}), le générateur d'ancrages algébriques à partir
%d'un métamodèle EMF Ecore (\texttt{emf}), ainsi que la plateforme
%(\texttt{platform}) qui mutualise une partie du code de {\tom} et de {\gom}
%(gestion des phases). La Table~\ref{table:stats} résume cela avec quelques
%valeurs chiffrées \ttodo{Mettre à jour}.
%
%\begin{table}[H]
%  \begin{center}
%    \input{figures/tomstats}
%    \caption{Nombre de lignes de code dans le compilateur Tom}
%    \label{table:stats}
%  \end{center}
%\end{table}

Les travaux d'implémentation pour étendre le langage ont concerné deux parties
du projet {\tom} : d'une part le compilateur {\tom}, d'autre part l'outil
{\tomemf}. 

Avant de détailler la manière dont nous avons mis en œuvre notre extension du
projet, nous décrivons l'architecture du projet {\tom} ainsi que le processus
de compilation dans le contexte de {\java}.
%le projet {\tom} d'un point de vue technique et nous
%expliquons son architecture ainsi que le processus de compilation dans le
%contexte de {\java}. 
Cela nous permettra ensuite d'expliquer comment nous nous
sommes intégrés dans l'existant.

\subsection{Architecture du projet Tom et chaîne de compilation}
%\subsection{\todo{Architecture actuelle} vs \todo{Chaîne de compilation et architecture du compilateur Tom}}
%\section{Langages supportés : \emph{backends}}

Le projet {\tom} s'articule autour de trois outils distincts utilisables
indépendamment : le compilateur lui-même, {\gom} et l'outil de génération
d'ancrages formels {\tomemf}.

%Le projet {\tom} s'articule autour de trois outils distincts : le compilateur
%lui-même, {\gom} que nous ne détaillerons pas ici et l'outil de génération
%d'ancrages formels {\tomemf}. 
Le projet {\tom} comprend aussi un ensemble de bibliothèques (notamment la
bibliothèque de stratégies \texttt{sl}, des ancrages algébriques, un outil de
conversion {DOM \xml} vers {\gom} et inverse, une bibliothèque de
\emph{bytecode} {\java}, etc.) ainsi que de très nombreux exemples et tests
unitaires. La gestion des phases de compilation est assurée par la plateforme
sur laquelle s'appuient {\tom} et {\gom}.

%D'un point de vue plus macroscopique, le projet {\tom} compte environ 60000
%lignes de code, réparties dans les sous-projets suivants : le compilateur
%{\tom} lui-même (\texttt{engine}), le générateur d'ancrages algébriques et de
%structures de données {\java} à partir d'une signature (\texttt{gom}), les
%bibliothèques (\texttt{library}), le générateur d'ancrages algébriques à partir
%d'un métamodèle EMF Ecore (\texttt{emf}), ainsi que la plateforme
%(\texttt{platform}) qui mutualise une partie du code de {\tom} et de {\gom}
%(gestion des phases). La Table~\ref{table:stats} résume cela avec quelques
%valeurs chiffrées \ttodo{Mettre à jour}.

L'ensemble du projet compte environ \num{60000} lignes de code, réparties dans les
sous-projets \texttt{engine} (compilateur {\tom} lui-même), \texttt{gom},
\texttt{library}, \texttt{emf}, ainsi que \texttt{platform}. L'essentiel du
code source est écrit en {\tom} (+{\java}) ainsi qu'en {\java} pur. La
Table~\ref{table:stats} résume cette répartition par projet et par langage.

\begin{table}[H]
  \begin{center}
    \input{figures/tomstats}
    \caption{Nombre de lignes de code dans le projet {\tom}, par sous-projet et par langage}
    \label{table:stats}
  \end{center}
\end{table}



%\subsection{Backends}
Le langage {\tom} a été conçu pour étendre des langages hôtes. La chaîne de
compilation (figure~\ref{fig:tomArchi}) a été pensée de manière à minimiser le
code spécifique à chaque langage hôte. Le compilateur ne traitant que la partie
{\tom} et n'analysant pas le code hôte, seules les constructions {\tom} sont
\emph{parsées} puis traitées par chaque phase du compilateur, jusqu'à la
compilation à proprement parler. Durant cette phase, plutôt que de compiler
directement vers le langage cible, {\tom} compile vers un langage intermédiaire
(IL) qui sert de langage pivot. Les constructions de ce langage sont ensuite
traduites dans le langage cible lors de la dernière phase de compilation.
Ainsi, l'extension à un nouveau langage passe par l'écriture d'un nouveau
\emph{backend} sans forcément avoir à réécrire ou adapter la chaîne complète du
compilateur.

Nos exemples sont centrés sur {\java} étant donné que son \emph{backend} est
le plus avancé. Cependant {\tom} supporte d'autres langages : {\ada}, {\C},
{\caml}, {\csharp}, {\python}. Le tableau ~\ref{table:backends} donne
l'implémentation des fonctionnalités en fonction des \emph{backends}.

\begin{table}[H]
  \begin{center}
    \input{figures/tomFeatures}
  \end{center}
    \caption{Implémentation de fonctionnalités de {\tom} par langage cible.}
    \label{table:backends}
\end{table}

%\subsection{Vue d'ensemble du compilateur}

Un programme est écrit en {\tom}+langage hôte, accompagné d'ancrages pour faire
le lien avec les structures de données hôtes. Le compilateur analyse les
constructions {\tom} et génère le code hôte correspondant qui, couplé aux
structures de données hôtes, constitue un programme écrit dans le langage hôte
que l'on compile avec le compilateur adéquat. La
figure~\ref{fig:wholeTomProcess}
%~\ref{fig:tomGomCompiler}
explique ce fonctionnement global des outils du projet {\tom} dans
l'environnement {\java}. La partie haute décrit le processus de compilation
d'un programme {\tom} couplé à {\gom}, tandis que la partie basse se concentre
sur le processus dans le cadre des transformations de modèles, c'est-à-dire en
utilisant l'outil {\tomemf} pour générer les ancrages algébriques. Ces outils
peuvent bien évidemment être utilisés indépendamment.

%\todo{[ancienne version (manque EMF):]}
%\input{figures/bckp.tomGomCompiler}
%\input{figures/tomGomCompiler}
%\todo{[version en cours de modification : ajout de EMF : wholeTomProcess]}
%\todo{[test, première version]}

\begin{figure}[H]
  \begin{center}
    \input{figures/wholeTomProcess}
  \end{center}
  \caption{Diagramme d'activité décrivant le processus de compilation d'un programme {\tom}.}
  \label{fig:wholeTomProcess}
\end{figure}

%\todo{[test, ou autre version~\ref{fig:wholeTomProcess2} :]}
%\input{figures/wholeTomProcess2}
%\todo{[TEST schéma, en faire un plus simple pour expliquer Tom-EMF ; et un plus
%complexe pour expliquer toute l'archi du projet (à la place de la figure
%au-dessus]}
%\input{figures/tomEMFCompiler} 
%Figure~\ref{fig:tomEMFCompiler} 
%\subsection{Architecture du compilateur Tom}

Le compilateur {\tom} se décompose en phases -- écrites en {\tomjava} -- qui
sont chaînées les unes après les autres. Chacune procède à une transformation
bien définie sur l'entrée, et fournit une sortie à la phase suivante. Nous
décrivons brièvement chacune de ces phases ci-après, et nous représentons
l'architecture du compilateur {\tom} avec la figure~\ref{fig:tomArchi}. Les
blocs marqués en traits pointillés indiquent les phases où nos travaux
d'implémentation se sont essentiellement concentrés tandis que la phase colorée
était inexistante avant ce travail de thèse. C'est le cœur de
l'implémentation permettant de traiter l'extension du langage dédiée aux
transformations de modèles.

\begin{figure}[h]
  \begin{center}
    \input{figures/tomArchi}
  \end{center}
  \caption{Phases du compilateur {\tom}.}
  \label{fig:tomArchi}
\end{figure}

\begin{description}

  \item[Parser :] Le \emph{parser} produit un arbre de syntaxe abstraite (AST,
    \emph{Abstract-Syntax Tree}) à partir du code d'entrée. Les constructions
    {\tom} sont représentées par des nœuds particuliers tandis que les blocs de
    code hôte sont stockés dans l'arbre comme des chaînes de caractères. Dans
    le cas d'une construction \lex{\%gom} (ou de l'utilisation d'un fichier
    \texttt{.gom}), l'outil {\gom} est appelé et son \emph{parser} prend le
    relais pour l'analyse du bloc.

  \item[Transformer :] Le \emph{transformer} est une phase qui a été ajoutée
    durant cette thèse afin de traiter les constructions du langage dédiées aux
    transformations de modèles. Il traite en particulier les constructions
    \lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink}, les AST issus
    de ces deux dernières étant des sous-arbres de l'AST issu de
    \lex{\%transformation}. La mise en œuvre de cette phase est détaillée dans
    la section~\ref{subsec:meoExt}.

  \item[Syntax checker :] Le \emph{syntax checker} effectue des vérifications
    syntaxiques sur l'{\AST}. Par exemple, il vérifie que chaque symbole de
    fonction a été déclaré et qu'il n'y a pas de dépendance circulaire entre
    les conditions de filtrage.

  \item[Desugarer :] Le \emph{desugarer} simplifie l'{\AST} en transformant les
    différents types de nœuds représentant des constructeurs de langage hôte en
    nœuds génériques. De plus, les variables anonymes y sont nommées avec des
    noms \emph{frais} (noms qui n'ont jamais été utilisés précédemment).

  \item[Typer :] Le \emph{typer} effectue l'inférence de type et propage les
    types inférés dans l'{\AST}.

  \item[Typer checker :] Le \emph{type checker} vérifie les types et les rangs
    des symboles. Il vérifie par exemple que les occurrences d'une même
    variable sont du même type.

  \item[Expander :] L'\emph{expander} transforme une dernière fois l'{\AST}
    avant la compilation : il traite les nœuds issus des constructions
    \lex{\%strategy} et génère les introspecteurs (structures pour parcourir un
    terme).

  \item[Compiler :] Le \emph{compiler} transforme les nœuds {\tom} en
    instructions du langage intermédiaire (IL, pour \emph{Intermediate
    Language}) qui sert de langage pivot.

  \item[Optimizer :] L'\emph{optimizer} est responsable de l'optimisation du
    code écrit dans le langage intermédiaire. Il limite par exemple le nombre
    d'assignations de variables.

  \item[Backend :] Le \emph{backend} est le générateur de code cible. Durant
    cette phase, le langage intermédiaire est traduit en instructions du
    langage cible.

\end{description}



\subsection{Générateur d'ancrages algébriques}
\label{ch:outils:subsec:tomemf}
%\ttodo{Tom-EMF ; traitement de gros MM : UML2, Ecore}

Dans cette partie, nous décrivons techniquement le générateur d'ancrages
formels {\tomemf}. Il a été écrit pour répondre au besoin de représentation des
modèles {\emf} sous la forme de termes {\tom}. Il est lui-même écrit en
{\tomjava} et fonctionne de manière complètement indépendante de l'extension du
langage dédiée aux transformations de modèles. Il est utilisé de manière
\emph{stand-alone}, c'est-à-dire comme un logiciel à part entière, exécuté sans
être appelé par un programme {\tom} externe. La figure~\ref{fig:tomEMF} décrit
le principe général de fonctionnement que nous expliquons ci-après :
%\ttodo{supprimer ces interlignes pourris}
\begin{enumerate}
    %\compresslist
  \item {\eclipse} : métamodélisation et génération des structures {java}
    \begin{enumerate}
    %\compresslist
      \item L'utilisateur écrit un métamodèle {\ecore} manuellement, ou en
        utilisant les \emph{modeling tools} de {\eclipse} ;
      \item Il génère ensuite le générateur de code {\java} (\emph{GenModel}) 
        à partir de ce métamodèle via {\eclipse} ;
      \item Il génère ensuite les structures {\java} correspondantes et les exporte
        sous la forme d'une archive (\texttt{.jar}) ;
    \end{enumerate}
  \item {\tomemf} : génération des ancrages algébriques
    %\compresslist
    \begin{enumerate}
    %\compresslist
  \item L'utilisateur charge les structures {\java} générées et spécifie à
    {\tomemf} le(s) \emph{EPackage(s)} pour le(s)quel(s) il souhaite générer des
    ancrages ;
  \item Un fichier de \emph{mappings} (\texttt{<nom.complet.du.paquet>.tom})
    est généré par paquet ;
    \end{enumerate}
  \item {\tom} et {\java} : transformation de modèles
    %\compresslist
    \begin{enumerate}
    %\compresslist
  \item L'utilisateur inclut les ancrages dans sa transformation via la
    construction \lex{\%include} et importe les structures de données {\java}
      (\texttt{import}) ;
    \item L'utilisateur peut alors utiliser les types apparaissant dans le
      métamodèle et écrire la transformation en {\tomjava}, en utilisant ou non
      l'extension du langage, dédiée aux transformations de modèles ;
    \item La suite du processus est identique à une utilisation classique de
      {\tom} (compilation du code {\tom}, puis du code {\java}).
    \end{enumerate}
\end{enumerate}
%\ttodo{insérer schéma de fonctionnement {\tomemf} (comme dans les
%présentations)}

\begin{figure}[h]
  \begin{center}
    \input{figures/tomEMF}
  \end{center}
  \caption{Processus de compilation d'une transformation de modèles {\tomemf}.}
  \label{fig:tomEMF}
\end{figure}

%\todo{[tests schéma idée Marion v1]}
%\input{figures/tests_marion/v1_myTomGomCompiler}
%\todo{[tests schéma idée Marion v2]}
%\input{figures/tests_marion/v2_tomGomCompiler}

Ce générateur extrait une signature algébrique utilisable par {\tom} à partir
du code {\java-\emf} représentant le métamodèle.
%traduit le code du métamodèle sous la forme d'une signature
%algébrique utilisable par {\tom}.

%\ttodo{fonctionnalités : gestion des paquestmultiples, gestion des doublons,
%des types builtin, des types venus de Ecore et de UML2, gestion des préfixes}

%Le générateur d'ancrages {\tomemf} était au départ un \emph{proof of concept}

Au départ en tant que \emph{proof of concept}, nous avons adapté et étendu le
générateur d'ancrages {\tomemf} afin de construire un générateur pleinement
opérationnel dédié aux modèles. Compte tenu de la forte utilisation de {\java}
dans le développement logiciel ainsi que de celle de {\eclipse} et de {\emf}
dans la communauté de l'ingénierie dirigée par les modèles, nous avons fait le
choix de nous concentrer dans un premier temps sur ces technologies pour
obtenir un outil fonctionnel. Cependant, nous ne nous limitons pas à ces choix
et n'excluons pas une ouverture de {\tomemf} à d'autres technologies et
langages. Notamment, certaines expériences ont été menées dans le but d'étendre
l'outil au langage {\ada} et au \emph{framework} {\gms}. Une autre piste
d'extension envisagée est l'utilisation de {\kmf}~\footnote{\emph{Kevoree
Modeling Framework} : \url{http://www.kevoree.org/kmf}}. Le développement d'une
transformation en {\java-\emf} nécessitant de toute manière de générer la
structure de données du métamodèle pour l'utiliser au sein du programme, nous
avons choisi de conserver dans un premier temps ce fonctionnement de génération
de signature algébrique à partir du code. Cependant, si l'outil devait être
étendu à d'autres langages et technologies, nous pourrions revoir nos choix
afin de générer la signature directement à partir du métamodèle au format
\texttt{.ecore}.
%\todo{$^{[\text{à voir}]}$}.

Dans sa forme actuelle, {\tomemf} est en mesure de traiter plusieurs paquetages
{\ecore} (\emph{EPackages}) en entrée, et de générer un fichier d'ancrages pour
chacun d'entre eux. Si des éléments du métamodèle sont utilisés alors qu'ils
appartiennent à un autre \emph{EPackage} du métamodèle (ou d'un autre
métamodèle chargé en mémoire), alors notre générateur génère les
\emph{mappings} en cascade, tout en évitant la génération multiple d'un même
paquetage. De la même manière, cet outil ne génère les ancrages formels que
pour les types qui n'en ont pas déjà. Durant l'opération, nous maintenons donc
un ensemble d'ancrages générés et à générer pour les types rencontrés.

Pour chaque \emph{EPackage} spécifié par l'utilisateur, {\tomemf} récupère les
\emph{EClassifiers} (surclasse commune de \emph{EClass} et \emph{EDataType}
permettant de spécifier les types d'opérations, de \emph{structural features}
et de paramètres) et génère les ancrages algébriques associés.
%\emph{EClassifier} (surclasse commune de \emph{EClass} et
%\emph{EDataType} permettant de spécifier les types d'opérations, de
%\emph{structural features} et de paramètres) d'un métamodèle {\ecore}, un
%ancrage algébrique est généré. 
Si le métamodèle spécifie qu'un élément
\emph{EClass} possède la propriété \emph{abstract}, l'opérateur (\lex{\%op})
n'est naturellement pas généré. Lorsque la multiplicité d'un attribut est
strictement supérieure à 1 (\emph{structural feature} \texttt{many}), le champ
de l'opérateur est un type liste. Un ancrage supplémentaire est alors généré,
accompagné de l'opérateur variadique correspondant. Les associations et
compositions sont donc représentées de cette manière. Il est à noter que {\tom}
disposant d'un moteur d'inférence de type équipé du
sous-typage~\cite{tavares09}, nous avons intégré cette fonctionnalité dans
{\tomemf}. Lorsque l'option adéquate (\texttt{-nt}) est activée, les ancrages
générés prennent en compte le sous-typage proposé par {\ecore}. Si un type n'a
pas de surtype explicitement donné, le surtype généré dans l'ancrage est
\emph{EObject} (le type \emph{Object} de {\ecore}) afin de correspondre aux
conventions de {\emf}.  Cette fonctionnalité de génération des sous-types est
toutefois limitée au sous-typage simple : en effet {\ecore} supporte l'héritage
multiple, mais pas {\java} (au niveau des classes). Nous verrons dans la
section suivante que la fonctionnalité de sous-typage de {\tom} est utilisée en
interne par le mécanisme de résolution (génération et remplacement des éléments
\emph{resolve}).

S'agissant des types issus des métamodèles {\ecore} ou {\uml} (ainsi que les
types dits \emph{builtin}), ceux-ci sont traités à part (et non en cascade
lorsqu'ils apparaissent) étant donné qu'il s'agit de métamodèles très utilisés
et que leurs types sont souvent inclus dans les transformations. De ce fait,
nous diffusons les ancrages pour ces métamodèles en tant que bibliothèques dans
le projet {\tom}. L'outil {\tomemf} lui-même est écrit en {\tomjava} et utilise
ces ancrages {\ecore}. La première utilisation de notre générateur a donc été
pour terminer son \emph{bootstrap}, ce qui nous a permis de remplacer les
ancrages écrits manuellement par des ancrages générés, comme l'illustre la
figure~\ref{fig:bootstrapTomEMF}. Dans cette figure, les flèches en trait plein
sont à comprendre comme des flux d'entrée et sortie, tandis que les flèches en
pointillés signifient \emph{intégration à l'outil}.


\begin{figure}[h]
  \begin{center}
    \input{figures/bootstrapTomEMF}
  \end{center}
  \caption{\emph{Bootstrap} de {\tomemf} : remplacement des ancrages algébriques \texttt{Ecore.tom} écrits manuellement par les ancrages générés.}
  \label{fig:bootstrapTomEMF}
\end{figure}


{\tomemf} gère aussi le préfixage des noms de types et d'opérateurs générés. En
effet, il n'est pas rare de nommer de la même manière des éléments de
métamodèles différents, mais qui n'appartiennent pas aux mêmes paquetages.
Cependant, {\tom} n'ayant pas de système d'espaces de noms (\emph{namespaces})
pour ses types et opérateurs, nous offrons à l'utilisateur la possibilité de
préfixer les ancrages générés.

%\ttodo{Quoi d'autre à dire sur la partie technique de {\tomemf} ?
%EcoreContainmentIntrospector}

Enfin, pour rendre complètement opérationnel le pont entre les deux espaces
technologiques, {\tomemf} comprend un outil additionnel :
\texttt{EcoreContainmentIntrospector}. Il s'agit d'une bibliothèque permettant
le parcours de modèles par des stratégies. Elle repose sur le fait que le
modèle possède une structure arborescente par la relation de composition et
définit le parcours de modèles suivant ces relations. Cette bibliothèque
s'utilise en conjonction des stratégies (l'utilisateur passe cet
\emph{introspecteur} dédié à {\ecore} en paramètre de la stratégie).
Techniquement, cette bibliothèque spécialisée fournit des services nécessaires
à {\tom} pour compter, récupérer et modifier les enfants d'un nœud d'un terme
représentant un modèle.


\subsection{Mise en œuvre de l'extension}
\label{subsec:meoExt}
%\todo{à traiter : comment est faite l'implémentation ? Quelle(s) phase(s)
%concernée(s) ? comment c'est compilé ? etc.}

Dans cette partie, nous décrivons la mise en œuvre de l'extension du langage au
sein du compilateur {\tom}. %Il s'agissait d'intégrer les constructions
%\lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink} au langage

%\ttodo{ajout du transformer, modif du parser+backend forcément, modif de
%l'expander pour ajouter des bouts de code aux stratégies si besoin (pour
%resolve), adt}

Lors de l'implémentation de constructions d'un langage, plusieurs modifications
de la chaîne de compilation sont nécessaires, de l'analyseur syntaxique au
générateur de code. Dans notre cas, s'agissant de nouvelles constructions avec
de nouveaux lexèmes, il fallait étendre le \emph{parser} (début de chaîne) pour
pouvoir les reconnaître. Ensuite, ces constructions entraînant la génération de
code qui n'était pas encore traité par le compilateur, le \emph{backend} (fin
de chaîne) a aussi été étendu. Cependant, ces deux tâches ne sont pas le cœur
de la mise en œuvre de l'extension du langage dédiée aux transformations de
modèles. En effet, l'essentiel de l'implémentation réside dans l'ajout d'une
nouvelle phase ---~le \emph{transformer}~--- dont la charge est de transformer
les nœuds de l'arbre spécialisé dans la transformation de modèles en des
stratégies. À cela s'ajoute la génération automatique d'ancrages ainsi que
celle de la trace dont les instructions sont ajoutées à l'arbre.

%\todo{[Pas grand chose à dire côté parsing, c'est très classique, rien de bien
%compliqué, l'intelligence n'est pas là]\\}

\paragraph{Parser.} L'aspect inhabituel de l'analyseur syntaxique de {\tom}
réside dans le fait qu'il n'analyse pas tout le code, mais uniquement les îlots
formels. Le code hôte est quant à lui vu comme une chaîne de caractères qui est
parcourue jusqu'à l'îlot suivant. Ce type d'analyse où la grammaire du langage
n'est pas totalement définie est appelé \emph{fuzzy parsing} : seule la
grammaire de {\tom} l'est, totalement (on parle de grammaire îlot ou
\emph{island grammar}). L'analyseur syntaxique de {\tom} repose sur le très
populaire générateur de \emph{parser} {\antlr}~\footnote{\emph{ANother Tool for
Language Recognition} : \url{http://www.antlr.org}}, ainsi que sur
{\gomantlradapter}, un outil du projet permettant de lier les arbres générés
par {\antlr} aux structures {\gom}. Lorsque le \emph{parser} principal détecte
une construction donnée, il donne la main à un \emph{parser} dédié ({\tom} ou
{\gom}). Il s'agissait donc d'étendre ces analyseurs pour mettre en œuvre les
nouvelles constructions, en ajoutant de nouvelles règles adéquates dans la
grammaire. En parallèle, la signature de {\tom} a été étendue afin de prendre
en compte ces nouvelles constructions.


\paragraph{Transformer.} Le cœur de la mise en œuvre de l'extension de {\tom}
dédiée aux transformations de modèles se situe au niveau du \emph{plugin}
\emph{transformer}, juste après l'analyseur syntaxique, et avant la phase de
typage. Ce choix de nous insérer tôt dans la chaîne de compilation est tout à
fait logique : la seule contrainte forte que nous avions était d'apparaître
avant l'\emph{expander} ---~\emph{plugin} dédié aux stratégies~--- et nous
souhaitions aussi bénéficier au maximum des éléments de contrôle déjà
implémentés dans le compilateur {\tom} (\emph{syntax checker}, \emph{typer},
\emph{type checker}).

Cette phase prend en entrée l'arbre issu de l'analyseur syntaxique et produit
un arbre syntaxique ne contenant plus aucun sous-arbre de type
\emph{Transformation} obtenu après \emph{parsing} de la construction
\lex{\%transformation}. Elle est implémentée de manière classique ---~du point
de vue d'un développeur {\tom}~---, à savoir qu'une stratégie {\tom} est
appliquée sur l'arbre en entrée.

Les nœuds de type \emph{Resolve} et \emph{Tracelink} obtenus à partir du
\emph{parsing} des constructions \lex{\%resolve} et \lex{\%tracelink} sont
forcément des sous-arbres des arbres dont la racine est un nœud
\emph{Transformation} étant donné que ces constructions sont uniquement
utilisables dans le cadre des transformations de modèles. En ne manipulant que
ces derniers, nous sommes donc en mesure de collecter et traiter tous les nœuds
\emph{Resolve} et \emph{Tracelink}.

%\todo{
%\begin{itemize}
%\item run : process transfonode -> abstractdecl
%\item gen resolve element nodes à partir des instructions Resolve
%\item concElementaryTransfo (genElementaryStrategy + elemenStratSymbol
%\item gen stratégie resolve
%\item on empaquette tout dans une séquence
%\end{itemize}
%}

Dans le sous-arbre représentant une transformation, nous filtrons les nœuds de
type \emph{Resolve} correspondant aux utilisations de la construction
\lex{\%resolve}. Si un tel motif est filtré, le mécanisme d'enrichissement du
métamodèle cible présenté dans le chapitre~\ref{ch:approach} est déclenché. Il
est alors nécessaire de créer d'une part les structures de données concrètes
représentant les éléments \emph{resolve}, et d'autre part des ancrages
algébriques correspondants. Pour illustrer concrètement ce mécanisme, reprenons
l'instruction \verb+%resolve(l:AText,target_left:Circle);+ de l'exemple
précédent transformant du texte en figure géométrique. Elle entraîne la
génération de la structure {\java} par le \emph{backend}, donnée dans le
listing~\ref{code:resolveClassA2Shape} (par souci de lisibilité, les noms ont
été simplifiés et les attributs sont publics). 

\begin{figure}[h]
  \begin{center}
    \input{code/resolveClassA2Shape}
  \end{center}
  %\caption{Exemple de classe {\java} générée implémentant les éléments \emph{resolve}.}
  %\label{code:resolveClassA2Shape}
\end{figure}

La classe générée ---~ici \texttt{ResolveATextCircle}~--- étend naturellement
la classe de l'élément cible ---~\texttt{Circle} dans notre cas~--- que
l'élément \emph{resolve} est censé représenter. Cette classe est associée à un
ancrage et la relation d'héritage de {\java} est exprimée par un sous-type dans
le \emph{mapping} décrit dans le listing~\ref{code:resolveMappingA2Shape}.
Étant donné que ce mécanisme a lieu durant le processus de compilation
{\textsf{Tom}\texttt{->}\java}, cet ancrage n'apparaît pas en tant que tel, mais
est directement généré en mémoire pour être traduit en {\java} par la suite.
Le listing~\ref{code:resolveMappingA2Shape} est néanmoins une traduction fidèle
du \emph{mapping} qui serait écrit en {\tom}.

\begin{figure}[h]
  \begin{center}
    \input{code/resolveMappingA2Shape}
  \end{center}
  %\caption{Exemple d'ancrage algébrique pour un élément \emph{resolve}.}
  %\label{code:resolveMappingA2Shape}
\end{figure}

C'est aussi dans le \emph{transformer} que nous filtrons tous les symboles de
type \emph{Tracelink}. Pour chaque instruction de traçage, le
\emph{transformer} crée (ou récupère si elle existe déjà) ce que nous appelons
une \texttt{ReferenceClass}. Il s'agit d'une structure de données permettant de
référencer les éléments cibles tracés. 

En termes d'implémentation {\java}, nous fournissons une interface
\texttt{ReferenceClass} extrêmement simple
(listing~\ref{code:referenceClassInterface}) que les structures de données
générées implémentent.

\begin{figure}[h]
  \begin{center}
    \input{code/referenceClassInterface}
  %\caption{Interface devant être implémentée par les structures de type \texttt{ReferenceClass}.}
  %\label{code:referenceClassInterface}
  \end{center}
\end{figure}

Ces classes sont essentiellement constituées d'attributs (les références vers
les éléments cibles), de leurs méthodes d'accès (\texttt{get} et \texttt{set})
ainsi que d'une méthode permettant d'associer un nom à un élément. Le
listing~\ref{code:exreferenceClass} montre une classe qui serait générée
dans le cas de notre exemple de transformation de texte en formes géométriques.

\begin{figure}[h]
  \begin{center}
    \input{code/exreferenceClass}
  %\caption{Exemple de classes générées implémentant l'interface \texttt{ReferenceClass} dans le cas de la transformation \emph{Text2Shape}.}
  %\label{code:exreferenceClass}
  \end{center}
\end{figure}

Une structure de type \texttt{ReferenceClass} est elle-même liée à l'élément
source filtré par la règle qui lui a donné naissance. Techniquement, cela
consiste à maintenir une table de hachage dont les clefs sont des sources de
type \texttt{EObject} et dont les valeurs sont ces structures de données. Cette
table de hachage fait partie intégrante du modèle de lien de la transformation,
implémenté par la classe \texttt{LinkClass} (fournie en tant que bibliothèque
avec son ancrage associé).

Toute \emph{définition} d'un sous-arbre \emph{Transformation} est quant à elle
transformée en une stratégie comprenant les règles de la \emph{définition},
accompagnée de son symbole. Une stratégie plus complexe est ensuite composée à
partir de ces stratégies. Finalement, tout nœud de type \emph{Transformation}
est remplacé par sa stratégie nouvellement créée ainsi que par une éventuelle
stratégie de résolution.

%déclaration de ReferenceClass, générée par la suite une fois que toutes les
%tracelink instructins sont données
%HashMap, stockage, LinkClass : table:ConcurrentHashMap EObject-> ReferenceClass


%\ttodo{\emph{backend} : il y a plus de choses à dire que pour le \emph{parsing}
%(génération du métamodèle de lien/trace, resolve, adaptation de la génération
%des stratégies pour le cas où on ajoute du code}

\paragraph{Backend.} En fin de chaîne de compilation, au niveau du générateur
de code (\emph{backend}), le travail a consisté à ajouter des fonctions de
génération de la phase de résolution ainsi que celles pour le métamodèle de
lien qui n'existaient pas auparavant. Ces dernières produisent du code
similaire à celui que nous avons montré précédemment dans les
listings~\ref{code:referenceClassInterface} et~\ref{code:exreferenceClass},
dans la partie décrivant la mécanique du greffon \emph{transformer}.

%du métamodèle de lien ainsi que celles pour la phase de résolution.
%La génération du métamodèle 
%
%Un autre aspect important de l'extension du \emph{backend} est l'ajout des
%fonctions de génération du modèle de trace qui n'existaient pas auparavant.
%Elles produisent du code similaire à celui que nous avons montré précédemment
%dans les listings~\ref{code:referenceClassInterface}
%et~\ref{code:exreferenceClass}, dans la partie décrivant la mécanique du
%greffon \emph{transformer}.


%\todo{parler de l'évolution de l'encodage résolution (ici ?): 
%\begin{itemize}
%  \item[v1] : stratégie + procédure de résolution iresolveInverseLinks avec
%  services EMF ;
%  \item[v2] : stratégie + procédure de résolution resodveInverseLinks en
%  enlevant les services EMF ;
%  \item[v3] : procédure resolve() à la place de la stratégie + procédure
%  customResolveInverseLinks.
%\end{itemize}}

La mise en œuvre de la génération de la phase de résolution a fait l'objet de
nombreuses évolutions au cours de ce travail. Nous décrirons son état stable
actuel (inclus dans la dernière version stable publiée : {\tom}-2.10) ainsi que
celui de la prochaine version stable.

La phase de résolution étant encodée sous la forme d'une stratégie de
réécriture, sa génération est en partie identique à la génération de stratégies
classiques. Cependant, elle se distingue d'elles par le fait qu'il faille aussi
écrire une procédure supplémentaire permettant d'effectuer la \emph{résolution
de liens inverses}. Cette procédure consiste à notifier tous les objets du
modèle ayant un pointeur vers l'objet qui vient d'être modifié pour que ce
pointeur pointe vers le nouvel objet et non plus vers l'élément \emph{resolve}.

La figure~\ref{fig:resolutionInverse} illustre ce mécanisme. La
figure~\ref{fig:resolutionInverse-a} est l'état du modèle en fin de première
phase. Il est constitué d'éléments cibles ainsi que d'éléments \emph{resolve}
(en pointillés). Les éléments à résoudre sont détectés et l'élément cible
effectif est identifié (figure~\ref{fig:resolutionInverse-b}).  Tous les
éléments faisant référence à cet élément \emph{resolve} doivent aussi être mis
à jour.  Dans l'exemple, le connecteur entre le pentagone bleu et le carré vert
référence le carré vert temporaire. Son extrémité (un pointeur vers l'élément
\emph{resolve}) est mise à jour pour référencer l'élément cible final
(figure~\ref{fig:resolutionInverse-c}). Une fois la \emph{résolution de liens
inverses} effectuée, le modèle ne comprend plus d'élément \emph{resolve}
(\ref{fig:resolutionInverse-d}).
%En effet, il faut notifier tous les objets du modèle ayant
%un pointeur vers l'objet qui vient d'être modifié pour que ce pointeur pointe
%vers le nouvel objet et non plus vers l'élément \emph{resolve}.

\begin{figure}[h]
%  \centering
%  \begin{tabular}{cccc}
    \begin{subfigure}{0.21\textwidth}
      %\centering
      \input{figures/resolutionInverse-a}
      \subcaption{}
      \label{fig:resolutionInverse-a}
    \end{subfigure} 
%      &
    \quad
    \begin{subfigure}{0.21\textwidth}
      %\centering
      \input{figures/resolutionInverse-b}
      \subcaption{}
      \label{fig:resolutionInverse-b}
    \end{subfigure}
%    &
    \quad
    \begin{subfigure}{0.21\textwidth}
      %\centering
      \input{figures/resolutionInverse-c}
      \subcaption{}
      \label{fig:resolutionInverse-c}
    \end{subfigure}
%    &
    \quad
    \begin{subfigure}{0.21\textwidth}
      %\centering
      \input{figures/resolutionInverse-d}
      \subcaption{}
      \label{fig:resolutionInverse-d}
    \end{subfigure}
%    \\
%  \end{tabular}
  \caption{Processus de résolution de liens inverses.}%FIXME\ttodo{alignement ???} 
  \label{fig:resolutionInverse}
\end{figure}

Dans le contexte de {\emf}, ce traitement peut être fait en utilisant les
services fournis. Dans la stratégie de résolution, nous effectuons donc une
résolution de liens inverses pour chaque élément \emph{resolve} trouvé et
remplacé. La procédure de résolution de liens inverses peut être automatisée ;
mais dépendant des types des éléments du modèle, elle ne peut être générique et
doit donc être générée pour chaque transformation. Pour rendre possible la
génération de ce code additionnel dans les stratégies, il a été nécessaire de
modifier la signature des stratégies afin de pouvoir embarquer du code
supplémentaire, ainsi que l'\emph{expander}. Le \emph{backend} des stratégies a
ensuite été adapté afin de prendre en compte cette nouveauté.

Signalons que la phase de résolution n'apparaît pas dans l'extrait de
code présenté plus tôt dans le chapitre. Il ne s'agit pas d'une simplification
du code pour les besoins de notre propos, mais bien du fonctionnement normal de
nos outils. En effet, la phase de résolution est entièrement générée, en
fonction de l'utilisation des constructions \lex{\%resolve} au sein de la
transformation.  Ainsi, une transformation ne nécessitant pas d'élément
\emph{resolve} (donc sans utilisation du lexème \lex{\%resolve}) n'a pas de
phase de résolution.
À l'inverse, l'utilisation de la construction provoque la génération du bloc de
résolution dédié au type traité. Dans la version actuellement publiée de
l'outil ({\tom-2.10}), cette phase est encodée par une unique stratégie que
l'utilisateur n'écrit qu'indirectement par l'usage judicieux des constructions
de résolution. L'application de la stratégie de résolution est néanmoins à la
charge de l'utilisateur au sein de son programme.  Il doit appeler la stratégie
en l'appliquant sur le modèle intermédiaire créé lors de la première phase.

Par la suite, nous avons expérimenté notre langage et avons constaté que
l'utilisation intensive des services {\emf} avait des conséquences importantes
sur les performances de la transformation, tant du point de vue de la mémoire
consommée que du temps. Nous avons donc fait évoluer la phase de résolution en
nous passant des services {\emf} pour la résolution de liens. Dans un premier
temps, plutôt que d'utiliser les méthodes {\emf}, nous avons écrit notre propre
méthode de résolution en évitant de parcourir tous les objets du modèle comme
le fait {\emf}. Dans un second temps, nous avons écrit une phase de résolution
sans stratégie afin de ne plus du tout parcourir le modèle intermédiaire. Pour
réaliser cette optimisation, nous conservons tout au long de la transformation
un ensemble de références inverses pour chaque élément \emph{resolve} créé (les
seuls éléments du modèle intermédiaire concernés par la résolution de liens
inverses). Nous détaillerons l'aspect performances de nos outils dans le
chapitre~\ref{ch:evaluation}.

Nous avons aussi expérimenté une version modulaire de la phase de résolution.
Plutôt que de générer une stratégie monolithique effectuant toute la
résolution, nous avons écrit une solution alternative générant plusieurs
stratégies de résolution partielle, chacune de ces stratégies n'effectuant la
réconciliation que sur un type de terme donné. Dans notre exemple, cette
alternative générerait deux stratégies distinctes, ainsi qu'une stratégie
combinant les deux. L'inconvénient de cette solution est qu'elle est plus
complexe à prendre en main pour l'utilisateur. Cependant, elle a l'avantage
d'offrir une plus grande modularité en décomposant la seconde phase. Ainsi, le
code généré pour une \emph{définition} peut être réutilisé dans une autre
transformation, et l'utilisateur averti prendra soin d'accompagner la
définition de la (ou des) stratégie(s) de résolution correspondante(s).
Pour des raisons d'utilisabilité de nos outils, nous avons fait le choix de
diffuser la version du générateur de phase de résolution monolithique dans la
version stable de {\tom}.

%\section{\todo{ici ? Travaux connexes}}
%: approche classique en MDE, outils, différences

\section{Synthèse}
\label{ch:outils:synth}

%\ttodo{
%  \begin{itemize}
%    \item Extension du langage + critères
%      \begin{itemize}
%        \item transfo
%        \item resolution
%        \item traçabilité
%      \end{itemize}
%    \item Implémentation
%      \begin{itemize}
%        \item archi, fonctionnalité, stats, tour des phases
%        \item générateur d'ancrages algébriques
%        \item mise en œuvre de l'extension : parser / transformer / backend
%        \item exemple d'utilisation (ligne de commande, etc.)
%      \end{itemize}
%    \item 
%  \end{itemize}
%}

Dans ce chapitre, nous avons d'abord montré une utilisation concrète de nos
outils appliquée sur un exemple simple. Nous avons présenté l'extension du
langage {\tom} permettant de mettre en œuvre notre approche de transformation.
Les trois aspects principaux de cette extension sont : l'expression de la
transformation elle-même, le mécanisme de résolution et d'extension du
métamodèle cible par des éléments temporaires, ainsi que la traçabilité. Ces
éléments sont respectivement mis en œuvre par les constructions
\lex{\%transformation}, \lex{\%resolve} et \lex{\%tracelink}.

Nous avons  par ailleurs présenté nos travaux d'implémentation ainsi que leur
intégration au sein du projet {\tom}. Nous avons notamment décrit le générateur
d'ancrages algébriques {\tomemf} permettant d'opérer le changement d'espace
technologique $mod\grave eles\rightarrow termes$. Nous avons de plus expliqué
comment nous analysions et transformions les sous-arbres issus des nouvelles
constructions du langage {\tom} dans la phase \emph{transformer}, et quel était
le code généré par le \emph{backend}.

Nous avons expérimenté nos outils et les premiers retours nous donnent des
pistes de travail intéressantes sur l'usage des technologies externes sur
lesquelles le prototype repose, sur le concept de modularité d'une
transformation (et donc aussi de la résolution), mais aussi sur la conception
du langage lui-même (séparation explicite des traçabilités). Nous reparlerons
de ces expériences et des perspectives offertes dans la suite de ce document.

Tout au long de ce chapitre, nous nous sommes appuyés sur l'exemple simple
d'une transformation de texte en formes géométriques colorées pour expliquer
les mécanismes en jeu. Nous nous proposons d'étudier une transformation
complète dans le chapitre suivant.%~\ref{ch:usecase}.

% vim:spell spelllang=fr
