未验证 提交 65b696cf 编写于 作者: G github-actions[bot] 提交者: GitHub

Filter list of candidate invocations for parsing in binding generator (#89266)

Co-authored-by: NLayomi Akinrinade <laakinri@microsoft.com>
上级 77f7f9ec
......@@ -111,7 +111,9 @@ internal enum MethodsToGen_Extensions_OptionsBuilder
// Method group. BindConfiguration_T is its own method group.
Bind = Bind_T | Bind_T_BinderOptions,
Any = Bind | BindConfiguration_T_path_BinderOptions,
BindConfiguration = BindConfiguration_T_path_BinderOptions,
Any = Bind | BindConfiguration,
}
/// <summary>
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.CodeAnalysis;
using System.Threading;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
......@@ -15,8 +15,9 @@ internal sealed record BinderInvocation
public static BinderInvocation? Create(GeneratorSyntaxContext context, CancellationToken cancellationToken)
{
if (context.Node is not InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax } invocationSyntax ||
context.SemanticModel.GetOperation(invocationSyntax, cancellationToken) is not IInvocationOperation operation)
if (!IsCandidateInvocationExpressionSyntax(context.Node, out InvocationExpressionSyntax? invocationSyntax) ||
context.SemanticModel.GetOperation(invocationSyntax, cancellationToken) is not IInvocationOperation operation ||
!IsCandidateInvocation(operation))
{
return null;
}
......@@ -27,5 +28,72 @@ internal sealed record BinderInvocation
Location = invocationSyntax.GetLocation()
};
}
private static bool IsCandidateInvocationExpressionSyntax(SyntaxNode node, out InvocationExpressionSyntax? invocationSyntax)
{
if (node is InvocationExpressionSyntax
{
Expression: MemberAccessExpressionSyntax
{
Name.Identifier.ValueText: string memberName
}
} syntax && IsCandidateBindingMethodName(memberName))
{
invocationSyntax = syntax;
return true;
}
invocationSyntax = null;
return false;
static bool IsCandidateBindingMethodName(string name) =>
IsCandidateMethodName_ConfigurationBinder(name) ||
IsCandidateMethodName_OptionsBuilderConfigurationExtensions(name) ||
IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(name);
}
private static bool IsCandidateInvocation(IInvocationOperation operation)
{
if (operation.TargetMethod is not IMethodSymbol
{
IsExtensionMethod: true,
Name: string methodName,
ContainingType: ITypeSymbol
{
Name: string containingTypeName,
ContainingNamespace: INamespaceSymbol { } containingNamespace,
} containingType
} method ||
containingNamespace.ToDisplayString() is not string containingNamespaceName)
{
return false;
}
return (containingTypeName) switch
{
"ConfigurationBinder" =>
containingNamespaceName is "Microsoft.Extensions.Configuration" &&
IsCandidateMethodName_ConfigurationBinder(methodName),
"OptionsBuilderConfigurationExtensions" =>
containingNamespaceName is "Microsoft.Extensions.DependencyInjection" &&
IsCandidateMethodName_OptionsBuilderConfigurationExtensions(methodName),
"OptionsConfigurationServiceCollectionExtensions" =>
containingNamespaceName is "Microsoft.Extensions.DependencyInjection" &&
IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(methodName),
_ => false,
};
}
private static bool IsCandidateMethodName_ConfigurationBinder(string name) => name is
nameof(MethodsToGen_ConfigurationBinder.Bind) or
nameof(MethodsToGen_ConfigurationBinder.Get) or
nameof(MethodsToGen_ConfigurationBinder.GetValue);
private static bool IsCandidateMethodName_OptionsBuilderConfigurationExtensions(string name) => name is
nameof(MethodsToGen_Extensions_OptionsBuilder.Bind) or
nameof(MethodsToGen_Extensions_OptionsBuilder.BindConfiguration);
private static bool IsValidMethodName_OptionsConfigurationServiceCollectionExtensions(string name) => name is
nameof(MethodsToGen_Extensions_ServiceCollection.Configure);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册