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

ImmediatePlatform / Immediate.Apis / 30317553066

28 Jul 2026 12:31AM UTC coverage: 96.259% (-0.001%) from 96.26%
30317553066

Pull #325

github

web-flow
Merge e59f8987b into e752e66bd
Pull Request #325: Support adding `TransformResult` for `ValueTask` endpoints

35 of 36 new or added lines in 2 files covered. (97.22%)

1415 of 1470 relevant lines covered (96.26%)

3.85 hits per line

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

94.57
/src/Immediate.Apis.CodeFixes/MissingTransformResultMethodCodeFixProvider.cs
1
using System.Collections.Immutable;
2
using Immediate.Apis.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 static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
10

11
namespace Immediate.Apis.CodeFixes;
12

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

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

21
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
22
        {
23
                // We link only one diagnostic and assume there is only one diagnostic in the context.
24
                var diagnostic = context.Diagnostics.Single();
4✔
25

26
                // 'SourceSpan' of 'Location' is the highlighted area. We're going to use this area to find the 'SyntaxNode' to rename.
27
                var diagnosticSpan = diagnostic.Location.SourceSpan;
4✔
28

29
                var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
4✔
30

31
                if (root?.FindNode(diagnosticSpan) is ClassDeclarationSyntax classDeclarationSyntax
4✔
32
                        && root is CompilationUnitSyntax compilationUnitSyntax)
4✔
33
                {
34
                        context.RegisterCodeFix(
4✔
35
                                CodeAction.Create(
4✔
36
                                        title: "Add `TransformResult` method",
4✔
37
                                        createChangedDocument: c =>
4✔
38
                                                AddTransformResultMethodAsync(context.Document, compilationUnitSyntax, classDeclarationSyntax, c),
4✔
39
                                        equivalenceKey: nameof(MissingCustomizeEndpointMethodCodeFixProvider)
4✔
40
                                ),
4✔
41
                                diagnostic);
4✔
42
                }
43
        }
4✔
44

45
        private static async Task<Document> AddTransformResultMethodAsync(
46
                Document document,
47
                CompilationUnitSyntax root,
48
                ClassDeclarationSyntax classDeclarationSyntax,
49
                CancellationToken cancellationToken
50
        )
51
        {
52
                var model = await document.GetSemanticModelAsync(cancellationToken) ?? throw new InvalidOperationException("Could not get semantic model");
4✔
53

54
                if (model.GetDeclaredSymbol(classDeclarationSyntax, cancellationToken: cancellationToken) is not { } handlerClassSymbol)
4✔
55
                        return document;
×
56

57
                var handleMethodSymbol = handlerClassSymbol
4✔
58
                        .GetMembers()
4✔
59
                        .OfType<IMethodSymbol>()
4✔
60
                        .FirstOrDefault(x => x.Name is "Handle" or "HandleAsync");
4✔
61

62
                if (handleMethodSymbol is null)
4✔
63
                        return document;
×
64

65
                if (await handleMethodSymbol.DeclaringSyntaxReferences[0]
4✔
66
                                .GetSyntaxAsync(cancellationToken)
4✔
67
                                is not MethodDeclarationSyntax handleMethodSyntax)
4✔
68
                {
69
                        return document;
×
70
                }
71

72
                var (valid, returnType) = handleMethodSyntax.ReturnType switch
4✔
73
                {
4✔
74
                        GenericNameSyntax
4✔
75
                        {
4✔
76
                                TypeArgumentList.Arguments: [{ } rt],
4✔
77
                        } => (true, rt),
4✔
78

4✔
79
                        IdentifierNameSyntax => (true, null),
4✔
80

4✔
NEW
81
                        _ => (false, null),
×
82
                };
4✔
83

84
                if (!valid)
4✔
85
                {
86
                        return document;
×
87
                }
88

89
                var transformResultMethodSyntax = MethodDeclaration(
4✔
90
                                returnType ?? ParseTypeName("object"),
4✔
91
                                Identifier("TransformResult"))
4✔
92
                        .WithModifiers(
4✔
93
                                TokenList(
4✔
94
                                [
4✔
95
                                        Token(SyntaxKind.InternalKeyword),
4✔
96
                                        Token(SyntaxKind.StaticKeyword),
4✔
97
                                ]))
4✔
98
                        .WithParameterList(
4✔
99
                                ParameterList(
4✔
100
                                        returnType switch
4✔
101
                                        {
4✔
102
                                                { } =>
4✔
103
                                                        SingletonSeparatedList(
4✔
104
                                                                Parameter(
4✔
105
                                                                        Identifier("result")
4✔
106
                                                                )
4✔
107
                                                                .WithType(returnType)
4✔
108
                                                        ),
4✔
109

4✔
110
                                                _ => [],
4✔
111
                                        }
4✔
112
                                )
4✔
113
                        )
4✔
114
                        .WithBody(
4✔
115
                                Block(
4✔
116
                                        SingletonList<StatementSyntax>(
4✔
117
                                                ReturnStatement(
4✔
118
                                                        returnType switch
4✔
119
                                                        {
4✔
120
                                                                { } => IdentifierName("result"),
4✔
121
                                                                _ => ParseExpression("new()"),
4✔
122
                                                        }
4✔
123
                                                )
4✔
124
                                        )
4✔
125
                                )
4✔
126
                        )
4✔
127
                        .WithAdditionalAnnotations(Formatter.Annotation);
4✔
128

129
                // Manually add trailing trivia to ensure proper spacing
130
                var newMembers = classDeclarationSyntax.Members
4✔
131
                        .Insert(
4✔
132
                                0,
4✔
133
                                transformResultMethodSyntax
4✔
134
                        );
4✔
135

136
                var newClassDecl = classDeclarationSyntax
4✔
137
                        .WithMembers(newMembers);
4✔
138

139
                // Replace the old class declaration with the new one
140
                var newRoot = root.ReplaceNode(classDeclarationSyntax, newClassDecl);
4✔
141

142
                // Create a new document with the updated syntax root
143
                var newDocument = document.WithSyntaxRoot(newRoot);
4✔
144

145
                // Return the new document
146
                return newDocument;
4✔
147
        }
4✔
148
}
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