修复15分钟任务Kafka主题异常的问题,新增增量源码工厂类
This commit is contained in:
parent
01264dd3ec
commit
53e6bb252a
@ -14,17 +14,14 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
|
||||
{
|
||||
private const string AttributeFullName = "JiShe.CollectBus.Analyzers.Shared.SourceAnalyzersAttribute";
|
||||
private const string SourceEntityAccessorFactoryNamespace = "JiShe.CollectBus.Analyzers.Shared";
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
//Debugger.Launch();
|
||||
|
||||
context.RegisterPostInitializationOutput(ctx =>
|
||||
{
|
||||
ctx.AddSource("GeneratorInit.g.cs", "// Initialization Marker");
|
||||
});
|
||||
|
||||
// 步骤1:筛选带有 [GenerateAccessors] 的类
|
||||
// 步骤1:筛选带有 [SourceAnalyzers] 的类
|
||||
var classDeclarations = context.SyntaxProvider
|
||||
.CreateSyntaxProvider(
|
||||
predicate: static (s, _) => IsClassWithAttribute(s),
|
||||
@ -40,7 +37,6 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
|
||||
private static bool IsClassWithAttribute(SyntaxNode node) => node is ClassDeclarationSyntax cds && cds.AttributeLists.Count > 0;
|
||||
|
||||
|
||||
private static ClassDeclarationSyntax GetClassDeclaration(GeneratorSyntaxContext context)
|
||||
{
|
||||
var classDecl = (ClassDeclarationSyntax)context.Node;
|
||||
@ -76,6 +72,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成代码
|
||||
/// </summary>
|
||||
/// <param name="compilation"></param>
|
||||
/// <param name="classes"></param>
|
||||
/// <param name="context"></param>
|
||||
private static void GenerateCode(
|
||||
Compilation compilation,
|
||||
IEnumerable<ClassDeclarationSyntax> classes,
|
||||
@ -86,8 +88,8 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
if (!classes.Any())
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
new DiagnosticDescriptor("GEN002", "No Targets",
|
||||
"No classes with [GenerateAccessors] found", "Debug", DiagnosticSeverity.Warning, true),
|
||||
new DiagnosticDescriptor("GEN002", "没有目标类",
|
||||
"没有找到SourceAnalyzers标记的类", "Debug", DiagnosticSeverity.Warning, true),
|
||||
Location.None));
|
||||
}
|
||||
|
||||
@ -99,46 +101,66 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
if (classSymbol == null || !processedTypes.Add(classSymbol))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
new DiagnosticDescriptor("GEN003", "Invalid Symbol",
|
||||
$"Class symbol is null for {classDecl.Identifier.Text}", "Error", DiagnosticSeverity.Error, true),
|
||||
new DiagnosticDescriptor("GEN003", "无效符号",
|
||||
$"类名称为{classDecl.Identifier.Text} 符号为空", "Error", DiagnosticSeverity.Error, true),
|
||||
Location.None));
|
||||
continue;
|
||||
}
|
||||
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
new DiagnosticDescriptor(
|
||||
"PA001",
|
||||
"Generated Accessors",
|
||||
$"Generating accessors for {classSymbol.Name}",
|
||||
"Performance",
|
||||
DiagnosticSeverity.Info,
|
||||
true),
|
||||
Location.None));
|
||||
//context.ReportDiagnostic(Diagnostic.Create(
|
||||
//new DiagnosticDescriptor(
|
||||
// "PA001",
|
||||
// "Generated Accessors",
|
||||
// $"Generating accessors for {classSymbol.Name}",
|
||||
// "Performance",
|
||||
// DiagnosticSeverity.Info,
|
||||
// true),
|
||||
//Location.None));
|
||||
|
||||
// 新增:输出继承链信息
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
|
||||
$"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
|
||||
"Debug", DiagnosticSeverity.Info, true),
|
||||
Location.None));
|
||||
//// 新增:输出继承链信息
|
||||
//context.ReportDiagnostic(Diagnostic.Create(
|
||||
// new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
|
||||
// $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
|
||||
// "Debug", DiagnosticSeverity.Info, true),
|
||||
// Location.None));
|
||||
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
new DiagnosticDescriptor("PA002", "Class Found",
|
||||
$"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
|
||||
Location.None));
|
||||
//context.ReportDiagnostic(Diagnostic.Create(
|
||||
//new DiagnosticDescriptor("PA002", "Class Found",
|
||||
//$"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
|
||||
//Location.None));
|
||||
|
||||
var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
|
||||
//System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
|
||||
|
||||
context.AddSource($"{classSymbol.Name}Extension.g.cs", code);
|
||||
|
||||
|
||||
var code3 = BuildAccessorsForType2(classSymbol, compilation, processedTypes);
|
||||
context.AddSource($"{classSymbol.Name}Accessor.g.cs", code3);
|
||||
|
||||
//code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
|
||||
//if (classSymbol.ContainingNamespace.ToDisplayString() == "JiShe.CollectBus.IoTDB")
|
||||
//{
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
// 生成工厂注册代码
|
||||
context.AddSource("SourceEntityAccessorFactory.g.cs", BuildFactoryCode());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建类的属性访问器代码
|
||||
/// </summary>
|
||||
/// <param name="classSymbol"></param>
|
||||
/// <param name="compilation"></param>
|
||||
/// <param name="processedTypes"></param>
|
||||
/// <returns></returns>
|
||||
private static string BuildAccessorsForType(
|
||||
INamedTypeSymbol classSymbol,
|
||||
Compilation compilation,
|
||||
HashSet<ITypeSymbol> processedTypes)
|
||||
INamedTypeSymbol classSymbol,
|
||||
Compilation compilation,
|
||||
HashSet<ITypeSymbol> processedTypes)
|
||||
{
|
||||
var code = new StringBuilder();
|
||||
code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
|
||||
@ -151,25 +173,67 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
code.AppendLine($"public static class {classSymbol.Name}Extension{GetGenericParams(classSymbol)}");
|
||||
code.AppendLine("{");
|
||||
|
||||
//foreach (var prop in classSymbol.GetMembers().OfType<IPropertySymbol>())
|
||||
//{
|
||||
// if (prop.IsIndexer) continue;
|
||||
|
||||
// GeneratePropertyAccessors(prop, code, compilation, processedTypes);
|
||||
//}
|
||||
|
||||
foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
|
||||
{
|
||||
if (prop.IsIndexer) continue;
|
||||
GeneratePropertyAccessors(prop, code, compilation, processedTypes);
|
||||
GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
|
||||
}
|
||||
|
||||
code.AppendLine("}");
|
||||
return code.ToString();
|
||||
}
|
||||
|
||||
//private static string GetGenericParams(INamedTypeSymbol symbol)
|
||||
// => symbol.IsGenericType ? $"<{string.Join(", ", symbol.TypeParameters.Select(t => t.Name))}>" : "";
|
||||
/// <summary>
|
||||
/// 构建类的属性访问器代码
|
||||
/// </summary>
|
||||
/// <param name="classSymbol"></param>
|
||||
/// <param name="compilation"></param>
|
||||
/// <param name="processedTypes"></param>
|
||||
/// <returns></returns>
|
||||
private static string BuildAccessorsForType2(
|
||||
INamedTypeSymbol classSymbol,
|
||||
Compilation compilation,
|
||||
HashSet<ITypeSymbol> processedTypes)
|
||||
{
|
||||
var code = new StringBuilder();
|
||||
code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
|
||||
code.AppendLine("// Generated code for " + classSymbol.Name);
|
||||
code.AppendLine("// <auto-generated/>");
|
||||
code.AppendLine("#nullable enable");
|
||||
code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
|
||||
code.AppendLine();
|
||||
|
||||
code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>");
|
||||
code.AppendLine("{");
|
||||
|
||||
foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
|
||||
{
|
||||
if (prop.IsIndexer) continue;
|
||||
GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
|
||||
}
|
||||
|
||||
code.AppendLine("}");
|
||||
|
||||
//var code3 = $@"
|
||||
// public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>
|
||||
// {{
|
||||
// public object GetPropertyValue({classSymbol.Name} entity, string propName) => propName switch
|
||||
// {{
|
||||
// {GeneratePropertyCases(classSymbol)}
|
||||
// _ => throw new ArgumentException(""无效属性名"")
|
||||
// }};
|
||||
|
||||
// {GenerateTupleSupport(classSymbol)}
|
||||
// }}";
|
||||
|
||||
return code.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取泛型参数
|
||||
/// </summary>
|
||||
/// <param name="symbol"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetGenericParams(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (!symbol.IsGenericType) return "";
|
||||
@ -177,13 +241,20 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
return $"<{string.Join(", ", parameters)}>";
|
||||
}
|
||||
|
||||
private static void GeneratePropertyAccessors(
|
||||
/// <summary>
|
||||
/// 生成属性访问器代码
|
||||
/// </summary>
|
||||
/// <param name="prop"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="compilation"></param>
|
||||
/// <param name="processedTypes"></param>
|
||||
private static void GeneratePropertyAccessorsForType(
|
||||
IPropertySymbol prop,
|
||||
StringBuilder code,
|
||||
Compilation compilation,
|
||||
HashSet<ITypeSymbol> processedTypes)
|
||||
{
|
||||
// 关键修复点1:安全类型转换
|
||||
// 安全类型转换
|
||||
if (prop.Type is not ITypeSymbol propType) return;
|
||||
|
||||
code.AppendLine($" // Processing property: {prop.Name}");
|
||||
@ -200,6 +271,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理元组类型
|
||||
/// </summary>
|
||||
/// <param name="prop"></param>
|
||||
/// <param name="tupleType"></param>
|
||||
/// <param name="code"></param>
|
||||
private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
|
||||
{
|
||||
var elements = tupleType.TupleElements;
|
||||
@ -222,6 +299,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成标准属性的访问器
|
||||
/// </summary>
|
||||
/// <param name="prop"></param>
|
||||
/// <param name="propType"></param>
|
||||
/// <param name="code"></param>
|
||||
private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
|
||||
{
|
||||
var parentType = prop.ContainingType.ToDisplayString();
|
||||
@ -233,6 +316,13 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 处理嵌套类型
|
||||
/// </summary>
|
||||
/// <param name="typeSymbol"></param>
|
||||
/// <param name="compilation"></param>
|
||||
/// <param name="processedTypes"></param>
|
||||
private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet<ITypeSymbol> processedTypes)
|
||||
{
|
||||
if (typeSymbol is not INamedTypeSymbol namedType) return;
|
||||
@ -242,6 +332,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
var code = BuildAccessorsForType(namedType, compilation, processedTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理嵌套类型
|
||||
/// </summary>
|
||||
/// <param name="symbol"></param>
|
||||
/// <returns></returns>
|
||||
private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
|
||||
{
|
||||
return symbol.DeclaredAccessibility == Accessibility.Public &&
|
||||
@ -250,5 +345,33 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
||||
!symbol.IsImplicitlyDeclared &&
|
||||
!symbol.Name.StartsWith("<");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成扩展类工厂代码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string BuildFactoryCode()
|
||||
{
|
||||
return """
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
namespace JiShe.CollectBus.Analyzers.Shared;
|
||||
public static class SourceEntityAccessorFactory
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Type, object> _accessors = new();
|
||||
|
||||
public static ISourceEntityAccessor<T> GetAccessor<T>()
|
||||
{
|
||||
if (!_accessors.TryGetValue(typeof(T), out var accessor))
|
||||
{
|
||||
accessor = Activator.CreateInstance(
|
||||
Type.GetType($"{typeof(T).Namespace}.{typeof(T).Name}Accessor")!)!;
|
||||
_accessors.TryAdd(typeof(T), accessor);
|
||||
}
|
||||
return (ISourceEntityAccessor<T>)accessor!;
|
||||
}
|
||||
}
|
||||
""";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,6 +53,10 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
|
||||
[HttpGet]
|
||||
public async Task UseSessionPool(long testTime)
|
||||
{
|
||||
var dataTime = DateTime.Now;
|
||||
|
||||
List<string> values = new List<string>() { $"{dataTime:yy}", $"{dataTime:MM}", $"{dataTime:dd}", $"{dataTime:HH}", $"{dataTime:mm}", };
|
||||
|
||||
|
||||
ElectricityMeterTreeModel meter = new ElectricityMeterTreeModel()
|
||||
{
|
||||
@ -67,6 +71,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
|
||||
Timestamps = testTime// DateTimeOffset.UtcNow.ToUnixTimeNanoseconds()//testTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
|
||||
};
|
||||
//ElectricityMeterTreeModelExtension.GetCurrent()
|
||||
//SourceEntityAccessorFactory.SetCurrent(meter);
|
||||
await _iotDBProvider.InsertAsync(meter);
|
||||
}
|
||||
|
||||
|
||||
@ -262,7 +262,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
||||
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||
return;
|
||||
}
|
||||
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, Tuple.Create(ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName, tempTask));
|
||||
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, Tuple.Create(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempTask));
|
||||
});
|
||||
}
|
||||
else if (meteryType == MeterTypeEnum.WaterMeter.ToString())
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace JiShe.CollectBus.Analyzers
|
||||
namespace JiShe.CollectBus.Analyzers.Shared
|
||||
{
|
||||
public interface ISourceAnalyzersProvider<T>
|
||||
public interface ISourceEntityAccessor<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取属性值
|
||||
Loading…
x
Reference in New Issue
Block a user