XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.AutoImplement

【DLL】自动生成实现类

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.AutoImplement

从XFEExtetnsion迁移

f1d0292
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

9 个文件 +191 -8
Modified LICENSE.txt +1 -1
@@ -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
Added README.md +24 -0
@@ -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 ```
Added XFEExtension.NetCore.AutoImplement.Analyzer/Generator/ImplementAutoGenerator.cs +100 -0
@@ -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 }
Added XFEExtension.NetCore.AutoImplement.Analyzer/XFEExtension.NetCore.AutoImplement.Analyzer.csproj +20 -0
@@ -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>
Modified XFEExtension.NetCore.AutoImplement.sln +9 -0
@@ -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
Deleted XFEExtension.NetCore.AutoImplement/Class1.cs +0 -7
@@ -1,7 +0,0 @@
1 namespace XFEExtension.NetCore.AutoImplement
2 {
3 public class Class1
4 {
5
6 }
7 }
Added XFEExtension.NetCore.AutoImplement/CreateImpl.cs +7 -0
@@ -0,0 +1,7 @@
1 namespace XFEExtension.NetCore.AutoImplement;
2
3 /// <summary>
4 /// 创建一个类的实现类
5 /// </summary>
6 [AttributeUsage(AttributeTargets.Class)]
7 public class CreateImpl : Attribute { }
Modified XFEExtension.NetCore.AutoImplement/XFEExtension.NetCore.AutoImplement.csproj +30 -0
@@ -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>
Added logoIcon.png +0 -0
二进制文件已变更,无法进行逐行预览。