Stratégie d'indentation
Résumé
Ce document explique comment gérer l'indentation du code Acceleo comme celle du code généré en décrivant le comportement de base des script, des if et des for.
Par William Piers, Obeo (France)
L'objectif de ce document est de fournir un maximum d'éléments pour réaliser une indentation correcte lors de la construction d'un script, c'est-à-dire la gestion des espaces, tabulations et retours à la ligne.
Les éléments script, if et for ont une influence particulière sur le code généré, leur comportement ayant été étudié pour fournir un maximum de possibilités d'indentation tout en conservant une lisibilité correcte. La section qui suit décrit le comportement de ces balises et donne les informations nécessaires à leur bonne utilisation.
Lors de la génération du code, les espaces et tabulations placés après un script, un if ou un for sont supprimés. Le retour chariot de fin de ligne est également supprimé. Ainsi dans l'exemple suivant, seul le contenu du if apparaît dans le code généré.
La capture d'écran présente les éléments suivants :
en haut à gauche, l'aperçu du code généré par le template (onglet source),
en bas à gauche, le template utilisé,
à droite, l'outline décrivant la structure du modèle utilisé pour générer le code.
|
Les tabulations, espaces et retours à la ligne contenus dans le if (ou le for) sont générés à l'identique, comme nous pouvons voir dans l'exemple ci-dessous :
|
Les tabulations et espaces situés entre le début d'une ligne et les balises ouvrantes et fermantes d'un if ou d'un for sont ignorées. Ces balises peuvent donc être placées n'importe où sur la ligne sans répercussions sur le code généré. De cette façon, elles peuvent respecter une stratégie d'indentation propre au générateur permettant une meilleure compréhension du code acceleo.
Dans l'exemple suivant, le if a donc été décalé par une tabulation.
|
En revanche, si la zone située entre le début de ligne et la balise contient du texte, elle n'est pas supprimée et est ajoutée au code généré, comme les commentaire Java (/* et */) de l'exemple ci-dessous.
|
La boucle for de l'exemple suivant génère une ligne par attribut, en reproduisant la tabulation de début de ligne et le retour chariot de fin de ligne. Ainsi sur cet l'exemple, chaque déclaration d'attribut est générée sur une ligne :
|
Sur l'exemple suivant, un retour à la ligne a été inséré dans la boucle, ce qui se répercute sur le code par l'intercalation d'une ligne entre chaque attribut.
|
Pour empêcher la boucle for de passer à la ligne à chaque itération, il est possible de supprimer le retour chariot précédant la balise fermante. En effet, comme le retour à la ligne qui suit la balise fermante est ignoré, la boucle génère tout le code sur une ligne :
|
La stratégie d'indentation d'un script peut être modifiée grâce à l'option « post » de son entête :
<%script type="Type" name="javaType" post="trim()"%>Ce paramètre permet d'appliquer une méthode sur le texte renvoyé par le script. Ce procédé fournit une solution pratique à de nombreux problèmes de génération (compréhension du code, scripts récursifs).
La fonction trim() supprime les espaces contenus dans le code généré par le script. Cela permet, par exemple, de structurer le contenu d'un script selon une indentation en améliorant la lisibilité sans que cela n'influe sur le code généré.
L'exemple suivant utilise un script qui calcule le paramètre Java d'un type donné. Ce calcul est basé sur l'imbrication d'une série de if, et sa compréhension est fortement améliorée par une indentation correcte. Cependant, le code généré est « pollué » par les tabulations, espaces et retours à la lignes dûs à cette indentation.
|
Afin de conserver l'indentation du générateur sans appliquer les retours à la ligne et les tabulations, la méthode trim() peut être appliquée au script, comme dans l'exemple suivant :
|
Par défaut, un script génère le code à partir de l'endroit ou il est appelé, en respectant l'indentation de son contenu. Lors de l'appel d'un sous-script dont le contenu génère plusieurs lignes, il est préconisé de le placer au début de la ligne afin d'éviter les problèmes de décalages, comme l'appel au script genAttributes sur l'exemple qui suit
![]() |
Dans les modèles certaines parties ont souvent une notion de récursion (héritage, contenance). La génération du code correspondant peut alors se traduire par une indentation à base d'espaces ou de tabulations. Les méthodes indentTab() ou indentSpace() sont alors très utiles lors de l'appel récursif d'un script.
L'exemple suivant démontre l'intérêt de ces fonctions dans le cadre de la génération d'une série de classes imbriquées : le script principal genClass génère une classe, puis appelle le script genNestedClass. Ce script rappelle le script genClass en appliquant la méthode indentTab(), qui s'appliquera donc à la sortie du script genClass.
|
Enfin, cet exemple montre le résultat obtenu par l'utilisation de la méthode indentSpace à la place d'indentTab.
|
Ce document fait le point sur les règles permettant d'indenter clairement à la fois le générateur et le code généré. L'indentation du code du générateur est primordiale car elle contribue en grande partie à permettre sa réutilisation.
Lors du développement d'un module, il convient de respecter la procédure suivante :
- développement du générateur dans son aspect fonctionnel, en résolvant toutes les contraintes techniques, et en indentant correctement le code acceleo. Durant cette phase les problèmes d'indentation du code généré peuvent être ignorés.
- vérification du code généré et si besoin, correction des problèmes d'indentation à l'aide des règles édictées dans ce document.
Cette façon de faire permet à la fois de faciliter le développement d'un module et d'augmenter sa lisibilité, la souplesse du code Acceleo permettant de retoucher aisément le générateur en vue de corriger les problèmes d'indentation.