diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs index 20951e5..8ec5eb9 100644 --- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs +++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs @@ -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), @@ -35,12 +32,11 @@ namespace JiShe.CollectBus.IncrementalGenerator var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect()); context.RegisterSourceOutput(compilationAndClasses, (spc, source) => - GenerateCode(source.Left, source.Right!, spc)); + GenerateCode(source.Left, source.Right!, spc)); } 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,18 +72,24 @@ namespace JiShe.CollectBus.IncrementalGenerator } } + /// + /// 生成代码 + /// + /// + /// + /// private static void GenerateCode( Compilation compilation, IEnumerable classes, SourceProductionContext context) { var processedTypes = new HashSet(SymbolEqualityComparer.Default); - + 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()); } + /// + /// 构建类的属性访问器代码 + /// + /// + /// + /// + /// private static string BuildAccessorsForType( - INamedTypeSymbol classSymbol, - Compilation compilation, - HashSet processedTypes) + INamedTypeSymbol classSymbol, + Compilation compilation, + HashSet 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()) - //{ - // 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))}>" : ""; + /// + /// 构建类的属性访问器代码 + /// + /// + /// + /// + /// + private static string BuildAccessorsForType2( + INamedTypeSymbol classSymbol, + Compilation compilation, + HashSet processedTypes) + { + var code = new StringBuilder(); + code.AppendLine("#pragma warning disable CS0419 // 禁用警告"); + code.AppendLine("// Generated code for " + classSymbol.Name); + code.AppendLine("// "); + 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(); + } + + /// + /// 获取泛型参数 + /// + /// + /// 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( + /// + /// 生成属性访问器代码 + /// + /// + /// + /// + /// + private static void GeneratePropertyAccessorsForType( IPropertySymbol prop, StringBuilder code, Compilation compilation, HashSet processedTypes) { - // 关键修复点1:安全类型转换 + // 安全类型转换 if (prop.Type is not ITypeSymbol propType) return; code.AppendLine($" // Processing property: {prop.Name}"); @@ -200,6 +271,12 @@ namespace JiShe.CollectBus.IncrementalGenerator } } + /// + /// 处理元组类型 + /// + /// + /// + /// private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code) { var elements = tupleType.TupleElements; @@ -222,6 +299,12 @@ namespace JiShe.CollectBus.IncrementalGenerator } } + /// + /// 生成标准属性的访问器 + /// + /// + /// + /// private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code) { var parentType = prop.ContainingType.ToDisplayString(); @@ -233,6 +316,13 @@ namespace JiShe.CollectBus.IncrementalGenerator } } + + /// + /// 处理嵌套类型 + /// + /// + /// + /// private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet processedTypes) { if (typeSymbol is not INamedTypeSymbol namedType) return; @@ -242,6 +332,11 @@ namespace JiShe.CollectBus.IncrementalGenerator var code = BuildAccessorsForType(namedType, compilation, processedTypes); } + /// + /// 处理嵌套类型 + /// + /// + /// private static bool ShouldProcessNestedType(INamedTypeSymbol symbol) { return symbol.DeclaredAccessibility == Accessibility.Public && @@ -250,5 +345,33 @@ namespace JiShe.CollectBus.IncrementalGenerator !symbol.IsImplicitlyDeclared && !symbol.Name.StartsWith("<"); } + + /// + /// 生成扩展类工厂代码 + /// + /// + private static string BuildFactoryCode() + { + return """ + using System; + using System.Collections.Concurrent; + namespace JiShe.CollectBus.Analyzers.Shared; + public static class SourceEntityAccessorFactory + { + private static readonly ConcurrentDictionary _accessors = new(); + + public static ISourceEntityAccessor GetAccessor() + { + 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)accessor!; + } + } + """; + } } } \ No newline at end of file diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs index ea2415e..79f0244 100644 --- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs @@ -53,6 +53,10 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS [HttpGet] public async Task UseSessionPool(long testTime) { + var dataTime = DateTime.Now; + + List values = new List() { $"{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); } diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs index 2104d28..47b8a99 100644 --- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs +++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs @@ -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()) diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs similarity index 92% rename from shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs rename to shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs index 905f0ef..3395239 100644 --- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs +++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Text; -namespace JiShe.CollectBus.Analyzers +namespace JiShe.CollectBus.Analyzers.Shared { - public interface ISourceAnalyzersProvider + public interface ISourceEntityAccessor { /// /// 获取属性值