refactor(generator): 重构上下文获取生成器的代码结构

- 将 ContextSymbols 的创建提取为独立方法 CreateContextSymbols
- 将源码生成逻辑提取为独立方法 GenerateSources
- 将绑定收集逻辑提取为独立方法 CollectBindings
- 将显式绑定添加逻辑提取为独立方法 AddExplicitBindings
- 将推断绑定添加逻辑提取为独立方法 AddInferredBindings
- 将绑定推断检查逻辑提取为独立方法 CanInferBinding
- 优化了代码组织结构和可读性
This commit is contained in:
GeWuYou 2026-03-28 11:47:59 +08:00
parent 78af119f38
commit ee2936e0a2

View File

@ -171,11 +171,22 @@ public sealed class ContextGetGenerator : IIncrementalGenerator
var descriptors = ResolveBindingDescriptors(compilation); var descriptors = ResolveBindingDescriptors(compilation);
var getAllAttribute = compilation.GetTypeByMetadataName(GetAllAttributeMetadataName); var getAllAttribute = compilation.GetTypeByMetadataName(GetAllAttributeMetadataName);
if (descriptors.Length == 0 && getAllAttribute is null) if (descriptors.Length == 0 && getAllAttribute is null)
return; return;
var symbols = new ContextSymbols( var symbols = CreateContextSymbols(compilation);
var workItems = CollectWorkItems(
fieldCandidates,
typeCandidates,
descriptors,
getAllAttribute);
GenerateSources(context, descriptors, symbols, workItems);
}
private static ContextSymbols CreateContextSymbols(Compilation compilation)
{
return new ContextSymbols(
compilation.GetTypeByMetadataName(ContextAwareAttributeMetadataName), compilation.GetTypeByMetadataName(ContextAwareAttributeMetadataName),
compilation.GetTypeByMetadataName(IContextAwareMetadataName), compilation.GetTypeByMetadataName(IContextAwareMetadataName),
compilation.GetTypeByMetadataName(ContextAwareBaseMetadataName), compilation.GetTypeByMetadataName(ContextAwareBaseMetadataName),
@ -184,83 +195,20 @@ public sealed class ContextGetGenerator : IIncrementalGenerator
compilation.GetTypeByMetadataName(IUtilityMetadataName), compilation.GetTypeByMetadataName(IUtilityMetadataName),
compilation.GetTypeByMetadataName(IReadOnlyListMetadataName), compilation.GetTypeByMetadataName(IReadOnlyListMetadataName),
compilation.GetTypeByMetadataName(GodotNodeMetadataName)); compilation.GetTypeByMetadataName(GodotNodeMetadataName));
}
var workItems = CollectWorkItems( private static void GenerateSources(
fieldCandidates, SourceProductionContext context,
typeCandidates, ImmutableArray<ResolvedBindingDescriptor> descriptors,
descriptors, ContextSymbols symbols,
getAllAttribute); Dictionary<INamedTypeSymbol, TypeWorkItem> workItems)
{
foreach (var workItem in workItems.Values) foreach (var workItem in workItems.Values)
{ {
if (!CanGenerateForType(context, workItem, symbols)) if (!CanGenerateForType(context, workItem, symbols))
continue; continue;
var bindings = new List<BindingInfo>(); var bindings = CollectBindings(context, workItem, descriptors, symbols);
var explicitFields = new HashSet<IFieldSymbol>(SymbolEqualityComparer.Default);
foreach (var candidate in workItem.FieldCandidates
.OrderBy(static candidate => candidate.Variable.SpanStart)
.ThenBy(static candidate => candidate.FieldSymbol.Name, StringComparer.Ordinal))
{
var matches = ResolveExplicitBindings(candidate.FieldSymbol, descriptors);
if (matches.Length == 0)
continue;
explicitFields.Add(candidate.FieldSymbol);
if (matches.Length > 1)
{
ReportFieldDiagnostic(
context,
ContextGetDiagnostics.MultipleBindingAttributesNotSupported,
candidate);
continue;
}
if (!TryCreateExplicitBinding(
context,
candidate,
matches[0],
symbols,
out var binding))
continue;
bindings.Add(binding);
}
if (workItem.GetAllDeclaration is not null)
{
foreach (var field in GetAllFields(workItem.TypeSymbol))
{
if (explicitFields.Contains(field))
continue;
if (field.IsStatic)
{
ReportFieldDiagnostic(
context,
ContextGetDiagnostics.StaticFieldNotSupported,
field);
continue;
}
if (field.IsReadOnly)
{
ReportFieldDiagnostic(
context,
ContextGetDiagnostics.ReadOnlyFieldNotSupported,
field);
continue;
}
if (!TryCreateInferredBinding(field, symbols, out var binding))
continue;
bindings.Add(binding);
}
}
if (bindings.Count == 0 && workItem.GetAllDeclaration is null) if (bindings.Count == 0 && workItem.GetAllDeclaration is null)
continue; continue;
@ -269,6 +217,106 @@ public sealed class ContextGetGenerator : IIncrementalGenerator
} }
} }
private static List<BindingInfo> CollectBindings(
SourceProductionContext context,
TypeWorkItem workItem,
ImmutableArray<ResolvedBindingDescriptor> descriptors,
ContextSymbols symbols)
{
var bindings = new List<BindingInfo>();
var explicitFields = new HashSet<IFieldSymbol>(SymbolEqualityComparer.Default);
AddExplicitBindings(context, workItem, descriptors, symbols, bindings, explicitFields);
AddInferredBindings(context, workItem, symbols, bindings, explicitFields);
return bindings;
}
private static void AddExplicitBindings(
SourceProductionContext context,
TypeWorkItem workItem,
ImmutableArray<ResolvedBindingDescriptor> descriptors,
ContextSymbols symbols,
ICollection<BindingInfo> bindings,
ISet<IFieldSymbol> explicitFields)
{
foreach (var candidate in workItem.FieldCandidates
.OrderBy(static candidate => candidate.Variable.SpanStart)
.ThenBy(static candidate => candidate.FieldSymbol.Name, StringComparer.Ordinal))
{
var matches = ResolveExplicitBindings(candidate.FieldSymbol, descriptors);
if (matches.Length == 0)
continue;
explicitFields.Add(candidate.FieldSymbol);
if (matches.Length > 1)
{
ReportFieldDiagnostic(
context,
ContextGetDiagnostics.MultipleBindingAttributesNotSupported,
candidate);
continue;
}
if (!TryCreateExplicitBinding(
context,
candidate,
matches[0],
symbols,
out var binding))
continue;
bindings.Add(binding);
}
}
private static void AddInferredBindings(
SourceProductionContext context,
TypeWorkItem workItem,
ContextSymbols symbols,
ICollection<BindingInfo> bindings,
ISet<IFieldSymbol> explicitFields)
{
if (workItem.GetAllDeclaration is null)
return;
foreach (var field in GetAllFields(workItem.TypeSymbol))
{
if (explicitFields.Contains(field))
continue;
if (!CanInferBinding(context, field))
continue;
if (!TryCreateInferredBinding(field, symbols, out var binding))
continue;
bindings.Add(binding);
}
}
private static bool CanInferBinding(SourceProductionContext context, IFieldSymbol field)
{
if (field.IsStatic)
{
ReportFieldDiagnostic(
context,
ContextGetDiagnostics.StaticFieldNotSupported,
field);
return false;
}
if (!field.IsReadOnly)
return true;
ReportFieldDiagnostic(
context,
ContextGetDiagnostics.ReadOnlyFieldNotSupported,
field);
return false;
}
private static Dictionary<INamedTypeSymbol, TypeWorkItem> CollectWorkItems( private static Dictionary<INamedTypeSymbol, TypeWorkItem> CollectWorkItems(
ImmutableArray<FieldCandidateInfo?> fieldCandidates, ImmutableArray<FieldCandidateInfo?> fieldCandidates,
ImmutableArray<TypeCandidateInfo?> typeCandidates, ImmutableArray<TypeCandidateInfo?> typeCandidates,