Formalized Comments, Multiline Comments and Documentation generation - TypeCobolTeam/TypeCobol GitHub Wiki
Les commentaires formalisés ont pour but de permettre au développeur de renseigner des métas donnés concernant les Nodes suivants :
- Fonctions/Procédures
- Types
- Programmes On récupère ces informations pour générer une documentation en y ajoutant des informations des Nodes eux même comme le nom, le Namespace ou encore la visibilité.
Les TokenTypes et leur TokenFamilly sont présents dans TypeCobol/Compiler/Scanner/TokenType.cs.
Tout d’abord les balises ouvrantes et fermantes (des commentaires formalisés et multilignes) ne sont pas prises comme des commentaires standards pour qu’ils passent dans le scanner.
// Comment line => return only one token with type CommentLine
// Debug line => treated as a comment line if debugging mode was not activated
if (textLine.Type == CobolTextLineType.Comment ||
(textLine.Type == CobolTextLineType.Debug && !tokensLine.InitialScanState.WithDebuggingMode))
{
string lineText = textLine.Text.Trim();
if (!lineText.StartsWith("*<<") && !lineText.StartsWith("*>>"))
{
Token commentToken = new Token(TokenType.CommentLine, startIndex, lastIndex, tokensLine);
tokensLine.AddToken(commentToken);
return;
}
}
TypeCobol.Compiler.Scanner.Scanner.cs : 104-116
Les balises ouvrantes sont traitées dans le switch principale :
// --- Main switch ---
switch (line[startIndex])
{
case '<':
else if (line[currentIndex - 1] == '*' && line[currentIndex + 1] == '<')
{
if (line.Length > currentIndex + 2 && line[currentIndex + 2] == '<')
{
// We are in the case of a Formalize Comment start
// consume the three < chars
currentIndex += 3;
return new Token(TokenType.FormalizedCommentsStart, startIndex-1, startIndex + 2, tokensLine);
}
else
{
// We are in the case of a Multiline comments start
currentIndex += 2;
return new Token(TokenType.MultilinesCommentsStart, startIndex-1, startIndex + 1, tokensLine);
}
}
}
TypeCobol.Compiler.Scanner.Scanner.cs : 728-969
Le premier caractère visible par le scanner est le ‘<’ car le ‘’ se trouve en colonne 7 et le scanner regarde a partir de la colonne 8. On teste quand même la présence du ‘’ à la position n-1.
On détecte aussi les balises ouvrantes hors colonne 7 pour mettre un warning et quand même créer les Tokens pour ne pas gêner le parsing.
// --- Main switch ---
switch (line[startIndex])
{
case '*':
// Multiline Comments or Formalized Comments start should begin on column 7
else if (line.Length > currentIndex + 2 && line[currentIndex + 1] == '<' && line[currentIndex + 2] == '<')
{
if (line.Length > currentIndex + 3 && line[currentIndex + 3] == '<')
{
// It is a Formalized Comment start that is not well positioned
tokensLine.AddDiagnostic(MessageCode.WrongFormalizedCommentMarckupPosition,
startIndex,
startIndex + 3);
// consume the * char and the three < chars
currentIndex += 4;
return new Token(TokenType.FormalizedCommentsStart, startIndex, startIndex + 3, tokensLine);
}
else
{
// It is a Multiline Comment start that is not well positioned
tokensLine.AddDiagnostic(MessageCode.WrongMultilineCommentMarckupPosition,
startIndex,
startIndex + 2);
// We are in the case of a Multiline Comment start
// consume the * char and the two < chars
currentIndex += 3;
return new Token(TokenType.MultilinesCommentsStart, startIndex, startIndex + 2, tokensLine);
}
}
}
TypeCobol.Compiler.Scanner.Scanner.cs : 728-852
Quand ajoute un Token de balise ouvrante ou fermante, on modifie le ScanState (MultilineScanState.cs) pour indiquer que l’on se trouve dans le contexte d’un commentaire formalisée.
// Inspect the new token and see if it changes the current Scan state
switch (newToken.TokenType)
{
case TokenType.FormalizedCommentsStart:
// Register the begin of the formalized Comments
InsideFormalizedComment = true;
break;
case TokenType.FormalizedCommentsStop:
// Register the end of the formalized Comments
InsideFormalizedComment = false;
InsideParamsField = false;
break;
case TokenType.MultilinesCommentsStart:
// Register the begin of the formalized Comments
InsideMultilineComments = true;
break;
case TokenType.MultilinesCommentsStop:
// Register the end of the formalized Comments
InsideMultilineComments = false;
return;
}
TypeCobol.Compiler.Scanner.MultilineScanState.cs : 178-261
Pour ne pas générer des Token propre à TypeCobol qui n’ont pas de sens dans le contexte des commentaires formalisées ou des commentaires multilignes, le reste du scanne se fait dans un switch séparé du switch principale.
// --- switch dedicated to formalized Comments as they are not compatible with TypeCobol grammar ---
if (currentState.InsideFormalizedComment)
{
switch (line[startIndex])
{
case ' ':
//SpaceSeparator=1,
return ScanWhitespace(startIndex);
case '-':
currentIndex++;
return new Token(TokenType.MinusOperator, startIndex, currentIndex - 1, tokensLine);
case '@':
currentIndex++;
return new Token(TokenType.AtSign, startIndex, currentIndex - 1, tokensLine);
case ':':
currentIndex++;
return new Token(TokenType.ColonSeparator, startIndex, currentIndex - 1, tokensLine);
case '*':
if (line[currentIndex + 1] == '>' && line[currentIndex + 2] == '>' && line[currentIndex + 3] == '>')
{
// We are in the case of a Formalize Comment stop with the '*' on column other than 7 wich is forbidden
tokensLine.AddDiagnostic(MessageCode.WrongFormalizedCommentMarckupPosition,
startIndex,
startIndex + 3);
// consume the * char and the three < chars
currentIndex += 4;
return new Token(TokenType.FormalizedCommentsStop, startIndex, startIndex + 3, tokensLine);
}
currentIndex ++;
return new Token(TokenType.MultiplyOperator, startIndex, currentIndex - 1, tokensLine);
case '>':
if (line[currentIndex - 1] == '*' && line[currentIndex + 1] == '>' && line[currentIndex + 2] == '>')
{
// We are in the case of a Formalize Comment stop with the '*' on column 7
// consume the three > chars
currentIndex += 3;
return new Token(TokenType.FormalizedCommentsStop, startIndex-1, startIndex + 2, tokensLine);
}
currentIndex++;
return new Token(TokenType.GreaterThanOperator, startIndex, currentIndex - 1, tokensLine);
default:
// If the previous significant Token is an At Sign then the following word have to be a field keyword
// If the previous significant Token is a Minus Operator then the following have to be a key in case of Params field
if (tokensLine.ScanState.LastSignificantToken.TokenType == TokenType.AtSign ||
(tokensLine.ScanState.LastSignificantToken.TokenType == TokenType.MinusOperator &&
tokensLine.ScanState.InsideParamsField))
{
Token token = ScanCharacterString(startIndex);
if (tokensLine.ScanState.LastSignificantToken.TokenType == TokenType.AtSign
&& token.TokenFamily != TokenFamily.FormalizedCommentsFamily)
{
tokensLine.AddDiagnostic(MessageCode.WrongFormalizedCommentKeyword, token);
}
else if (tokensLine.ScanState.LastSignificantToken.TokenType == TokenType.MinusOperator
&& token.TokenFamily == TokenFamily.FormalizedCommentsFamily)
{
token.CorrectType(TokenType.UserDefinedWord);
}
return token;
}
return ScanUntilDelimiter(startIndex, TokenType.FormComsValue, "*>>>");
}
}
TypeCobol.Compiler.Scanner.Scanner.cs : 664-726
Ainsi, comme le scanner ne passe que dans le switch dédié aux commentaires formalisés si une balise ouvrant est trouvé, la détection de la balise fermante ne se fait que dans ce switch.
Les mots clés sont reconnus si le dernier token significatif est un ‘@’ via ScanCharacterString(startIndex) qui évalue le mot démarrant à startIndex. Si nous somme dans le contexte d’un commentaire formalisé, on évalue le mot pour savoir à quel mot clés il correspond.
[IMAGE HERE]
TokenType.UserDefinedWord est utilisé pour une clé de Params.
Pour autoriser les mots clés dans le nommage des paramètres, on vérifie que si on trouve un mot clé, que nous somme juste après un ‘-‘ et que le précédent mot clé trouvé est le mot clé ‘@Parameters’. Si c’est le cas, on corrige le Type de Token en TokenType.UserDefinedWord.
[IMAGE HERE]
Enfin, si ce n’est ni un mot clé, ni une clé de ‘@Parameters’, c’est une valeur. Les valeurs ne pouvant pas précéder d’autre Token sur une ligne, on regroupe tout le reste de la ligne dans un même Token TokenType.FormComsValue grâce à ScanUntilDelimiter(startIndex, tokenType, delimiter)
[IMAGE HERE]
Cette méthode scanne le reste de la ligne et renvoi un Token du type spécifié allant jusqu’à la fin de la ligne ou jusqu’au délimiteur spécifié. Le délimiteur ici est "*>>>", malgré le fait que ce soit pour l’instant impossible de le rencontrer comme la balise fermante ne peux se trouver qu’en colonne 7, cela permettra dans le futur d’avoir une syntaxe comme celle-ci : *<<< Ici mon commentaire formalisé sur une seule ligne *>>>
La grammaire des commentaires formalisée se décompose comme suit :
[IMAGE HERE]
Elle est composé de : une balise ouvrante, n lignes et une balise fermante. Il existe trois types de lignes :
- Les lignes de niveau « extérieur » qui commencent par ‘’@’’ sont composé d’un mot clé + ‘’ : ’’ (optionnel, le ‘’ : ‘’ n’a qu’un but de clarté du code) et une valeur (optionnel)
- Les lignes de niveau « intérieur » servant à lister des valeurs se composent de ‘’-‘’ + une valeur dans le cas d’un listing simple (pour Todo et Needs) ou de ‘’-‘’ + clé (UserDefinedWord) + ‘’ : ’’ (optionnel, toujours un but de clarté) et une valeur. Un listItem de type clé-valeur ne s’applique que à ‘@Params’.
- Les lignes simplement composé d’une valeur qui sera rattaché à l’instruction précédente. Cette grammaire s’intègre au début de celle d’une Fonction, d’une définition de type et d’une Procedure Division ainsi les token du commentaire formalisé sont inclue dans le CodeElements suivant et il n’y a donc pas de CodeElements dédié aux commentaires formalisées
[IMAGE HERE]
On implémente l’interface IFormalizedCommentable aux CodeElements applicables. Cette interface force ces CodeElements à avoir une propriété FormalizedCommentDocumentation de type FormalizedCommentDocumentation qui contiendra les données du commentaire formalisé.
[IMAGE HERE]
La propriété privée _lastParameterRegistered enregistre la dernière clé ajouté à la propriété Parameters pour y rattacher les valeurs seul sur leur ligne (le cas d’une continuation de ligne). En effet, comme c’est un Dictionnaire, la propriété n’est pas ordonnée et n’a donc pas de « dernière » élément comme les listes Needs et ToDo Les autres Propriétés sont les données enseignables dans un commentaire formalisé.
Il y a deux méthodes Add qui servent à ajouter une valeur à la propriété associé à un mot clé. void Add(Fields parameter, IToken symbol, bool isContinuation) Pour les valeurs simple (tout sauf @Params). isContinuation sert, dans le cas des listes, à spécifier si c’est la continuité d’une valeur ou une nouvelle valeur donc de savoir s’il faut créer un nouvelle élément ou concaténer la valeur au dernier élément. void Add(Fields parameter, string key, string value) Pour les couples clé-valeur (@Params)
Le constructeur s’occupe de décortiquer le contexte retourné par Antlr et ajouter les bonnes valeurs aux bonnes propriétés.
Ces Propriétés sont créées au CodeElementBuilders directement après le parsing d’Antlr.
Il faut injecter les tokens des commentaires multilignes dans les CodeElement correspondant à leurs lignes pour pouvoir les repérer et les commenter dans la phase de génération de Code. Ceci est effectué dans CodeElementsParserStep :
[IMAGE HERE]
Pour les fonctions on vérifie si il y a des paramètres dans‘@Params’ qui ne correspondent pas à des paramètres présent dans la signature de la Fonction pour y placer un Warning.
[IMAGE HERE]
De la même manière on vérifie si des paramètres présent dans la signature de la Fonction ne le sont pas dans la section ‘@Params’ des commentaires formalisées pour y placer un Warning.
[IMAGE HERE]
On vérifie enfin s’il y a un mot clé qui est déclaré deux fois pour y placer un Warning. Cette action est factorisée dans une méthode statique car elle est utilisée pour chaque structure acceptant un commentaire formalisé.
[IMAGE HERE]
Pour les types on vérifie si il y le champ ‘@Params’ déclaré pour y placer un Warning.
[IMAGE HERE]
Enfin on vérifie s’il y a un mot clé qui est déclaré deux fois pour y placer un Warning.
[IMAGE HERE]
Pour les fonctions on vérifie si il y a des paramètres dans‘@Params’ qui ne correspondent pas à des paramètres présent dans la section using de la Procedure Division pour y placer un Warning.
[IMAGE HERE]
De la même manière on vérifie si des paramètres présent dans la section using de la Procedure Division ne le sont pas dans la section ‘@Params’ des commentaires formalisées pour y placer un Warning.
[IMAGE HERE]
On vérifie enfin s’il y a un mot clé qui est déclaré deux fois pour y placer un Warning.
[IMAGE HERE]
On vérifie si la Procédure Division à laquelle est rattaché le commentaire formalisé est bien la procédure division d’un Programme et pas d’une déclaration de fonction.
[IMAGE HERE]
La Génération de la documentation se fait en mettant l’argument du CLI OutputFormat à Documentation (-f 4 OU -f Documentation). Le générateur de s’occupant de la documentation utilise un Visiteur dédié qui crée un DTO pour chaque TypeDefinition, FunctionDeclaration et Program et les stocke dans une liste de documentation.
[IMAGE HERE]
Les DTOs :
[IMAGE HERE]
A noter que les DTOs possèdent tous un constructeur par default vide qui est nécessaire à la sérialisation.
[IMAGE HERE]
Documentation est la classe de base qui implémenta les propriétés et la logique commune aux trois types de commentaires formalisées. Elle contient tous les champs des commentaires formalisé sauf ‘@Params’ qui n’est utilisé que pour les fonctions et les procédures. Elle contient aussi des informations qui ne se trouvent pas dans les commentaires formalisées comme le Nom, la visibilité et le nameSpace. Elle initialise ses propriétés avec son constructeur : A noter que Deprecated ne s’initialise pas comme les autres propriétés car il peut représenter un booléen à true si il contient un string vide, il ne faut donc pas utiliser IsNullOrEmpty().
Documentation possède aussi la méthode CreateAppropriateDocumentation() qui permet de créer un documentation sans savoir si le node est de type Program, FunctionDeclaration ou TypeDefinition. C’est la méthode qui est toujours utilisé pour créer une documentation.
[IMAGE HERE]
C’est aussi Documentation qui implémente les méthodes de sérialisation. Pour l’instant en XML mais si un autre format est nécessaire, il faudra juste faire implémenter la nouvelle méthode à Documentation.
[IMAGE HERE]
DocumentationDataType définies les données communes aux variables présentes dans la documentation comme le type lui-même, ses éventuelles enfante, les paramètres de fonctions et les paramètres de programmes.
[IMAGE HERE]
Elle est composée de deux constructeurs : DocumentationDataType(DataDefinition dataDef) Qui prend en paramètre un DataDefinition, un node qui définit une donnée mais n’est pas serialisable directement. Ce constructeur en extrait la majeure partie de ses données directement et récupère la valeur par défaut de la variable avec son codeElement.
[IMAGE HERE]
Le second constructeur : DocumentationDataType(DataUsage? usage = null, long maxOccurence = 1, string defaultValue = null, string typeName = null, string picture = null) N’est jamais utilisé pour l’instant mais peut être utile si on doit créer un dataType sans avoir de DataDefinition.
DocumentationTypeChildren regroupe les données des enfants du type si ce dernier est un groupe. En plus du DocumentationDataType il comporte des propriétés que l’on peut retrouver que chez les enfantes d’un Type tel que les conditions des niveaux 88, IsBlankWheneZero, Justified etc. IsSubGroupe indique que cette enfant a lui-même des enfants.
[IMAGE HERE]
Il est composé d’un constructeur prenant en paramètre un DataDefinition qui permet d’instancier toute les propriétés de l’objet.
[IMAGE HERE]
Représente la documentation propre aux définitions de types. En plus des propriétés héritées de Documentation elle contient les des propriétés définissant son type de donnée DocDataType de type DocumentationDataType, IsBlankWheneZero et Justified qui sont des options utilisable pour un Type et ses enfants mais pas pour des paramètres de fonction/programmes donc ne figurent pas dans DocumentationDataType. Elle comprend aussi la liste d’enfant du type pour y enregistrer leur DocumentationTypeChildren. À l’instar des Nodes, la liste de childrens ne possède que la DocumentationTypeChildren des enfants direct du type, les sous enfants se trouvent dans la liste de children de leurs parents directs.
[IMAGE HERE]
Le constructeur de DocumentationForType prend le node documentable TypeDefinition pour en tirer, avec son codeElement, un maximum d’inormations.
[IMAGE HERE]
DocumentationParameter regroupe les données des paramètres des fonctions et des programmes. En plus du DocumentationDataType il comporte des propriétés que l’on peut retrouver que chez les parametres tel que les informations renseigné dans les commentaires formalisé (@Params), Le passing type (input, output, inout) et son nom.
[IMAGE HERE]
Il est composé de deux constructeurs : public DocumentationParameter(ParameterDescription parameter, string info) Le premier constructeur prend en paramètre un ParameterDescription contenant les informations liées au dataType et un string qui contient la description du commentaire formalisé si elle existe. Le passing type est contenu dans le ParameterDescription. Ce constructeur est utilisé par les Fonctions.
[IMAGE HERE] public DocumentationParameter(DataDefinition dataDef, string info, bool determinePassing = true) Le second constructeur prend en paramètre une DataDefinition contenant les informations liées au dataType, un string qui contient la description du commentaire formalisé si elle existe et un booléen qui indique si on doit déterminer le PassingTypes avec la description du commentaire formalisée ou non. Ce constructeur est utilisé par les Programmes car DataDefinition ne supporte pas le PassingTypes. Il faut donc le déterminer si possible.
[IMAGE HERE]
La reconnaissance du PassingTypes se fait par la méthode suivante Tuple<PassingTypes, string> DetermineType(string info) Elle prend en paramètre la description du commentaire formalisée et en extrait le premier mot. Si ce dernier est ‘INPUT’, ‘OUTPUT’, ‘INOUT’ (case insensitive) alors on enregistre le passing type adéquat et on tronc l’info jusqu’au premier caractère alphabétique et on renvoi un Tuple<PassingTypes, string> du passing type trouvé et de la description tronqué. Ainsi, une description du type : ‘Input – Description de mon paramètre’ Donne le Tuple {PassingTypes.Input, ‘Description de mon paramètre’} Et pas le Tuple {PassingTypes.Input, ‘ - Description de mon paramètre’}
[IMAGE HERE]
En plus des propriétés héritées de Documentation, DocumentationForFunction n’a qu’une liste de DocumentationParameter.
[IMAGE HERE]
Elle possède un seul constructeur qui construit la liste des paramètres :
[IMAGE HERE]
Comme DocumentationForFunction, DocumentationForProgram n’ajoute qu’une liste de DocumentationParameter aux propriétés héritées de Documentation.
[IMAGE HERE]
Elle possède un seul constructeur qui construit la liste des paramètres à partir des paramètres spécifié dans la clause USING de la Procédure Division. À la différence de DocumentationForFunction, le passing type est déterminé à partir du commentaire formalisé et non pas dans la définition du paramètre.
[IMAGE HERE]
Le passage du paramètre CLI OutputFormat à 4 (Documentation) permet d’utiliser Le generateur dédié à la documentation DocumentationGenerator au lieu du générateur par défault. Il utilise un visiteur, DocumentationBuilder, qui contient une liste de DTOs. Il parcourra les Nodes en créant le DTO approprié selon le node trouvé (Program – Function – TypeDefinition) si ces derniers sont Publics. Enfin DocumentationGenerator récupère cette liste et, pour chacun d’eux, les sérialisent et les concatène dans this.Destination.
[IMAGE HERE]
La fonction Generate de DocumentationGenerator :
[IMAGE HERE] Le Visiteur DocumentationBuilder :
[IMAGE HERE]
La génération du code est assez simple en théorie puisque nous n’avons qu’à commenter les lignes du commentaire formalisé. En pratique, il n’est pas possible de procéder comme pour les autre Nodes que nous devons commenter car les commentaires formalisées ne constitue pas de Nodes propre mais font partie de codeElements existant et nous ne pouvons que commenter l’intégralité d’un Node. Les Nodes de Function et de TypeDefinition sont déjà commentées dans le CodeGen. Il ne reste donc que les Nodes de Procedure Division directement enfants des Programs.
Ce Node se génère de deux manières, s’il contient une fonction déclaré en public ou non: Avec une fonction public, C’est la propriété IEnumerable<TypeCobol.Compiler.Text.ITextLine> Lines du Node ProcedureDivision qui génère le code via son getter. On parcoure les ConsumedTokens du Node, S’ils sont compris dans un commentaire formalisé, on commente la TokensLine (les autres ConsumedTokens de la TokensLine sont ignoré).
[IMAGE HERE] Sans fonction public. C’est la méthode CommentSpecificParts dans LinearNodeSourceCodeMapper qui commente ces lignes.
[IMAGE HERE]
Cette méthode est appelée pour chaque Node et s’occupe de commenter les commentaires formalisées des ProcedureDivision appartenant au Program et les Commentaires Multilignes pouvant apparaitre n’ importe où. Dans les deux cas, la méthode void CommentBetweenTokens(Node node, TokenType startTokenType, TokenType stopTokenType) est appelé. Cette méthode commente toute les lignes se trouvant entre les deux tokens passé en paramètre en injectant un ‘*’ dans leur buffer.
[IMAGE HERE] Un problème se pose cependant, Razor Utilise le caractère ‘@’ comme mot clé. Cela pose donc problème pour les champs des commentaires formalisés. Il faut donc les échapper dans RazorEngine :
[IMAGE HERE] Enfin il ne reste que le cas de la génération des signatures à commenter dans SignaturesGenerator. Pour se faire, à la création de chaque ligne à inscrire dans le fichier de sortie Pour chaque ligne, si elle est dans un Commentaire formalisé (entre les deux balises), on ajoute la ligne commenté. Sinon on ajoute la ligne sans y toucher.
[IMAGE HERE]
Pour les commentaires multilignes, on distingue deux cas de figures :
- Les commentaires multilignes appartenant à un Node (avec le commentaire entre deux lignes d’un même node par exemple)
- Les commentaires multilignes libre donc sans Nodes (comme les commentaires classiques)
Les premiers sont commentés dans LinearNodeSourceCodeMapper avec la méthode CommentSpecificParts. Comme pour les commentaires formalisés, on parcoure chaque Nodes et on commente tout ce qui se trouve entre les balises.
[IMAGE HERE] Le second cas est géré dans DefaultGenerator. Pour chaque ligne n’appartenant à aucun Node, si elles sont entre les balises d’un commentaire multilignes, on les commente.
[IMAGE HERE]
Pour ajouter un nouveau mot clé au commentaire formalisé il faut suivre les étapes suivantes :
- L’ajouter au Tokens et à la TokenFamily.
- Dans TokenUtils, modifier la méthode TokenType GetFormalComTokenTypeFromTokenString(string tokenString) pour que le scanner reconnaisse le nouveau mot clé.
- Inclure le nouveau dans CobolWords.g4 et dans la grammaire dans la liste des formalizedCommentParam.
- Ajouter sa propriété à FormalizedCommentDocumentation choisir le type selon les valeurs qu’on peut y mettre :
- string pour une valeur simple et un flag
- List pour une série de valeurs
- Dictionary<string, string> pour une série de couples clé – valeurs
- Extraire sa valeur dans le constructeur de FormalizedCommentDocumentation et l’ajouté à la propriété créé précédemment
- Ajouter sa propriété à Documentation, DocumentationForType, DocumentationForFunction ou DocumentationForProgram selon ce à quoi s’applique le mot clé et y assigné la valeur extraite et transformé si besoin du commentaire formalisé.
Pour ajouter un nouveau Node pouvant contenir un commentaire formalisé il faut suivre les étapes suivantes :
- Créer le Node désiré implémentant l’interface IDocumentable.
- Créer un nouveau CodeElement implémentant IFormalizedCommentable ou si c’est un CodeElement existant qui sera utiliser, lui faire implémenter IFormalizedCommentable.
- Modifier ou créer la grammaire de ce CodeElement en y ajoutant formalisedComment à l’emplacement souhaité.
- Dans CodeElementBuilder, modifier la méthode lié à ce Node pour y mettre l’instanciation de FormalizedCommentDocumentation si le contexte Antlr contiens formalizedComment(), donc si Antlr a repéré un commentaire formalisé pour ce Node. Il faut passer au constructeur de FormalizedCommentDocumentation les formalizedCommentLine du contexte Antlr.
- Vérifier si besoin dans CrossCheck que les champs du commentaire formalisé sont correctement remplis.
- Il faut ensuite créer son DTO dans Documentation.cs héritant de la classe Documentation. Si la documentation du Node doit avoir des propriétés autre que celles commune dans documentation, alors il faut les ajouter à ce DTO et les instancier dans son constructeur.
- Enfin, pour que la documentation se fasse correctement, Dans DocumentationGenerator, au visiteur DocumentationBuilder, il faut ajouter une méthode Visit prenant en paramètre ce Node, y construire son DTO et l’ajouter à la liste de DTOs du visiteur.
En cas de modification des commentaires formalisés il est bon de de créer des tests unitaires ou de mettre à jour les tests unitaires dédié ou:
-
Test du processus complet :
- CLI/test/ressources/documentation/CLIArguments.txt
- CLI/test/ressources/documentation/input/DocGen.tcbl
- CLI/test/ressources/documentation/output_expected/DocGen.json
- CLI/test/ressources/documentation/output_expected/error.txt
-
Test du CodeGen :
- Codegen/test/resources/input/TypeCobol/FormalizedComments.tcbl
- Codegen/test/resources/input/TypeCobol/MultilinesComments.tcbl
- Codegen/test/resources/output/TypeCobol/FormalizedComments.tcbl
- Codegen/test/resources/output/TypeCobol/MultilinesComments.tcbl
-
Test de sérialisation et CodeElement :
- TypeCobol.Test/Parser/Documentation/DocumentationCombined.rdz.json
- TypeCobol.Test/Parser/Documentation/DocumentationCombined.rdz.tcbl
- TypeCobol.Test/Parser/Documentation/DocumentationCombined.rdzDoc.txt
- TypeCobol.Test/Parser/Documentation/DocumentationFunctions.rdz.json
- TypeCobol.Test/Parser/Documentation/DocumentationFunctions.rdz.tcbl
- TypeCobol.Test/Parser/Documentation/DocumentationFunctions.rdzDoc.txt
- TypeCobol.Test/Parser/Documentation/DocumentationPrograms.rdz.json
- TypeCobol.Test/Parser/Documentation/DocumentationPrograms.rdz.tcbl
- TypeCobol.Test/Parser/Documentation/DocumentationPrograms.rdzDoc.txt
- TypeCobol.Test/Parser/Documentation/DocumentationTypeDefs.rdz.json
- TypeCobol.Test/Parser/Documentation/DocumentationTypeDefs.rdz.tcbl
- TypeCobol.Test/Parser/Documentation/DocumentationTypeDefs.rdzDoc.txt