Skip to content

Commit 394fb66

Browse files
committed
Polish
1 parent 85a0065 commit 394fb66

11 files changed

+888
-136
lines changed

src/Http/Http.Extensions/gen/Resources.resx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@
130130
<value>Unable to statically resolve endpoint handler method. Only method groups, lambda expressions or readonly fields/variables are allowed. Compile-time endpoint generation will skip this endpoint and the endpoint will be generated at runtime. For more information, please see aka.ms/aot-known-issues</value>
131131
</data>
132132
<data name="UnableToResolveParameter_Message" xml:space="preserve">
133-
<value>Unable to statically resolve property named '{0}' for endpoint. Compile-time endpoint generation will skip this endpoint and the endpoint will be generated at runtime. For more information, please see https://aka.ms/aot-known-issues</value>
133+
<value>Unable to statically resolve parameter named '{0}' for endpoint. Compile-time endpoint generation will skip this endpoint and the endpoint will be generated at runtime. For more information, please see https://aka.ms/aot-known-issues</value>
134134
</data>
135135
<data name="UnableToResolveParameter_Title" xml:space="preserve">
136-
<value>Unable to resolve property</value>
136+
<value>Unable to resolve parameter</value>
137137
</data>
138138
<data name="UnableToResolveAnonymousReturnType_Message" xml:space="preserve">
139139
<value>Unable to resolve anonymous return type. Compile-time endpoint generation will skip this endpoint and the endpoint will be generated at runtime. For more information, please see https://aka.ms/aot-known-issues</value>

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EmitterExtensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
3+
using System;
34
using System.Diagnostics.CodeAnalysis;
45
using Microsoft.AspNetCore.Analyzers.Infrastructure;
56
using Microsoft.CodeAnalysis;
@@ -30,4 +31,13 @@ public static bool IsSerializableJsonResponse(this EndpointResponse endpointResp
3031
}
3132
return false;
3233
}
34+
35+
public static string EmitHandlerArgument(this EndpointParameter endpointParameter) => $"{endpointParameter.SymbolName}_local";
36+
37+
public static string EmitArgument(this EndpointParameter endpointParameter) => endpointParameter.Source switch
38+
{
39+
EndpointParameterSource.JsonBody or EndpointParameterSource.Route or EndpointParameterSource.RouteOrQuery or EndpointParameterSource.JsonBodyOrService or EndpointParameterSource.FormBody => endpointParameter.IsOptional ? endpointParameter.EmitHandlerArgument() : $"{endpointParameter.EmitHandlerArgument()}!",
40+
EndpointParameterSource.Unknown => throw new Exception("Unreachable!"),
41+
_ => endpointParameter.EmitHandlerArgument()
42+
};
3343
}

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointEmitter.cs

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Microsoft.AspNetCore.Http.RequestDelegateGenerator.StaticRouteHandlerModel.Emitters;
1212
internal static class EndpointEmitter
1313
{
14-
internal static string EmitParameterPreparation(this IEnumerable<EndpointParameter> endpointParameters, int baseIndent = 0)
14+
internal static string EmitParameterPreparation(this IEnumerable<EndpointParameter> endpointParameters, EmitterContext emitterContext, int baseIndent = 0)
1515
{
1616
using var stringWriter = new StringWriter(CultureInfo.InvariantCulture);
1717
using var parameterPreparationBuilder = new CodeWriter(stringWriter, baseIndent);
@@ -32,25 +32,30 @@ internal static string EmitParameterPreparation(this IEnumerable<EndpointParamet
3232
parameter.EmitRouteParameterPreparation(parameterPreparationBuilder);
3333
break;
3434
case EndpointParameterSource.RouteOrQuery:
35+
emitterContext.HasRouteOrQuery = true;
3536
parameter.EmitRouteOrQueryParameterPreparation(parameterPreparationBuilder);
3637
break;
3738
case EndpointParameterSource.BindAsync:
39+
emitterContext.HasBindAsync = true;
3840
parameter.EmitBindAsyncPreparation(parameterPreparationBuilder);
3941
break;
4042
case EndpointParameterSource.JsonBody:
43+
emitterContext.HasJsonBody = true;
4144
parameter.EmitJsonBodyParameterPreparationString(parameterPreparationBuilder);
4245
break;
4346
case EndpointParameterSource.FormBody:
47+
emitterContext.HasFormBody = true;
4448
parameter.EmitFormParameterPreparation(parameterPreparationBuilder, ref readFormEmitted);
4549
break;
4650
case EndpointParameterSource.JsonBodyOrService:
51+
emitterContext.HasJsonBodyOrService = true;
4752
parameter.EmitJsonBodyOrServiceParameterPreparationString(parameterPreparationBuilder);
4853
break;
4954
case EndpointParameterSource.Service:
5055
parameter.EmitServiceParameterPreparation(parameterPreparationBuilder);
5156
break;
5257
case EndpointParameterSource.AsParameters:
53-
parameter.EmitAsParametersParameterPreparation(parameterPreparationBuilder);
58+
parameter.EmitAsParametersParameterPreparation(parameterPreparationBuilder, emitterContext);
5459
break;
5560
}
5661
}
@@ -61,30 +66,25 @@ internal static string EmitParameterPreparation(this IEnumerable<EndpointParamet
6166
public static void EmitRouteOrQueryResolver(this Endpoint endpoint, CodeWriter codeWriter)
6267
{
6368
foreach (var parameter in endpoint.Parameters)
69+
{
70+
ProcessParameter(parameter, codeWriter, endpoint);
71+
if (parameter is { Source: EndpointParameterSource.AsParameters, EndpointParameters: {} innerParameters })
72+
{
73+
foreach (var innerParameter in innerParameters)
74+
{
75+
ProcessParameter(innerParameter, codeWriter, endpoint);
76+
}
77+
}
78+
}
79+
80+
static void ProcessParameter(EndpointParameter parameter, CodeWriter codeWriter, Endpoint endpoint)
6481
{
6582
if (parameter.Source == EndpointParameterSource.RouteOrQuery)
6683
{
6784
var parameterName = parameter.SymbolName;
6885
codeWriter.Write($@"var {parameterName}_RouteOrQueryResolver = ");
6986
codeWriter.WriteLine($@"GeneratedRouteBuilderExtensionsCore.ResolveFromRouteOrQuery(""{parameterName}"", options?.RouteParameterNames);");
70-
}
71-
if (parameter is
72-
{
73-
Source: EndpointParameterSource.AsParameters,
74-
EndpointParameters:
75-
{} asParametersList
76-
})
77-
{
78-
foreach (var (_, innerParameter) in asParametersList)
79-
{
80-
if (innerParameter.Source == EndpointParameterSource.RouteOrQuery)
81-
{
82-
var parameterName = innerParameter.SymbolName;
83-
codeWriter.Write($@"var {parameterName}_RouteOrQueryResolver = ");
84-
codeWriter.WriteLine($@"GeneratedRouteBuilderExtensionsCore.ResolveFromRouteOrQuery(""{parameterName}"", options?.RouteParameterNames);");
85-
endpoint.EmitterContext.HasRouteOrQuery = true;
86-
}
87-
}
87+
endpoint.EmitterContext.HasRouteOrQuery = true;
8888
}
8989
}
9090
}
@@ -93,6 +93,18 @@ public static void EmitJsonBodyOrServiceResolver(this Endpoint endpoint, CodeWri
9393
{
9494
var serviceProviderEmitted = false;
9595
foreach (var parameter in endpoint.Parameters)
96+
{
97+
ProcessParameter(parameter, codeWriter, ref serviceProviderEmitted);
98+
if (parameter is { Source: EndpointParameterSource.AsParameters, EndpointParameters: {} innerParameters })
99+
{
100+
foreach (var innerParameter in innerParameters)
101+
{
102+
ProcessParameter(innerParameter, codeWriter, ref serviceProviderEmitted);
103+
}
104+
}
105+
}
106+
107+
static void ProcessParameter(EndpointParameter parameter, CodeWriter codeWriter, ref bool serviceProviderEmitted)
96108
{
97109
if (parameter.Source == EndpointParameterSource.JsonBodyOrService)
98110
{
@@ -105,32 +117,7 @@ public static void EmitJsonBodyOrServiceResolver(this Endpoint endpoint, CodeWri
105117
var shortParameterTypeName = parameter.Type.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat);
106118
codeWriter.WriteLine($"ResolveJsonBodyOrService<{parameter.Type.ToDisplayString(EmitterConstants.DisplayFormat)}>(logOrThrowExceptionHelper, {SymbolDisplay.FormatLiteral(shortParameterTypeName, true)}, {SymbolDisplay.FormatLiteral(parameter.SymbolName, true)}, serviceProviderIsService);");
107119
}
108-
109-
if (parameter is
110-
{
111-
Source: EndpointParameterSource.AsParameters,
112-
EndpointParameters:
113-
{} asParametersList
114-
})
115-
{
116-
foreach (var (_, innerParameter) in asParametersList)
117-
{
118-
if (innerParameter.Source == EndpointParameterSource.JsonBodyOrService)
119-
{
120-
if (!serviceProviderEmitted)
121-
{
122-
codeWriter.WriteLine("var serviceProviderIsService = serviceProvider?.GetService<IServiceProviderIsService>();");
123-
serviceProviderEmitted = true;
124-
}
125-
codeWriter.Write($@"var {innerParameter.SymbolName}_JsonBodyOrServiceResolver = ");
126-
var shortParameterTypeName = innerParameter.Type.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat);
127-
codeWriter.WriteLine($"ResolveJsonBodyOrService<{innerParameter.Type.ToDisplayString(EmitterConstants.DisplayFormat)}>(logOrThrowExceptionHelper, {SymbolDisplay.FormatLiteral(shortParameterTypeName, true)}, {SymbolDisplay.FormatLiteral(innerParameter.SymbolName, true)}, serviceProviderIsService);");
128-
129-
}
130-
}
131-
}
132120
}
133-
134121
}
135122

136123
public static void EmitLoggingPreamble(this Endpoint endpoint, CodeWriter codeWriter)

src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointParameterEmitter.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5-
using System.Globalization;
6-
using System.Linq;
75
using Microsoft.AspNetCore.Analyzers.Infrastructure;
86
using Microsoft.AspNetCore.Analyzers.RouteEmbeddedLanguage.Infrastructure;
97
using Microsoft.CodeAnalysis;
@@ -282,27 +280,17 @@ internal static void EmitServiceParameterPreparation(this EndpointParameter endp
282280
codeWriter.WriteLine($"var {endpointParameter.EmitHandlerArgument()} = {assigningCode};");
283281
}
284282

285-
internal static void EmitAsParametersParameterPreparation(this EndpointParameter endpointParameter, CodeWriter codeWriter)
283+
internal static void EmitAsParametersParameterPreparation(this EndpointParameter endpointParameter, CodeWriter codeWriter, EmitterContext emitterContext)
286284
{
287285
codeWriter.WriteLine(endpointParameter.EmitParameterDiagnosticComment());
288-
289-
var endpointParameters = endpointParameter.EndpointParameters?.Select(p => p.Item2);
290-
codeWriter.WriteLine(endpointParameters?.EmitParameterPreparation());
291-
286+
codeWriter.WriteLine(endpointParameter.EndpointParameters?.EmitParameterPreparation(baseIndent: codeWriter.Indent, emitterContext: emitterContext));
292287
codeWriter.WriteLine($"var {endpointParameter.EmitHandlerArgument()} = {endpointParameter.AssigningCode};");
293288
}
294289

295290
private static string EmitParameterDiagnosticComment(this EndpointParameter endpointParameter) => $"// Endpoint Parameter: {endpointParameter.SymbolName} (Type = {endpointParameter.Type}, IsOptional = {endpointParameter.IsOptional}, IsParsable = {endpointParameter.IsParsable}, IsArray = {endpointParameter.IsArray}, Source = {endpointParameter.Source})";
296-
public static string EmitHandlerArgument(this EndpointParameter endpointParameter) => $"{endpointParameter.SymbolName}_local";
291+
297292
private static string EmitTempArgument(this EndpointParameter endpointParameter) => $"{endpointParameter.SymbolName}_temp";
298293

299294
private static string EmitParsedTempArgument(this EndpointParameter endpointParameter) => $"{endpointParameter.SymbolName}_parsed_temp";
300295
private static string EmitAssigningCodeResult(this EndpointParameter endpointParameter) => $"{endpointParameter.SymbolName}_raw";
301-
302-
public static string EmitArgument(this EndpointParameter endpointParameter) => endpointParameter.Source switch
303-
{
304-
EndpointParameterSource.JsonBody or EndpointParameterSource.Route or EndpointParameterSource.RouteOrQuery or EndpointParameterSource.JsonBodyOrService or EndpointParameterSource.FormBody => endpointParameter.IsOptional ? endpointParameter.EmitHandlerArgument() : $"{endpointParameter.EmitHandlerArgument()}!",
305-
EndpointParameterSource.Unknown => throw new Exception("Unreachable!"),
306-
_ => endpointParameter.EmitHandlerArgument()
307-
};
308296
}

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public Endpoint(IInvocationOperation operation, WellKnownTypes wellKnownTypes, S
8383
IsAwaitable = true;
8484
break;
8585
case EndpointParameterSource.AsParameters:
86-
IsAwaitable = parameter.EndpointParameters.Any(parameters => parameters.Item2.Source is EndpointParameterSource.JsonBody || parameters.Item2.Source == EndpointParameterSource.FormBody || parameters.Item2.Source == EndpointParameterSource.JsonBodyOrService);
86+
IsAwaitable = parameter.EndpointParameters?.Any(p => p.Source is EndpointParameterSource.JsonBody or EndpointParameterSource.FormBody or EndpointParameterSource.JsonBodyOrService) ?? false;
8787
break;
8888
case EndpointParameterSource.Unknown:
8989
Diagnostics.Add(Diagnostic.Create(
@@ -100,11 +100,7 @@ public Endpoint(IInvocationOperation operation, WellKnownTypes wellKnownTypes, S
100100

101101
EmitterContext.HasEndpointParameterMetadataProvider = Parameters.Any(p => p.IsEndpointParameterMetadataProvider);
102102
EmitterContext.HasEndpointMetadataProvider = Response!.IsEndpointMetadataProvider || Parameters.Any(p => p.IsEndpointMetadataProvider || p.IsEndpointParameterMetadataProvider);
103-
104-
EmitterContext.HasFormBody = Parameters.Any(parameter => parameter.Source == EndpointParameterSource.FormBody);
105-
EmitterContext.HasRouteOrQuery = Parameters.Any(parameter => parameter.Source == EndpointParameterSource.RouteOrQuery || (parameter.Source == EndpointParameterSource.AsParameters && parameter.EndpointParameters.Any(p => p.Item2.Source == EndpointParameterSource.RouteOrQuery)));
106-
EmitterContext.HasBindAsync = Parameters.Any(parameter => parameter.Source == EndpointParameterSource.BindAsync);
107-
EmitterContext.HasParsable = Parameters.Any(parameter => parameter.IsParsable || (parameter.Source == EndpointParameterSource.AsParameters && parameter.EndpointParameters.Any(p => p.Item2.IsParsable)));
103+
EmitterContext.HasParsable = Parameters.Any(parameter => parameter.IsParsable || (parameter.Source == EndpointParameterSource.AsParameters && parameter.EndpointParameters.Any(p => p.IsParsable)));
108104
EmitterContext.RequiresLoggingHelper = !Parameters.All(parameter =>
109105
parameter.Source == EndpointParameterSource.SpecialType ||
110106
parameter is { IsArray: true, ElementType.SpecialType: SpecialType.System_String, Source: EndpointParameterSource.Query });
@@ -114,7 +110,7 @@ public Endpoint(IInvocationOperation operation, WellKnownTypes wellKnownTypes, S
114110
public bool IsAwaitable { get; }
115111
public bool NeedsParameterArray { get; }
116112
public string? RoutePattern { get; }
117-
public EmitterContext EmitterContext { get; }
113+
public EmitterContext EmitterContext { get; }
118114
public EndpointResponse? Response { get; }
119115
public EndpointParameter[] Parameters { get; } = Array.Empty<EndpointParameter>();
120116
public List<Diagnostic> Diagnostics { get; } = new List<Diagnostic>();

0 commit comments

Comments
 (0)