refactor(generator): 优化GetNodeGenerator代码结构

- 使用语法树遍历替代字符串匹配来检测注入方法调用
- 添加IsGeneratedInjectionInvocation辅助方法提高代码可读性
- 将字段分组逻辑从列表查找改为字典映射提升性能
- 优化GroupByContainingType方法的时间复杂度
This commit is contained in:
GeWuYou 2026-03-22 15:23:51 +08:00
parent 9ab09cf47b
commit b95c65a30e

View File

@ -270,20 +270,34 @@ public sealed class GetNodeGenerator : IIncrementalGenerator
if (syntaxReference.GetSyntax() is not MethodDeclarationSyntax methodSyntax) if (syntaxReference.GetSyntax() is not MethodDeclarationSyntax methodSyntax)
continue; continue;
var bodyText = methodSyntax.Body?.ToString(); if (methodSyntax.DescendantNodes()
if (!string.IsNullOrEmpty(bodyText) && .OfType<InvocationExpressionSyntax>()
bodyText.Contains(InjectionMethodName, StringComparison.Ordinal)) .Any(IsGeneratedInjectionInvocation))
return true;
var expressionBodyText = methodSyntax.ExpressionBody?.ToString();
if (!string.IsNullOrEmpty(expressionBodyText) &&
expressionBodyText.Contains(InjectionMethodName, StringComparison.Ordinal))
return true; return true;
} }
return false; return false;
} }
private static bool IsGeneratedInjectionInvocation(InvocationExpressionSyntax invocation)
{
switch (invocation.Expression)
{
case IdentifierNameSyntax identifierName:
return string.Equals(
identifierName.Identifier.ValueText,
InjectionMethodName,
StringComparison.Ordinal);
case MemberAccessExpressionSyntax memberAccess:
return string.Equals(
memberAccess.Name.Identifier.ValueText,
InjectionMethodName,
StringComparison.Ordinal);
default:
return false;
}
}
private static bool ResolveRequired(AttributeData attribute) private static bool ResolveRequired(AttributeData attribute)
{ {
return attribute.GetNamedArgument("Required", true); return attribute.GetNamedArgument("Required", true);
@ -479,23 +493,23 @@ public sealed class GetNodeGenerator : IIncrementalGenerator
private static IReadOnlyList<TypeGroup> GroupByContainingType(IEnumerable<FieldCandidate> candidates) private static IReadOnlyList<TypeGroup> GroupByContainingType(IEnumerable<FieldCandidate> candidates)
{ {
var groups = new List<TypeGroup>(); var groupMap = new Dictionary<INamedTypeSymbol, TypeGroup>(SymbolEqualityComparer.Default);
var orderedGroups = new List<TypeGroup>();
foreach (var candidate in candidates) foreach (var candidate in candidates)
{ {
var group = groups.FirstOrDefault(existing => var typeSymbol = candidate.FieldSymbol.ContainingType;
SymbolEqualityComparer.Default.Equals(existing.TypeSymbol, candidate.FieldSymbol.ContainingType)); if (!groupMap.TryGetValue(typeSymbol, out var group))
if (group is null)
{ {
group = new TypeGroup(candidate.FieldSymbol.ContainingType); group = new TypeGroup(typeSymbol);
groups.Add(group); groupMap.Add(typeSymbol, group);
orderedGroups.Add(group);
} }
group.Fields.Add(candidate); group.Fields.Add(candidate);
} }
return groups; return orderedGroups;
} }
private sealed class FieldCandidate private sealed class FieldCandidate