修复15分钟任务Kafka主题异常的问题,新增增量源码工厂类
This commit is contained in:
parent
01264dd3ec
commit
53e6bb252a
@ -14,17 +14,14 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
|
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
|
||||||
{
|
{
|
||||||
private const string AttributeFullName = "JiShe.CollectBus.Analyzers.Shared.SourceAnalyzersAttribute";
|
private const string AttributeFullName = "JiShe.CollectBus.Analyzers.Shared.SourceAnalyzersAttribute";
|
||||||
|
private const string SourceEntityAccessorFactoryNamespace = "JiShe.CollectBus.Analyzers.Shared";
|
||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
{
|
{
|
||||||
//Debugger.Launch();
|
//Debugger.Launch();
|
||||||
|
|
||||||
context.RegisterPostInitializationOutput(ctx =>
|
|
||||||
{
|
|
||||||
ctx.AddSource("GeneratorInit.g.cs", "// Initialization Marker");
|
|
||||||
});
|
|
||||||
|
|
||||||
// 步骤1:筛选带有 [GenerateAccessors] 的类
|
// 步骤1:筛选带有 [SourceAnalyzers] 的类
|
||||||
var classDeclarations = context.SyntaxProvider
|
var classDeclarations = context.SyntaxProvider
|
||||||
.CreateSyntaxProvider(
|
.CreateSyntaxProvider(
|
||||||
predicate: static (s, _) => IsClassWithAttribute(s),
|
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 bool IsClassWithAttribute(SyntaxNode node) => node is ClassDeclarationSyntax cds && cds.AttributeLists.Count > 0;
|
||||||
|
|
||||||
|
|
||||||
private static ClassDeclarationSyntax GetClassDeclaration(GeneratorSyntaxContext context)
|
private static ClassDeclarationSyntax GetClassDeclaration(GeneratorSyntaxContext context)
|
||||||
{
|
{
|
||||||
var classDecl = (ClassDeclarationSyntax)context.Node;
|
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(
|
private static void GenerateCode(
|
||||||
Compilation compilation,
|
Compilation compilation,
|
||||||
IEnumerable<ClassDeclarationSyntax> classes,
|
IEnumerable<ClassDeclarationSyntax> classes,
|
||||||
@ -86,8 +88,8 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
if (!classes.Any())
|
if (!classes.Any())
|
||||||
{
|
{
|
||||||
context.ReportDiagnostic(Diagnostic.Create(
|
context.ReportDiagnostic(Diagnostic.Create(
|
||||||
new DiagnosticDescriptor("GEN002", "No Targets",
|
new DiagnosticDescriptor("GEN002", "没有目标类",
|
||||||
"No classes with [GenerateAccessors] found", "Debug", DiagnosticSeverity.Warning, true),
|
"没有找到SourceAnalyzers标记的类", "Debug", DiagnosticSeverity.Warning, true),
|
||||||
Location.None));
|
Location.None));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,46 +101,66 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
if (classSymbol == null || !processedTypes.Add(classSymbol))
|
if (classSymbol == null || !processedTypes.Add(classSymbol))
|
||||||
{
|
{
|
||||||
context.ReportDiagnostic(Diagnostic.Create(
|
context.ReportDiagnostic(Diagnostic.Create(
|
||||||
new DiagnosticDescriptor("GEN003", "Invalid Symbol",
|
new DiagnosticDescriptor("GEN003", "无效符号",
|
||||||
$"Class symbol is null for {classDecl.Identifier.Text}", "Error", DiagnosticSeverity.Error, true),
|
$"类名称为{classDecl.Identifier.Text} 符号为空", "Error", DiagnosticSeverity.Error, true),
|
||||||
Location.None));
|
Location.None));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ReportDiagnostic(Diagnostic.Create(
|
//context.ReportDiagnostic(Diagnostic.Create(
|
||||||
new DiagnosticDescriptor(
|
//new DiagnosticDescriptor(
|
||||||
"PA001",
|
// "PA001",
|
||||||
"Generated Accessors",
|
// "Generated Accessors",
|
||||||
$"Generating accessors for {classSymbol.Name}",
|
// $"Generating accessors for {classSymbol.Name}",
|
||||||
"Performance",
|
// "Performance",
|
||||||
DiagnosticSeverity.Info,
|
// DiagnosticSeverity.Info,
|
||||||
true),
|
// true),
|
||||||
Location.None));
|
//Location.None));
|
||||||
|
|
||||||
// 新增:输出继承链信息
|
//// 新增:输出继承链信息
|
||||||
context.ReportDiagnostic(Diagnostic.Create(
|
//context.ReportDiagnostic(Diagnostic.Create(
|
||||||
new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
|
// new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
|
||||||
$"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
|
// $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
|
||||||
"Debug", DiagnosticSeverity.Info, true),
|
// "Debug", DiagnosticSeverity.Info, true),
|
||||||
Location.None));
|
// Location.None));
|
||||||
|
|
||||||
context.ReportDiagnostic(Diagnostic.Create(
|
//context.ReportDiagnostic(Diagnostic.Create(
|
||||||
new DiagnosticDescriptor("PA002", "Class Found",
|
//new DiagnosticDescriptor("PA002", "Class Found",
|
||||||
$"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
|
//$"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
|
||||||
Location.None));
|
//Location.None));
|
||||||
|
|
||||||
var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
|
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);
|
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(
|
private static string BuildAccessorsForType(
|
||||||
INamedTypeSymbol classSymbol,
|
INamedTypeSymbol classSymbol,
|
||||||
Compilation compilation,
|
Compilation compilation,
|
||||||
HashSet<ITypeSymbol> processedTypes)
|
HashSet<ITypeSymbol> processedTypes)
|
||||||
{
|
{
|
||||||
var code = new StringBuilder();
|
var code = new StringBuilder();
|
||||||
code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
|
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($"public static class {classSymbol.Name}Extension{GetGenericParams(classSymbol)}");
|
||||||
code.AppendLine("{");
|
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))
|
foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
|
||||||
{
|
{
|
||||||
if (prop.IsIndexer) continue;
|
if (prop.IsIndexer) continue;
|
||||||
GeneratePropertyAccessors(prop, code, compilation, processedTypes);
|
GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
code.AppendLine("}");
|
code.AppendLine("}");
|
||||||
return code.ToString();
|
return code.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//private static string GetGenericParams(INamedTypeSymbol symbol)
|
/// <summary>
|
||||||
// => symbol.IsGenericType ? $"<{string.Join(", ", symbol.TypeParameters.Select(t => t.Name))}>" : "";
|
/// 构建类的属性访问器代码
|
||||||
|
/// </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)
|
public static string GetGenericParams(INamedTypeSymbol symbol)
|
||||||
{
|
{
|
||||||
if (!symbol.IsGenericType) return "";
|
if (!symbol.IsGenericType) return "";
|
||||||
@ -177,13 +241,20 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
return $"<{string.Join(", ", parameters)}>";
|
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,
|
IPropertySymbol prop,
|
||||||
StringBuilder code,
|
StringBuilder code,
|
||||||
Compilation compilation,
|
Compilation compilation,
|
||||||
HashSet<ITypeSymbol> processedTypes)
|
HashSet<ITypeSymbol> processedTypes)
|
||||||
{
|
{
|
||||||
// 关键修复点1:安全类型转换
|
// 安全类型转换
|
||||||
if (prop.Type is not ITypeSymbol propType) return;
|
if (prop.Type is not ITypeSymbol propType) return;
|
||||||
|
|
||||||
code.AppendLine($" // Processing property: {prop.Name}");
|
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)
|
private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
|
||||||
{
|
{
|
||||||
var elements = tupleType.TupleElements;
|
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)
|
private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
|
||||||
{
|
{
|
||||||
var parentType = prop.ContainingType.ToDisplayString();
|
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)
|
private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet<ITypeSymbol> processedTypes)
|
||||||
{
|
{
|
||||||
if (typeSymbol is not INamedTypeSymbol namedType) return;
|
if (typeSymbol is not INamedTypeSymbol namedType) return;
|
||||||
@ -242,6 +332,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
var code = BuildAccessorsForType(namedType, compilation, processedTypes);
|
var code = BuildAccessorsForType(namedType, compilation, processedTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理嵌套类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="symbol"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
|
private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
|
||||||
{
|
{
|
||||||
return symbol.DeclaredAccessibility == Accessibility.Public &&
|
return symbol.DeclaredAccessibility == Accessibility.Public &&
|
||||||
@ -250,5 +345,33 @@ namespace JiShe.CollectBus.IncrementalGenerator
|
|||||||
!symbol.IsImplicitlyDeclared &&
|
!symbol.IsImplicitlyDeclared &&
|
||||||
!symbol.Name.StartsWith("<");
|
!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]
|
[HttpGet]
|
||||||
public async Task UseSessionPool(long testTime)
|
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()
|
ElectricityMeterTreeModel meter = new ElectricityMeterTreeModel()
|
||||||
{
|
{
|
||||||
@ -67,6 +71,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
|
|||||||
Timestamps = testTime// DateTimeOffset.UtcNow.ToUnixTimeNanoseconds()//testTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
|
Timestamps = testTime// DateTimeOffset.UtcNow.ToUnixTimeNanoseconds()//testTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
|
||||||
};
|
};
|
||||||
//ElectricityMeterTreeModelExtension.GetCurrent()
|
//ElectricityMeterTreeModelExtension.GetCurrent()
|
||||||
|
//SourceEntityAccessorFactory.SetCurrent(meter);
|
||||||
await _iotDBProvider.InsertAsync(meter);
|
await _iotDBProvider.InsertAsync(meter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -262,7 +262,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
|
|||||||
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
|
||||||
return;
|
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())
|
else if (meteryType == MeterTypeEnum.WaterMeter.ToString())
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace JiShe.CollectBus.Analyzers
|
namespace JiShe.CollectBus.Analyzers.Shared
|
||||||
{
|
{
|
||||||
public interface ISourceAnalyzersProvider<T>
|
public interface ISourceEntityAccessor<T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取属性值
|
/// 获取属性值
|
||||||
Loading…
x
Reference in New Issue
Block a user