1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
+
3
4
using System ;
4
5
using System . Collections . Generic ;
5
6
using System . Linq ;
@@ -12,61 +13,118 @@ namespace Microsoft.AspNetCore.Http.Generators.StaticRouteHandlerModel;
12
13
13
14
internal class Endpoint
14
15
{
15
- public string HttpMethod { get ; }
16
- public EndpointRoute Route { get ; }
17
- public EndpointResponse Response { get ; }
18
- public List < DiagnosticDescriptor > Diagnostics { get ; } = new List < DiagnosticDescriptor > ( ) ;
19
- public ( string , int ) Location { get ; }
20
- public IInvocationOperation Operation { get ; }
21
-
22
- private WellKnownTypes WellKnownTypes { get ; }
16
+ private string ? _argumentListCache ;
23
17
24
18
public Endpoint ( IInvocationOperation operation , WellKnownTypes wellKnownTypes )
25
19
{
26
20
Operation = operation ;
27
- WellKnownTypes = wellKnownTypes ;
28
- Location = GetLocation ( ) ;
29
- HttpMethod = GetHttpMethod ( ) ;
30
- Response = new EndpointResponse ( Operation , wellKnownTypes ) ;
31
- Route = new EndpointRoute ( Operation ) ;
32
- }
21
+ Location = GetLocation ( operation ) ;
22
+ HttpMethod = GetHttpMethod ( operation ) ;
33
23
34
- private ( string , int ) GetLocation ( )
35
- {
36
- var filePath = Operation . Syntax . SyntaxTree . FilePath ;
37
- var span = Operation . Syntax . SyntaxTree . GetLineSpan ( Operation . Syntax . Span ) ;
38
- var lineNumber = span . EndLinePosition . Line + 1 ;
39
- return ( filePath , lineNumber ) ;
40
- }
24
+ if ( ! operation . TryGetRouteHandlerPattern ( out var routeToken ) )
25
+ {
26
+ Diagnostics . Add ( DiagnosticDescriptors . UnableToResolveRoutePattern ) ;
27
+ return ;
28
+ }
41
29
42
- private string GetHttpMethod ( )
43
- {
44
- var syntax = ( InvocationExpressionSyntax ) Operation . Syntax ;
45
- var expression = ( MemberAccessExpressionSyntax ) syntax . Expression ;
46
- var name = ( IdentifierNameSyntax ) expression . Name ;
47
- var identifier = name . Identifier ;
48
- return identifier . ValueText ;
30
+ RoutePattern = routeToken . ValueText ;
31
+
32
+ if ( ! operation . TryGetRouteHandlerMethod ( out var method ) )
33
+ {
34
+ Diagnostics . Add ( DiagnosticDescriptors . UnableToResolveMethod ) ;
35
+ return ;
36
+ }
37
+
38
+ Response = new EndpointResponse ( method , wellKnownTypes ) ;
39
+
40
+ if ( method . Parameters . Length == 0 )
41
+ {
42
+ return ;
43
+ }
44
+
45
+ var parameters = new EndpointParameter [ method . Parameters . Length ] ;
46
+
47
+ for ( var i = 0 ; i < method . Parameters . Length ; i ++ )
48
+ {
49
+ var parameter = new EndpointParameter ( method . Parameters [ i ] , wellKnownTypes ) ;
50
+
51
+ if ( parameter . Source == EndpointParameterSource . Unknown )
52
+ {
53
+ Diagnostics . Add ( DiagnosticDescriptors . GetUnableToResolveParameterDescriptor ( parameter . Name ) ) ;
54
+ return ;
55
+ }
56
+
57
+ parameters [ i ] = parameter ;
58
+ }
59
+
60
+ Parameters = parameters ;
49
61
}
50
62
51
- public override bool Equals ( object o )
63
+ public string HttpMethod { get ; }
64
+ public string ? RoutePattern { get ; }
65
+ public EndpointResponse ? Response { get ; }
66
+ public EndpointParameter [ ] Parameters { get ; } = Array . Empty < EndpointParameter > ( ) ;
67
+ public string EmitArgumentList ( ) => _argumentListCache ??= string . Join ( ", " , Parameters . Select ( p => p . EmitArgument ( ) ) ) ;
68
+
69
+ public List < DiagnosticDescriptor > Diagnostics { get ; } = new List < DiagnosticDescriptor > ( ) ;
70
+
71
+ public ( string File , int LineNumber ) Location { get ; }
72
+ public IInvocationOperation Operation { get ; }
73
+
74
+ public override bool Equals ( object o ) =>
75
+ o is Endpoint other && Location == other . Location && SignatureEquals ( this , other ) ;
76
+
77
+ public override int GetHashCode ( ) =>
78
+ HashCode . Combine ( Location , GetSignatureHashCode ( this ) ) ;
79
+
80
+ public static bool SignatureEquals ( Endpoint a , Endpoint b )
52
81
{
53
- if ( o is null )
82
+ if ( ! a . Response . WrappedResponseType . Equals ( b . Response . WrappedResponseType , StringComparison . Ordinal ) ||
83
+ ! a . HttpMethod . Equals ( b . HttpMethod , StringComparison . Ordinal ) ||
84
+ a . Parameters . Length != b . Parameters . Length )
54
85
{
55
86
return false ;
56
87
}
57
88
58
- if ( o is Endpoint endpoint )
89
+ for ( var i = 0 ; i < a . Parameters . Length ; i ++ )
59
90
{
60
- return endpoint . HttpMethod . Equals ( HttpMethod , StringComparison . OrdinalIgnoreCase ) &&
61
- endpoint . Location . Item1 . Equals ( Location . Item1 , StringComparison . OrdinalIgnoreCase ) &&
62
- endpoint . Location . Item2 . Equals ( Location . Item2 ) &&
63
- endpoint . Response . Equals ( Response ) &&
64
- endpoint . Diagnostics . SequenceEqual ( Diagnostics ) ;
91
+ if ( a . Parameters [ i ] . Equals ( b . Parameters [ i ] ) )
92
+ {
93
+ return false ;
94
+ }
65
95
}
66
96
67
- return false ;
97
+ return true ;
68
98
}
69
99
70
- public override int GetHashCode ( ) =>
71
- HashCode . Combine ( HttpMethod , Route , Location , Response , Diagnostics ) ;
100
+ public static int GetSignatureHashCode ( Endpoint endpoint )
101
+ {
102
+ var hashCode = new HashCode ( ) ;
103
+ hashCode . Add ( endpoint . Response . WrappedResponseType ) ;
104
+ hashCode . Add ( endpoint . HttpMethod ) ;
105
+
106
+ foreach ( var parameter in endpoint . Parameters )
107
+ {
108
+ hashCode . Add ( parameter ) ;
109
+ }
110
+
111
+ return hashCode . ToHashCode ( ) ;
112
+ }
113
+
114
+ private static ( string , int ) GetLocation ( IInvocationOperation operation )
115
+ {
116
+ var filePath = operation . Syntax . SyntaxTree . FilePath ;
117
+ var span = operation . Syntax . SyntaxTree . GetLineSpan ( operation . Syntax . Span ) ;
118
+ var lineNumber = span . StartLinePosition . Line + 1 ;
119
+ return ( filePath , lineNumber ) ;
120
+ }
121
+
122
+ private static string GetHttpMethod ( IInvocationOperation operation )
123
+ {
124
+ var syntax = ( InvocationExpressionSyntax ) operation . Syntax ;
125
+ var expression = ( MemberAccessExpressionSyntax ) syntax . Expression ;
126
+ var name = ( IdentifierNameSyntax ) expression . Name ;
127
+ var identifier = name . Identifier ;
128
+ return identifier . ValueText ;
129
+ }
72
130
}
0 commit comments