• 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