XFEExtension
【DLL】XFE各类拓展是一个C#的DLL库,旨在优化C#代码中常用语句的使用,并提供更简洁的访问方式,同时提供Xunit测试框架,快速搭建服务器/客户端,免费ChatGPTAPI接口,免费通讯服务器,XFE下载器,新增格式等
关注
0
Fork
0
Star
0
返回提交历史
Added
XFE各类拓展.NetCore.Analyzer/ProfilePropertyAutoGenerator.cs
+98
-0
Modified
XFE各类拓展.NetCore/ProfileExtension/ProfilePropertyAttribute.cs
+21
-3
XFEstudio/XFEExtension
准备添加自动生成配置属性支持
878f6fa
代码差异
2 个文件
+119
-3
@@ -0,0 +1,98 @@
1
using Microsoft.CodeAnalysis;
2
using Microsoft.CodeAnalysis.CSharp;
3
using Microsoft.CodeAnalysis.CSharp.Syntax;
4
using System.Linq;
5
6
namespace XFE各类拓展.NetCore.Analyzer
7
{
8
[Generator]
9
public class ProfilePropertyAutoGenerator : ISourceGenerator
10
{
11
public void Initialize(GeneratorInitializationContext context)
12
{
13
}
14
15
public void Execute(GeneratorExecutionContext context)
16
{
17
var syntaxTrees = context.Compilation.SyntaxTrees;
18
foreach (var syntaxTree in syntaxTrees)
19
{
20
var root = syntaxTree.GetRoot();
21
var classDeclarations = root.DescendantNodes().OfType<ClassDeclarationSyntax>()
22
.Where(classDeclaration => classDeclaration.AttributeLists.Any(IsProfilePropertyAttribute));
23
var usingDirectives = root.DescendantNodes().OfType<UsingDirectiveSyntax>().ToArray();
24
FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax = null;
25
var namespaceResults = root.DescendantNodes().OfType<FileScopedNamespaceDeclarationSyntax>();
26
if (namespaceResults != null && namespaceResults.Count() > 0)
27
fileScopedNamespaceDeclarationSyntax = namespaceResults.First();
28
foreach (var classDeclaration in classDeclarations)
29
{
30
var className = classDeclaration.Identifier.ValueText;
31
var implementationSyntaxTree = GenerateImplementationSyntaxTree(classDeclaration, usingDirectives, fileScopedNamespaceDeclarationSyntax);
32
context.AddSource($"{className}Impl.g.cs", implementationSyntaxTree.ToString());
33
}
34
}
35
}
36
37
private static bool IsProfilePropertyAttribute(AttributeListSyntax attributeList) => attributeList.Attributes.Any(attribute => attribute.Name.ToString() == "ProfileProperty");
38
39
private static SyntaxTree GenerateImplementationSyntaxTree(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usingDirectiveSyntaxes, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
40
{
41
var className = classDeclaration.Identifier.ValueText;
42
ClassDeclarationSyntax implementationClass;
43
if (classDeclaration.ParameterList is null)
44
{
45
implementationClass = SyntaxFactory.ClassDeclaration($"{className}Impl")
46
.AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword))
47
.AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(className)))
48
.AddMembers(classDeclaration.Members.OfType<ConstructorDeclarationSyntax>().Select(constructor =>
49
{
50
return constructor.WithIdentifier(SyntaxFactory.Identifier($"{className}Impl"))
51
.WithInitializer(SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(constructor.ParameterList.Parameters.Select(parameter =>
52
SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Identifier)))))));
53
}).ToArray())
54
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
55
/// <seealso cref=""{className}Impl""/> 是根据 <seealso cref=""{className}""/> 自动生成的实现类
56
/// </summary>
57
"))
58
.NormalizeWhitespace();
59
}
60
else
61
{
62
implementationClass = SyntaxFactory.ClassDeclaration($"{className}Impl")
63
.AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword))
64
.AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(className)))
65
.AddMembers(SyntaxFactory.ConstructorDeclaration($"{className}Impl")
66
.AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword))
67
.WithBody(SyntaxFactory.Block())
68
.WithParameterList(classDeclaration.ParameterList)
69
.WithInitializer(SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(classDeclaration.ParameterList.Parameters.Select(parameter => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Identifier))))))))
70
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
71
/// <seealso cref=""{className}Impl""/> 是根据 <seealso cref=""{className}""/> 自动生成的实现类
72
/// </summary>
73
"))
74
.NormalizeWhitespace();
75
}
76
MemberDeclarationSyntax memberDeclaration;
77
if (fileScopedNamespaceDeclarationSyntax is null)
78
{
79
var namespaceDeclaration = classDeclaration.FirstAncestorOrSelf<NamespaceDeclarationSyntax>();
80
if (namespaceDeclaration is null)
81
memberDeclaration = implementationClass;
82
else
83
memberDeclaration = SyntaxFactory.NamespaceDeclaration(namespaceDeclaration.Name)
84
.AddMembers(implementationClass);
85
}
86
else
87
{
88
memberDeclaration = SyntaxFactory.FileScopedNamespaceDeclaration(fileScopedNamespaceDeclarationSyntax.Name)
89
.AddMembers(implementationClass);
90
}
91
var implementationCompilationUnit = SyntaxFactory.CompilationUnit()
92
.AddUsings(usingDirectiveSyntaxes)
93
.AddMembers(memberDeclaration)
94
.NormalizeWhitespace();
95
return SyntaxFactory.SyntaxTree(implementationCompilationUnit);
96
}
97
}
98
}
@@ -1,7 +1,25 @@
1
1
namespace XFE各类拓展.NetCore.ProfileExtension;
2
2
3
3
/// <summary>
4
/// 将属性视添加至储存列表
4
/// 将属性添加至储存列表
5
5
/// </summary>
6
[AttributeUsage(AttributeTargets.Property)]
7
public class ProfilePropertyAttribute : Attribute { }
6
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
7
public class ProfilePropertyAttribute : Attribute
8
{
9
/// <summary>
10
/// 自动生成的属性名称
11
/// </summary>
12
public string PropertyName { get; set; } = string.Empty;
13
/// <summary>
14
/// 将属性添加至存储列表
15
/// </summary>
16
public ProfilePropertyAttribute() { }
17
/// <summary>
18
/// 将属性添加至存储列表,给定属性名
19
/// </summary>
20
/// <param name="propertyName">属性名</param>
21
public ProfilePropertyAttribute(string propertyName)
22
{
23
PropertyName = propertyName;
24
}
25
}