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 . Threading ;
4
5
using Microsoft . CodeAnalysis . CSharp . Syntax ;
5
6
using Microsoft . CodeAnalysis . Operations ;
6
7
using Microsoft . CodeAnalysis ;
7
- using System . Threading ;
8
8
9
9
namespace Microsoft . Extensions . Configuration . Binder . SourceGeneration
10
10
{
@@ -15,8 +15,9 @@ internal sealed record BinderInvocation
15
15
16
16
public static BinderInvocation ? Create ( GeneratorSyntaxContext context , CancellationToken cancellationToken )
17
17
{
18
- if ( context . Node is not InvocationExpressionSyntax { Expression : MemberAccessExpressionSyntax } invocationSyntax ||
19
- context . SemanticModel . GetOperation ( invocationSyntax , cancellationToken ) is not IInvocationOperation operation )
18
+ if ( ! IsCandidateInvocationExpressionSyntax ( context . Node , out InvocationExpressionSyntax ? invocationSyntax ) ||
19
+ context . SemanticModel . GetOperation ( invocationSyntax , cancellationToken ) is not IInvocationOperation operation ||
20
+ ! IsCandidateInvocation ( operation ) )
20
21
{
21
22
return null ;
22
23
}
@@ -27,5 +28,72 @@ internal sealed record BinderInvocation
27
28
Location = invocationSyntax . GetLocation ( )
28
29
} ;
29
30
}
31
+
32
+ private static bool IsCandidateInvocationExpressionSyntax ( SyntaxNode node , out InvocationExpressionSyntax ? invocationSyntax )
33
+ {
34
+ if ( node is InvocationExpressionSyntax
35
+ {
36
+ Expression : MemberAccessExpressionSyntax
37
+ {
38
+ Name . Identifier . ValueText : string memberName
39
+ }
40
+ } syntax && IsCandidateBindingMethodName ( memberName ) )
41
+ {
42
+ invocationSyntax = syntax ;
43
+ return true ;
44
+ }
45
+
46
+ invocationSyntax = null ;
47
+ return false ;
48
+
49
+ static bool IsCandidateBindingMethodName ( string name ) =>
50
+ IsCandidateMethodName_ConfigurationBinder ( name ) ||
51
+ IsCandidateMethodName_OptionsBuilderConfigurationExtensions ( name ) ||
52
+ IsValidMethodName_OptionsConfigurationServiceCollectionExtensions ( name ) ;
53
+ }
54
+
55
+ private static bool IsCandidateInvocation ( IInvocationOperation operation )
56
+ {
57
+ if ( operation . TargetMethod is not IMethodSymbol
58
+ {
59
+ IsExtensionMethod : true ,
60
+ Name : string methodName ,
61
+ ContainingType : ITypeSymbol
62
+ {
63
+ Name : string containingTypeName ,
64
+ ContainingNamespace : INamespaceSymbol { } containingNamespace ,
65
+ } containingType
66
+ } method ||
67
+ containingNamespace . ToDisplayString ( ) is not string containingNamespaceName )
68
+ {
69
+ return false ;
70
+ }
71
+
72
+ return ( containingTypeName ) switch
73
+ {
74
+ "ConfigurationBinder" =>
75
+ containingNamespaceName is "Microsoft.Extensions.Configuration" &&
76
+ IsCandidateMethodName_ConfigurationBinder ( methodName ) ,
77
+ "OptionsBuilderConfigurationExtensions" =>
78
+ containingNamespaceName is "Microsoft.Extensions.DependencyInjection" &&
79
+ IsCandidateMethodName_OptionsBuilderConfigurationExtensions ( methodName ) ,
80
+ "OptionsConfigurationServiceCollectionExtensions" =>
81
+ containingNamespaceName is "Microsoft.Extensions.DependencyInjection" &&
82
+ IsValidMethodName_OptionsConfigurationServiceCollectionExtensions ( methodName ) ,
83
+ _ => false ,
84
+ } ;
85
+ }
86
+
87
+ private static bool IsCandidateMethodName_ConfigurationBinder ( string name ) => name is
88
+ nameof ( MethodsToGen_ConfigurationBinder . Bind ) or
89
+ nameof ( MethodsToGen_ConfigurationBinder . Get ) or
90
+ nameof ( MethodsToGen_ConfigurationBinder . GetValue ) ;
91
+
92
+ private static bool IsCandidateMethodName_OptionsBuilderConfigurationExtensions ( string name ) => name is
93
+ nameof ( MethodsToGen_Extensions_OptionsBuilder . Bind ) or
94
+ nameof ( MethodsToGen_Extensions_OptionsBuilder . BindConfiguration ) ;
95
+
96
+ private static bool IsValidMethodName_OptionsConfigurationServiceCollectionExtensions ( string name ) => name is
97
+ nameof ( MethodsToGen_Extensions_ServiceCollection . Configure ) ;
30
98
}
31
99
}
0 commit comments