Skip to content

Commit 692440b

Browse files
authored
Remove static analysis for route parameter in RDG (#48320)
1 parent b791bc4 commit 692440b

10 files changed

+86
-97
lines changed

src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
155155
}
156156
else
157157
{
158-
codeWriter.WriteLine($"{SymbolDisplay.FormatLiteral(endpoint.RoutePattern!, true)},");
158+
codeWriter.WriteLine($"{SymbolDisplay.FormatLiteral("{*path:nonfile}", true)},");
159159
}
160160
codeWriter.WriteLine("handler,");
161161
codeWriter.WriteLine($"{endpoint.EmitVerb()},");

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Endpoint.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@ public Endpoint(IInvocationOperation operation, WellKnownTypes wellKnownTypes, S
2222
HttpMethod = GetHttpMethod(operation);
2323
EmitterContext = new EmitterContext();
2424

25-
if (!operation.TryGetRouteHandlerPattern(out var routeToken))
26-
{
27-
Diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.UnableToResolveRoutePattern, Operation.Syntax.GetLocation()));
28-
return;
29-
}
30-
31-
RoutePattern = routeToken;
32-
3325
if (!operation.TryGetRouteHandlerMethod(semanticModel, out var method))
3426
{
3527
Diagnostics.Add(Diagnostic.Create(DiagnosticDescriptors.UnableToResolveMethod, Operation.Syntax.GetLocation()));

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/InvocationOperationExtensions.cs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace Microsoft.AspNetCore.Http.RequestDelegateGenerator.StaticRouteHandlerM
1010

1111
internal static class InvocationOperationExtensions
1212
{
13-
private const int RoutePatternArgumentOrdinal = 1;
1413
public static readonly string[] KnownMethods =
1514
{
1615
"MapGet",
@@ -64,33 +63,6 @@ public static bool TryGetMapMethodName(this SyntaxNode node, out string? methodN
6463
return false;
6564
}
6665

67-
public static bool TryGetRouteHandlerPattern(this IInvocationOperation invocation, [NotNullWhen(true)] out string? token)
68-
{
69-
token = default;
70-
if (invocation.Syntax.TryGetMapMethodName(out var methodName))
71-
{
72-
if (methodName == "MapFallback" && invocation.Arguments.Length == 2)
73-
{
74-
token = "{*path:nonfile}";
75-
return true;
76-
}
77-
foreach (var argument in invocation.Arguments)
78-
{
79-
if (argument.Parameter?.Ordinal == RoutePatternArgumentOrdinal)
80-
{
81-
if (argument?.Syntax is not ArgumentSyntax routePatternArgumentSyntax ||
82-
routePatternArgumentSyntax.Expression is not LiteralExpressionSyntax routePatternArgumentLiteralSyntax)
83-
{
84-
return false;
85-
}
86-
token = routePatternArgumentLiteralSyntax.Token.ValueText;
87-
return true;
88-
}
89-
}
90-
}
91-
return false;
92-
}
93-
9466
private static IMethodSymbol? ResolveMethodFromOperation(IOperation operation, SemanticModel semanticModel) => operation switch
9567
{
9668
IArgumentOperation argument => ResolveMethodFromOperation(argument.Value, semanticModel),
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
namespace Microsoft.AspNetCore.Http.Generators.Tests;
4+
5+
public partial class CompileTimeCreationTests : RequestDelegateCreationTests
6+
{
7+
[Fact]
8+
public async Task SupportsRoutePatternInVariable()
9+
{
10+
var source = """
11+
var route = "/hello";
12+
app.MapGet(route, () =>
13+
{
14+
return "Hello world!";
15+
});
16+
""";
17+
var (result, compilation) = await RunGeneratorAsync(source);
18+
var endpoint = GetEndpointFromCompilation(compilation);
19+
20+
VerifyStaticEndpointModel(result, endpointModel =>
21+
{
22+
Assert.Equal("MapGet", endpointModel.HttpMethod);
23+
});
24+
25+
var httpContext = CreateHttpContext();
26+
await endpoint.RequestDelegate(httpContext);
27+
await VerifyResponseBodyAsync(httpContext, "Hello world!");
28+
}
29+
30+
[Fact]
31+
public async Task SupportsRoutePatternInConst()
32+
{
33+
var source = """
34+
const string route = "/hello";
35+
app.MapGet(route, () =>
36+
{
37+
return "Hello world!";
38+
});
39+
""";
40+
var (result, compilation) = await RunGeneratorAsync(source);
41+
var endpoint = GetEndpointFromCompilation(compilation);
42+
43+
VerifyStaticEndpointModel(result, endpointModel =>
44+
{
45+
Assert.Equal("MapGet", endpointModel.HttpMethod);
46+
});
47+
48+
var httpContext = CreateHttpContext();
49+
await endpoint.RequestDelegate(httpContext);
50+
await VerifyResponseBodyAsync(httpContext, "Hello world!");
51+
}
52+
53+
[Fact]
54+
public async Task SupportsComputedRoutePattern()
55+
{
56+
var source = """
57+
for (int i = 0; i < 5; i++)
58+
{
59+
var route = $"/hello/{i}";
60+
app.MapGet(route, () =>
61+
{
62+
return $"Hello world!";
63+
});
64+
}
65+
""";
66+
var (result, compilation) = await RunGeneratorAsync(source);
67+
var endpoints = GetEndpointsFromCompilation(compilation);
68+
69+
VerifyStaticEndpointModel(result, endpointModel =>
70+
{
71+
Assert.Equal("MapGet", endpointModel.HttpMethod);
72+
});
73+
74+
for (int i = 0; i < 5; i++)
75+
{
76+
var endpoint = endpoints[i];
77+
var httpContext = CreateHttpContext();
78+
await endpoint.RequestDelegate(httpContext);
79+
await VerifyResponseBodyAsync(httpContext, $"Hello world!");
80+
}
81+
82+
}
83+
}

src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public async Task MapAction_ProducesCorrectContentType(string source, string exp
3939

4040
VerifyStaticEndpointModel(result, endpointModel =>
4141
{
42-
Assert.Equal("/", endpointModel.RoutePattern);
4342
Assert.Equal("MapGet", endpointModel.HttpMethod);
4443
Assert.Equal(expectedContentType, endpointModel.Response.ContentType);
4544
});
@@ -57,27 +56,4 @@ public async Task MapAction_ExplicitRouteParamWithInvalidName_SimpleReturn()
5756
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => endpoint.RequestDelegate(httpContext));
5857
Assert.Equal("'invalidName' is not a route parameter.", exception.Message);
5958
}
60-
61-
[Fact]
62-
public async Task MapAction_WarnsForUnsupportedRouteVariable()
63-
{
64-
var source = """
65-
var route = "/hello";
66-
app.MapGet(route, () => "Hello world!");
67-
""";
68-
var (generatorRunResult, compilation) = await RunGeneratorAsync(source);
69-
70-
// Emits diagnostic but generates no source
71-
var result = Assert.IsType<GeneratorRunResult>(generatorRunResult);
72-
var diagnostic = Assert.Single(result.Diagnostics);
73-
Assert.Equal(DiagnosticDescriptors.UnableToResolveRoutePattern.Id, diagnostic.Id);
74-
Assert.Empty(result.GeneratedSources);
75-
76-
// Falls back to runtime-generated endpoint
77-
var endpoint = GetEndpointFromCompilation(compilation, false);
78-
79-
var httpContext = CreateHttpContext();
80-
await endpoint.RequestDelegate(httpContext);
81-
await VerifyResponseBodyAsync(httpContext, "Hello world!");
82-
}
8359
}

src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.Arrays.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public async Task MapAction_ExplicitQuery_ComplexTypeArrayParam()
2828

2929
VerifyStaticEndpointModel(results, endpointModel =>
3030
{
31-
Assert.Equal("/hello", endpointModel.RoutePattern);
3231
Assert.Equal("MapGet", endpointModel.HttpMethod);
3332
});
3433

@@ -50,7 +49,6 @@ public async Task MapAction_ExplicitHeader_ComplexTypeArrayParam()
5049

5150
VerifyStaticEndpointModel(results, endpointModel =>
5251
{
53-
Assert.Equal("/hello", endpointModel.RoutePattern);
5452
Assert.Equal("MapGet", endpointModel.HttpMethod);
5553
});
5654

@@ -72,7 +70,6 @@ public async Task MapAction_ExplicitHeader_StringArrayParam()
7270

7371
VerifyStaticEndpointModel(results, endpointModel =>
7472
{
75-
Assert.Equal("/hello", endpointModel.RoutePattern);
7673
Assert.Equal("MapGet", endpointModel.HttpMethod);
7774
});
7875

@@ -94,7 +91,6 @@ public async Task MapAction_ExplicitHeader_NullableStringArrayParam()
9491

9592
VerifyStaticEndpointModel(results, endpointModel =>
9693
{
97-
Assert.Equal("/hello", endpointModel.RoutePattern);
9894
Assert.Equal("MapGet", endpointModel.HttpMethod);
9995
});
10096

@@ -168,7 +164,6 @@ public async Task RequestDelegateHandlesArraysFromQueryString(string typeName, s
168164

169165
VerifyStaticEndpointModel(results, endpointModel =>
170166
{
171-
Assert.Equal("/hello", endpointModel.RoutePattern);
172167
Assert.Equal("MapGet", endpointModel.HttpMethod);
173168
});
174169

@@ -194,7 +189,6 @@ public async Task MapAction_ImplicitQuery_ComplexTypeArrayParam()
194189

195190
VerifyStaticEndpointModel(results, endpointModel =>
196191
{
197-
Assert.Equal("/hello", endpointModel.RoutePattern);
198192
Assert.Equal("MapGet", endpointModel.HttpMethod);
199193
});
200194

@@ -216,7 +210,6 @@ public async Task MapAction_ExplicitQuery_StringArrayParam()
216210

217211
VerifyStaticEndpointModel(results, endpointModel =>
218212
{
219-
Assert.Equal("/hello", endpointModel.RoutePattern);
220213
Assert.Equal("MapGet", endpointModel.HttpMethod);
221214
});
222215

@@ -238,7 +231,6 @@ public async Task MapAction_ImplicitQuery_StringArrayParam()
238231

239232
VerifyStaticEndpointModel(results, endpointModel =>
240233
{
241-
Assert.Equal("/hello", endpointModel.RoutePattern);
242234
Assert.Equal("MapGet", endpointModel.HttpMethod);
243235
});
244236

@@ -260,7 +252,6 @@ public async Task MapAction_ImplicitQuery_NullableStringArrayParam_QueryNotPrese
260252

261253
VerifyStaticEndpointModel(results, endpointModel =>
262254
{
263-
Assert.Equal("/hello", endpointModel.RoutePattern);
264255
Assert.Equal("MapGet", endpointModel.HttpMethod);
265256
});
266257

@@ -281,7 +272,6 @@ public async Task MapAction_ImplicitQuery_NullableStringArrayParam_EmptyQueryVal
281272

282273
VerifyStaticEndpointModel(results, endpointModel =>
283274
{
284-
Assert.Equal("/hello", endpointModel.RoutePattern);
285275
Assert.Equal("MapGet", endpointModel.HttpMethod);
286276
});
287277

@@ -303,7 +293,6 @@ public async Task MapAction_ExplicitQuery_NullableStringArrayParam()
303293

304294
VerifyStaticEndpointModel(results, endpointModel =>
305295
{
306-
Assert.Equal("/hello", endpointModel.RoutePattern);
307296
Assert.Equal("MapGet", endpointModel.HttpMethod);
308297
});
309298

@@ -325,7 +314,6 @@ public async Task MapAction_ImplicitQuery_NullableStringArrayParam()
325314

326315
VerifyStaticEndpointModel(results, endpointModel =>
327316
{
328-
Assert.Equal("/hello", endpointModel.RoutePattern);
329317
Assert.Equal("MapGet", endpointModel.HttpMethod);
330318
});
331319

@@ -347,7 +335,6 @@ public async Task MapPost_WithArrayQueryString_ShouldFail()
347335

348336
VerifyStaticEndpointModel(results, endpointModel =>
349337
{
350-
Assert.Equal("/hello", endpointModel.RoutePattern);
351338
Assert.Equal("MapPost", endpointModel.HttpMethod);
352339
});
353340

@@ -369,7 +356,6 @@ public async Task MapPost_WithArrayQueryString_AndBody_ShouldUseBody()
369356

370357
VerifyStaticEndpointModel(results, endpointModel =>
371358
{
372-
Assert.Equal("/hello", endpointModel.RoutePattern);
373359
Assert.Equal("MapPost", endpointModel.HttpMethod);
374360
});
375361

src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.QueryParameters.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ public async Task MapAction_SingleNullableStringParam_WithEmptyQueryStringValueP
9090

9191
VerifyStaticEndpointModel(results, endpointModel =>
9292
{
93-
Assert.Equal("/hello", endpointModel.RoutePattern);
9493
Assert.Equal("MapGet", endpointModel.HttpMethod);
9594
var p = Assert.Single(endpointModel.Parameters);
9695
Assert.Equal(EndpointParameterSource.Query, p.Source);
@@ -115,7 +114,6 @@ public async Task MapAction_MultipleStringParam_StringReturn()
115114

116115
VerifyStaticEndpointModel(results, endpointModel =>
117116
{
118-
Assert.Equal("/hello", endpointModel.RoutePattern);
119117
Assert.Equal("MapGet", endpointModel.HttpMethod);
120118
});
121119

@@ -156,7 +154,6 @@ public async Task MapAction_ExplicitQueryParam_NameTest(string name, string look
156154

157155
VerifyStaticEndpointModel(results, (endpointModel) =>
158156
{
159-
Assert.Equal("/", endpointModel.RoutePattern);
160157
Assert.Equal("MapGet", endpointModel.HttpMethod);
161158
var p = Assert.Single(endpointModel.Parameters);
162159
Assert.Equal(EndpointParameterSource.Query, p.Source);

0 commit comments

Comments
 (0)