Skip to content

Commit

Permalink
支持导出只有基础继承类型
Browse files Browse the repository at this point in the history
  • Loading branch information
lindexi committed Oct 21, 2023
1 parent ae3e34e commit 056443d
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers;
/// <summary>
/// 从标记的方法导出类型
/// </summary>
// 形如 private static partial IEnumerable<(Type type, FooAttribute attribute, Func<FooBase> creator)> ExportFooEnumerable();
[Generator(LanguageNames.CSharp)]
public class TelescopeExportTypeToMethodIncrementalGenerator : IIncrementalGenerator
{
Expand Down Expand Up @@ -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<FooBase> creator)> ExportFooEnumerable();` 的情况,没有中间的 Attribute 约束,也就是只需要导出所有继承了 FooBase 的类型即可
if (TypeSymbolHelper.TypeSymbolToFullName(tupleType.TupleElements[0].Type) != "global::System.Type")
{
// 如果首个不是 Type 类型,这就是错误的
return ReturnTypeError(nameof(Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator));
}

// Func<Base>
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);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3;
[F1]
public class F3 : F1
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1;

namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3;

public class FooWithAttribute : F1
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ static void Main(string[] args)
{
}

var program = new Program();
foreach (var (_, xxx) in program.ExportF1Enumerable())
{
}

var attributedTypesExport = new __AttributedTypesExport__();
ICompileTimeAttributedTypesExporter<Base, FooAttribute> exporter = attributedTypesExport;
foreach (var exportedTypeMetadata in exporter.ExportAttributeTypes())
Expand All @@ -21,6 +26,9 @@ static void Main(string[] args)

[dotnetCampus.Telescope.TelescopeExportAttribute(IncludeReferences = true)]
private static partial IEnumerable<(Type, F1Attribute xx, Func<DemoLib1.F1> xxx)> ExportFooEnumerable();

[dotnetCampus.Telescope.TelescopeExportAttribute(IncludeReferences = true)]
private partial IEnumerable<(Type, Func<DemoLib1.F1> xxx)> ExportF1Enumerable();
}

[F1]
Expand Down

0 comments on commit 056443d

Please sign in to comment.