diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs b/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs index 896ed2a..919dca2 100644 --- a/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs +++ b/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs @@ -151,11 +151,11 @@ namespace {@namespace} {{"); } - var generatedCodeAttributeSource = AssemblyInfo.GeneratedCodeAttribute; + // 不要带上 System.CodeDom.Compiler.GeneratedCodeAttribute 特性,因为一个类型如果是分部类型,可能有多个逻辑都在生成在不同的文件,如果这些文件同时都加上 GeneratedCodeAttribute 特性,将会导致 error CS0579: “global::System.CodeDom.Compiler.GeneratedCode”特性重复 + //var generatedCodeAttributeSource = AssemblyInfo.GeneratedCodeAttribute; // Add the core implementation for the derived context class. string partialContextImplementation = $@" -{generatedCodeAttributeSource} {declarationList[0]} {{ {IndentSource(memberCode, Math.Max(1, declarationCount - 1))} diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs index a138ba7..5cf6b44 100644 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs +++ b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs @@ -35,18 +35,32 @@ public string GenerateSourceCode(ExportMethodReturnTypeCollectionResult exportMe foreach (var namedTypeSymbol in list) { token.ThrowIfCancellationRequested(); - // yield return (typeof(CurrentFoo), new F1Attribute(), () => new CurrentFoo()); - - var attribute = namedTypeSymbol.GetAttributes().First(t => - SymbolEqualityComparer.Default.Equals(t.AttributeClass, - exportMethodReturnTypeCollectionResult - .ExpectedClassAttributeType)); - var attributeCreatedCode = AttributeCodeReWriter.GetAttributeCreatedCode(attribute); - - var typeName = TypeSymbolHelper.TypeSymbolToFullName(namedTypeSymbol); - methodCode.AppendLine(SourceCodeGeneratorHelper.IndentSource( - $" yield return (typeof({typeName}), {attributeCreatedCode}, () => new {typeName}());", - numIndentations: 1)); + + if (exportMethodReturnTypeCollectionResult.ExpectedClassAttributeType is null) + { + // 这是不带 Attribute 的收集 + // 以下生成格式大概如下的代码 + // yield return (typeof(CurrentFoo), () => new CurrentFoo()); + var typeName = TypeSymbolHelper.TypeSymbolToFullName(namedTypeSymbol); + methodCode.AppendLine(SourceCodeGeneratorHelper.IndentSource( + $" yield return (typeof({typeName}), () => new {typeName}());", + numIndentations: 1)); + } + else + { + // 以下生成格式大概如下的代码 + // yield return (typeof(CurrentFoo), new F1Attribute(), () => new CurrentFoo()); + var attribute = namedTypeSymbol.GetAttributes().First(t => + SymbolEqualityComparer.Default.Equals(t.AttributeClass, + exportMethodReturnTypeCollectionResult + .ExpectedClassAttributeType)); + var attributeCreatedCode = AttributeCodeReWriter.GetAttributeCreatedCode(attribute); + + var typeName = TypeSymbolHelper.TypeSymbolToFullName(namedTypeSymbol); + methodCode.AppendLine(SourceCodeGeneratorHelper.IndentSource( + $" yield return (typeof({typeName}), {attributeCreatedCode}, () => new {typeName}());", + numIndentations: 1)); + } } var methodSource = SourceCodeGeneratorHelper.GeneratePartialMethodCode( diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs index f9598d1..31450a7 100644 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs +++ b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs @@ -22,6 +22,7 @@ namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; /// /// 从标记的方法导出类型 /// +// 形如 private static partial IEnumerable<(Type type, FooAttribute attribute, Func creator)> ExportFooEnumerable(); [Generator(LanguageNames.CSharp)] public class TelescopeExportTypeToMethodIncrementalGenerator : IIncrementalGenerator { @@ -144,6 +145,30 @@ namedTypeSymbol.TypeArguments[0] is INamedTypeSymbol tupleType && tupleType.IsTu return new ExportMethodReturnTypeCollectionResult(expectedClassBaseType, expectedClassAttributeType, exportTypeCollectionResult, ExportMethodReturnType.EnumerableValueTupleWithTypeAttributeCreator); } + else if (tupleType.TupleElements.Length == 2) + { + // 判断是否 `partial IEnumerable<(Type type, Func creator)> ExportFooEnumerable();` 的情况,没有中间的 Attribute 约束,也就是只需要导出所有继承了 FooBase 的类型即可 + if (TypeSymbolHelper.TypeSymbolToFullName(tupleType.TupleElements[0].Type) != "global::System.Type") + { + // 如果首个不是 Type 类型,这就是错误的 + return ReturnTypeError(nameof(Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator)); + } + + // Func + var funcTypeSymbol = (INamedTypeSymbol) tupleType.TupleElements[1].Type; + if (!funcTypeSymbol.IsGenericType || TypeSymbolHelper.TypeSymbolToFullName(funcTypeSymbol) != "global::System.Func") + { + // 不是 Func 的 + return ReturnTypeError(nameof(Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator)); + } + + // 准备导出的类型的基类型 + var expectedClassBaseType = funcTypeSymbol.TypeArguments[0]; + return new ExportMethodReturnTypeCollectionResult(expectedClassBaseType, + // 没有预期的特性类型 + expectedClassAttributeType: null, + exportTypeCollectionResult, ExportMethodReturnType.EnumerableValueTupleWithTypeAttributeCreator); + } } } } diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs b/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs index 41a7d3a..b80d50b 100644 --- a/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs +++ b/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs @@ -11,4 +11,4 @@ namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3; [F1] public class F3 : F1 { -} +} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib3/FooWithAttribute.cs b/src/TelescopeSourceGenerator/Demo/DemoLib3/FooWithAttribute.cs new file mode 100644 index 0000000..2fce78b --- /dev/null +++ b/src/TelescopeSourceGenerator/Demo/DemoLib3/FooWithAttribute.cs @@ -0,0 +1,7 @@ +using dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1; + +namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3; + +public class FooWithAttribute : F1 +{ +} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs b/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs index 993d7ee..04a003d 100644 --- a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs +++ b/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs @@ -21,6 +21,9 @@ static void Main(string[] args) [dotnetCampus.Telescope.TelescopeExportAttribute(IncludeReferences = true)] private static partial IEnumerable<(Type, F1Attribute xx, Func xxx)> ExportFooEnumerable(); + + [dotnetCampus.Telescope.TelescopeExportAttribute(IncludeReferences = true)] + private partial IEnumerable<(Type, Func xxx)> ExportF1Enumerable(); } [F1]