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

ImmediatePlatform / Immediate.Validations / 31621615623

12 Aug 2026 05:14PM UTC coverage: 84.08%. First build
31621615623

Pull #309

github

web-flow
Merge 77fbc4d59 into 9074d3107
Pull Request #309: Improve `[Validate]` codefixer behavior

48 of 49 new or added lines in 1 file covered. (97.96%)

1896 of 2255 relevant lines covered (84.08%)

3.36 hits per line

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

95.45
/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
                        .WithAdditionalAnnotations(Simplifier.AddImportsAnnotation, annotation)
4✔
68
                        .WithTrailingTrivia(newLineSyntax);
4✔
69

70
                var newDecl = typeDeclaration.AttributeLists switch
4✔
71
                {
4✔
72
                        [] =>
4✔
73
                                typeDeclaration
4✔
74
                                        .WithoutLeadingTrivia()
4✔
75
                                        .WithAttributeLists(
4✔
76
                                                typeDeclaration.AttributeLists
4✔
77
                                                        .Add(
4✔
78
                                                                validateAttribute
4✔
79
                                                                        .WithLeadingTrivia(typeDeclaration.GetLeadingTrivia())
4✔
80
                                                                        .WithAdditionalAnnotations(Formatter.Annotation)
4✔
81
                                                        )
4✔
82
                                        ),
4✔
83

4✔
84
                        _ =>
4✔
85
                                typeDeclaration
4✔
86
                                        .WithAttributeLists(
4✔
87
                                                typeDeclaration.AttributeLists
4✔
88
                                                        .Add(
4✔
89
                                                                validateAttribute
4✔
90
                                                                        .WithAdditionalAnnotations(Formatter.Annotation)
4✔
91
                                                        )
4✔
92
                                        ),
4✔
93
                };
4✔
94

95
                var newRoot = root.ReplaceNode(
4✔
96
                        typeDeclaration,
4✔
97
                        newDecl
4✔
98
                );
4✔
99

100
                return document.WithSyntaxRoot(newRoot);
4✔
101
        }
4✔
102
}
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