1using System.Collections.Immutable;
2using System.Composition;
4using System.Threading.Tasks;
15 [ExportCodeFixProvider(LanguageNames.CSharp)]
21 ImmutableArray.Create(Constants.AnalyzerIdentifiers.PublicNoArgumentConstructorIsMissing);
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 classNode = root.FindNode(diagnostic.Location.SourceSpan) as ClassDeclarationSyntax;
34 context.CancellationToken.ThrowIfCancellationRequested();
36 var hasNonPublicNoArgumentConstructor =
bool.Parse(
37 diagnostic.Properties[PublicNoArgumentConstructorIsMissingConstants.HasNonPublicNoArgumentConstructor]);
39 if (hasNonPublicNoArgumentConstructor)
41 if (context.Document.SupportsSemanticModel)
43 var model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(
false);
44 AddCodeFixWithUpdatingNonPublicConstructor(
45 context, root, diagnostic, classNode, model);
50 AddCodeFixWithNewPublicConstructor(
51 context, root, diagnostic, classNode);
55 private static void AddCodeFixWithNewPublicConstructor(CodeFixContext context, SyntaxNode root,
56 Diagnostic diagnostic, ClassDeclarationSyntax classNode)
59 var constructor = SyntaxFactory.ConstructorDeclaration(classNode.Identifier)
61 SyntaxFactory.TokenList(
62 SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
63 .WithParameterList(SyntaxFactory.ParameterList()
65 SyntaxFactory.Token(SyntaxKind.OpenParenToken))
68 SyntaxKind.CloseParenToken)))
69 .WithBody(SyntaxFactory.Block()
72 SyntaxKind.OpenBraceToken))
75 SyntaxKind.CloseBraceToken))).NormalizeWhitespace().WithAdditionalAnnotations(Formatter.Annotation);
76 var newClassNode = classNode.AddMembers(constructor);
77 var newRoot = root.ReplaceNode(classNode, newClassNode);
79 context.RegisterCodeFix(
81 CheckConstructorsAnalyzerPublicConstructorCodeFixConstants.AddPublicConstructorDescription,
82 _ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)),
83 CheckConstructorsAnalyzerPublicConstructorCodeFixConstants.AddPublicConstructorDescription), diagnostic);
86 private static void AddCodeFixWithUpdatingNonPublicConstructor(CodeFixContext context, SyntaxNode root,
87 Diagnostic diagnostic, ClassDeclarationSyntax classNode, SemanticModel model)
89 var publicModifier = SyntaxFactory.Token(SyntaxKind.PublicKeyword);
90 var classSymbol = model.GetDeclaredSymbol(classNode);
92 if (classSymbol !=
null)
94 var constructorSymbol = classSymbol.Constructors
95 .Single(_ => _.Parameters.Count() == 0 &&
96 !_.DeclaredAccessibility.HasFlag(Accessibility.Public));
98 var constructor = constructorSymbol.DeclaringSyntaxReferences[0].GetSyntax(context.CancellationToken);
100 var newConstructor = constructor;
102 var generator = SyntaxGenerator.GetGenerator(context.Document);
103 newConstructor = generator.WithAccessibility(newConstructor, Accessibility.Public);
105 var newRoot = root.ReplaceNode(constructor, newConstructor);
107 context.RegisterCodeFix(
109 CheckConstructorsAnalyzerPublicConstructorCodeFixConstants.UpdateNonPublicConstructorToPublicDescription,
110 _ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)),
111 CheckConstructorsAnalyzerPublicConstructorCodeFixConstants.UpdateNonPublicConstructorToPublicDescription), diagnostic);
override async Task RegisterCodeFixesAsync(CodeFixContext context)
sealed override FixAllProvider GetFixAllProvider()
override ImmutableArray< string > FixableDiagnosticIds