返回提交历史
Modified
LICENSE.txt
+1
-1
Added
README.md
+24
-0
Added
XFEExtension.NetCore.AutoImplement.Analyzer/Generator/ImplementAutoGenerator.cs
+100
-0
Added
XFEExtension.NetCore.AutoImplement.Analyzer/XFEExtension.NetCore.AutoImplement.Analyzer.csproj
+20
-0
Modified
XFEExtension.NetCore.AutoImplement.sln
+9
-0
Deleted
XFEExtension.NetCore.AutoImplement/Class1.cs
+0
-7
Added
XFEExtension.NetCore.AutoImplement/CreateImpl.cs
+7
-0
Modified
XFEExtension.NetCore.AutoImplement/XFEExtension.NetCore.AutoImplement.csproj
+30
-0
Added
logoIcon.png
+0
-0
XFEstudio/XFEExtension.NetCore.AutoImplement
从XFEExtetnsion迁移
f1d0292
代码差异
9 个文件
+191
-8
@@ -1,6 +1,6 @@
1
1
MIT License
2
2
3
Copyright (c) [year] [fullname]
3
Copyright (c) [2024] [XFEstudio]
4
4
5
5
Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,24 @@
1
# XFEExtension.NetCore.AutoImplement
2
3
## 描述
4
5
自动生成实现类
6
7
## 自动生成实现类
8
9
```csharp
10
[CreateImpl]
11
abstract class TestAbstractClass(int num)
12
{
13
public int Num { get; set; } = num;
14
}
15
16
class Program
17
{
18
static void Main(string[] args)
19
{
20
var testAbstractClass = new TestAbstractClassImpl(123);
21
Console.WriteLine(testAbstractClass.Num);
22
}
23
}
24
```
@@ -0,0 +1,100 @@
1
using Microsoft.CodeAnalysis;
2
using Microsoft.CodeAnalysis.CSharp;
3
using Microsoft.CodeAnalysis.CSharp.Syntax;
4
using System.Linq;
5
6
namespace XFEExtension.NetCore.AutoImplement.Analyzer.Generator
7
{
8
[Generator]
9
public class ImplementAutoGenerator : 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(IsCreateImplAttribute));
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 IsCreateImplAttribute(AttributeListSyntax attributeList) => attributeList.Attributes.Any(attribute => attribute.Name.ToString() == "CreateImpl");
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), SyntaxFactory.Token(SyntaxKind.SealedKeyword))
47
.AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(className)))
48
.AddMembers(classDeclaration.Members.OfType<ConstructorDeclarationSyntax>().Select(constructor =>
49
{
50
return SyntaxFactory.ConstructorDeclaration($"{className}Impl")
51
.AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword))
52
.WithBody(SyntaxFactory.Block())
53
.WithParameterList(constructor.ParameterList)
54
.WithInitializer(SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(constructor.ParameterList.Parameters.Select(parameter => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Identifier)))))));
55
}).ToArray())
56
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
57
/// <seealso cref=""{className}Impl""/> 是根据 <seealso cref=""{className}""/> 自动生成的实现类
58
/// </summary>
59
"))
60
.NormalizeWhitespace();
61
}
62
else
63
{
64
implementationClass = SyntaxFactory.ClassDeclaration($"{className}Impl")
65
.AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword))
66
.AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(className)))
67
.AddMembers(SyntaxFactory.ConstructorDeclaration($"{className}Impl")
68
.AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword))
69
.WithBody(SyntaxFactory.Block())
70
.WithParameterList(classDeclaration.ParameterList)
71
.WithInitializer(SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(classDeclaration.ParameterList.Parameters.Select(parameter => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Identifier))))))))
72
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
73
/// <seealso cref=""{className}Impl""/> 是根据 <seealso cref=""{className}""/> 自动生成的实现类
74
/// </summary>
75
"))
76
.NormalizeWhitespace();
77
}
78
MemberDeclarationSyntax memberDeclaration;
79
if (fileScopedNamespaceDeclarationSyntax is null)
80
{
81
var namespaceDeclaration = classDeclaration.FirstAncestorOrSelf<NamespaceDeclarationSyntax>();
82
if (namespaceDeclaration is null)
83
memberDeclaration = implementationClass;
84
else
85
memberDeclaration = SyntaxFactory.NamespaceDeclaration(namespaceDeclaration.Name)
86
.AddMembers(implementationClass);
87
}
88
else
89
{
90
memberDeclaration = SyntaxFactory.FileScopedNamespaceDeclaration(fileScopedNamespaceDeclarationSyntax.Name)
91
.AddMembers(implementationClass);
92
}
93
var implementationCompilationUnit = SyntaxFactory.CompilationUnit()
94
.AddUsings(usingDirectiveSyntaxes)
95
.AddMembers(memberDeclaration)
96
.NormalizeWhitespace();
97
return SyntaxFactory.SyntaxTree(implementationCompilationUnit);
98
}
99
}
100
}
@@ -0,0 +1,20 @@
1
<Project Sdk="Microsoft.NET.Sdk">
2
3
<PropertyGroup>
4
<TargetFramework>netstandard2.0</TargetFramework>
5
</PropertyGroup>
6
7
<PropertyGroup>
8
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
9
<!-- Generates a package at build -->
10
<IncludeBuildOutput>false</IncludeBuildOutput>
11
<!-- Do not include the generator as a lib dependency -->
12
</PropertyGroup>
13
14
<ItemGroup>
15
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
16
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
17
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.9.2" />
18
</ItemGroup>
19
20
</Project>
@@ -3,12 +3,21 @@ Microsoft Visual Studio Solution File, Format Version 12.00
3
3
VisualStudioVersion = 17.11.34929.205
4
4
MinimumVisualStudioVersion = 10.0.40219.1
5
5
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFEExtension.NetCore.AutoImplement", "XFEExtension.NetCore.AutoImplement\XFEExtension.NetCore.AutoImplement.csproj", "{E74B6938-9516-4211-88EB-5C68EB76FD62}"
6
ProjectSection(ProjectDependencies) = postProject
7
{BECB5988-CA6E-471E-AFE8-C8416BC5A9B2} = {BECB5988-CA6E-471E-AFE8-C8416BC5A9B2}
8
EndProjectSection
9
EndProject
10
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XFEExtension.NetCore.AutoImplement.Analyzer", "XFEExtension.NetCore.AutoImplement.Analyzer\XFEExtension.NetCore.AutoImplement.Analyzer.csproj", "{BECB5988-CA6E-471E-AFE8-C8416BC5A9B2}"
6
11
EndProject
7
12
Global
8
13
GlobalSection(ExtensibilityGlobals) = postSolution
9
14
SolutionGuid = {3C237470-3400-4B76-862D-63B1608FE3D8}
10
15
EndGlobalSection
11
16
GlobalSection(ProjectConfigurationPlatforms) = postSolution
17
{BECB5988-CA6E-471E-AFE8-C8416BC5A9B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18
{BECB5988-CA6E-471E-AFE8-C8416BC5A9B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
19
{BECB5988-CA6E-471E-AFE8-C8416BC5A9B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
20
{BECB5988-CA6E-471E-AFE8-C8416BC5A9B2}.Release|Any CPU.Build.0 = Release|Any CPU
12
21
{E74B6938-9516-4211-88EB-5C68EB76FD62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13
22
{E74B6938-9516-4211-88EB-5C68EB76FD62}.Debug|Any CPU.Build.0 = Debug|Any CPU
14
23
{E74B6938-9516-4211-88EB-5C68EB76FD62}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -1,7 +0,0 @@
1
namespace XFEExtension.NetCore.AutoImplement
2
{
3
public class Class1
4
{
5
6
}
7
}
@@ -0,0 +1,7 @@
1
namespace XFEExtension.NetCore.AutoImplement;
2
3
/// <summary>
4
/// 创建一个类的实现类
5
/// </summary>
6
[AttributeUsage(AttributeTargets.Class)]
7
public class CreateImpl : Attribute { }
@@ -4,6 +4,36 @@
4
4
<TargetFramework>net8.0</TargetFramework>
5
5
<ImplicitUsings>enable</ImplicitUsings>
6
6
<Nullable>enable</Nullable>
7
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
8
<Title>AutoImplement</Title>
9
<Authors>XFEstudio</Authors>
10
<Company>寰宇朽力网络科技有限公司</Company>
11
<Copyright>寰宇朽力网络科技有限公司版权所有</Copyright>
12
<Description>自动生成实现类</Description>
13
<PackageProjectUrl>https://github.com/XFEstudio/XFEExtension.NetCore.AutoImplement.git</PackageProjectUrl>
14
<PackageIcon>logoIcon.png</PackageIcon>
15
<PackageReadmeFile>README.md</PackageReadmeFile>
16
<RepositoryUrl>https://github.com/XFEstudio/XFEExtension.NetCore.AutoImplement.git</RepositoryUrl>
17
<PackageTags>XFE;impl;implement;auto</PackageTags>
18
<PackageReleaseNotes>First Release</PackageReleaseNotes>
19
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
20
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
7
21
</PropertyGroup>
8
22
23
<ItemGroup>
24
<None Include="..\LICENSE.txt">
25
<Pack>True</Pack>
26
<PackagePath>\</PackagePath>
27
</None>
28
<None Include="..\logoIcon.png">
29
<Pack>True</Pack>
30
<PackagePath>\</PackagePath>
31
</None>
32
<None Include="..\README.md">
33
<Pack>True</Pack>
34
<PackagePath>\</PackagePath>
35
</None>
36
<None Include="..\XFEExtension.NetCore.AutoImplement.Analyzer\bin\Release\netstandard2.0\XFEExtension.NetCore.AutoImplement.Analyzer.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
37
</ItemGroup>
38
9
39
</Project>
二进制文件已变更,无法进行逐行预览。