Skip to content

Add initial parameter support to RequestDelegateGenerator #46407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 7, 2023

Conversation

halter73
Copy link
Member

@halter73 halter73 commented Feb 2, 2023

  • The only supported EndpointParameterSources are initially "SpecialTypes" like HttpRequest and CancellationToken.

Partially address #46275

@halter73 halter73 changed the title Add support for response writing to RequestDelegateGenerator Add initial parameter support to RequestDelegateGenerator Feb 2, 2023

if (!operation.TryGetRouteHandlerPattern(out var routeToken))
{
Diagnostics.Add(DiagnosticDescriptors.UnableToResolveRoutePattern);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm inclined to have each component of the model maintain its own diagnostics. As we build up the diagnostics we emit, it'll make it easier to warn for specific scenarios that might not be immediately accessible at the top-level.

For example, let's say that we find a TryParse method on a parameter that doesn't have the correct signature. It would be easier to read and track if we were to capture that diagnostic when we're constructing the parameter instead of bubbling it up and capturing them all at the top.

The downside is it does make the code to aggregate them all when we emit a little honky but that seems worth it for the benefits of having diagnostics localized to where they would be thrown (similar to an exception).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to give EndpointParameter a backreference to Endpoints.Diagnostics if we want to capture the diagnostic while constructing the parameter. I just didn't like greedily creating a list for each small component even though it's not that expensive. The aggregation and repeated declarations were kind of verbose too as you say.

@mkArtakMSFT mkArtakMSFT added the old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Feb 2, 2023
Base automatically changed from safia/rdg-responses to main February 3, 2023 01:40
@captainsafia
Copy link
Member

captainsafia commented Feb 6, 2023

@halter73 Thoughts on rebasing this and taking it out of draft?

@halter73
Copy link
Member Author

halter73 commented Feb 6, 2023

@halter73 Thoughts on rebasing this and taking it out of draft?

I'm doing that now.

@mitchdenny
Copy link
Member

@halter73 Thoughts on rebasing this and taking it out of draft?

Was going to ask the same thing as I'm keen to riff off this but didn't want to get 3 layers deep in merge conflicts ;)

- The only supported EndpointParameterSources are initially "SpecialTypes" like HttpRequest and CancellationToken.

# Conflicts:
#	src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs
#	src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Endpoint.cs
#	src/Http/Http.Extensions/gen/StaticRouteHandlerModel/EndpointResponse.cs
#	src/Http/Http.Extensions/gen/StaticRouteHandlerModel/StaticRouteHandlerModel.Emitter.cs
#	src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateGeneratorTestBase.cs
@halter73 halter73 marked this pull request as ready for review February 7, 2023 01:57
@@ -68,7 +65,7 @@ public static string EmitRequestHandler(this Endpoint endpoint)
{{handlerSignature}}
{
{{setContentType}}
{{resultAssignment}}{{awaitHandler}}handler();
{{resultAssignment}}{{awaitHandler}}handler({{endpoint.EmitArgumentList()}});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably something that will need to change when I start working on the parsing, because this list of arguments will need to be mapped to a set of local variables which are injected beforehand to store the results of the appropriate TryParse(...) operation.

Copy link
Member

@mitchdenny mitchdenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I think it is something that would be good to get in and start iterating on.

@@ -7,19 +7,39 @@ internal static class WellKnownTypeData
{
public enum WellKnownType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the other classes internal even though I don't think it matters much in a source generator/analzyer. This one I didn't bother with since it's inside of internal static class WellKnownTypeData, and I want to move this to the top level in another PR anyway.

}
}

// TODO: Handle special form types like IFormFileCollection that need special body-reading logic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for curiosity, what is your idea about form types? Probably you'll need to track them to call ReadFormAsync somewhere, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It will be similar to JSON bodies, BindAsync, and even TryParse handling.

@halter73
Copy link
Member Author

halter73 commented Feb 7, 2023

There's definitely follow up work, but I think this is in a good state to merge. Can someone please approve this PR?

@halter73
Copy link
Member Author

halter73 commented Feb 7, 2023

I noticed a bug when testing with the MinimalSample where we were using the StartLinePosition instead of EndLinePostion. This could lead to KeyNotFoundException's at startup like the following.

Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key '(C:\dev\dotnet\aspnetcore\src\Http\samples\MinimalSample\Program.cs, 15)' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F7174CD3CED625D68146A5AD64E1117AD1DCB273ED9FB961765E672E7C9CE3350__GeneratedRouteBuilderExtensionsCore.MapCore(IEndpointRouteBuilder routes, String pattern, Delegate handler, IEnumerable`1 httpMethods, String filePath, Int32 lineNumber) in C:\dev\dotnet\aspnetcore\src\Http\samples\MinimalSample\Microsoft.AspNetCore.Http.Generators\Microsoft.AspNetCore.Http.Generators.RequestDelegateGenerator\GeneratedRouteBuilderExtensions.g.cs:line 380
   at Microsoft.AspNetCore.Builder.GenerateRouteBuilderEndpoints.MapGet(IEndpointRouteBuilder endpoints, String pattern, Func`1 handler, String filePath, Int32 lineNumber) in C:\dev\dotnet\aspnetcore\src\Http\samples\MinimalSample\Microsoft.AspNetCore.Http.Generators\Microsoft.AspNetCore.Http.Generators.RequestDelegateGenerator\GeneratedRouteBuilderExtensions.g.cs:line 47
   at Program.<Main>$(String[] args) in C:\dev\dotnet\aspnetcore\src\Http\samples\MinimalSample\Program.cs:line 15

I added the fix along with a regression test to this already-approved PR with 258d799 (#46407).

@halter73 halter73 enabled auto-merge (squash) February 7, 2023 21:12
@halter73 halter73 merged commit c21b67c into main Feb 7, 2023
@halter73 halter73 deleted the halter73/46275-p1 branch February 7, 2023 22:53
@ghost ghost added this to the 8.0-preview2 milestone Feb 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants