diff --git a/src/DependencyInjection/IncrementalGenerator.cs b/src/DependencyInjection/IncrementalGenerator.cs index cb43e79..3f1dc36 100644 --- a/src/DependencyInjection/IncrementalGenerator.cs +++ b/src/DependencyInjection/IncrementalGenerator.cs @@ -141,7 +141,7 @@ bool IsExport(AttributeData attr) // First get all AddServices(type, regex, lifetime) invocations. var methodInvocations = context.SyntaxProvider .CreateSyntaxProvider( - predicate: static (node, _) => node is InvocationExpressionSyntax, + predicate: static (node, _) => node is InvocationExpressionSyntax invocation && invocation.ArgumentList.Arguments.Count != 0 && GetInvokedMethodName(invocation) == nameof(AddServicesNoReflectionExtension.AddServices), transform: static (ctx, _) => GetServiceRegistration((InvocationExpressionSyntax)ctx.Node, ctx.SemanticModel)) .Where(details => details != null) .Collect(); @@ -205,21 +205,17 @@ void RegisterServicesOutput(IncrementalGeneratorInitializationContext context, I (ctx, data) => AddPartial("AddKeyedTransient", ctx, data)); } - static ServiceRegistration? GetServiceRegistration(InvocationExpressionSyntax invocation, SemanticModel semanticModel) + static string? GetInvokedMethodName(InvocationExpressionSyntax invocation) => invocation.Expression switch { - static string? GetInvokedMethodName(InvocationExpressionSyntax invocation) => invocation.Expression switch - { - MemberAccessExpressionSyntax memberAccess => memberAccess.Name.Identifier.Text, - IdentifierNameSyntax identifierName => identifierName.Identifier.Text, - _ => null - }; - - // Quick checks first without semantic analysis of any kind. - if (invocation.ArgumentList.Arguments.Count == 0 || GetInvokedMethodName(invocation) != nameof(AddServicesNoReflectionExtension.AddServices)) - return null; + MemberAccessExpressionSyntax memberAccess => memberAccess.Name.Identifier.Text, + IdentifierNameSyntax identifierName => identifierName.Identifier.Text, + _ => null + }; + static ServiceRegistration? GetServiceRegistration(InvocationExpressionSyntax invocation, SemanticModel semanticModel) + { // This is somewhat expensive, so we try to first discard invocations that don't look like our - // target first (no args and wrong method name), before moving on to semantic analyis. + // target first (no args and wrong method name), in the predicate, before moving on to semantic analyis here. var options = (CSharpParseOptions)invocation.SyntaxTree.Options;