/// <summary> /// Réordonne les assignations d'un constructeur. /// </summary> /// <param name="document">Le document.</param> /// <param name="constructeur">Le constructeur.</param> /// <param name="jetonAnnulation">Le jeton d'annulation.</param> /// <returns>Le nouveau document.</returns> private async Task <Document> OrdonnerAssignations(Document document, ConstructorDeclarationSyntax constructeur, CancellationToken jetonAnnulation) { // On récupère la racine et le modèle sémantique. var racine = await document .GetSyntaxRootAsync(jetonAnnulation) .ConfigureAwait(false); var modèleSémantique = await document.GetSemanticModelAsync(jetonAnnulation); // On récupère le corps du constructeur. var corps = constructeur.ChildNodes().First(nœud => nœud as BlockSyntax != null) as BlockSyntax; // On récupère toutes les conditions sur les paramètres. var conditions = ConstructorOrdering.TrouveConditionsParametres(corps.Statements, constructeur.ParameterList, modèleSémantique); // On récupère les assignations et on les ordonne. var assignations = ConstructorOrdering.TrouverAssignations(corps.Statements, modèleSémantique) .OrderBy(e => e.ToString()); // On construit le nouveau corps du constructeur. var corpsOrdonné = corps.WithStatements( SyntaxFactory.List( conditions .Concat(assignations) .Concat(corps.Statements .Except(conditions) .Except(assignations)))); // Et on met à jour la racine. var nouvelleRacine = racine.ReplaceNode(corps, corpsOrdonné); return(document.WithSyntaxRoot(nouvelleRacine)); }
/// <summary> /// Détermine si l'ordre d'assignations des champs est correct (en tête, par ordre alphabétique). /// </summary> /// <param name="context">Le contexte du symbole.</param> /// <returns>Oui ou non.</returns> private static bool OrdreAssignationEstFaux(SymbolAnalysisContext context) { // On vérifie que la méthode est bien un constructeur. if ((context.Symbol as IMethodSymbol)?.MethodKind != MethodKind.Constructor) { return(false); } // On récupère les informations nécessaires du contexte du symbole. var location = context.Symbol.Locations.First(); var racine = location.SourceTree.GetRoot(); var modèleSémantique = context.Compilation.GetSemanticModel(location.SourceTree); var méthode = racine.FindNode(location.SourceSpan) as ConstructorDeclarationSyntax; // On récupère le corps du constructeur. var corps = méthode?.ChildNodes().FirstOrDefault(nœud => nœud as BlockSyntax != null) as BlockSyntax; if (corps == null) { return(false); } // On récupère toutes les conditions sur les paramètres. var conditions = ConstructorOrdering.TrouveConditionsParametres(corps.Statements, méthode.ParameterList, modèleSémantique); // On récupère toutes les assignations de champs par des paramètres. var assignations = ConstructorOrdering.TrouverAssignations(corps.Statements, modèleSémantique); // On vérifie que toutes les conditions puis toutes les assignations sont au début. if (!conditions.Concat(assignations).SequenceEqual(corps.Statements.Take(conditions.Count() + assignations.Count()))) { return(true); } // Et on vérifie l'ordre. return(!assignations.SequenceEqual(assignations.OrderBy(x => x.ToString()))); }