1using System.Collections.Immutable;
2using System.Composition;
4using System.Threading.Tasks;
10using Microsoft.CodeAnalysis.CSharp.Syntax;
15 [ExportCodeFixProvider(LanguageNames.CSharp)]
21 ImmutableArray.Create(Constants.AnalyzerIdentifiers.AsynchronousBusinessRuleInheritance);
23 public sealed
override FixAllProvider
GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
27 var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(
false);
29 context.CancellationToken.ThrowIfCancellationRequested();
31 var diagnostic = context.Diagnostics.First();
32 var methodNode = root.FindNode(diagnostic.Location.SourceSpan) as MethodDeclarationSyntax;
34 context.CancellationToken.ThrowIfCancellationRequested();
35 await AddCodeFixAsync(context, root, diagnostic, methodNode);
38 private static async Task AddCodeFixAsync(CodeFixContext context, SyntaxNode root,
39 Diagnostic diagnostic, MethodDeclarationSyntax methodNode)
41 var model = await context.Document.GetSemanticModelAsync(context.CancellationToken);
42 var methodSymbol = model.GetDeclaredSymbol(methodNode);
43 var typeSymbol = methodSymbol.ContainingType;
47 foreach (var typeSymbolReference
in typeSymbol.DeclaringSyntaxReferences)
49 var typeNode = typeSymbolReference.GetSyntax() as TypeDeclarationSyntax;
51 var newTypeNode = typeNode.WithBaseList(GetBaseTypes(typeNode))
52 .WithTriviaFrom(typeNode);
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);
61 var newMethodNode = currentMethodNode.WithReturnType(newReturnType)
62 .WithIdentifier(newIdentifier)
63 .WithTriviaFrom(currentMethodNode);
65 newTypeNode = newTypeNode.ReplaceNode(currentMethodNode, newMethodNode);
66 newRoot = newRoot.ReplaceNode(typeNode, newTypeNode);
68 if (!newRoot.HasUsing(Namespaces.SystemThreadingTasks))
70 newRoot = (newRoot as CompilationUnitSyntax).AddUsings(
71 SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(
72 Namespaces.SystemThreadingTasks)));
76 context.RegisterCodeFix(
78 AsynchronousBusinessRuleInheritingFromBusinessRuleChangeToBusinessRuleAsyncCodeFixConstants.UpdateToAsyncEquivalentsDescription,
79 _ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)),
80 AsynchronousBusinessRuleInheritingFromBusinessRuleChangeToBusinessRuleAsyncCodeFixConstants.UpdateToAsyncEquivalentsDescription), diagnostic);
83 private static BaseListSyntax GetBaseTypes(TypeDeclarationSyntax typeNode)
85 var currentBaseList = typeNode.BaseList;
87 var list =
new SeparatedSyntaxList<BaseTypeSyntax>();
89 foreach (var baseTypeNode
in typeNode.BaseList.DescendantNodes(_ =>
true).OfType<SimpleBaseTypeSyntax>())
91 var baseTypeNodeIdentifier = baseTypeNode.DescendantNodes().OfType<IdentifierNameSyntax>().
Single();
93 if (baseTypeNodeIdentifier.Identifier.ValueText ==
"BusinessRule")
95 list = list.Add(SyntaxFactory.SimpleBaseType(SyntaxFactory.IdentifierName(
"BusinessRuleAsync"))
96 .WithTriviaFrom(baseTypeNode));
98 else if (baseTypeNodeIdentifier.Identifier.ValueText ==
"IBusinessRule")
100 list = list.Add(SyntaxFactory.SimpleBaseType(SyntaxFactory.IdentifierName(
"IBusinessRuleAsync"))
101 .WithTriviaFrom(baseTypeNode));
105 list = list.Add(baseTypeNode);
109 return SyntaxFactory.BaseList(list).WithTriviaFrom(currentBaseList);
Csla.Test.DataPortalTest.Single Single
override ImmutableArray< string > FixableDiagnosticIds
override async Task RegisterCodeFixesAsync(CodeFixContext context)
sealed override FixAllProvider GetFixAllProvider()