Skip to content

Commit 265bf07

Browse files
committed
Optimize generator by checking invocations in the predicate
Rather than on the transform. This should reduce the amount of invocations to the transform delegate and improve performance.
1 parent e7ba415 commit 265bf07

File tree

1 file changed

+9
-13
lines changed

1 file changed

+9
-13
lines changed

src/DependencyInjection/IncrementalGenerator.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ bool IsExport(AttributeData attr)
141141
// First get all AddServices(type, regex, lifetime) invocations.
142142
var methodInvocations = context.SyntaxProvider
143143
.CreateSyntaxProvider(
144-
predicate: static (node, _) => node is InvocationExpressionSyntax,
144+
predicate: static (node, _) => node is InvocationExpressionSyntax invocation && invocation.ArgumentList.Arguments.Count != 0 && GetInvokedMethodName(invocation) == nameof(AddServicesNoReflectionExtension.AddServices),
145145
transform: static (ctx, _) => GetServiceRegistration((InvocationExpressionSyntax)ctx.Node, ctx.SemanticModel))
146146
.Where(details => details != null)
147147
.Collect();
@@ -205,21 +205,17 @@ void RegisterServicesOutput(IncrementalGeneratorInitializationContext context, I
205205
(ctx, data) => AddPartial("AddKeyedTransient", ctx, data));
206206
}
207207

208-
static ServiceRegistration? GetServiceRegistration(InvocationExpressionSyntax invocation, SemanticModel semanticModel)
208+
static string? GetInvokedMethodName(InvocationExpressionSyntax invocation) => invocation.Expression switch
209209
{
210-
static string? GetInvokedMethodName(InvocationExpressionSyntax invocation) => invocation.Expression switch
211-
{
212-
MemberAccessExpressionSyntax memberAccess => memberAccess.Name.Identifier.Text,
213-
IdentifierNameSyntax identifierName => identifierName.Identifier.Text,
214-
_ => null
215-
};
216-
217-
// Quick checks first without semantic analysis of any kind.
218-
if (invocation.ArgumentList.Arguments.Count == 0 || GetInvokedMethodName(invocation) != nameof(AddServicesNoReflectionExtension.AddServices))
219-
return null;
210+
MemberAccessExpressionSyntax memberAccess => memberAccess.Name.Identifier.Text,
211+
IdentifierNameSyntax identifierName => identifierName.Identifier.Text,
212+
_ => null
213+
};
220214

215+
static ServiceRegistration? GetServiceRegistration(InvocationExpressionSyntax invocation, SemanticModel semanticModel)
216+
{
221217
// This is somewhat expensive, so we try to first discard invocations that don't look like our
222-
// target first (no args and wrong method name), before moving on to semantic analyis.
218+
// target first (no args and wrong method name), in the predicate, before moving on to semantic analyis here.
223219

224220
var options = (CSharpParseOptions)invocation.SyntaxTree.Options;
225221

0 commit comments

Comments
 (0)