From 8e1cd89bf0f6a2facaac6c5727fb3f0281f67382 Mon Sep 17 00:00:00 2001 From: lindexi Date: Fri, 2 Feb 2024 11:02:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=20Telescope=20=E6=94=BE=E5=9C=A8?= =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/dotnet-campus/Telescope --- .github/workflows/dotnetcore.yml | 1 - .github/workflows/nuget publish.yml | 1 - README.md | 2 + SourceFusion.sln | 78 ---- build/config.xml | 5 - .../AssemblyCandidateClassParseResult.cs | 50 --- .../Context_/MarkClassParseResult.cs | 47 -- .../MarkExportAttributeParseResult.cs | 24 - .../Analyzers/Core/AccessibilityHelper.cs | 18 - .../Analyzers/Core/AssemblyInfo.cs | 36 -- .../Analyzers/Core/AssemblySymbolHelper.cs | 92 ---- .../Analyzers/Core/AttributeCodeReWriter.cs | 102 ----- .../Core/ExportedTypesCodeTextGenerator.cs | 120 ----- .../Core/IncrementalValuesProviderHelper.cs | 17 - .../Core/SourceCodeGeneratorHelper.cs | 251 ----------- .../Analyzers/Core/TypeSymbolHelper.cs | 57 --- .../Core/ValueTuple_/ValueTupleInfo.cs | 16 - .../Core/ValueTuple_/ValueTupleInfoParser.cs | 47 -- .../ValueTupleItemSyntaxAndSymbolInfo.cs | 25 -- .../Analyzers/Diagnostics/TesDiagnostics.cs | 79 ---- .../TelescopeExportAttribute.cs | 12 - .../CandidateClassCollectionResult.cs | 17 - .../CandidateClassTypeResult.cs | 21 - ...upleExportMethodReturnTypeCodeGenerator.cs | 71 --- .../ExportMethodCodeGenerator.cs | 32 -- .../ExportMethodReturnType.cs | 13 - ...ortMethodReturnTypeCollectionDiagnostic.cs | 20 - .../ExportMethodReturnTypeCollectionResult.cs | 77 ---- .../ExportTypeCollectionResult.cs | 47 -- .../IExportMethodCodeGenerator.cs | 14 - ...IExportMethodReturnTypeCollectionResult.cs | 9 - ...eExportTypeToMethodIncrementalGenerator.cs | 424 ------------------ .../Analyzers/Properties/Resource.Designer.cs | 63 --- .../Properties/Resources.Designer.cs | 108 ----- .../Analyzers/Properties/Resources.resx | 135 ------ .../Analyzers/README.md | 79 ---- .../TelescopeIncrementalGenerator.cs | 243 ---------- ....Telescope.SourceGeneratorAnalyzers.csproj | 38 -- ...ourceGeneratorAnalyzers.csproj.DotSettings | 6 - .../Demo/DemoLib1/F1.cs | 13 - ...e.SourceGeneratorAnalyzers.DemoLib1.csproj | 13 - .../Demo/DemoLib2/F2.cs | 14 - ...e.SourceGeneratorAnalyzers.DemoLib2.csproj | 13 - .../Demo/DemoLib3/F3.cs | 14 - .../Demo/DemoLib3/FooWithAttribute.cs | 7 - ...e.SourceGeneratorAnalyzers.DemoLib3.csproj | 13 - .../AssemblyInfo.cs | 4 - .../TelescopeSourceGeneratorDemo/Program.cs | 75 ---- ...scope.SourceGeneratorAnalyzers.Demo.csproj | 17 - ...cope.SourceGeneratorAnalyzers.NuGet.csproj | 22 - .../Assets/build/Package.targets | 110 ----- .../buildMultiTargeting/Package.targets | 10 - .../Assets/tools/.gitignore | 2 - .../dotnetCampus.Telescope.NuGet.csproj | 36 -- .../DemoAttribute.cs | 19 - .../Directory.Build.targets | 3 - src/dotnetCampus.Telescope.Sample/IDemo.cs | 13 - .../Impl/Demo1.cs | 16 - .../Impl/Demo2.cs | 10 - src/dotnetCampus.Telescope.Sample/Program.cs | 19 - .../Properties/AssemblyInfo.cs | 10 - .../dotnetCampus.Telescope.Sample.csproj | 15 - .../AttributedTypeMetadata.cs | 25 -- src/dotnetCampus.Telescope/AttributedTypes.cs | 102 ----- .../ICompileTimeAttributedTypesExporter.cs | 19 - .../InternalContracts.cs | 29 -- .../MarkExportAttribute.cs | 30 -- .../dotnetCampus.Telescope.csproj | 13 - src/dotnetCampus.TelescopeTask/Cli/Options.cs | 27 -- .../AttributedTypesExportFileGenerator.cs | 77 ---- src/dotnetCampus.TelescopeTask/Program.cs | 35 -- .../Tasks/CommandLineTask.cs | 12 - .../Tasks/CompileTask.cs | 124 ----- .../AllFilesLastWriteTimeRebuildingTester.cs | 35 -- .../Utils/RebuildingTester.cs | 29 -- .../dotnetCampus.TelescopeTask.csproj | 33 -- 76 files changed, 2 insertions(+), 3553 deletions(-) delete mode 100644 build/config.xml delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Context_/AssemblyCandidateClassParseResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Context_/MarkClassParseResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Context_/MarkExportAttributeParseResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/AccessibilityHelper.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/AssemblyInfo.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/AssemblySymbolHelper.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/AttributeCodeReWriter.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/ExportedTypesCodeTextGenerator.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/IncrementalValuesProviderHelper.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/TypeSymbolHelper.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfo.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfoParser.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleItemSyntaxAndSymbolInfo.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Diagnostics/TesDiagnostics.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/EmbeddedResourceCode/TelescopeExportAttribute.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassCollectionResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassTypeResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodCodeGenerator.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnType.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionDiagnostic.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportTypeCollectionResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodCodeGenerator.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodReturnTypeCollectionResult.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Properties/Resource.Designer.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Properties/Resources.Designer.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/Properties/Resources.resx delete mode 100644 src/TelescopeSourceGenerator/Analyzers/README.md delete mode 100644 src/TelescopeSourceGenerator/Analyzers/TelescopeIncrementalGenerator.cs delete mode 100644 src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj delete mode 100644 src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj.DotSettings delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib1/F1.cs delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib1/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1.csproj delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib2/F2.cs delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib2/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2.csproj delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib3/FooWithAttribute.cs delete mode 100644 src/TelescopeSourceGenerator/Demo/DemoLib3/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3.csproj delete mode 100644 src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/AssemblyInfo.cs delete mode 100644 src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs delete mode 100644 src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.csproj delete mode 100644 src/TelescopeSourceGenerator/NuGet/dotnetCampus.Telescope.SourceGeneratorAnalyzers.NuGet.csproj delete mode 100644 src/dotnetCampus.Telescope.NuGet/Assets/build/Package.targets delete mode 100644 src/dotnetCampus.Telescope.NuGet/Assets/buildMultiTargeting/Package.targets delete mode 100644 src/dotnetCampus.Telescope.NuGet/Assets/tools/.gitignore delete mode 100644 src/dotnetCampus.Telescope.NuGet/dotnetCampus.Telescope.NuGet.csproj delete mode 100644 src/dotnetCampus.Telescope.Sample/DemoAttribute.cs delete mode 100644 src/dotnetCampus.Telescope.Sample/Directory.Build.targets delete mode 100644 src/dotnetCampus.Telescope.Sample/IDemo.cs delete mode 100644 src/dotnetCampus.Telescope.Sample/Impl/Demo1.cs delete mode 100644 src/dotnetCampus.Telescope.Sample/Impl/Demo2.cs delete mode 100644 src/dotnetCampus.Telescope.Sample/Program.cs delete mode 100644 src/dotnetCampus.Telescope.Sample/Properties/AssemblyInfo.cs delete mode 100644 src/dotnetCampus.Telescope.Sample/dotnetCampus.Telescope.Sample.csproj delete mode 100644 src/dotnetCampus.Telescope/AttributedTypeMetadata.cs delete mode 100644 src/dotnetCampus.Telescope/AttributedTypes.cs delete mode 100644 src/dotnetCampus.Telescope/ICompileTimeAttributedTypesExporter.cs delete mode 100644 src/dotnetCampus.Telescope/InternalContracts.cs delete mode 100644 src/dotnetCampus.Telescope/MarkExportAttribute.cs delete mode 100644 src/dotnetCampus.Telescope/dotnetCampus.Telescope.csproj delete mode 100644 src/dotnetCampus.TelescopeTask/Cli/Options.cs delete mode 100644 src/dotnetCampus.TelescopeTask/CodeGenerating/AttributedTypesExportFileGenerator.cs delete mode 100644 src/dotnetCampus.TelescopeTask/Program.cs delete mode 100644 src/dotnetCampus.TelescopeTask/Tasks/CommandLineTask.cs delete mode 100644 src/dotnetCampus.TelescopeTask/Tasks/CompileTask.cs delete mode 100644 src/dotnetCampus.TelescopeTask/Utils/AllFilesLastWriteTimeRebuildingTester.cs delete mode 100644 src/dotnetCampus.TelescopeTask/Utils/RebuildingTester.cs delete mode 100644 src/dotnetCampus.TelescopeTask/dotnetCampus.TelescopeTask.csproj diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index e2a9349..13cd165 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -14,6 +14,5 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: '8.0.x' - include-prerelease: true - name: Build with dotnet run: dotnet build --configuration Release -v n diff --git a/.github/workflows/nuget publish.yml b/.github/workflows/nuget publish.yml index f01d921..820522b 100644 --- a/.github/workflows/nuget publish.yml +++ b/.github/workflows/nuget publish.yml @@ -15,7 +15,6 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: '8.0.x' - include-prerelease: true - name: Install dotnet tool run: dotnet tool install -g dotnetCampus.TagToVersion diff --git a/README.md b/README.md index 294dfb9..267452b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ SourceFusion 是一套预编译框架。 |--|--| |![](https://github.com/dotnet-campus/SourceFusion/workflows/.NET%20Core/badge.svg)|[![](https://img.shields.io/nuget/v/dotnetCampus.SourceFusion.svg)](https://www.nuget.org/packages/dotnetCampus.SourceFusion)| +** 由于 SourceFusion 编写过早导致技术过于陈旧且 API 设计不够现代化,更推荐你使用设计和兼容性更优的 [Telescope](https://github.com/dotnet-campus/Telescope) 代替 ** + ## 入门 ### 安装 NuGet 包 diff --git a/SourceFusion.sln b/SourceFusion.sln index f2117d9..15d5c62 100644 --- a/SourceFusion.sln +++ b/SourceFusion.sln @@ -20,31 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution build\Version.props = build\Version.props EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope", "src\dotnetCampus.Telescope\dotnetCampus.Telescope.csproj", "{556913DF-6532-4532-B514-2D1184ADC75B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{78213588-C3B8-4E86-A19B-73DECD1ABA7B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.Sample", "src\dotnetCampus.Telescope.Sample\dotnetCampus.Telescope.Sample.csproj", "{50AE25A2-DF1B-4DE9-A7BE-C406F6497376}" - ProjectSection(ProjectDependencies) = postProject - {84DA7EE9-B511-407E-A510-DF390C742F0D} = {84DA7EE9-B511-407E-A510-DF390C742F0D} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.TelescopeTask", "src\dotnetCampus.TelescopeTask\dotnetCampus.TelescopeTask.csproj", "{09FF40A1-C13C-4D29-93B2-7A7C34D15694}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.NuGet", "src\dotnetCampus.Telescope.NuGet\dotnetCampus.Telescope.NuGet.csproj", "{84DA7EE9-B511-407E-A510-DF390C742F0D}" - ProjectSection(ProjectDependencies) = postProject - {09FF40A1-C13C-4D29-93B2-7A7C34D15694} = {09FF40A1-C13C-4D29-93B2-7A7C34D15694} - {556913DF-6532-4532-B514-2D1184ADC75B} = {556913DF-6532-4532-B514-2D1184ADC75B} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SourceGenerator", "SourceGenerator", "{A9879CB9-D164-4A0F-9F7A-D4B86C66BD68}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.SourceGeneratorAnalyzers", "src\TelescopeSourceGenerator\Analyzers\dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj", "{C8BB3F7F-344C-40B4-BF00-005575C8C91A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo", "src\TelescopeSourceGenerator\Demo\TelescopeSourceGeneratorDemo\dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.csproj", "{350C2DAF-7AD8-4285-9C8F-737D4D078B65}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.SourceGeneratorAnalyzers.NuGet", "src\TelescopeSourceGenerator\NuGet\dotnetCampus.Telescope.SourceGeneratorAnalyzers.NuGet.csproj", "{F1E2D63D-A05A-4647-ADB3-750A9F651D22}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub Actions", "GitHub Actions", "{5A85E9ED-415C-4720-BF26-8CF8A97CB832}" ProjectSection(SolutionItems) = preProject ..\Ipc\.github\workflows\dotnet-core.yml = ..\Ipc\.github\workflows\dotnet-core.yml @@ -52,12 +27,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub Actions", "GitHub Ac ..\Ipc\.github\workflows\nuget-tag-publish.yml = ..\Ipc\.github\workflows\nuget-tag-publish.yml EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1", "src\TelescopeSourceGenerator\Demo\DemoLib1\dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1.csproj", "{D9EA5A56-A4E4-4994-B634-8C1B1256D393}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2", "src\TelescopeSourceGenerator\Demo\DemoLib2\dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2.csproj", "{804D6902-6885-42A7-9EC3-BB0E09AAD3F2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3", "src\TelescopeSourceGenerator\Demo\DemoLib3\dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3.csproj", "{F1E050D2-E840-4793-8E97-024FBAD8908A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -76,59 +45,12 @@ Global {5978AAB0-C4C1-44AF-AB92-27F8ECBF6F69}.Debug|Any CPU.Build.0 = Debug|Any CPU {5978AAB0-C4C1-44AF-AB92-27F8ECBF6F69}.Release|Any CPU.ActiveCfg = Release|Any CPU {5978AAB0-C4C1-44AF-AB92-27F8ECBF6F69}.Release|Any CPU.Build.0 = Release|Any CPU - {556913DF-6532-4532-B514-2D1184ADC75B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {556913DF-6532-4532-B514-2D1184ADC75B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {556913DF-6532-4532-B514-2D1184ADC75B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {556913DF-6532-4532-B514-2D1184ADC75B}.Release|Any CPU.Build.0 = Release|Any CPU - {50AE25A2-DF1B-4DE9-A7BE-C406F6497376}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50AE25A2-DF1B-4DE9-A7BE-C406F6497376}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50AE25A2-DF1B-4DE9-A7BE-C406F6497376}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50AE25A2-DF1B-4DE9-A7BE-C406F6497376}.Release|Any CPU.Build.0 = Release|Any CPU - {09FF40A1-C13C-4D29-93B2-7A7C34D15694}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {09FF40A1-C13C-4D29-93B2-7A7C34D15694}.Debug|Any CPU.Build.0 = Debug|Any CPU - {09FF40A1-C13C-4D29-93B2-7A7C34D15694}.Release|Any CPU.ActiveCfg = Release|Any CPU - {09FF40A1-C13C-4D29-93B2-7A7C34D15694}.Release|Any CPU.Build.0 = Release|Any CPU - {84DA7EE9-B511-407E-A510-DF390C742F0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {84DA7EE9-B511-407E-A510-DF390C742F0D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {84DA7EE9-B511-407E-A510-DF390C742F0D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {84DA7EE9-B511-407E-A510-DF390C742F0D}.Release|Any CPU.Build.0 = Release|Any CPU - {C8BB3F7F-344C-40B4-BF00-005575C8C91A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C8BB3F7F-344C-40B4-BF00-005575C8C91A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C8BB3F7F-344C-40B4-BF00-005575C8C91A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C8BB3F7F-344C-40B4-BF00-005575C8C91A}.Release|Any CPU.Build.0 = Release|Any CPU - {350C2DAF-7AD8-4285-9C8F-737D4D078B65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {350C2DAF-7AD8-4285-9C8F-737D4D078B65}.Debug|Any CPU.Build.0 = Debug|Any CPU - {350C2DAF-7AD8-4285-9C8F-737D4D078B65}.Release|Any CPU.ActiveCfg = Release|Any CPU - {350C2DAF-7AD8-4285-9C8F-737D4D078B65}.Release|Any CPU.Build.0 = Release|Any CPU - {F1E2D63D-A05A-4647-ADB3-750A9F651D22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1E2D63D-A05A-4647-ADB3-750A9F651D22}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1E2D63D-A05A-4647-ADB3-750A9F651D22}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1E2D63D-A05A-4647-ADB3-750A9F651D22}.Release|Any CPU.Build.0 = Release|Any CPU - {D9EA5A56-A4E4-4994-B634-8C1B1256D393}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9EA5A56-A4E4-4994-B634-8C1B1256D393}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9EA5A56-A4E4-4994-B634-8C1B1256D393}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9EA5A56-A4E4-4994-B634-8C1B1256D393}.Release|Any CPU.Build.0 = Release|Any CPU - {804D6902-6885-42A7-9EC3-BB0E09AAD3F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {804D6902-6885-42A7-9EC3-BB0E09AAD3F2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {804D6902-6885-42A7-9EC3-BB0E09AAD3F2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {804D6902-6885-42A7-9EC3-BB0E09AAD3F2}.Release|Any CPU.Build.0 = Release|Any CPU - {F1E050D2-E840-4793-8E97-024FBAD8908A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1E050D2-E840-4793-8E97-024FBAD8908A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1E050D2-E840-4793-8E97-024FBAD8908A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1E050D2-E840-4793-8E97-024FBAD8908A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {5978AAB0-C4C1-44AF-AB92-27F8ECBF6F69} = {02D03DE5-1A19-4002-92BD-0E3DC61A53C4} - {50AE25A2-DF1B-4DE9-A7BE-C406F6497376} = {78213588-C3B8-4E86-A19B-73DECD1ABA7B} - {C8BB3F7F-344C-40B4-BF00-005575C8C91A} = {A9879CB9-D164-4A0F-9F7A-D4B86C66BD68} - {350C2DAF-7AD8-4285-9C8F-737D4D078B65} = {A9879CB9-D164-4A0F-9F7A-D4B86C66BD68} - {F1E2D63D-A05A-4647-ADB3-750A9F651D22} = {A9879CB9-D164-4A0F-9F7A-D4B86C66BD68} - {D9EA5A56-A4E4-4994-B634-8C1B1256D393} = {A9879CB9-D164-4A0F-9F7A-D4B86C66BD68} - {804D6902-6885-42A7-9EC3-BB0E09AAD3F2} = {A9879CB9-D164-4A0F-9F7A-D4B86C66BD68} - {F1E050D2-E840-4793-8E97-024FBAD8908A} = {A9879CB9-D164-4A0F-9F7A-D4B86C66BD68} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {22702A10-22E1-4670-8FCA-9581202E6CAB} diff --git a/build/config.xml b/build/config.xml deleted file mode 100644 index c8c6697..0000000 --- a/build/config.xml +++ /dev/null @@ -1,5 +0,0 @@ - - ..\SourceFusion.sln - ..\bin\Release - CC\SourceFusion - diff --git a/src/TelescopeSourceGenerator/Analyzers/Context_/AssemblyCandidateClassParseResult.cs b/src/TelescopeSourceGenerator/Analyzers/Context_/AssemblyCandidateClassParseResult.cs deleted file mode 100644 index 1268948..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Context_/AssemblyCandidateClassParseResult.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Collections.Immutable; - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 程序集里可能被标记导出的类型 -/// -readonly struct AssemblyCandidateClassParseResult -{ - public AssemblyCandidateClassParseResult(INamedTypeSymbol exportedTypeSymbol, ImmutableArray attributes, GeneratorSyntaxContext generatorSyntaxContext) - { - ExportedTypeSymbol = exportedTypeSymbol; - Attributes = attributes; - GeneratorSyntaxContext = generatorSyntaxContext; - Success = true; - } - - public AssemblyCandidateClassParseResult() - { - Success = false; - ExportedTypeSymbol = default!; // 这个瞬间就被过滤掉了,先不考虑可空的复杂写法了 - Attributes = default; - GeneratorSyntaxContext = default; - } - - /// - /// 导出类型的语义符号 - /// - public INamedTypeSymbol ExportedTypeSymbol { get; } - - /// - /// 导出类型的语法符号 - /// - public ClassDeclarationSyntax ExportedTypeClassDeclarationSyntax => (ClassDeclarationSyntax) GeneratorSyntaxContext.Node; - - /// - /// 类型标记的特性 - /// - public ImmutableArray Attributes { get; } - - public GeneratorSyntaxContext GeneratorSyntaxContext { get; } - - /// - /// 是否成功,用于过滤掉不满足条件的对象 - /// - public bool Success { get; } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Context_/MarkClassParseResult.cs b/src/TelescopeSourceGenerator/Analyzers/Context_/MarkClassParseResult.cs deleted file mode 100644 index 1d1c0a6..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Context_/MarkClassParseResult.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 被标记的类型的转换结果,约等于生成代码前的最终结果 -/// -readonly struct MarkClassParseResult -{ - public MarkClassParseResult(INamedTypeSymbol exportedTypeSymbol, ClassDeclarationSyntax exportedTypeClassDeclarationSyntax, - AttributeData matchAssemblyMarkAttributeData, AttributeSyntax matchAssemblyMarkAttributeSyntax, - MarkExportAttributeParseResult markExportAttributeParseResult, - GeneratorSyntaxContext generatorSyntaxContext) - { - ExportedTypeSymbol = exportedTypeSymbol; - ExportedTypeClassDeclarationSyntax = exportedTypeClassDeclarationSyntax; - MatchAssemblyMarkAttributeData = matchAssemblyMarkAttributeData; - MatchAssemblyMarkAttributeSyntax = matchAssemblyMarkAttributeSyntax; - MarkExportAttributeParseResult = markExportAttributeParseResult; - GeneratorSyntaxContext = generatorSyntaxContext; - } - - /// - /// 导出的 class 类型的语义 - /// - public INamedTypeSymbol ExportedTypeSymbol { get; } - /// - /// 导出的 class 类型的语法 - /// - public ClassDeclarationSyntax ExportedTypeClassDeclarationSyntax { get; } - /// - /// 类型上标记的程序集指定特性的语义 - /// - public AttributeData MatchAssemblyMarkAttributeData { get; } - /// - /// 类型上标记的程序集指定特性的语法 - /// - public AttributeSyntax MatchAssemblyMarkAttributeSyntax { get; } - - /// - /// 程序集特性里面的定义结果 - /// - public MarkExportAttributeParseResult MarkExportAttributeParseResult { get; } - - public GeneratorSyntaxContext GeneratorSyntaxContext { get; } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Context_/MarkExportAttributeParseResult.cs b/src/TelescopeSourceGenerator/Analyzers/Context_/MarkExportAttributeParseResult.cs deleted file mode 100644 index 721d7d9..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Context_/MarkExportAttributeParseResult.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -readonly struct MarkExportAttributeParseResult -{ - public MarkExportAttributeParseResult(bool success, ITypeSymbol baseClassOrInterfaceTypeInfo, - ITypeSymbol attributeTypeInfo) - { - Success = success; - BaseClassOrInterfaceTypeInfo = baseClassOrInterfaceTypeInfo; - AttributeTypeInfo = attributeTypeInfo; - } - - public bool Success { get; } - public ITypeSymbol BaseClassOrInterfaceTypeInfo { get; } - - public ITypeSymbol AttributeTypeInfo { get; } - - /// - /// 获取表示失败的特性解析结果。 - /// - public static MarkExportAttributeParseResult Failure { get; } = new MarkExportAttributeParseResult(false, default!, default!); -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/AccessibilityHelper.cs b/src/TelescopeSourceGenerator/Analyzers/Core/AccessibilityHelper.cs deleted file mode 100644 index b69caa2..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/AccessibilityHelper.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -static class AccessibilityHelper -{ - public static string ToCSharpCode(this Accessibility accessibility) - => accessibility switch - { - Accessibility.Public => "public", - Accessibility.Private => "private", - Accessibility.Internal => "internal", - Accessibility.Protected => "protected", - Accessibility.ProtectedAndInternal => "private protected", - _ => string.Empty - }; -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/AssemblyInfo.cs b/src/TelescopeSourceGenerator/Analyzers/Core/AssemblyInfo.cs deleted file mode 100644 index 2a41196..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -internal static class AssemblyInfo -{ - public static string ToolName => - Assembly.GetExecutingAssembly().GetCustomAttribute().Product; - - public static string ToolVersion => - Assembly.GetExecutingAssembly().GetCustomAttribute() - .InformationalVersion; - - /// - /// 如果需要为类加上 ,则使用此字符串。 - /// - public static string GeneratedCodeAttribute => - $@"[global::System.CodeDom.Compiler.GeneratedCode(""{ToolName}"", ""{ToolVersion}"")]"; - - /// - /// 获取可以为每一个生成的文件都增加的文件头。 - /// - public const string GeneratedCodeComment = - $@"//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -#define GENERATED_CODE - -"; -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/AssemblySymbolHelper.cs b/src/TelescopeSourceGenerator/Analyzers/Core/AssemblySymbolHelper.cs deleted file mode 100644 index a1d4c2b..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/AssemblySymbolHelper.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Microsoft.CodeAnalysis; - -using System.Collections.Generic; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -static class AssemblySymbolHelper -{ - /// - /// 获取当前程序集里面的所有类型 - /// - /// - /// - public static IEnumerable GetAllTypeSymbols(IAssemblySymbol assemblySymbol) => GetAllTypeSymbols(assemblySymbol.GlobalNamespace); - - public static IEnumerable GetAllTypeSymbols(INamespaceSymbol namespaceSymbol) - { - var typeMemberList = namespaceSymbol.GetTypeMembers(); - - foreach (var typeSymbol in typeMemberList) - { - yield return typeSymbol; - } - - foreach (var namespaceMember in namespaceSymbol.GetNamespaceMembers()) - { - foreach (var typeSymbol in GetAllTypeSymbols(namespaceMember)) - { - yield return typeSymbol; - } - } - } - - public static bool IsReference(IAssemblySymbol currentAssemblySymbol, IAssemblySymbol requiredAssemblySymbol) - { - var visited = new Dictionary(SymbolEqualityComparer.Default); - return IsReference(currentAssemblySymbol, requiredAssemblySymbol, visited); - } - - public static bool IsReference(IAssemblySymbol currentAssemblySymbol, IAssemblySymbol requiredAssemblySymbol, - Dictionary visited) - { - if (SymbolEqualityComparer.Default.Equals(currentAssemblySymbol, requiredAssemblySymbol)) - { - // 这个就看业务了,如果两个程序集是相同的,是否判断为引用关系 - return true; - } - - foreach (var moduleSymbol in currentAssemblySymbol.Modules) - { - foreach (var referencedAssemblySymbol in moduleSymbol.ReferencedAssemblySymbols) - { - if (SymbolEqualityComparer.Default.Equals(referencedAssemblySymbol, requiredAssemblySymbol)) - { - // 记录当前程序集存在引用关系 - visited[currentAssemblySymbol] = true; - return true; - } - else if (SymbolEqualityComparer.Default.Equals(referencedAssemblySymbol, currentAssemblySymbol)) - { - // 循环引用,跳过 - continue; - } - else - { - if (visited.TryGetValue(referencedAssemblySymbol, out var isReference)) - { - // 这个是访问过的,那就从字典获取缓存,不需要再访问一次 - // 同时也能解决程序集循环引用问题 - } - else - { - // 进入递归之前,先将自身设置到字典,先设置为没有引用。防止循环引用炸掉 - visited[referencedAssemblySymbol] = false; - - // 没有访问过的,获取引用的程序集是否存在引用关系 - isReference = IsReference(referencedAssemblySymbol, requiredAssemblySymbol, visited); - visited[referencedAssemblySymbol] = isReference; - } - - if (isReference) - { - // 如果这个程序集有引用,那也算上 - return true; - } - } - } - } - - return false; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/AttributeCodeReWriter.cs b/src/TelescopeSourceGenerator/Analyzers/Core/AttributeCodeReWriter.cs deleted file mode 100644 index f0a86be..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/AttributeCodeReWriter.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -static class AttributeCodeReWriter -{ - /// - /// 从 转换为特性生成代码。从 `[Foo(xx, xxx)]` 语义转换为 `new Foo(xx, xxx)` 的生成代码 - /// - /// - /// - public static string GetAttributeCreatedCode(AttributeData attributeData) - { - // 放在特性的构造函数的参数列表,例如 [Foo(1,2,3)] 将会获取到 `1` `2` `3` 三个参数 - var constructorArgumentCodeList = new List(); - foreach (TypedConstant constructorArgument in attributeData.ConstructorArguments) - { - var constructorArgumentCode = TypedConstantToCodeString(constructorArgument); - - constructorArgumentCodeList.Add(constructorArgumentCode); - } - - var namedArgumentCodeList = new List<(string propertyName, string valueCode)>(); - foreach (var keyValuePair in attributeData.NamedArguments) - { - var key = keyValuePair.Key; - - var typedConstant = keyValuePair.Value; - var argumentCode = TypedConstantToCodeString(typedConstant); - - namedArgumentCodeList.Add((key, argumentCode)); - } - - return - $@"new {TypeSymbolHelper.TypeSymbolToFullName(attributeData.AttributeClass!)}({string.Join(",", constructorArgumentCodeList)}) -{{ - {string.Join(@", - ", namedArgumentCodeList.Select(x => $"{x.propertyName} = {x.valueCode}"))} -}}"; - - static string TypedConstantToCodeString(TypedConstant typedConstant) - { - var constructorArgumentValue = typedConstant.Value; - - string constructorArgumentCode; - switch (typedConstant.Kind) - { - case TypedConstantKind.Enum: - { - // "(Foo.Enum1) 1" - constructorArgumentCode = - $"({TypeSymbolHelper.TypeSymbolToFullName(typedConstant.Type!)}) {typedConstant.Value}"; - break; - } - case TypedConstantKind.Type: - { - var typeSymbol = (ITypeSymbol?)constructorArgumentValue; - if (typeSymbol is null) - { - constructorArgumentCode = "null"; - } - else - { - constructorArgumentCode = $"typeof({TypeSymbolHelper.TypeSymbolToFullName(typeSymbol)})"; - } - - break; - } - case TypedConstantKind.Primitive: - { - if (typedConstant.Value is string text) - { - constructorArgumentCode = "\"" + text + "\""; - } - else if (typedConstant.Value is true) - { - constructorArgumentCode = "true"; - } - else if (typedConstant.Value is false) - { - constructorArgumentCode = "false"; - } - else - { - constructorArgumentCode = typedConstant.Value?.ToString() ?? "null"; - } - - break; - } - default: - { - constructorArgumentCode = typedConstant.Value?.ToString() ?? "null"; - break; - } - } - - return constructorArgumentCode; - } - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/ExportedTypesCodeTextGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/Core/ExportedTypesCodeTextGenerator.cs deleted file mode 100644 index 5a7ffc4..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/ExportedTypesCodeTextGenerator.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -class ExportedTypesCodeTextGenerator -{ - public string Generate(ImmutableArray markClassCollection, CancellationToken token) - { - if (markClassCollection.Length == 0) - { - // 如果没有任何需要导出的类型,那就不要创建任何代码 - return string.Empty; - } - - // 导出的接口 - var exportedInterfaces = new List(); - // 导出的方法 - var exportedMethodCodes = new List(); - - foreach (var markClassGroup in markClassCollection.GroupBy(t => t.MarkExportAttributeParseResult)) - { - token.ThrowIfCancellationRequested(); - - var markExportAttributeParseResult = markClassGroup.Key; - - var baseClassOrInterfaceName = - TypeSymbolHelper.TypeSymbolToFullName(markExportAttributeParseResult.BaseClassOrInterfaceTypeInfo); - var attributeName = TypeSymbolHelper.TypeSymbolToFullName(markExportAttributeParseResult.AttributeTypeInfo); - - var exportedItemList = new List(); - - foreach (var markClassParseResult in markClassGroup) - { - var typeName = TypeSymbolHelper.TypeSymbolToFullName(markClassParseResult.ExportedTypeSymbol); - - var attributeCreatedCode = - AttributeCodeReWriter.GetAttributeCreatedCode(markClassParseResult.MatchAssemblyMarkAttributeData); - - var itemCode = - @$"new AttributedTypeMetadata<{baseClassOrInterfaceName}, {attributeName}>(typeof({typeName}), {attributeCreatedCode}, () => new {typeName}())"; - exportedItemList.Add(itemCode); - } - - var arrayExpression = $@"new AttributedTypeMetadata<{baseClassOrInterfaceName}, {attributeName}>[] - {{ - {string.Join(@", - ", exportedItemList)} - }}"; - - var methodCode = - $@"AttributedTypeMetadata<{baseClassOrInterfaceName}, {attributeName}>[] ICompileTimeAttributedTypesExporter<{baseClassOrInterfaceName}, {attributeName}>.ExportAttributeTypes() - {{ - return {arrayExpression}; - }}"; - - exportedMethodCodes.Add(methodCode); - - exportedInterfaces.Add( - $@"ICompileTimeAttributedTypesExporter<{baseClassOrInterfaceName}, {attributeName}>"); - } - - var code = $@"using dotnetCampus.Telescope; - -namespace dotnetCampus.Telescope -{{ - public partial class __AttributedTypesExport__ : {string.Join(", ", exportedInterfaces)} - {{ - {string.Join(@" - ", exportedMethodCodes)} - }} -}}"; - code = FormatCode(code); - // 生成的代码示例: - /* -using dotnetCampus.Telescope; - -namespace dotnetCampus.Telescope -{ - public partial class __AttributedTypesExport__ : ICompileTimeAttributedTypesExporter - { - AttributedTypeMetadata[] ICompileTimeAttributedTypesExporter.ExportAttributeTypes() - { - return new AttributedTypeMetadata[] - { - new AttributedTypeMetadata - ( - typeof(global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.Foo), - new global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.FooAttribute(1, (global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.FooEnum)1, typeof(global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.Base), null) - { - Number2 = 2, - Type2 = typeof(global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.Foo), - FooEnum2 = (global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.FooEnum)0, - Type3 = null - }, - () => new global::dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.Foo() - ) - }; - } - } -} - */ - return code; - } - - /// - /// 格式化代码。 - /// - /// 未格式化的源代码。 - /// 格式化的源代码。 - private static string FormatCode(string sourceCode) - { - var rootSyntaxNode = CSharpSyntaxTree.ParseText(sourceCode).GetRoot(); - return rootSyntaxNode.NormalizeWhitespace().ToFullString(); - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/IncrementalValuesProviderHelper.cs b/src/TelescopeSourceGenerator/Analyzers/Core/IncrementalValuesProviderHelper.cs deleted file mode 100644 index 5fcaea9..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/IncrementalValuesProviderHelper.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -static class IncrementalValuesProviderHelper -{ - /// - /// 过滤掉空的值 - /// - /// - /// - /// - public static IncrementalValuesProvider ExcludeNulls(this IncrementalValuesProvider provider) - { - return provider.Where(static t => t != null).Select(static (t, _) => t!); - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs b/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs deleted file mode 100644 index 919dca2..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/SourceCodeGeneratorHelper.cs +++ /dev/null @@ -1,251 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading; - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -static class SourceCodeGeneratorHelper -{ - /// - /// 创建分部方法的代码 - /// - /// - /// 放在方法内的代码 - /// - /// - public static string GeneratePartialMethodCode(IMethodSymbol partialMethodSymbol, string methodCode, CancellationToken token) - { - var methodSource = new StringBuilder(); - - var accessibilityCode = - partialMethodSymbol.DeclaredAccessibility.ToCSharpCode(); - methodSource.Append(accessibilityCode).Append(' '); - - if (partialMethodSymbol.IsStatic) - { - methodSource.Append("static "); - } - - if (partialMethodSymbol.IsPartialDefinition) - { - methodSource.Append("partial "); - } - - var returnType = partialMethodSymbol.ReturnType; - GenerateTypeCode(returnType, methodSource, token); - - methodSource.Append(' '); - methodSource.Append(partialMethodSymbol.Name); - methodSource.AppendLine("()"); // 暂时只支持无参函数 - methodSource.AppendLine("{"); - methodSource.AppendLine(IndentSource(methodCode, 1, shouldFirstLine: true)); - methodSource.Append('}'); - - return methodSource.ToString(); - } - - /// - /// 根据传入的类型创建代码 - /// - /// - public static void GenerateTypeCode(ITypeSymbol typeSymbol, StringBuilder output, CancellationToken token) - { - var returnTypeCode = TypeSymbolHelper.TypeSymbolToFullName(typeSymbol); - output.Append(returnTypeCode); - if (typeSymbol is INamedTypeSymbol returnTypeNamedTypeSymbol && returnTypeNamedTypeSymbol.IsGenericType) - { - output.Append('<'); - for (var i = 0; i < returnTypeNamedTypeSymbol.TypeArguments.Length; i++) - { - token.ThrowIfCancellationRequested(); - - var typeArgument = returnTypeNamedTypeSymbol.TypeArguments[i]; - - if (typeArgument.IsTupleType && - ValueTupleInfoParser.TryParse(typeArgument, token, out var valueTupleInfo)) - { - output.Append('('); - for (var index = 0; index < valueTupleInfo.ItemList.Count; index++) - { - var info = valueTupleInfo.ItemList[index]; - - GenerateTypeCode(info.ItemType, output, token); - - if (!string.IsNullOrEmpty(info.ItemName)) - { - output.Append(' ') - .Append(info.ItemName); - } - - if (index != valueTupleInfo.ItemList.Count - 1) - { - output.Append(',').Append(' '); - } - } - - output.Append(')'); - } - else - { - GenerateTypeCode(typeArgument, output, token); - } - - if (i != returnTypeNamedTypeSymbol.TypeArguments.Length - 1) - { - output.Append(','); - } - } - - output.Append('>'); - } - } - - /// - /// 创建 partial 类型的代码 - /// - /// - /// 放在类型里面的代码 - /// - public static string GeneratePartialClassCode(INamedTypeSymbol partialClassType, string memberCode) - { - var symbolDisplayFormat = new SymbolDisplayFormat - ( - // 带上命名空间和类型名 - SymbolDisplayGlobalNamespaceStyle.Omitted, - // 命名空间之前加上 global 防止冲突 - SymbolDisplayTypeQualificationStyle - .NameAndContainingTypesAndNamespaces - ); - var @namespace = partialClassType.ContainingNamespace?.ToDisplayString(symbolDisplayFormat); - - if (TryGetClassDeclarationList(partialClassType, out var declarationList)) - { - int declarationCount = declarationList!.Count; - /* 以下代码用来解决嵌套类型 - for (int i = 0; i < declarationCount - 1; i++) - { - string declarationSource = $@" - {declarationList[declarationCount - 1 - i]} - {{"; - sb.Append($@" - {IndentSource(declarationSource, numIndentations: i + 1)} - "); - } - */ - - var isIncludeNamespace = !string.IsNullOrEmpty(@namespace); - var stringBuilder = new StringBuilder(AssemblyInfo.GeneratedCodeComment); - - if (isIncludeNamespace) - { - stringBuilder.Append(@$" - -namespace {@namespace} -{{"); - } - - // 不要带上 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 = $@" -{declarationList[0]} -{{ - {IndentSource(memberCode, Math.Max(1, declarationCount - 1))} -}}"; - stringBuilder.AppendLine(IndentSource(partialContextImplementation, numIndentations: declarationCount)); - if (isIncludeNamespace) - { - stringBuilder.AppendLine("}"); - } - - return stringBuilder.ToString(); - } - else - { - throw new ArgumentException($"无法为 {partialClassType} 创建代码"); - } - } - - /// - /// 尝试获取类型的定义 - /// - /// - /// 嵌套类的定义 - /// - private static bool TryGetClassDeclarationList(INamedTypeSymbol typeSymbol, out List? classDeclarationList) - { - INamedTypeSymbol currentSymbol = typeSymbol; - classDeclarationList = null; - - while (currentSymbol != null) - { - ClassDeclarationSyntax? classDeclarationSyntax = currentSymbol.DeclaringSyntaxReferences.First().GetSyntax() as ClassDeclarationSyntax; - - if (classDeclarationSyntax != null) - { - SyntaxTokenList tokenList = classDeclarationSyntax.Modifiers; - int tokenCount = tokenList.Count; - - bool isPartial = false; - - string[] declarationElements = new string[tokenCount + 2]; - - for (int i = 0; i < tokenCount; i++) - { - SyntaxToken token = tokenList[i]; - declarationElements[i] = token.Text; - - if (token.IsKind(SyntaxKind.PartialKeyword)) - { - isPartial = true; - } - } - - if (!isPartial) - { - classDeclarationList = null; - return false; - } - - declarationElements[tokenCount] = "class"; - declarationElements[tokenCount + 1] = currentSymbol.Name; - - (classDeclarationList ??= new List()).Add(string.Join(" ", declarationElements)); - } - - currentSymbol = currentSymbol.ContainingType; - } - - Debug.Assert(classDeclarationList != null); - Debug.Assert(classDeclarationList!.Count > 0); - return true; - } - - /// - /// 提供缩进的方法 - /// - /// - /// - /// - /// - public static string IndentSource(string source, int numIndentations, bool shouldFirstLine = false) - { - Debug.Assert(numIndentations >= 1); - var result = source.Replace("\r", "").Replace("\n", $"\r\n{new string(' ', 4 * numIndentations)}"); - - if (shouldFirstLine) - { - result = new string(' ', 4 * numIndentations) + result; - } - - return result; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/TypeSymbolHelper.cs b/src/TelescopeSourceGenerator/Analyzers/Core/TypeSymbolHelper.cs deleted file mode 100644 index 62e4234..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/TypeSymbolHelper.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -static class TypeSymbolHelper -{ - /// - /// 输出类型的完全限定名 - /// - public static string TypeSymbolToFullName(ITypeSymbol typeSymbol) - { - // 带上 global 格式的输出 FullName 内容 - var symbolDisplayFormat = new SymbolDisplayFormat - ( - // 带上命名空间和类型名 - SymbolDisplayGlobalNamespaceStyle.Included, - // 命名空间之前加上 global 防止冲突 - SymbolDisplayTypeQualificationStyle - .NameAndContainingTypesAndNamespaces - ); - - return typeSymbol.ToDisplayString(symbolDisplayFormat); - } - - /// - /// 判断类型继承关系 - /// - /// 当前的类型 - /// 需要继承的类型 - /// - public static bool IsInherit(ITypeSymbol currentType, ITypeSymbol requiredType) - { - var baseType = currentType.BaseType; - while (baseType is not null) - { - if (SymbolEqualityComparer.Default.Equals(baseType, requiredType)) - { - // 如果基类型是的话 - return true; - } - - // 否则继续找基类型 - baseType = baseType.BaseType; - } - - foreach (var currentInheritInterfaceType in currentType.AllInterfaces) - { - if (SymbolEqualityComparer.Default.Equals(currentInheritInterfaceType, requiredType)) - { - // 如果继承的类型是的话 - return true; - } - } - - return false; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfo.cs b/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfo.cs deleted file mode 100644 index c125e69..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfo.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -/// -/// 表示 ValueTuple 的信息 -/// -public class ValueTupleInfo -{ - public ValueTupleInfo(IReadOnlyList itemList) - { - ItemList = itemList; - } - - public IReadOnlyList ItemList { get; } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfoParser.cs b/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfoParser.cs deleted file mode 100644 index 0977cef..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleInfoParser.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -public static class ValueTupleInfoParser -{ - public static bool TryParse(ITypeSymbol type, CancellationToken token, out ValueTupleInfo valueTupleInfo) - { - valueTupleInfo = null!; - - if (type is not INamedTypeSymbol typeArgument) - { - return false; - } - - // 尝试判断是 ValueTuple 的情况 - // (Type type, FooAttribute xx, Func xxx) - if (type.IsValueType && typeArgument.TupleElements.Length > 0 && typeArgument.DeclaringSyntaxReferences[0].GetSyntax(token) is TupleTypeSyntax - valueTupleSyntaxNode) - { - Debug.Assert(typeArgument.TupleElements.Length == valueTupleSyntaxNode.Elements.Count); - - var list = new List(typeArgument.TupleElements.Length); - - for (var i = 0; i < valueTupleSyntaxNode.Elements.Count; i++) - { - var tupleItemTypeSymbol = typeArgument.TupleElements[i]; - ITypeSymbol typeSymbol = tupleItemTypeSymbol.Type; - // 这个是不对的,在开发者没有设置命名时,拿到的是 Item1 Item2 这样的命名 - //var name = tupleItemTypeSymbol.Name; - var tupleItemSyntax = valueTupleSyntaxNode.Elements[i]; - var name = tupleItemSyntax.Identifier.Text; - - list.Add(new ValueTupleItemSyntaxAndSymbolInfo(typeSymbol, name)); - } - - valueTupleInfo = new ValueTupleInfo(list); - return true; - } - - return false; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleItemSyntaxAndSymbolInfo.cs b/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleItemSyntaxAndSymbolInfo.cs deleted file mode 100644 index 9197e70..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Core/ValueTuple_/ValueTupleItemSyntaxAndSymbolInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -/// -/// 表示 ValueTuple 的每一项的定义内容 -/// -public class ValueTupleItemSyntaxAndSymbolInfo -{ - public ValueTupleItemSyntaxAndSymbolInfo(ITypeSymbol itemType, string itemName) - { - ItemType = itemType; - ItemName = itemName; - } - - /// - /// 类型 - /// - public ITypeSymbol ItemType { get; } - - /// - /// 命名。如果没有命名,那就是空字符串 - /// - public string ItemName { get; } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Diagnostics/TesDiagnostics.cs b/src/TelescopeSourceGenerator/Analyzers/Diagnostics/TesDiagnostics.cs deleted file mode 100644 index 09d3d31..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Diagnostics/TesDiagnostics.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Microsoft.CodeAnalysis; - -using System; -using System.Collections.Generic; -using System.Resources; -using System.Text; -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties; -using static dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources; - -using static Microsoft.CodeAnalysis.WellKnownDiagnosticTags; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Diagnostics; - -static class TesDiagnostics -{ - // ReSharper disable InconsistentNaming - public static DiagnosticDescriptor Tes000_UnknownError => new DiagnosticDescriptor - ( - nameof(Tes000), - Localize(nameof(Tes000)), - Localize(nameof(Tes000_Message)), - Categories.Compiler, - DiagnosticSeverity.Error, - true, - customTags: new[] { AnalyzerException, NotConfigurable } - ); - - public static DiagnosticDescriptor Tes001_MethodReturnTypeError => new DiagnosticDescriptor - ( - nameof(Tes001), - Localize(nameof(Tes001)), - Localize(nameof(Tes001_Message)), - Categories.Compiler, - DiagnosticSeverity.Error, - true, - customTags: new[] { AnalyzerException, NotConfigurable } - ); - - - private static class Categories - { - /// - /// 可能产生 bug,则报告此诊断。 - /// - public const string AvoidBugs = "dotnetCampus.AvoidBugs"; - - /// - /// 为了提供代码生成能力,则报告此诊断。 - /// - public const string CodeFixOnly = "dotnetCampus.CodeFixOnly"; - - /// - /// 因编译要求而必须满足的条件没有满足,则报告此诊断。 - /// - public const string Compiler = "dotnetCampus.Compiler"; - - /// - /// 因 Telescope 库内的机制限制,必须满足此要求 Telescope 才可正常工作,则报告此诊断。 - /// - public const string Mechanism = "dotnetCampus.Mechanism"; - - /// - /// 为了代码可读性,使之更易于理解、方便调试,则报告此诊断。 - /// - public const string Readable = "dotnetCampus.Readable"; - - /// - /// 能写得出来正常编译,但会引发运行时异常,则报告此诊断。 - /// - public const string RuntimeException = "dotnetCampus.RuntimeException"; - - /// - /// 编写了无法生效的代码,则报告此诊断。 - /// - public const string Useless = "dotnetCampus.Useless"; - } - - public static LocalizableString Localize(string key) => new LocalizableResourceString(key, dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources.ResourceManager, typeof(Resources)); -} diff --git a/src/TelescopeSourceGenerator/Analyzers/EmbeddedResourceCode/TelescopeExportAttribute.cs b/src/TelescopeSourceGenerator/Analyzers/EmbeddedResourceCode/TelescopeExportAttribute.cs deleted file mode 100644 index f6a49ba..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/EmbeddedResourceCode/TelescopeExportAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// ReSharper disable once CheckNamespace 这个代码将会被编到用户的代码里面,请不要随意改动 -namespace dotnetCampus.Telescope -{ - [global::System.AttributeUsage(global::System.AttributeTargets.Method, Inherited = false, AllowMultiple = false)] - sealed class TelescopeExportAttribute : global::System.Attribute - { - /// - /// 是否包含引用的程序集和 DLL 里面的类型导出。默认只导出当前程序集 - /// - public bool IncludeReferences { set; get; } - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassCollectionResult.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassCollectionResult.cs deleted file mode 100644 index ca702cc..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassCollectionResult.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 候选收集的结果 -/// -/// 包含所有的导出结果。比如项目里面有多个导出方法,每一个导出方法就是一个 CandidateClassTypeResult 对象 -class CandidateClassCollectionResult -{ - public CandidateClassCollectionResult(IReadOnlyList candidateClassTypeResultList) - { - CandidateClassTypeResultList = candidateClassTypeResultList; - } - - public IReadOnlyList CandidateClassTypeResultList { get; } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassTypeResult.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassTypeResult.cs deleted file mode 100644 index 6e595db..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/CandidateClassTypeResult.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 候选的导出类型结果 -/// -/// 包含标记导出的方法信息,以及程序集里面导出的类型 -class CandidateClassTypeResult -{ - public CandidateClassTypeResult(ExportMethodReturnTypeCollectionResult exportMethodReturnTypeCollectionResult, IReadOnlyList assemblyClassTypeSymbolList) - { - ExportMethodReturnTypeCollectionResult = exportMethodReturnTypeCollectionResult; - AssemblyClassTypeSymbolList = assemblyClassTypeSymbolList; - } - - public ExportMethodReturnTypeCollectionResult ExportMethodReturnTypeCollectionResult { get; } - - public IReadOnlyList AssemblyClassTypeSymbolList { get; } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs deleted file mode 100644 index 5cf6b44..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/EnumerableValueTupleExportMethodReturnTypeCodeGenerator.cs +++ /dev/null @@ -1,71 +0,0 @@ -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; - -using Microsoft.CodeAnalysis; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 采用 IEnumerable 的 ValueTuple 返回值类型的生成方法 -/// -class EnumerableValueTupleExportMethodReturnTypeCodeGenerator : IExportMethodCodeGenerator -{ - public string GenerateSourceCode(ExportMethodReturnTypeCollectionResult exportMethodReturnTypeCollectionResult, List list, - CancellationToken token) - { - /* - private static partial IEnumerable<(Type, F1Attribute xx, Func xxx)> ExportFooEnumerable() - { - yield return (typeof(CurrentFoo), new F1Attribute(), () => new CurrentFoo()); - } - */ - if (exportMethodReturnTypeCollectionResult.ExportMethodReturnType != - ExportMethodReturnType.EnumerableValueTupleWithTypeAttributeCreator) - { - throw new ArgumentException($"调用错误,其他返回值类型不应该调用"); - } - - var methodCode = new StringBuilder(); - - foreach (var namedTypeSymbol in list) - { - token.ThrowIfCancellationRequested(); - - 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( - exportMethodReturnTypeCollectionResult.ExportPartialMethodSymbol, methodCode.ToString(), token); - - return methodSource; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodCodeGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodCodeGenerator.cs deleted file mode 100644 index a9799b4..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodCodeGenerator.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; - -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 生成导出类型方法的代码 -/// -/// 这个类型只是一个分发工厂,由于存在不同的返回值等需要支持,于是拆分为不同的实现方法 -static class ExportMethodCodeGenerator -{ - public static string GenerateSourceCode( - ExportMethodReturnTypeCollectionResult exportMethodReturnTypeCollectionResult, List list, - CancellationToken token) - { - IExportMethodCodeGenerator codeGenerator = - exportMethodReturnTypeCollectionResult.ExportMethodReturnType switch - { - ExportMethodReturnType - .EnumerableValueTupleWithTypeAttributeCreator - => - new EnumerableValueTupleExportMethodReturnTypeCodeGenerator(), - // 还没支持其他返回值的情况 - _ => throw new NotSupportedException() - }; - - return codeGenerator.GenerateSourceCode(exportMethodReturnTypeCollectionResult, list, token); - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnType.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnType.cs deleted file mode 100644 index 72694ef..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 导出方法的返回类型 -/// -public enum ExportMethodReturnType -{ - /// - /// 采用 IEnumerable 导出 ValueTuple 包含 Type Attribute 和 Creator 三个参数 - /// - // static partial IEnumerable<(Type, FooAttribute xx, Func xxx)> ExportFooEnumerable() - EnumerableValueTupleWithTypeAttributeCreator, -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionDiagnostic.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionDiagnostic.cs deleted file mode 100644 index 3120036..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionDiagnostic.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -class ExportMethodReturnTypeCollectionDiagnostic : IExportMethodReturnTypeCollectionResult -{ - public ExportMethodReturnTypeCollectionDiagnostic(DiagnosticDescriptor diagnosticDescriptor, - Location? location = null, params object[]? messageArgs) - { - DiagnosticDescriptor = diagnosticDescriptor; - Location = location; - MessageArgs = messageArgs; - } - - public Location? Location { get; set; } - public DiagnosticDescriptor DiagnosticDescriptor { get; } - public object[]? MessageArgs { set; get; } - - public Diagnostic ToDiagnostic() => Diagnostic.Create(DiagnosticDescriptor, Location, MessageArgs); -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionResult.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionResult.cs deleted file mode 100644 index d667e2f..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportMethodReturnTypeCollectionResult.cs +++ /dev/null @@ -1,77 +0,0 @@ -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 导出的方法的导出类型返回值结果 -/// -class ExportMethodReturnTypeCollectionResult : IExportMethodReturnTypeCollectionResult -{ - public ExportMethodReturnTypeCollectionResult(ITypeSymbol expectedClassBaseType, ITypeSymbol? expectedClassAttributeType, ExportTypeCollectionResult exportTypeCollectionResult, ExportMethodReturnType exportMethodReturnType) - { - ExpectedClassBaseType = expectedClassBaseType; - ExpectedClassAttributeType = expectedClassAttributeType; - ExportTypeCollectionResult = exportTypeCollectionResult; - ExportMethodReturnType= exportMethodReturnType; - } - - /// - /// 期望收集的类型所继承的基础类型 - /// - public ITypeSymbol ExpectedClassBaseType { get; } - - /// - /// 期望类型标记的特性,可选 - /// - public ITypeSymbol? ExpectedClassAttributeType { get; } - - public ExportTypeCollectionResult ExportTypeCollectionResult { get; } - - /// - /// 程序集里面标记了导出的分部方法,将用来生成代码 - /// - public IMethodSymbol ExportPartialMethodSymbol => ExportTypeCollectionResult.ExportPartialMethodSymbol; - - /// - /// 导出类型的返回类型信息 - /// - public ExportMethodReturnType ExportMethodReturnType { get; } - - /// - /// 判断传入的程序集类型满足当前的要求条件 - /// - /// - /// - public bool IsMatch(INamedTypeSymbol assemblyClassTypeSymbol) - { - if (assemblyClassTypeSymbol.IsAbstract) - { - // 抽象类不能提供 - return false; - } - - // 先判断是否继承,再判断是否标记特性 - if (!TypeSymbolHelper.IsInherit(assemblyClassTypeSymbol, ExpectedClassBaseType)) - { - // 没有继承基类,那就是不符合了 - return false; - } - - if (ExpectedClassAttributeType is null) - { - // 如果没有特性要求,那就返回符合 - return true; - } - - foreach (var attributeData in assemblyClassTypeSymbol.GetAttributes()) - { - if (SymbolEqualityComparer.Default.Equals(attributeData.AttributeClass, ExpectedClassAttributeType)) - { - return true; - } - } - - return false; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportTypeCollectionResult.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportTypeCollectionResult.cs deleted file mode 100644 index da73e12..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/ExportTypeCollectionResult.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -class ExportTypeCollectionResult : IEquatable -{ - public ExportTypeCollectionResult(IMethodSymbol methodSymbol, GeneratorSyntaxContext generatorSyntaxContext) - { - ExportPartialMethodSymbol = methodSymbol; - GeneratorSyntaxContext = generatorSyntaxContext; - } - - /// - /// 是否包含引用的程序集和 DLL 里面的类型导出。默认只导出当前程序集 - /// - public bool IncludeReference { set; get; } - /// - /// 程序集里面标记了导出的分部方法,将用来生成代码 - /// - public IMethodSymbol ExportPartialMethodSymbol { get; } - public GeneratorSyntaxContext GeneratorSyntaxContext { get; } - - public bool Equals(ExportTypeCollectionResult? other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - return GeneratorSyntaxContext.Equals(other.GeneratorSyntaxContext) && SymbolEqualityComparer.Default.Equals(ExportPartialMethodSymbol, other.ExportPartialMethodSymbol); - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((ExportTypeCollectionResult) obj); - } - - public override int GetHashCode() - { - unchecked - { - return (SymbolEqualityComparer.Default.GetHashCode(ExportPartialMethodSymbol) * 397) ^ GeneratorSyntaxContext.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodCodeGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodCodeGenerator.cs deleted file mode 100644 index ffb10e0..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodCodeGenerator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using Microsoft.CodeAnalysis; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 导入方法的生成器 -/// -interface IExportMethodCodeGenerator -{ - string GenerateSourceCode(ExportMethodReturnTypeCollectionResult exportMethodReturnTypeCollectionResult, - List list, CancellationToken token); -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodReturnTypeCollectionResult.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodReturnTypeCollectionResult.cs deleted file mode 100644 index 5930a2a..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/IExportMethodReturnTypeCollectionResult.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 收集导出方法返回值类型 -/// -/// 可以是收集到了,也可以是返回开发者定义错误代码 -interface IExportMethodReturnTypeCollectionResult -{ -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs deleted file mode 100644 index 31450a7..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/ExportTypeToMethod_/TelescopeExportTypeToMethodIncrementalGenerator.cs +++ /dev/null @@ -1,424 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Data; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; - -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Diagnostics; - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; - -using static dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -/// -/// 从标记的方法导出类型 -/// -// 形如 private static partial IEnumerable<(Type type, FooAttribute attribute, Func creator)> ExportFooEnumerable(); -[Generator(LanguageNames.CSharp)] -public class TelescopeExportTypeToMethodIncrementalGenerator : IIncrementalGenerator -{ - public void Initialize(IncrementalGeneratorInitializationContext context) - { -#if DEBUG - if (!Debugger.IsAttached) - { - Debugger.Launch(); - } -#endif - // 先找到定义 - IncrementalValuesProvider exportMethodIncrementalValuesProvider = context.SyntaxProvider.CreateSyntaxProvider(static (syntaxNode, _) => - { - // 先要求是分部的方法,分部的方法必定在分部类里面,这部分判断分部类里面还可以省略 - if (syntaxNode is MethodDeclarationSyntax methodDeclarationSyntax && methodDeclarationSyntax.AttributeLists.Any()) - { - // 同时满足以下条件: - // 1. 是方法 - // 2. 方法带特性 - // 3. 是分部方法 - if (methodDeclarationSyntax.Modifiers.Any(t => t.IsKind(SyntaxKind.PartialKeyword))) - { - return true; - } - } - - return false; - }, static (generatorSyntaxContext, token) => - { - // 语义分析,判断方法是否标记了 TelescopeExportAttribute 特性 - - var methodDeclarationSyntax = (MethodDeclarationSyntax) generatorSyntaxContext.Node; - - // 从语法转换为语义,用于后续判断是否标记了特性 - IMethodSymbol? methodSymbol = - generatorSyntaxContext.SemanticModel.GetDeclaredSymbol(methodDeclarationSyntax, token); - - if (methodSymbol is null) - { - return default; - } - - var attributeDataArray = methodSymbol.GetAttributes(); - foreach (var attributeData in attributeDataArray) - { - token.ThrowIfCancellationRequested(); - - if (attributeData.AttributeClass is null) continue; - - var attributeName = TypeSymbolHelper.TypeSymbolToFullName(attributeData.AttributeClass); - if (attributeName == "global::dotnetCampus.Telescope.TelescopeExportAttribute") - { - var attributeDataNamedArguments = attributeData.NamedArguments; - var includeReference = - attributeDataNamedArguments - .FirstOrDefault(t => t.Key == nameof(TelescopeExportAttribute.IncludeReferences)).Value - .Value is true; - - return new ExportTypeCollectionResult(methodSymbol, generatorSyntaxContext) - { - IncludeReference = includeReference - }; - } - } - - return null; - }) - // 过滤不满足条件的 - .ExcludeNulls(); - - // 获取方法返回值导出类型 - var exportMethodReturnTypeCollectionResultIncrementalValuesProvider = exportMethodIncrementalValuesProvider.Select(static (exportTypeCollectionResult, token) => - { - ITypeSymbol methodSymbolReturnType = exportTypeCollectionResult.ExportPartialMethodSymbol.ReturnType; - - //if (methodSymbolReturnType is IArrayTypeSymbol arrayTypeSymbol) - //{ - // // 如果是如 partial Base[] ExportFoo() 这样的,收集起来 - // ITypeSymbol elementType = arrayTypeSymbol.ElementType; - // return new ExportMethodReturnTypeCollectionResult(elementType, null, exportTypeCollectionResult.MethodSymbol) as IExportMethodReturnTypeCollectionResult; - //} - //else - if (methodSymbolReturnType is INamedTypeSymbol namedTypeSymbol) - { - if (namedTypeSymbol.IsGenericType && TypeSymbolHelper.TypeSymbolToFullName(namedTypeSymbol) == - "global::System.Collections.Generic.IEnumerable") - { - // 尝试判断是 ValueTuple 的情况 - // 要求符合以下定义 - // static partial IEnumerable<(Type, FooAttribute xx, Func xxx)> ExportFooEnumerable() - if (namedTypeSymbol.TypeArguments.Length == 1 && - namedTypeSymbol.TypeArguments[0] is INamedTypeSymbol tupleType && tupleType.IsTupleType && - tupleType.TupleElements.Length > 0) - { - if (tupleType.TupleElements.Length == 3) - { - // static partial IEnumerable<(Type, FooAttribute xx, Func xxx)> ExportFooEnumerable() - - if (TypeSymbolHelper.TypeSymbolToFullName(tupleType.TupleElements[0].Type) != "global::System.Type") - { - // 这就是错误的 - return ReturnTypeError(nameof(Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator)); - } - - // 表示的特性 - var expectedClassAttributeType = tupleType.TupleElements[1].Type; - - // Func - var funcTypeSymbol = (INamedTypeSymbol) tupleType.TupleElements[2].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, - 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); - } - } - } - } - - // 其他不认识的,要告诉开发者不能这样写哦 - return new ExportMethodReturnTypeCollectionDiagnostic(TesDiagnostics.Tes000_UnknownError) as IExportMethodReturnTypeCollectionResult; - - Location GetLocation() - { - var syntaxNode = exportTypeCollectionResult.GeneratorSyntaxContext.Node; - var location = Location.Create(syntaxNode.SyntaxTree, syntaxNode.Span); - return location; - } - - ExportMethodReturnTypeCollectionDiagnostic ReturnTypeError(string messageKey) - { - return new ExportMethodReturnTypeCollectionDiagnostic - ( - TesDiagnostics.Tes001_MethodReturnTypeError, - GetLocation(), - TesDiagnostics.Localize(messageKey) - ); - } - }); - - // 这是有定义出错的,需要反馈给到开发者的 - var diagnosticIncrementalValuesProvider = exportMethodReturnTypeCollectionResultIncrementalValuesProvider.Select(static (t, _) => t as ExportMethodReturnTypeCollectionDiagnostic) - .ExcludeNulls(); - - context.RegisterSourceOutput(diagnosticIncrementalValuesProvider, static (productionContext, diagnostic) => - { - productionContext.ReportDiagnostic(diagnostic.ToDiagnostic()); - }); - - // 收集到了期望收集的内容,将开始进行整个项目的类型收集 - - // 将这些需要包含引用程序集的加进来返回值类型。因为标记导出支持带引用程序集的 - var assemblyReferenceExportReturnTypeProvider = exportMethodReturnTypeCollectionResultIncrementalValuesProvider - .Select(static (t, _) => t as ExportMethodReturnTypeCollectionResult) - // 只有非空且包含引用程序集的,才加入 - .Where(static t => t is not null && t.ExportTypeCollectionResult.IncludeReference) - .Select(static (t, _) => t!) - .Collect(); - - // 收集引用的程序集的类型 - var referenceAssemblyTypeIncrementalValueProvider = context.CompilationProvider - .Select(static (compilation, _) => compilation.SourceModule.ReferencedAssemblySymbols) - .Combine(assemblyReferenceExportReturnTypeProvider).Select(static (tuple, token) => - { - // 获取到所有引用程序集 - var referencedAssemblySymbols = tuple.Left; - - // 所有导出类型的定义逻辑 - var exportMethodReturnTypeCollectionResults = tuple.Right; - - var candidateClassList = new List(); - - foreach (var exportMethodReturnTypeCollectionResult in exportMethodReturnTypeCollectionResults) - { - token.ThrowIfCancellationRequested(); - - var assemblyClassTypeSymbolList = new List(); - var candidateClassTypeResult = new CandidateClassTypeResult(exportMethodReturnTypeCollectionResult, assemblyClassTypeSymbolList); - candidateClassList.Add(candidateClassTypeResult); - - // 期望继承的基础类型 - var expectedClassBaseType = exportMethodReturnTypeCollectionResult.ExpectedClassBaseType; - - // 当前项目的程序集,用来判断 internal 可见性 - var currentAssembly = exportMethodReturnTypeCollectionResult.ExportPartialMethodSymbol.ContainingAssembly; - - var visited = new Dictionary(SymbolEqualityComparer.Default); - - foreach (var referencedAssemblySymbol in referencedAssemblySymbols) - { - // 过滤程序集,只有引用了期望继承的基础类型所在程序集的,才可以被收集到。如果没有引用,那自然写不出继承基础类型的代码 - token.ThrowIfCancellationRequested(); - if (!AssemblySymbolHelper.IsReference(referencedAssemblySymbol, expectedClassBaseType.ContainingAssembly, visited)) - { - // 如果当前程序集没有直接或间接继承期望继承的基础类型所在程序集,那就证明当前程序集一定不存在任何可能被收集的类型 - continue; - } - - // 判断 referencedAssemblySymbol 是否设置 internal 可见 - var isInternalsVisibleTo = referencedAssemblySymbol.GivesAccessTo(currentAssembly); - - foreach (var assemblyClassTypeSymbol in AssemblySymbolHelper.GetAllTypeSymbols(referencedAssemblySymbol)) - { - if (!isInternalsVisibleTo && - assemblyClassTypeSymbol.DeclaredAccessibility != Accessibility.Public) - { - // 如果设置不可见的,那就不要加入了 - continue; - } - - if (exportMethodReturnTypeCollectionResult.IsMatch(assemblyClassTypeSymbol)) - { - assemblyClassTypeSymbolList.Add(assemblyClassTypeSymbol); - } - } - } - } - - return new CandidateClassCollectionResult(candidateClassList); - }); - - // 收集当前分析器所分析项目的类型 - // 收集所有的带返回类型,用来进行下一步的收集项目里的所有类型 - IncrementalValueProvider> returnTypeCollectionIncrementalValuesProvider = exportMethodReturnTypeCollectionResultIncrementalValuesProvider - .Select(static (t, _) => t as ExportMethodReturnTypeCollectionResult) - .ExcludeNulls() - .Collect(); - - // 收集整个项目里面所有的类型 - var candidateClassCollectionResultIncrementalValuesProvider = context.SyntaxProvider.CreateSyntaxProvider( - static (syntaxNode, _) => - { - return syntaxNode.IsKind(SyntaxKind.ClassDeclaration); - }, static (generatorSyntaxContext, token) => - { - var classDeclarationSyntax = (ClassDeclarationSyntax)generatorSyntaxContext.Node; - // 从语法转换为语义,用于后续判断是否标记了特性 - INamedTypeSymbol? assemblyClassTypeSymbol = - generatorSyntaxContext.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax, token); - if (assemblyClassTypeSymbol is not null && !assemblyClassTypeSymbol.IsAbstract) - { - return assemblyClassTypeSymbol; - } - - return null; - }) - .ExcludeNulls() - .Combine(returnTypeCollectionIncrementalValuesProvider) - .Select(static (tuple, token) => - { - var assemblyClassTypeSymbol = tuple.Left; - var exportMethodReturnTypeCollectionResultArray = tuple.Right; - - var result = new List(); - - foreach (var exportMethodReturnTypeCollectionResult in exportMethodReturnTypeCollectionResultArray) - { - token.ThrowIfCancellationRequested(); - if (exportMethodReturnTypeCollectionResult.IsMatch(assemblyClassTypeSymbol)) - { - result.Add(new CandidateClassTypeResult(exportMethodReturnTypeCollectionResult, - new[] { assemblyClassTypeSymbol })); - } - } - - if (result.Count > 0) - { - return new CandidateClassCollectionResult(result); - } - else - { - return null; - } - }) - .ExcludeNulls(); - - var collectionResultIncrementalValueProvider = referenceAssemblyTypeIncrementalValueProvider.Combine(candidateClassCollectionResultIncrementalValuesProvider.Collect()) - .SelectMany(static (tuple, _) => { return tuple.Right.Add(tuple.Left); }) - .Collect() - .Select(static (array, token) => - { - // 去掉重复的定义 - var dictionary = new Dictionary>(); - - foreach (var candidateClassCollectionResult in array) - { - token.ThrowIfCancellationRequested(); - foreach (var candidateClassTypeResult in candidateClassCollectionResult.CandidateClassTypeResultList) - { - token.ThrowIfCancellationRequested(); - var result = candidateClassTypeResult.ExportMethodReturnTypeCollectionResult; - - if (!dictionary.TryGetValue(result, out var list)) - { - list = new List(); - dictionary.Add(result, list); - } - - list.AddRange(candidateClassTypeResult.AssemblyClassTypeSymbolList); - } - } - - return dictionary; - }); - - // 转换为源代码输出 - // 源代码输出放在 Select 可以随时打断,实际 VisualStudio 性能会比放在 RegisterImplementationSourceOutput 高很多 - var sourceCodeProvider = collectionResultIncrementalValueProvider.Select(static (result, token) => - { - var codeList = new List<(string /*FileName*/, string /*SourceCode*/)>(result.Count); - foreach (var item in result) - { - token.ThrowIfCancellationRequested(); - - var exportMethodReturnTypeCollectionResult = item.Key; - var list = item.Value; - - var methodCode = - ExportMethodCodeGenerator.GenerateSourceCode(exportMethodReturnTypeCollectionResult, list, token); - - var partialClassType = (INamedTypeSymbol) exportMethodReturnTypeCollectionResult.ExportPartialMethodSymbol.ReceiverType!; - - var code = SourceCodeGeneratorHelper.GeneratePartialClassCode(partialClassType, methodCode); - - var fileName = - $"{partialClassType.Name}-{exportMethodReturnTypeCollectionResult.ExportPartialMethodSymbol.Name}"; - - codeList.Add((fileName, code)); - } - - return codeList; - }); - - // 可以被 IDE 选择不生成的代码,但是在完全生成输出时将会跑 - // 这里可以用来存放具体实现的代码,将不影响用户代码的语义,而不是用来做定义的代码 - context.RegisterImplementationSourceOutput(sourceCodeProvider, - static (productionContext, result) => - { - foreach (var (fileName, code) in result) - { - productionContext.AddSource(fileName, code); - } - }); - - // 在所有逻辑执行之前将会开始跑的代码,参与到用户代码里面,影响用户代码的语义 - // 一般是用来输出一些定义的代码 - context.RegisterPostInitializationOutput(static context => - { - var assembly = typeof(TelescopeExportTypeToMethodIncrementalGenerator).Assembly; - var telescopeExportAttributeCodeStream = assembly.GetManifestResourceStream("dotnetCampus.Telescope.SourceGeneratorAnalyzers.EmbeddedResourceCode.TelescopeExportAttribute.cs")!; - var sourceText = SourceText.From(telescopeExportAttributeCodeStream, - // error : Unhandled exception. System.ArgumentException: SourceText cannot be embedded. Provide encoding or canBeEmbedded = true at construction. (Parameter 'text') - canBeEmbedded: true); - context.AddSource("TelescopeExportAttribute", sourceText); - }); - } - - /// - /// 提供缩进的方法 - /// - /// - /// - /// - private static string IndentSource(string source, int numIndentations) - { - return SourceCodeGeneratorHelper.IndentSource(source, numIndentations); - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/Properties/Resource.Designer.cs b/src/TelescopeSourceGenerator/Analyzers/Properties/Resource.Designer.cs deleted file mode 100644 index 3bd3e2c..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Properties/Resource.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties { - using System; - - - /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 - /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resource { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resource() { - } - - /// - /// 返回此类使用的缓存的 ResourceManager 实例。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resource", typeof(Resource).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// 重写当前线程的 CurrentUICulture 属性,对 - /// 使用此强类型资源类的所有资源查找执行重写。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/src/TelescopeSourceGenerator/Analyzers/Properties/Resources.Designer.cs b/src/TelescopeSourceGenerator/Analyzers/Properties/Resources.Designer.cs deleted file mode 100644 index c7aa698..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Properties/Resources.Designer.cs +++ /dev/null @@ -1,108 +0,0 @@ -//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties { - using System; - - - /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 - /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// 返回此类使用的缓存的 ResourceManager 实例。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// 重写当前线程的 CurrentUICulture 属性,对 - /// 使用此强类型资源类的所有资源查找执行重写。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// 查找类似 Telescope unknown error 的本地化字符串。 - /// - internal static string Tes000 { - get { - return ResourceManager.GetString("Tes000", resourceCulture); - } - } - - /// - /// 查找类似 An unknown error occurred when generating. 的本地化字符串。 - /// - internal static string Tes000_Message { - get { - return ResourceManager.GetString("Tes000_Message", resourceCulture); - } - } - - /// - /// 查找类似 Return type error 的本地化字符串。 - /// - internal static string Tes001 { - get { - return ResourceManager.GetString("Tes001", resourceCulture); - } - } - - /// - /// 查找类似 The method return type not match Telescope rule. {0} 的本地化字符串。 - /// - internal static string Tes001_Message { - get { - return ResourceManager.GetString("Tes001_Message", resourceCulture); - } - } - - /// - /// 查找类似 The format that complies with the rules is: IEnumerable<(Type type, FooAttribute attribute, Func<Base> creator) 的本地化字符串。 - /// - internal static string Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator { - get { - return ResourceManager.GetString("Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator", resourceCulture); - } - } - } -} diff --git a/src/TelescopeSourceGenerator/Analyzers/Properties/Resources.resx b/src/TelescopeSourceGenerator/Analyzers/Properties/Resources.resx deleted file mode 100644 index 02e3b9f..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/Properties/Resources.resx +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Telescope unknown error - - - An unknown error occurred when generating. - - - Return type error - - - The method return type not match Telescope rule. {0} - - - The format that complies with the rules is: IEnumerable<(Type type, FooAttribute attribute, Func<Base> creator) - - \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/README.md b/src/TelescopeSourceGenerator/Analyzers/README.md deleted file mode 100644 index 82fb178..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# Telescope.SourceGeneratorAnalyzers - -使用 SourceGenerator 源代码生成器的 Telescope 版本 - -可以用来导出指定类型 - -## 用法 - -支持多个不同的导出写法 - -### 分部方法式 - -这是推荐的方法 - -在分部类里定义分部方法,分部方法标记 `dotnetCampus.Telescope.TelescopeExportAttribute` 特性,且返回值包括导出条件,如以下写法 - -```csharp -internal partial class Program -{ - [dotnetCampus.Telescope.TelescopeExportAttribute()] - private static partial IEnumerable<(Type type, F1Attribute attribute, Func creator)> ExportFooEnumerable(); -} -``` - -以上代码将导出当前项目标记了 `F1Attribute` 且继承 `Base` 的所有类型。经过 Telescope 源代码生成器即可生成大概如下的代码 - -```csharp - [global::System.CodeDom.Compiler.GeneratedCode("dotnetCampus.Telescope.SourceGeneratorAnalyzers", "1.0.0")] - internal partial class Program - { - private static partial IEnumerable<(Type type, F1Attribute attribute, Func creator)> ExportFooEnumerable() - { - yield return (typeof(F2), new F1Attribute() - { - - }, () => new F2()); - yield return (typeof(F3), new F1Attribute() - { - - }, () => new F3()); - } - } -``` - -高级用法: - -可以在 TelescopeExportAttribute 加上 IncludeReference 属性用来导出所有引用程序集的满足条件的类型,如以下代码 - -```csharp -internal partial class Program -{ - [dotnetCampus.Telescope.TelescopeExportAttribute(IncludeReference = true)] - private static partial IEnumerable<(Type type, F1Attribute attribute, Func creator)> ExportFooEnumerable(); -} -``` - -仅推荐在入口程序集加上 `IncludeReference = true` 属性,因为一旦加入此属性,任何引用程序集的变更都可能导致源代码生成器重复执行,降低 VisualStudio 性能 - -### 程序集标记 - -这是传统的 Telescope 实现方法,在需要导出类型的项目里标记 `dotnetCampus.Telescope.MarkExportAttribute` 特性,如以下代码 - -```csharp -[assembly: dotnetCampus.Telescope.MarkExportAttribute(typeof(Base), typeof(FooAttribute))] -``` - -标记之后将会自动生成 `dotnetCampus.Telescope.__AttributedTypesExport__` 类型,即可在代码里面直接使用,如以下代码 - -```csharp - var attributedTypesExport = new __AttributedTypesExport__(); - ICompileTimeAttributedTypesExporter exporter = attributedTypesExport; - foreach (var exportedTypeMetadata in exporter.ExportAttributeTypes()) - { - // 输出导出的类型 - Console.WriteLine(exportedTypeMetadata.RealType.FullName); - } -``` - -也可以使用 `dotnetCampus.Telescope.AttributedTypes` 辅助类获取所有导出类型 \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/TelescopeIncrementalGenerator.cs b/src/TelescopeSourceGenerator/Analyzers/TelescopeIncrementalGenerator.cs deleted file mode 100644 index 8a59053..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/TelescopeIncrementalGenerator.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers; - -[Generator(LanguageNames.CSharp)] -public class TelescopeIncrementalGenerator : IIncrementalGenerator -{ - public void Initialize(IncrementalGeneratorInitializationContext context) - { - // 先读取程序集特性,接着遍历整个程序集的所有代码文件,看看哪些是符合需求的,收集起来 - // 读取程序集特性 - - var assemblyAttributeSyntaxContextIncrementalValuesProvider = - context.SyntaxProvider.CreateSyntaxProvider - ( - // 语法分析,过滤只有是程序集特性 - (syntaxNode, cancellationToken) => - { - // 预先判断是 assembly 的特性再继续 - // [assembly: MarkExport(typeof(Base), typeof(FooAttribute))] - return syntaxNode.IsKind(SyntaxKind.AttributeList) && syntaxNode.ChildNodes() - .Any(subNode => subNode.IsKind(SyntaxKind.AttributeTargetSpecifier)); - }, - // 获取只有是属于程序集标记的特性才使用 - ParseMarkExportAttribute - ) - .Where(t => t.Success) - .Collect(); - - // 遍历整个程序集的所有代码文件 - // 获取出所有标记了特性的类型,用来在下一步判断是否属于导出的类型 - var assemblyClassIncrementalValuesProvider = - context.SyntaxProvider.CreateSyntaxProvider - ( - // 语法分析,只有是 class 类型定义的才可能满足需求 - (syntaxNode, cancellationToken) => syntaxNode.IsKind(SyntaxKind.ClassDeclaration), - - // 加上语义分析,了解当前的类型是否有添加任何标记 - (generatorSyntaxContext, cancellationToken) => - { - var classDeclarationSyntax = (ClassDeclarationSyntax) generatorSyntaxContext.Node; - - // 从语法转换为语义,用于后续判断是否标记了特性 - INamedTypeSymbol? namedTypeSymbol = - generatorSyntaxContext.SemanticModel.GetDeclaredSymbol(classDeclarationSyntax); - - // 如果可以获取到语义的类型,则尝试获取其标记的特性 - if (namedTypeSymbol is not null - // 抽象类不应该被加入创建 - && !namedTypeSymbol.IsAbstract) - { - var attributes = namedTypeSymbol.GetAttributes(); - - if (attributes.Length > 0) - { - return new AssemblyCandidateClassParseResult(namedTypeSymbol, attributes, - generatorSyntaxContext); - } - else - { - // 只有标记了特性的,才是可能候选的类型 - } - } - - return new AssemblyCandidateClassParseResult(); - } - ) - // 过滤掉不符合条件的类型 - .Where(t => t.Success); - - // 将程序集特性和类型组合一起,看看哪些类型符合程序集特性的要求,将其拼装到一起 - IncrementalValueProvider> collectionClass = - assemblyClassIncrementalValuesProvider - .Combine(assemblyAttributeSyntaxContextIncrementalValuesProvider) - .Select((tuple, token) => { return ParseMarkClassList(tuple.Left, tuple.Right); }) - .SelectMany((list, _) => list) - .Collect(); - - // 参考 AttributedTypesExportFileGenerator 逻辑生成代码 - IncrementalValueProvider generatedCodeProvider = collectionClass.Select((markClassCollection, token) => - { - var attributedTypesExportGenerator = new ExportedTypesCodeTextGenerator(); - string generatedCode = attributedTypesExportGenerator.Generate(markClassCollection, token); - return generatedCode; - }); - - // 注册到输出 - context.RegisterSourceOutput(generatedCodeProvider, - (sourceProductionContext, generatedCode) => - { - if(!string.IsNullOrEmpty(generatedCode)) - { - sourceProductionContext.AddSource("__AttributedTypesExport__", generatedCode); - } - }); - } - - /// - /// 转换被标记的类型的信息 - /// - /// 程序集里面的类型 - /// 程序集里面的各个标记 - /// - private List ParseMarkClassList(AssemblyCandidateClassParseResult classParseResult, - ImmutableArray markExportAttributeParseResultList) - { - var list = new List(); - foreach (MarkExportAttributeParseResult markExportAttributeParseResult in markExportAttributeParseResultList) - { - var result = ParseMarkClass(classParseResult, markExportAttributeParseResult); - if (result != null) - { - list.Add(result.Value); - } - } - - return list; - } - - /// - /// 转换被标记的类型的信息,判断当前的类型是否满足当前所选的程序集特性 - /// - /// - /// - /// - private MarkClassParseResult? ParseMarkClass(AssemblyCandidateClassParseResult classParseResult, - MarkExportAttributeParseResult markExportAttributeParseResult) - { - // 先判断满足的类型 - var matchAssemblyMarkAttributeData = classParseResult.Attributes.FirstOrDefault(t => - SymbolEqualityComparer.Default.Equals(t.AttributeClass, - markExportAttributeParseResult.AttributeTypeInfo)); - - if (matchAssemblyMarkAttributeData?.ApplicationSyntaxReference is null) - { - // 找不到匹配的特性,表示这个类型不应该被收集 - return default; - } - - // 同时获取其语法 - AttributeSyntax? markAttributeSyntax = classParseResult - .ExportedTypeClassDeclarationSyntax - .AttributeLists - .SelectMany(t => t.Attributes) - // 理论上 Span 是相同的,这里用 Contains 或 == 都应该是相同的结果 - .FirstOrDefault(t => t.Span.Contains(matchAssemblyMarkAttributeData.ApplicationSyntaxReference.Span)); - - if (markAttributeSyntax is null) - { - // 理论上不可能是空,因为已找到其特性 - return default; - } - - // 再判断继承类型 - var requiredBaseClassOrInterfaceType = markExportAttributeParseResult.BaseClassOrInterfaceTypeInfo; - - if (TypeSymbolHelper.IsInherit(classParseResult.ExportedTypeSymbol, requiredBaseClassOrInterfaceType)) - { - return new MarkClassParseResult(classParseResult.ExportedTypeSymbol, - classParseResult.ExportedTypeClassDeclarationSyntax, matchAssemblyMarkAttributeData, markAttributeSyntax, - markExportAttributeParseResult, classParseResult.GeneratorSyntaxContext); - } - - return null; - } - - /// - /// 解析出定义在程序集里面的特性 - /// - /// - /// - /// - private MarkExportAttributeParseResult ParseMarkExportAttribute(GeneratorSyntaxContext generatorSyntaxContext, - CancellationToken cancellationToken) - { - if (generatorSyntaxContext.Node is not AttributeListSyntax attributeListSyntax) - { - return MarkExportAttributeParseResult.Failure; - } - - foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes) - { - // [assembly: MarkExport(typeof(Base), typeof(FooAttribute))] - // attributeSyntax:拿到 MarkExport 符号 - // 由于只是拿到 MarkExport 符号,不等于是 `dotnetCampus.Telescope.MarkExportAttribute` 特性,需要走语义分析 - var typeInfo = generatorSyntaxContext.SemanticModel.GetTypeInfo(attributeSyntax); - if (typeInfo.Type is { } attributeType && attributeSyntax.ArgumentList is not null) - { - // 带上 global 格式的输出 FullName 内容 - var symbolDisplayFormat = new SymbolDisplayFormat( - // 带上命名空间和类型名 - SymbolDisplayGlobalNamespaceStyle.Included, - // 命名空间之前加上 global 防止冲突 - SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces); - var fullName = attributeType.ToDisplayString(symbolDisplayFormat); - - if (fullName == "global::dotnetCampus.Telescope.MarkExportAttribute") - { - // 这个是符合预期的 - var attributeArgumentSyntaxList = attributeSyntax.ArgumentList.Arguments; - if (attributeArgumentSyntaxList.Count == 2) - { - var baseClassOrInterfaceTypeSyntax = attributeArgumentSyntaxList[0]; - var attributeTypeSyntax = attributeArgumentSyntaxList[1]; - - // 原本采用的是 GuessTypeNameByTypeOfSyntax 方式获取的,现在可以通过语义获取 - var baseClassOrInterfaceTypeInfo = GetTypeInfoFromArgumentTypeOfSyntax(baseClassOrInterfaceTypeSyntax); - var attributeTypeInfo = GetTypeInfoFromArgumentTypeOfSyntax(attributeTypeSyntax); - - if (baseClassOrInterfaceTypeInfo?.Type is not null && attributeTypeInfo?.Type is not null) - { - return new MarkExportAttributeParseResult(true, baseClassOrInterfaceTypeInfo.Value.Type, - attributeTypeInfo.Value.Type); - } - - TypeInfo? GetTypeInfoFromArgumentTypeOfSyntax(AttributeArgumentSyntax attributeArgumentSyntax) - { - if (attributeArgumentSyntax.Expression is TypeOfExpressionSyntax typeOfExpressionSyntax) - { - var typeSyntax = typeOfExpressionSyntax.Type; - var typeOfType = generatorSyntaxContext.SemanticModel.GetTypeInfo(typeSyntax); - return typeOfType; - } - - return null; - } - } - } - } - } - - return MarkExportAttributeParseResult.Failure; - } -} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj b/src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj deleted file mode 100644 index 782df9e..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - netstandard2.0 - false - - true - - enable - false - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj.DotSettings b/src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj.DotSettings deleted file mode 100644 index 3b3ee1e..0000000 --- a/src/TelescopeSourceGenerator/Analyzers/dotnetCampus.Telescope.SourceGeneratorAnalyzers.csproj.DotSettings +++ /dev/null @@ -1,6 +0,0 @@ - - True - True - True - True - True \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib1/F1.cs b/src/TelescopeSourceGenerator/Demo/DemoLib1/F1.cs deleted file mode 100644 index a3dd43e..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib1/F1.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1; - -public class F1 -{ -} - -public class F1Attribute : Attribute{} \ No newline at end of file diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib1/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1.csproj b/src/TelescopeSourceGenerator/Demo/DemoLib1/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1.csproj deleted file mode 100644 index d5b4d08..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib1/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net6.0 - enable - enable - false - - - - - - diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib2/F2.cs b/src/TelescopeSourceGenerator/Demo/DemoLib2/F2.cs deleted file mode 100644 index 5c85c34..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib2/F2.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2; - -[F1] -public class F2 : F1 -{ -} diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib2/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2.csproj b/src/TelescopeSourceGenerator/Demo/DemoLib2/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2.csproj deleted file mode 100644 index 6d4439c..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib2/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib2.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net6.0 - enable - enable - false - - - - - - diff --git a/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs b/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs deleted file mode 100644 index b80d50b..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib3/F3.cs +++ /dev/null @@ -1,14 +0,0 @@ -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -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 deleted file mode 100644 index 2fce78b..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib3/FooWithAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -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/DemoLib3/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3.csproj b/src/TelescopeSourceGenerator/Demo/DemoLib3/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3.csproj deleted file mode 100644 index 10f7c00..0000000 --- a/src/TelescopeSourceGenerator/Demo/DemoLib3/dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib3.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net6.0 - enable - enable - false - - - - - - diff --git a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/AssemblyInfo.cs b/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/AssemblyInfo.cs deleted file mode 100644 index 4b47e23..0000000 --- a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using dotnetCampus.Telescope; -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo; - -//[assembly: MarkExport(typeof(Base), typeof(FooAttribute))] diff --git a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs b/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs deleted file mode 100644 index 04a003d..0000000 --- a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/Program.cs +++ /dev/null @@ -1,75 +0,0 @@ -using dotnetCampus.Telescope.SourceGeneratorAnalyzers.DemoLib1; - -namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo; - -internal partial class Program -{ - static void Main(string[] args) - { - foreach (var (_, xx, xxx) in ExportFooEnumerable()) - { - } - - //var attributedTypesExport = new __AttributedTypesExport__(); - //ICompileTimeAttributedTypesExporter exporter = attributedTypesExport; - //foreach (var exportedTypeMetadata in exporter.ExportAttributeTypes()) - //{ - // // 输出导出的类型 - // Console.WriteLine(exportedTypeMetadata.RealType.FullName); - //} - } - - [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] -public class CurrentFoo : DemoLib1.F1 -{ -} - -[Foo(0, FooEnum.N1, typeof(Foo), null)] -abstract class F1 : Base -{ -} - -[Foo(1ul, FooEnum.N2, typeof(Base), null, Number2 = 2L, Type2 = typeof(Foo), FooEnum2 = FooEnum.N1, Type3 = null)] -class Foo : Base -{ -} - -class Base -{ -} - -class FooAttribute : Attribute -{ - public FooAttribute(ulong number1, FooEnum fooEnum, Type? type1, Type? type3) - { - Number1 = number1; - FooEnum1 = fooEnum; - Type1 = type1; - } - - public ulong Number1 { get; set; } - public long Number2 { get; set; } - - public FooEnum FooEnum1 { get; set; } - public FooEnum FooEnum2 { get; set; } - public FooEnum FooEnum3 { get; set; } - - public Type? Type1 { get; set; } - public Type? Type2 { get; set; } - public Type? Type3 { get; set; } -} - -public enum FooEnum -{ - N1, - N2, - N3, -} - diff --git a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.csproj b/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.csproj deleted file mode 100644 index 17a567b..0000000 --- a/src/TelescopeSourceGenerator/Demo/TelescopeSourceGeneratorDemo/dotnetCampus.Telescope.SourceGeneratorAnalyzers.Demo.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - Exe - net6.0 - enable - enable - false - - - - - - - - - diff --git a/src/TelescopeSourceGenerator/NuGet/dotnetCampus.Telescope.SourceGeneratorAnalyzers.NuGet.csproj b/src/TelescopeSourceGenerator/NuGet/dotnetCampus.Telescope.SourceGeneratorAnalyzers.NuGet.csproj deleted file mode 100644 index 8ae2bf1..0000000 --- a/src/TelescopeSourceGenerator/NuGet/dotnetCampus.Telescope.SourceGeneratorAnalyzers.NuGet.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - net6.0;net5.0;netcoreapp3.1;netstandard2.0;net45 - dotnetCampus.Telescope.SourceGeneratorAnalyzers - $(PackageId) - false - ..\dotnetCampus.TelescopeTask\bin\$(Configuration)\ - - - - - - - - - - - - - - diff --git a/src/dotnetCampus.Telescope.NuGet/Assets/build/Package.targets b/src/dotnetCampus.Telescope.NuGet/Assets/build/Package.targets deleted file mode 100644 index bf9c98d..0000000 --- a/src/dotnetCampus.Telescope.NuGet/Assets/build/Package.targets +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - True - False - - $([System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription.ToString()) - <_TelescopeMSBuildRuntimeFramework Condition=" $(MSBuildRuntimeVersion.StartsWith('.NET Core 3')) ">netcoreapp3.1 - <_TelescopeMSBuildRuntimeFramework Condition=" $(MSBuildRuntimeVersion.StartsWith('.NET 6')) ">net6.0 - <_TelescopeMSBuildRuntimeFramework Condition=" '$(_TelescopeMSBuildRuntimeFramework)' == '' ">net5.0 - - - "$(MSBuildThisFileDirectory)../tools/net48/dotnetCampus.TelescopeTask.exe" - - - dotnet "$(MSBuildThisFileDirectory)../tools/$(_TelescopeMSBuildRuntimeFramework)/dotnetCampus.TelescopeTask.dll" - - - <_TelescopeSourceDefaultWorkingFolder Condition="'$(_TelescopeSourceDefaultWorkingFolder)' == ''">obj/$(Configuration)/$(TargetFramework)/ - $(_TelescopeSourceDefaultWorkingFolder) - $(TelescopeSourceWorkingFolder)TelescopeSource.Tools/ - $(TelescopeSourceWorkingFolder)TelescopeSource.GeneratedCodes/ - - - - - - - - - - - - - - - - - $(TelescopeSourceToolsFolder)CommandArgs.txt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_TelescopeSourceIncludedCompileFile Include="$(TelescopeSourceGeneratedCodeFolder)/*.cs" /> - - - - - - - - $(CleanDependsOn);_TelescopeSourceClean - - - - - - <_TelescopeSourceDefaultWorkingFolder Condition="'$(_TelescopeSourceDefaultWorkingFolder)' == ''">obj/$(Configuration)/$(TargetFramework)/ - $(_TelescopeSourceDefaultWorkingFolder) - $(TelescopeSourceWorkingFolder)TelescopeSource.Tools/ - $(TelescopeSourceWorkingFolder)TelescopeSource.GeneratedCodes/ - - - <_TelescopeSourceFilesToDelete Include="$(TelescopeSourceToolsFolder)*" /> - <_TelescopeSourceFilesToDelete Include="$(TelescopeSourceGeneratedCodeFolder)*" /> - - - - - - - - - \ No newline at end of file diff --git a/src/dotnetCampus.Telescope.NuGet/Assets/buildMultiTargeting/Package.targets b/src/dotnetCampus.Telescope.NuGet/Assets/buildMultiTargeting/Package.targets deleted file mode 100644 index cfe3370..0000000 --- a/src/dotnetCampus.Telescope.NuGet/Assets/buildMultiTargeting/Package.targets +++ /dev/null @@ -1,10 +0,0 @@ - - - - <_DefaultSourceFusionWorkingFolder>obj/$(Configuration)/$(TargetFramework)/ - obj/$(Configuration)/$(TargetFramework)/ - - - - - \ No newline at end of file diff --git a/src/dotnetCampus.Telescope.NuGet/Assets/tools/.gitignore b/src/dotnetCampus.Telescope.NuGet/Assets/tools/.gitignore deleted file mode 100644 index 4845f48..0000000 --- a/src/dotnetCampus.Telescope.NuGet/Assets/tools/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.gitignore -/net* diff --git a/src/dotnetCampus.Telescope.NuGet/dotnetCampus.Telescope.NuGet.csproj b/src/dotnetCampus.Telescope.NuGet/dotnetCampus.Telescope.NuGet.csproj deleted file mode 100644 index a8277e6..0000000 --- a/src/dotnetCampus.Telescope.NuGet/dotnetCampus.Telescope.NuGet.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - net6.0;net5.0;netcoreapp3.1;netstandard2.0;net45 - true - MIT - dotnetCampus.TelescopeSource - dotnetCampus.TelescopeSource - false - ..\dotnetCampus.TelescopeTask\bin\$(Configuration)\ - - - - - - - - - - - - - - - - - - - - <_TelescopeToCopyFiles Include="$(DevelopmentToolPath)**" /> - - - - - - diff --git a/src/dotnetCampus.Telescope.Sample/DemoAttribute.cs b/src/dotnetCampus.Telescope.Sample/DemoAttribute.cs deleted file mode 100644 index 5ef8856..0000000 --- a/src/dotnetCampus.Telescope.Sample/DemoAttribute.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace dotnetCampus.Telescope.Sample -{ - [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] - public sealed class DemoAttribute : Attribute - { - public DemoAttribute() - { - } - - public DemoAttribute(string value) - { - Value = value; - } - - public string? Value { get; } - } -} diff --git a/src/dotnetCampus.Telescope.Sample/Directory.Build.targets b/src/dotnetCampus.Telescope.Sample/Directory.Build.targets deleted file mode 100644 index ba48f13..0000000 --- a/src/dotnetCampus.Telescope.Sample/Directory.Build.targets +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/dotnetCampus.Telescope.Sample/IDemo.cs b/src/dotnetCampus.Telescope.Sample/IDemo.cs deleted file mode 100644 index 19c2def..0000000 --- a/src/dotnetCampus.Telescope.Sample/IDemo.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dotnetCampus.Telescope.Sample -{ - public interface IDemo - { - void Foo(); - } -} diff --git a/src/dotnetCampus.Telescope.Sample/Impl/Demo1.cs b/src/dotnetCampus.Telescope.Sample/Impl/Demo1.cs deleted file mode 100644 index 935ea69..0000000 --- a/src/dotnetCampus.Telescope.Sample/Impl/Demo1.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dotnetCampus.Telescope.Sample.Impl -{ - [Demo("1")] - public class Demo1 : IDemo - { - public void Foo() - { - } - } -} diff --git a/src/dotnetCampus.Telescope.Sample/Impl/Demo2.cs b/src/dotnetCampus.Telescope.Sample/Impl/Demo2.cs deleted file mode 100644 index ba4bb79..0000000 --- a/src/dotnetCampus.Telescope.Sample/Impl/Demo2.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace dotnetCampus.Telescope.Sample.Impl -{ - [Demo("2")] - public class Demo2 : IDemo - { - public void Foo() - { - } - } -} diff --git a/src/dotnetCampus.Telescope.Sample/Program.cs b/src/dotnetCampus.Telescope.Sample/Program.cs deleted file mode 100644 index e90d227..0000000 --- a/src/dotnetCampus.Telescope.Sample/Program.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace dotnetCampus.Telescope.Sample -{ - class Program - { - static void Main(string[] args) - { - var attributedTypes = AttributedTypes.FromAssembly(typeof(Program).Assembly); - foreach (var attributedType in attributedTypes) - { - var type = attributedType.RealType; - var attribute = attributedType.Attribute; - var instance = attributedType.CreateInstance(); - Console.WriteLine($"Type = {type.FullName}, Attribute = {attribute.Value}, Instance = {instance.GetHashCode()}"); - } - } - } -} diff --git a/src/dotnetCampus.Telescope.Sample/Properties/AssemblyInfo.cs b/src/dotnetCampus.Telescope.Sample/Properties/AssemblyInfo.cs deleted file mode 100644 index cc98f21..0000000 --- a/src/dotnetCampus.Telescope.Sample/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using dotnetCampus.Telescope; -using dotnetCampus.Telescope.Sample; - -[assembly: MarkExport(typeof(dotnetCampus.Telescope.Sample.IDemo), typeof(DemoAttribute))] diff --git a/src/dotnetCampus.Telescope.Sample/dotnetCampus.Telescope.Sample.csproj b/src/dotnetCampus.Telescope.Sample/dotnetCampus.Telescope.Sample.csproj deleted file mode 100644 index 7398b79..0000000 --- a/src/dotnetCampus.Telescope.Sample/dotnetCampus.Telescope.Sample.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - Exe - netcoreapp3.1 - latest - enable - false - - - - - - - diff --git a/src/dotnetCampus.Telescope/AttributedTypeMetadata.cs b/src/dotnetCampus.Telescope/AttributedTypeMetadata.cs deleted file mode 100644 index f44902a..0000000 --- a/src/dotnetCampus.Telescope/AttributedTypeMetadata.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Diagnostics; - -namespace dotnetCampus.Telescope -{ - [DebuggerDisplay("AttributedTypeMetadata<{RealType}, {Attribute}>")] - public class AttributedTypeMetadata - where TAttribute : Attribute - { - private readonly Func _instanceCreator; - - public AttributedTypeMetadata(Type realType, TAttribute attribute, Func instanceCreator) - { - RealType = realType ?? throw new ArgumentNullException(nameof(realType)); - Attribute = attribute ?? throw new ArgumentNullException(nameof(attribute)); - _instanceCreator = instanceCreator ?? throw new ArgumentNullException(nameof(instanceCreator)); - } - - public Type RealType { get; } - - public TAttribute Attribute { get; } - - public TBaseClassOrInterface CreateInstance() => _instanceCreator(); - } -} diff --git a/src/dotnetCampus.Telescope/AttributedTypes.cs b/src/dotnetCampus.Telescope/AttributedTypes.cs deleted file mode 100644 index 68a5825..0000000 --- a/src/dotnetCampus.Telescope/AttributedTypes.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.ExceptionServices; - -using static dotnetCampus.Telescope.InternalContracts; - -namespace dotnetCampus.Telescope -{ - /// - /// 当某程序集通过 dotnetCampus.TelescopeSource 编译后,可通过此类型高性能地查找类型并创建类型实例。 - /// - public static class AttributedTypes - { - /// - /// 从指定的程序集 中查找标记了 的子类(含自身)或接口的实现类。 - /// - /// 要查找的类型必须是此类型的子类(含自身)或此接口的实现类。如果任意类型均可,请使用 - /// 要查找的类型必须已标记的特性()类型。 - /// 要查找的程序集(或程序集集合)。 - /// 对这些程序集集合中所有已导出的指定类型的元数据的集合。 - public static IEnumerable> FromAssembly(params Assembly[] assemblies) - where TAttribute : Attribute - => FromAssembly((IEnumerable)assemblies); - - /// - /// 从指定的程序集 中查找标记了 的子类(含自身)或接口的实现类。 - /// - /// 要查找的类型必须是此类型的子类(含自身)或此接口的实现类。如果任意类型均可,请使用 - /// 要查找的类型必须已标记的特性()类型。 - /// 要查找的程序集(或程序集集合)。 - /// 对这些程序集集合中所有已导出的指定类型的元数据的集合。 - public static IEnumerable> FromAssembly(IEnumerable assemblies) - where TAttribute : Attribute - { - if (assemblies is null) - { - throw new ArgumentNullException(nameof(assemblies)); - } - - List? exceptions = null; - foreach (var assembly in assemblies) - { - IEnumerable>? metadataList = null; - try - { - metadataList = LoadFromAssembly(assembly); - } - catch (Exception ex) - { - exceptions ??= new List(); - exceptions.Add(ex); - } - if (metadataList is { }) - { - foreach (var metadata in metadataList) - { - yield return metadata; - } - } - } - if (exceptions is { } && exceptions.Count > 0) - { - ExceptionDispatchInfo.Capture(exceptions[0]).Throw(); - } - } - - /// - /// 从指定的程序集 中查找标记了 的子类(含自身)或接口的实现类。 - /// - /// 要查找的类型必须是此类型的子类(含自身)或此接口的实现类。如果任意类型均可,请使用 - /// 要查找的类型必须已标记的特性()类型。 - /// 要查找的程序集。 - /// 对这些程序集集合中所有已导出的指定类型的元数据的集合。 - private static IEnumerable> LoadFromAssembly(Assembly assembly) - where TAttribute : Attribute - { - if (assembly is null) - { - throw new ArgumentNullException(nameof(assembly)); - } - - var exportType = assembly.GetType(AttributedTypesExportFullClassName); - return exportType is { } && Activator.CreateInstance(exportType) is ICompileTimeAttributedTypesExporter exporter - ? LoadFromExporter(exporter) - : Enumerable.Empty>(); - } - - /// - /// 从指定的程序集已导出元数据中查找标记了 的子类(含自身)或接口的实现类。 - /// - /// 要查找的类型必须是此类型的子类(含自身)或此接口的实现类。如果任意类型均可,请使用 - /// 要查找的类型必须已标记的特性()类型。 - /// 已导出的元数据。 - /// 对这些程序集集合中所有已导出的指定类型的元数据的集合。 - private static IEnumerable> LoadFromExporter( - ICompileTimeAttributedTypesExporter exporter) - where TAttribute : Attribute - => exporter.ExportAttributeTypes(); - } -} diff --git a/src/dotnetCampus.Telescope/ICompileTimeAttributedTypesExporter.cs b/src/dotnetCampus.Telescope/ICompileTimeAttributedTypesExporter.cs deleted file mode 100644 index 4210740..0000000 --- a/src/dotnetCampus.Telescope/ICompileTimeAttributedTypesExporter.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace dotnetCampus.Telescope -{ - /// - /// 此接口的实现由编译器生成,用于以非反射的方式导出程序集中标记了特定特性()的类型和其元数据集合。 - /// - /// 要求此部分类型元数据必须是此类型的子类(含自身)或此接口的实现类。如果任意类型均可,请使用 - /// 标记的特性()类型。 - public interface ICompileTimeAttributedTypesExporter - where TAttribute : Attribute - { - /// - /// 编译器必须显式实现此接口方法,将此程序集中的类型元数据导出。 - /// - /// 此程序集中的类型元数据。 - AttributedTypeMetadata[] ExportAttributeTypes(); - } -} diff --git a/src/dotnetCampus.Telescope/InternalContracts.cs b/src/dotnetCampus.Telescope/InternalContracts.cs deleted file mode 100644 index 51ed49e..0000000 --- a/src/dotnetCampus.Telescope/InternalContracts.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dotnetCampus.Telescope -{ - /// - /// 包含生成代码的常量。 - /// - internal static class InternalContracts - { - /// - /// 生成的代码所在的命名空间。 - /// - internal const string GeneratedCodeNamespace = "dotnetCampus.Telescope"; - - /// - /// 为 生成的代码的类名。 - /// - internal const string AttributedTypesExportClassName = "__AttributedTypesExport__"; - - /// - /// 为 生成的代码的完整类名。 - /// - internal const string AttributedTypesExportFullClassName = GeneratedCodeNamespace + "." + AttributedTypesExportClassName; - } -} diff --git a/src/dotnetCampus.Telescope/MarkExportAttribute.cs b/src/dotnetCampus.Telescope/MarkExportAttribute.cs deleted file mode 100644 index b20a030..0000000 --- a/src/dotnetCampus.Telescope/MarkExportAttribute.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; - -namespace dotnetCampus.Telescope -{ - /// - /// 编译时,如果一个类型的基类或实现的接口是 类型,切标记了 特性,则将其导出。 - /// 标记导出后,在运行时,可通过 将导出的这些类型实例化。 - /// 此操作用来替代一部分的反射,用以解决掉应用程序启动时因反射导致的耗时。 - /// - [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)] - public sealed class MarkExportAttribute : Attribute - { - /// - /// 编译时,如果一个类型的基类或实现的接口是 类型,切标记了 特性,则将其导出。 - /// 标记导出后,在运行时,可通过 将导出的这些类型实例化。 - /// 此操作用来替代一部分的反射,用以解决掉应用程序启动时因反射导致的耗时。 - /// - /// 标记导出此程序集中的此类型的子类(含自身)或者此接口的实现类的类型。如果任意类型均可,请使用 typeof()。 - /// 类型上标记的特性()类型。 - public MarkExportAttribute(Type baseClassOrInterfaceType, Type attributeType) - { - RealType = baseClassOrInterfaceType; - AttributeType = attributeType; - } - - public Type RealType { get; } - - public Type AttributeType { get; } - } -} diff --git a/src/dotnetCampus.Telescope/dotnetCampus.Telescope.csproj b/src/dotnetCampus.Telescope/dotnetCampus.Telescope.csproj deleted file mode 100644 index 37ea35d..0000000 --- a/src/dotnetCampus.Telescope/dotnetCampus.Telescope.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net6.0;net5.0;netcoreapp3.1;netstandard2.0;net45 - latest - enable - - false - - - - - diff --git a/src/dotnetCampus.TelescopeTask/Cli/Options.cs b/src/dotnetCampus.TelescopeTask/Cli/Options.cs deleted file mode 100644 index 7f4ffe4..0000000 --- a/src/dotnetCampus.TelescopeTask/Cli/Options.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.IO; - -using dotnetCampus.Cli; - -namespace dotnetCampus.SourceFusion.Cli -{ - internal class Options - { - [Value(0, Description = "转换源码的工作路径。")] - public string WorkingDirectory { get; set; } - - [Option('t', "ToolFolder", Description = "SourceFusion 可以使用的临时文件夹路径。")] - public string ToolFolder { get; set; } - - [Option('c', "GeneratedCodeFolder", Description = "SourceFusion 生成的新源码文件所在的文件夹。")] - public string GeneratedCodeFolder { get; set; } - - [Option('p', "ProjectPropertyFile", Description = "一个文件,包含项目的各种所需属性和集合。")] - public string ProjectPropertyFile { get; set; } - - [Option('s', "PreprocessorSymbols", Description = "预处理符号,也就是条件编译符。")] - public string PreprocessorSymbols { get; set; } - - [Option("Debug", Description = "如果指定,将在启动编译时进入调试模式。")] - public bool DebugMode { get; set; } - } -} diff --git a/src/dotnetCampus.TelescopeTask/CodeGenerating/AttributedTypesExportFileGenerator.cs b/src/dotnetCampus.TelescopeTask/CodeGenerating/AttributedTypesExportFileGenerator.cs deleted file mode 100644 index 78afe32..0000000 --- a/src/dotnetCampus.TelescopeTask/CodeGenerating/AttributedTypesExportFileGenerator.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using dotnetCampus.SourceFusion.CompileTime; - -namespace dotnetCampus.TelescopeTask.CodeGenerating -{ - internal static class AttributedTypesExportFileGenerator - { - internal static string BuildClassImplementation( - IEnumerable exportedInterfaces, - IEnumerable exportedMethodCodes, - IEnumerable usings) - { - return $@"{string.Join(@" -", usings.Select(x => $"using {x};"))} - -namespace dotnetCampus.Telescope -{{ - public partial class __AttributedTypesExport__ : {string.Join(", ", exportedInterfaces)} - {{ - {string.Join(@" - ", exportedMethodCodes)} - }} -}}"; - } - - internal static string BuildExplicitMethodImplementation(IEnumerable types, - string baseClassOrInterfaceName, string attributeName) - { - var exportedTypes = types.Where(x => GuessTypeMatch(x, baseClassOrInterfaceName, attributeName)); - var arrayExpression = $@"new AttributedTypeMetadata<{baseClassOrInterfaceName}, {attributeName}>[] - {{ - {string.Join(@", - ", exportedTypes - .Select(x => BuildTypeAttributeMetadata( - x, - (CompileAttribute)x.Attributes.First(x => x.Match(attributeName)), - baseClassOrInterfaceName, - attributeName)))} - }}"; - return $@"AttributedTypeMetadata<{baseClassOrInterfaceName}, {attributeName}>[] ICompileTimeAttributedTypesExporter<{baseClassOrInterfaceName}, {attributeName}>.ExportAttributeTypes() - {{ - return {arrayExpression}; - }}"; - } - - internal static string BuildTypeAttributeMetadata(CompileType type, CompileAttribute attribute, - string baseClassOrInterfaceName, string attributeName) - { - return $@"new AttributedTypeMetadata<{baseClassOrInterfaceName}, {attributeName}>( - typeof({type.FullName}), - new {attributeName}({string.Join(", ", attribute.GetValues())}) - {{ - {string.Join(@", - ", attribute.GetProperties().Select(x => $"{x.property} = {x.value}"))} - }}, - () => new {type.FullName}() - )"; - } - - /// - /// 判断一个编译期类型是否继承自基类 且标记了 特性。0 - /// - /// - /// - /// - /// - private static bool GuessTypeMatch(ICompileType compileType, string baseClassOrInterfaceName, string attributeName) - { - return compileType.Attributes.Any(x => x.Match(attributeName)); - } - } -} diff --git a/src/dotnetCampus.TelescopeTask/Program.cs b/src/dotnetCampus.TelescopeTask/Program.cs deleted file mode 100644 index 0db26a9..0000000 --- a/src/dotnetCampus.TelescopeTask/Program.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Diagnostics; - -using dotnetCampus.Cli; -using dotnetCampus.Cli.Standard; -using dotnetCampus.MSBuildUtils; -using dotnetCampus.SourceFusion.Cli; -using dotnetCampus.TelescopeTask.Tasks; - -namespace dotnetCampus.TelescopeTask -{ - class Program - { - static void Main(string[] args) - { - var watch = Stopwatch.StartNew(); - try - { - new MSBuildMessage($"dotnetCampus.TelescopeTask:开始编译…").Message(); - CommandLine.Parse(args) - .AddStandardHandlers() - .AddHandler(o => new CompileTask().Run(o)) - .Run(); - } - catch (Exception ex) - { - new MSBuildMessage(ex.ToString().Replace(Environment.NewLine, " ")).Error(); - } - finally - { - new MSBuildMessage($"dotnetCampus.TelescopeTask:编译完成,耗时 {TimeSpan.FromMilliseconds(watch.ElapsedMilliseconds).TotalSeconds} s。").Message(); - } - } - } -} diff --git a/src/dotnetCampus.TelescopeTask/Tasks/CommandLineTask.cs b/src/dotnetCampus.TelescopeTask/Tasks/CommandLineTask.cs deleted file mode 100644 index 4196924..0000000 --- a/src/dotnetCampus.TelescopeTask/Tasks/CommandLineTask.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace dotnetCampus.TelescopeTask -{ - public abstract class CommandLineTask - { - public void Run() - { - RunCore(); - } - - protected abstract void RunCore(); - } -} diff --git a/src/dotnetCampus.TelescopeTask/Tasks/CompileTask.cs b/src/dotnetCampus.TelescopeTask/Tasks/CompileTask.cs deleted file mode 100644 index 6655b6d..0000000 --- a/src/dotnetCampus.TelescopeTask/Tasks/CompileTask.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -using dotnetCampus.Cli; -using dotnetCampus.Cli.Standard; -using dotnetCampus.MSBuildUtils; -using dotnetCampus.SourceFusion.Cli; -using dotnetCampus.SourceFusion.CompileTime; -using dotnetCampus.SourceFusion.Core; -using dotnetCampus.Telescope; -using dotnetCampus.TelescopeTask.Utils; - -using Walterlv.IO.PackageManagement; - -using static dotnetCampus.TelescopeTask.CodeGenerating.AttributedTypesExportFileGenerator; - -namespace dotnetCampus.TelescopeTask.Tasks -{ - internal class CompileTask - { - internal void Run(Options options) - { - // 准备编译环境。 - var context = new ProjectCompilingContext(options); - - // 进行重新编译测试。 - var shouldRebuild = CheckRebuild(context); - if (!shouldRebuild) - { - new MSBuildMessage($"dotnetCampus.TelescopeTask:项目已最新,无需导出编译信息。").Message(); - return; - } - - // 清除前一次生成的文件。 - new MSBuildMessage($"dotnetCampus.TelescopeTask:删除前一次的导出结果…").Message(); - PackageDirectory.Delete(context.GeneratedCodeFolder); - - // 收集并生成类。 - new MSBuildMessage($"dotnetCampus.TelescopeTask:正在生成新的编译信息…").Message(); - var code = GenerateAttributedTypesExportCode(context.Assembly); - if (string.IsNullOrWhiteSpace(code)) - { - return; - } - - // 将生成的类(编译单元)写入到文件中。 - new MSBuildMessage($"dotnetCampus.TelescopeTask:正在写入编译导出文件…").Message(); - PackageDirectory.Create(context.GeneratedCodeFolder); - var targetFile = Path.Combine(context.GeneratedCodeFolder, "AttributedTypesExport.g.cs"); - File.WriteAllText(targetFile, code); - - // 生成本次运行的摘要。 - var resultFile = new FileInfo(Path.Combine(context.WorkingFolder, context.ToolsFolder, "Result.txt")); - File.WriteAllText(resultFile.FullName, ""); - resultFile.LastAccessTimeUtc = DateTime.UtcNow; - } - - private bool CheckRebuild(ProjectCompilingContext context) - { - return new AllFilesLastWriteTimeRebuildingTester().CheckRebuild( - context.WorkingFolder, - context.ToolsFolder, - context.CompilingFiles); - } - - private static string GenerateAttributedTypesExportCode(CompileAssembly assembly) - { - // 从 AssemblyInfo.cs 中找出设置的导出类信息。 - var markedExports = assembly.Files - .SelectMany(x => x.AssemblyAttributes) - .Where(x => x.Match("MarkExport")) - .OfType() - .Select(x => new - { - BaseClassOrInterfaceName = GuessTypeNameByTypeOfSyntax(x[0]), - AttributeName = GuessTypeNameByTypeOfSyntax(x[1]) - }) - .ToList(); - - // 未标记任何导出,于是不生成类型。 - if (markedExports.Count == 0) - { - return ""; - } - - // 寻找并导出所有类,加入到接口列表/方法列表中,并生成类。 - var exportedInterfaces = markedExports.Select(x => $@"ICompileTimeAttributedTypesExporter<{x.BaseClassOrInterfaceName}, {x.AttributeName}>"); - var exportedMethodCodes = markedExports.Select(x => BuildExplicitMethodImplementation( - assembly.Files.SelectMany(x => x.Types).OfType(), - x.BaseClassOrInterfaceName, - x.AttributeName)); - var exportedFileUsings = assembly.Files - .SelectMany(x => x.Types) - .Where(x => markedExports.FindIndex(m => x.Attributes.Any(x => x.Match(m.AttributeName))) >= 0) - .SelectMany(x => x.UsingNamespaceList) - .Concat(assembly.Files - .Where(x => x.AssemblyAttributes.Any(x => x.Match("MarkExport"))) - .SelectMany(x => x.UsingNamespaceList)) - .Distinct(StringComparer.Ordinal) - .Where(x => !x.Contains('=')) - .OrderBy(x => x); - var exportedClass = BuildClassImplementation(exportedInterfaces, exportedMethodCodes, exportedFileUsings); - return exportedClass.Trim(); - } - - /// - /// 从 typeof(Namespace.Type) 字符串中取出 Type 部分。 - /// - /// typeof 字符串。 - /// typeof 字符串的 Type 部分。 - private static string GuessTypeNameByTypeOfSyntax(string typeofSyntaxString) - { - var match = Regex.Match(typeofSyntaxString, @"typeof\((?([\w_]+\.)*[\w_]+)\)", - RegexOptions.CultureInvariant, - TimeSpan.FromSeconds(1)); - return match.Success ? match.Groups["name"].Value : typeofSyntaxString; - } - } -} diff --git a/src/dotnetCampus.TelescopeTask/Utils/AllFilesLastWriteTimeRebuildingTester.cs b/src/dotnetCampus.TelescopeTask/Utils/AllFilesLastWriteTimeRebuildingTester.cs deleted file mode 100644 index 921b929..0000000 --- a/src/dotnetCampus.TelescopeTask/Utils/AllFilesLastWriteTimeRebuildingTester.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dotnetCampus.TelescopeTask.Utils -{ - public class AllFilesLastWriteTimeRebuildingTester : RebuildingTester - { - protected override bool CheckRebuildCore() - { - var resultFile = new FileInfo(Path.Combine(ToolDirectory.FullName, "Result.txt")); - var lastBuildingTime = resultFile.LastWriteTimeUtc; - - var projectDirectory = ProjectDirectory.FullName; - var objDirectory = Path.Combine(projectDirectory, "obj"); - var files = CompileFiles; - var newFiles = files - .Where(x => - // 是项目中的文件夹 - x.FullName.StartsWith(projectDirectory, StringComparison.OrdinalIgnoreCase) && - // 不是项目临时文件夹 - !x.FullName.StartsWith(objDirectory, StringComparison.OrdinalIgnoreCase) && - !x.FullName.StartsWith("obj", StringComparison.OrdinalIgnoreCase) - ) - .Where(x => x.LastWriteTimeUtc > lastBuildingTime); - - var shouldRebuild = newFiles.Any(); - return shouldRebuild; - } - } -} diff --git a/src/dotnetCampus.TelescopeTask/Utils/RebuildingTester.cs b/src/dotnetCampus.TelescopeTask/Utils/RebuildingTester.cs deleted file mode 100644 index 996bcfd..0000000 --- a/src/dotnetCampus.TelescopeTask/Utils/RebuildingTester.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dotnetCampus.TelescopeTask.Utils -{ - public abstract class RebuildingTester - { - public DirectoryInfo ProjectDirectory { get; private set; } - - public DirectoryInfo ToolDirectory { get; private set; } - - public IReadOnlyList CompileFiles { get; private set; } - - public bool CheckRebuild(string projectDirectory, string toolsFolder, IEnumerable compileFiles) - { - ProjectDirectory = new DirectoryInfo(projectDirectory); - ToolDirectory = new DirectoryInfo(Path.Combine(projectDirectory, toolsFolder)); - CompileFiles = compileFiles.Select(x => new FileInfo(x)).ToList(); - return CheckRebuildCore(); - } - - protected abstract bool CheckRebuildCore(); - } -} diff --git a/src/dotnetCampus.TelescopeTask/dotnetCampus.TelescopeTask.csproj b/src/dotnetCampus.TelescopeTask/dotnetCampus.TelescopeTask.csproj deleted file mode 100644 index fa4a480..0000000 --- a/src/dotnetCampus.TelescopeTask/dotnetCampus.TelescopeTask.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - Exe - net6.0;net5.0;netcoreapp3.1;net48 - Major - - - - - - - - - - - - - - - - - - - - - - - - - - -