• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ImmediatePlatform / Immediate.Validations / 31620039002

12 Aug 2026 04:55PM UTC coverage: 84.037% (+0.2%) from 83.852%
31620039002

Pull #309

github

web-flow
Merge 228c257b4 into 55baca521
Pull Request #309: Improve `[Validate]` codefixer behavior

42 of 43 new or added lines in 1 file covered. (97.67%)

1890 of 2249 relevant lines covered (84.04%)

3.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.0
/src/Immediate.Validations.CodeFixes/AddValidateAttributeCodefixProvider.cs
1
using System.Collections.Immutable;
2
using Immediate.Validations.Analyzers;
3
using Microsoft.CodeAnalysis;
4
using Microsoft.CodeAnalysis.CodeActions;
5
using Microsoft.CodeAnalysis.CodeFixes;
6
using Microsoft.CodeAnalysis.CSharp;
7
using Microsoft.CodeAnalysis.CSharp.Syntax;
8
using Microsoft.CodeAnalysis.Formatting;
9
using Microsoft.CodeAnalysis.Simplification;
10
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
11

12
namespace Immediate.Validations.CodeFixes;
13

14
[ExportCodeFixProvider(LanguageNames.CSharp)]
15
public sealed class AddValidateAttributeCodefixProvider : CodeFixProvider
16
{
17
        public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } =
18
                ImmutableArray.Create([DiagnosticIds.IV0012ValidateAttributeMissing]);
4 ✔
19

20
        public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
4 ✔
21

22
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
23
        {
24
                var diagnostic = context.Diagnostics.Single();
4 ✔
25
                var diagnosticSpan = diagnostic.Location.SourceSpan;
4 ✔
26

27
                if (await context.Document.GetSyntaxRootAsync(context.CancellationToken) is not CompilationUnitSyntax root)
4 ✔
28
                        return;
×
29

30
                if (root.FindNode(diagnosticSpan) is not TypeDeclarationSyntax typeDeclaration)
4 ✔
31
                        return;
×
32

33
                context.RegisterCodeFix(
4 ✔
34
                        CodeAction.Create(
4 ✔
35
                                "Add `[Validate]`",
4 ✔
36
                                createChangedDocument: token =>
4 ✔
37
                                        AddValidateAttribute(context.Document, root, typeDeclaration, token),
4 ✔
38
                                equivalenceKey: nameof(AddValidateAttributeCodefixProvider)
4 ✔
39
                        ),
4 ✔
40
                        diagnostic
4 ✔
41
                );
4 ✔
42
        }
4 ✔
43

44
        private static async Task<Document> AddValidateAttribute(Document document, CompilationUnitSyntax root, TypeDeclarationSyntax typeDeclaration, CancellationToken token)
45
        {
46
                var model = await document.GetSemanticModelAsync(token);
4 ✔
47

48
                var validateSymbol = model?.Compilation
4 ✔
49
                        .GetTypeByMetadataName("Immediate.Validations.Shared.ValidateAttribute")!;
4 ✔
50

51
                var referenceId = DocumentationCommentId.CreateReferenceId(validateSymbol);
4 ✔
52
                var annotation = new SyntaxAnnotation("SymbolId", referenceId);
4 ✔
53

54
                var newLineSyntax = typeDeclaration.DescendantTrivia()
4 ✔
55
                        .FirstOrDefault(t => t.IsKind(SyntaxKind.EndOfLineTrivia));
4 ✔
56

57
                if (newLineSyntax == default)
4 ✔
NEW
58
                        newLineSyntax = ElasticLineFeed;
×
59

60
                var validateAttribute = AttributeList(
4 ✔
61
                        SingletonSeparatedList(
4 ✔
62
                                Attribute(
4 ✔
63
                                        IdentifierName("Validate")
4 ✔
64
                                )
4 ✔
65
                        )
4 ✔
66
                )
4 ✔
67
                        .WithTrailingTrivia(newLineSyntax);
4 ✔
68

69
                var newDecl = typeDeclaration.AttributeLists switch
4 ✔
70
                {
4 ✔
71
                        [] =>
4 ✔
72
                                typeDeclaration
4 ✔
73
                                        .WithoutLeadingTrivia()
4 ✔
74
                                        .WithAttributeLists(
4 ✔
75
                                                typeDeclaration.AttributeLists
4 ✔
76
                                                        .Add(validateAttribute.WithLeadingTrivia(typeDeclaration.GetLeadingTrivia()))
4 ✔
77
                                        ),
4 ✔
78

4 ✔
79
                        _ =>
4 ✔
80
                                typeDeclaration
4 ✔
81
                                        .WithAttributeLists(
4 ✔
82
                                                typeDeclaration.AttributeLists
4 ✔
83
                                                        .Add(validateAttribute)
4 ✔
84
                                        ),
4 ✔
85
                };
4 ✔
86

87
                var newRoot = root.ReplaceNode(
4 ✔
88
                        typeDeclaration,
4 ✔
89
                        newDecl
4 ✔
90
                                .WithAdditionalAnnotations(Simplifier.AddImportsAnnotation, annotation)
4 ✔
91
                                .WithAdditionalAnnotations(Formatter.Annotation)
4 ✔
92
                );
4 ✔
93

94
                return document.WithSyntaxRoot(newRoot);
4 ✔
95
        }
4 ✔
96
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc