CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
AsynchronousBusinessRuleInheritingFromBusinessRuleChangeToBusinessRuleAsyncCodeFix.cs
Go to the documentation of this file.
1using System.Collections.Immutable;
2using System.Composition;
3using System.Linq;
4using System.Threading.Tasks;
6using Microsoft.CodeAnalysis;
7using Microsoft.CodeAnalysis.CodeActions;
8using Microsoft.CodeAnalysis.CodeFixes;
9using Microsoft.CodeAnalysis.CSharp;
10using Microsoft.CodeAnalysis.CSharp.Syntax;
11using static Csla.Analyzers.Constants;
12
13namespace Csla.Analyzers
14{
15 [ExportCodeFixProvider(LanguageNames.CSharp)]
16 [Shared]
18 : CodeFixProvider
19 {
20 public override ImmutableArray<string> FixableDiagnosticIds =>
21 ImmutableArray.Create(Constants.AnalyzerIdentifiers.AsynchronousBusinessRuleInheritance);
22
23 public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
24
25 public override async Task RegisterCodeFixesAsync(CodeFixContext context)
26 {
27 var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
28
29 context.CancellationToken.ThrowIfCancellationRequested();
30
31 var diagnostic = context.Diagnostics.First();
32 var methodNode = root.FindNode(diagnostic.Location.SourceSpan) as MethodDeclarationSyntax;
33
34 context.CancellationToken.ThrowIfCancellationRequested();
35 await AddCodeFixAsync(context, root, diagnostic, methodNode);
36 }
37
38 private static async Task AddCodeFixAsync(CodeFixContext context, SyntaxNode root,
39 Diagnostic diagnostic, MethodDeclarationSyntax methodNode)
40 {
41 var model = await context.Document.GetSemanticModelAsync(context.CancellationToken);
42 var methodSymbol = model.GetDeclaredSymbol(methodNode);
43 var typeSymbol = methodSymbol.ContainingType;
44
45 var newRoot = root;
46
47 foreach (var typeSymbolReference in typeSymbol.DeclaringSyntaxReferences)
48 {
49 var typeNode = typeSymbolReference.GetSyntax() as TypeDeclarationSyntax;
50
51 var newTypeNode = typeNode.WithBaseList(GetBaseTypes(typeNode))
52 .WithTriviaFrom(typeNode);
53
54 var currentMethodNode = newTypeNode.DescendantNodes(_ => true).OfType<MethodDeclarationSyntax>()
55 .Single(_ => _.Identifier.ValueText == "Execute");
56 var newReturnType = SyntaxFactory.IdentifierName(nameof(Task))
57 .WithTriviaFrom(currentMethodNode.ReturnType);
58 var newIdentifier = SyntaxFactory.Identifier("ExecuteAsync")
59 .WithTriviaFrom(currentMethodNode.Identifier);
60
61 var newMethodNode = currentMethodNode.WithReturnType(newReturnType)
62 .WithIdentifier(newIdentifier)
63 .WithTriviaFrom(currentMethodNode);
64
65 newTypeNode = newTypeNode.ReplaceNode(currentMethodNode, newMethodNode);
66 newRoot = newRoot.ReplaceNode(typeNode, newTypeNode);
67
68 if (!newRoot.HasUsing(Namespaces.SystemThreadingTasks))
69 {
70 newRoot = (newRoot as CompilationUnitSyntax).AddUsings(
71 SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(
72 Namespaces.SystemThreadingTasks)));
73 }
74 }
75
76 context.RegisterCodeFix(
77 CodeAction.Create(
78 AsynchronousBusinessRuleInheritingFromBusinessRuleChangeToBusinessRuleAsyncCodeFixConstants.UpdateToAsyncEquivalentsDescription,
79 _ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)),
80 AsynchronousBusinessRuleInheritingFromBusinessRuleChangeToBusinessRuleAsyncCodeFixConstants.UpdateToAsyncEquivalentsDescription), diagnostic);
81 }
82
83 private static BaseListSyntax GetBaseTypes(TypeDeclarationSyntax typeNode)
84 {
85 var currentBaseList = typeNode.BaseList;
86
87 var list = new SeparatedSyntaxList<BaseTypeSyntax>();
88
89 foreach (var baseTypeNode in typeNode.BaseList.DescendantNodes(_ => true).OfType<SimpleBaseTypeSyntax>())
90 {
91 var baseTypeNodeIdentifier = baseTypeNode.DescendantNodes().OfType<IdentifierNameSyntax>().Single();
92
93 if (baseTypeNodeIdentifier.Identifier.ValueText == "BusinessRule")
94 {
95 list = list.Add(SyntaxFactory.SimpleBaseType(SyntaxFactory.IdentifierName("BusinessRuleAsync"))
96 .WithTriviaFrom(baseTypeNode));
97 }
98 else if (baseTypeNodeIdentifier.Identifier.ValueText == "IBusinessRule")
99 {
100 list = list.Add(SyntaxFactory.SimpleBaseType(SyntaxFactory.IdentifierName("IBusinessRuleAsync"))
101 .WithTriviaFrom(baseTypeNode));
102 }
103 else
104 {
105 list = list.Add(baseTypeNode);
106 }
107 }
108
109 return SyntaxFactory.BaseList(list).WithTriviaFrom(currentBaseList);
110 }
111 }
112}
Csla.Test.DataPortalTest.Single Single