From bca72025586daaab407c258c6c240183f17cb031 Mon Sep 17 00:00:00 2001 From: ChenYi <296215406@outlook.com> Date: Wed, 7 May 2025 10:15:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A4=8D=E6=9D=82=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=A2=9E=E9=87=8F=E6=BA=90=E7=94=9F=E6=88=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComplexTypeSourceAnalyzers.cs | 247 ++++++++++++------ .../Model/TableModelSingleMeasuringEntity.cs | 2 +- .../Model/TreeModelSingleMeasuringEntity.cs | 2 +- .../Samples/SampleAppService.cs | 2 + .../ISourceEntityAccessor.cs | 26 +- 5 files changed, 177 insertions(+), 102 deletions(-) diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs index 8ec5eb9..3b25aa0 100644 --- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs +++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs @@ -1,5 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -8,7 +9,7 @@ using System.Text; namespace JiShe.CollectBus.IncrementalGenerator { /// - /// 复杂类型源生成器 + /// 复杂类型增量源生成器 /// [Generator(LanguageNames.CSharp)] public class ComplexTypeSourceAnalyzers : IIncrementalGenerator @@ -32,11 +33,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; @@ -106,44 +107,14 @@ namespace JiShe.CollectBus.IncrementalGenerator 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("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)); - - var code = BuildAccessorsForType(classSymbol, compilation, processedTypes); - - //System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出 + + var code = BuildAccessorsForType(classSymbol, compilation, processedTypes); context.AddSource($"{classSymbol.Name}Extension.g.cs", code); - var code3 = BuildAccessorsForType2(classSymbol, compilation, processedTypes); + var code3 = BuildAccessorsForSourceEntity(classSymbol, compilation, processedTypes); context.AddSource($"{classSymbol.Name}Accessor.g.cs", code3); - - //code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};"); - //if (classSymbol.ContainingNamespace.ToDisplayString() == "JiShe.CollectBus.IoTDB") - //{ - - //} } // 生成工厂注册代码 @@ -183,52 +154,6 @@ namespace JiShe.CollectBus.IncrementalGenerator return code.ToString(); } - /// - /// 构建类的属性访问器代码 - /// - /// - /// - /// - /// - 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(); - } - /// /// 获取泛型参数 /// @@ -262,11 +187,11 @@ namespace JiShe.CollectBus.IncrementalGenerator // 处理元组类型 if (propType is INamedTypeSymbol { IsTupleType: true } tupleType) { - GenerateTupleAccessors(prop, tupleType, code); + GenerateTupleAccessorsForType(prop, tupleType, code); } else if (propType is INamedTypeSymbol namedType) { - GenerateStandardAccessors(prop, namedType, code); + GenerateStandardAccessorsForType(prop, namedType, code); ProcessNestedType(namedType, compilation, processedTypes); } } @@ -277,7 +202,7 @@ namespace JiShe.CollectBus.IncrementalGenerator /// /// /// - private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code) + private static void GenerateTupleAccessorsForType(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code) { var elements = tupleType.TupleElements; var parentType = prop.ContainingType.ToDisplayString(); @@ -305,7 +230,7 @@ namespace JiShe.CollectBus.IncrementalGenerator /// /// /// - private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code) + private static void GenerateStandardAccessorsForType(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code) { var parentType = prop.ContainingType.ToDisplayString(); code.AppendLine($" public static {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};"); @@ -316,7 +241,7 @@ namespace JiShe.CollectBus.IncrementalGenerator } } - + /// /// 处理嵌套类型 /// @@ -373,5 +298,153 @@ namespace JiShe.CollectBus.IncrementalGenerator } """; } + + /// + /// 构建实体类的源属性访问器代码 + /// + /// + /// + /// + /// + private static string BuildAccessorsForSourceEntity( + 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("using System;"); + code.AppendLine("using JiShe.CollectBus.Analyzers.Shared;"); + code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};"); + code.AppendLine(); + + code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>"); + code.AppendLine("{"); + + GetGeneratePropertyValueForSourceEntity(GetAllPropertiesInHierarchy(classSymbol), code, compilation, classSymbol); + + SetGeneratePropertyValueForSourceEntity(GetAllPropertiesInHierarchy(classSymbol), code, compilation, classSymbol); + + code.AppendLine("}"); + + return code.ToString(); + } + + private static void GetGeneratePropertyValueForSourceEntity(IEnumerable propList, + StringBuilder code, + Compilation compilation, + INamedTypeSymbol classSymbol) + { + + code.AppendLine($" public object GetPropertyValue({classSymbol.Name} targetEntity, string propertyName)"); + code.AppendLine(" {"); + code.AppendLine(" return propertyName switch"); + code.AppendLine(" {"); + + // 遍历所有属性 + foreach (var property in propList) + { + // 安全类型转换 + if (property.Type is not ITypeSymbol propType) continue; + + // 处理元组类型 + if (propType is INamedTypeSymbol { IsTupleType: true } tupleType) + { + } + else if (propType is INamedTypeSymbol namedType) + { + // 生成属性访问的 + code.AppendLine($" \"{property.Name}\" => {classSymbol.Name}Extension.Get{property.Name}(targetEntity),"); + } + } + + + code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")"); + code.AppendLine(" };"); + code.AppendLine(" }"); + } + + + private static void SetGeneratePropertyValueForSourceEntity(IEnumerable propList, + StringBuilder code, + Compilation compilation, + INamedTypeSymbol classSymbol) + { + code.AppendLine($" public void SetPropertyValue({classSymbol.Name} targetEntity, string propertyName, object value)"); + code.AppendLine(" {"); + code.AppendLine(" return propertyName switch"); + code.AppendLine(" {"); + + // 遍历所有属性 + foreach (var property in propList) + { + // 安全类型转换 + if (property.Type is not ITypeSymbol propType) continue; + + // 处理元组类型 + if (propType is INamedTypeSymbol { IsTupleType: true } tupleType) + { + } + else if (propType is INamedTypeSymbol namedType) + { + // 生成属性设置赋值 + code.AppendLine($" \"{property.Name}\" => {classSymbol.Name}Extension.Set{property.Name}(targetEntity,({namedType.ToDisplayString()})value),"); + + } + } + + + code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")"); + code.AppendLine(" };"); + code.AppendLine(" }"); + } + + /// + /// 处理元组类型 + /// + /// + /// + /// + private static void GenerateTupleAccessorsForSourceEntity(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code) + { + var elements = tupleType.TupleElements; + var parentType = prop.ContainingType.ToDisplayString(); + + for (int i = 0; i < elements.Length; i++) + { + var element = elements[i]; + if (element.Type is not ITypeSymbol elementType) continue; + + var elementName = element.CorrespondingTupleField?.Name ?? $"Item{i + 1}"; + code.AppendLine($" public static {elementType.ToDisplayString()} Get{prop.Name}_{elementName}({parentType} obj) => obj.{prop.Name}.{elementName};"); + + if (prop.SetMethod != null) + { + var assignments = elements.Select((e, idx) => + idx == i ? "value" : $"obj.{prop.Name}.{e.Name}"); + code.AppendLine($" public static void Set{prop.Name}_{elementName}({parentType} obj, {elementType.ToDisplayString()} value) => obj.{prop.Name} = ({string.Join(", ", assignments)});"); + } + } + } + + /// + /// 生成标准属性的访问器 + /// + /// + /// + /// + private static void GenerateStandardAccessorsForSourceEntity(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code) + { + var parentType = prop.ContainingType.ToDisplayString(); + code.AppendLine($" public object {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};"); + + if (prop.SetMethod != null) + { + code.AppendLine($" public static void Set{prop.Name}({parentType} obj, {propType.ToDisplayString()} value) => obj.{prop.Name} = value;"); + } + } } } \ No newline at end of file diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs index 966f226..3355a33 100644 --- a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs +++ b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs @@ -8,7 +8,7 @@ namespace JiShe.CollectBus.IoTDB.Model /// Table模型单项数据实体 /// [EntityType(EntityTypeEnum.TableModel)] - [SourceAnalyzers] + //[SourceAnalyzers] public class TableModelSingleMeasuringEntity : IoTEntity { /// diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs index 719c3c3..f59f648 100644 --- a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs +++ b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs @@ -8,7 +8,7 @@ namespace JiShe.CollectBus.IoTDB.Model /// Tree模型单项数据实体 /// [EntityType(EntityTypeEnum.TreeModel)] - [SourceAnalyzers] + //[SourceAnalyzers] public class TreeModelSingleMeasuringEntity : IoTEntity { /// diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs index 79f0244..95ed072 100644 --- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs +++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs @@ -72,6 +72,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS }; //ElectricityMeterTreeModelExtension.GetCurrent() //SourceEntityAccessorFactory.SetCurrent(meter); + + ElectricityMeterTreeModelAccessor await _iotDBProvider.InsertAsync(meter); } diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs index 3395239..2a448c1 100644 --- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs +++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs @@ -22,19 +22,19 @@ namespace JiShe.CollectBus.Analyzers.Shared /// void SetPropertyValue(T entity, string propertyName, object value); - /// - /// 判断是否是元组属性 - /// - /// - /// - bool IsTupleProperty(string propertyName); + ///// + ///// 判断是否是元组属性 + ///// + ///// + ///// + //bool IsTupleProperty(string propertyName); - /// - /// 获取元组属性值 - /// - /// - /// - /// - (object Item1, object Item2) GetTupleParts(T entity, string tuplePropertyName); + ///// + ///// 获取元组属性值 + ///// + ///// + ///// + ///// + //(object Item1, object Item2) GetTupleParts(T entity, string tuplePropertyName); } }