Skip to content

Source generators for command handlers #1362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1bbd9c9
Playing with source generators
Keboo Jul 22, 2021
d183cfd
MVP minimum working sample....
Keboo Jul 23, 2021
eb6ab4a
An alternative
Keboo Jul 24, 2021
f3c3a60
Property binding
Keboo Jul 25, 2021
eb126af
Refactor and moving stuff around to avoid conflicts
Keboo Jul 25, 2021
972f80f
WIP getting generator logic built
Keboo Jul 26, 2021
936c6a5
More WIP on the generator
Keboo Jul 27, 2021
6328220
ctor model binding now working
Keboo Jul 27, 2021
6e50644
MVP of working generator
Keboo Jul 27, 2021
6ade863
Refactor classes into their own namespaces
Keboo Jul 27, 2021
0d4ad3f
Adding support for arguments
Keboo Jul 27, 2021
716060d
WIP, other return types.
Keboo Jul 27, 2021
f080f7e
Support int return types
Keboo Jul 27, 2021
aa7bd60
Adding in remaining well known types.
Keboo Jul 27, 2021
ef0e2f1
Async method support
Keboo Jul 28, 2021
ef89d1e
Fixing overload collision issue
Keboo Aug 9, 2021
2056cf1
Fixing partial after rebase
Keboo Aug 9, 2021
ddf0688
Remove unsafe block
Keboo Aug 15, 2021
e7b091b
Remove unused record
Keboo Aug 15, 2021
c20e6b0
Reverting unrelated changes
Keboo Aug 15, 2021
27e1621
Moving all of the generator code to their own assembly outside of Sys…
Keboo Aug 15, 2021
2c84e10
Reverting VS2022 sln changes
Keboo Aug 15, 2021
2d9662c
Fixing file path
Keboo Aug 15, 2021
9f8b4cf
Fixing file path
Keboo Aug 15, 2021
98c689f
Updating nuget
Keboo Aug 15, 2021
50cf35c
Fixing compile errors after rebase
Keboo Sep 1, 2021
268ff16
Adding Microsft.CodeAnalysis directly
Keboo Sep 3, 2021
98e9eb0
Downgrade C# code analysis version
Keboo Sep 7, 2021
916b174
Global.json change
Keboo Sep 7, 2021
d58949f
Attempting to update patch file
Keboo Sep 8, 2021
cfacc7a
Updating other patch file
Keboo Sep 9, 2021
ab415c7
Updating packing of nuget
Keboo Sep 9, 2021
198be27
Suppress warnings
Keboo Sep 9, 2021
92c95fc
Reverting the change that will be made in patch file 0002
Keboo Sep 9, 2021
568a4da
Updating patch to include to command generator project
Keboo Sep 9, 2021
fa46cf6
Fixing nullability warnings
Keboo Sep 9, 2021
0155e9d
More nullability clean up
Keboo Sep 9, 2021
6f6c06f
Updating patch
Keboo Sep 9, 2021
11839db
Removing Source Generator from source build
Keboo Sep 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions System.CommandLine.sln
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.CommandLine.Hosting.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostingPlayground", "samples\HostingPlayground\HostingPlayground.csproj", "{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CommandLine.CommandGenerator", "src\System.CommandLine.CommandGenerator\System.CommandLine.CommandGenerator.csproj", "{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -236,6 +238,18 @@ Global
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x64.Build.0 = Release|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x86.ActiveCfg = Release|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x86.Build.0 = Release|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x64.ActiveCfg = Debug|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x64.Build.0 = Debug|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x86.ActiveCfg = Debug|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x86.Build.0 = Debug|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|Any CPU.Build.0 = Release|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x64.ActiveCfg = Release|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x64.Build.0 = Release|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x86.ActiveCfg = Release|Any CPU
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -255,6 +269,7 @@ Global
{644C4B4A-4A32-4307-9F71-C3BF901FFB66} = {E5B1EC71-0FC4-4FAA-9C65-32D5016FBC45}
{39483140-BC26-4CAD-BBAE-3DC76C2F16CF} = {E5B1EC71-0FC4-4FAA-9C65-32D5016FBC45}
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906} = {6749FB3E-39DE-4321-A39E-525278E9408D}
{B0D00128-E41B-4648-9D22-9B91F8F6BF0C} = {E5B1EC71-0FC4-4FAA-9C65-32D5016FBC45}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5C159F93-800B-49E7-9905-EE09F8B8434A}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ Subject: [PATCH 1/3] Exclude dotnet-suggest from source-build.
This is not used by any downstream repos in source-build and adds a
bunch of prebuilts, so we can leave this out for now.
---
System.CommandLine.sln | 134 ------------------
.../dotnet-suggest.csproj | 1 +
2 files changed, 1 insertion(+), 134 deletions(-)
System.CommandLine.sln | 156 +------------------------------------------------
1 file changed, 3 insertions(+), 153 deletions(-)

diff --git a/System.CommandLine.sln b/System.CommandLine.sln
index ec97010..102aefe 100644
index 7441d0ef..1519e16c 100644
--- a/System.CommandLine.sln
+++ b/System.CommandLine.sln
@@ -30,31 +30,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E5B1EC71-0FC
@@ -30,35 +30,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E5B1EC71-0FC
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CommandLine", "src\System.CommandLine\System.CommandLine.csproj", "{0BE8E56E-7580-4526-BE24-D304E1779724}"
EndProject
Expand Down Expand Up @@ -43,10 +42,15 @@ index ec97010..102aefe 100644
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CommandLine.Hosting", "src\System.CommandLine.Hosting\System.CommandLine.Hosting.csproj", "{644C4B4A-4A32-4307-9F71-C3BF901FFB66}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.CommandLine.Hosting.Tests", "src\System.CommandLine.Hosting.Tests\System.CommandLine.Hosting.Tests.csproj", "{39483140-BC26-4CAD-BBAE-3DC76C2F16CF}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostingPlayground", "samples\HostingPlayground\HostingPlayground.csproj", "{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CommandLine.CommandGenerator", "src\System.CommandLine.CommandGenerator\System.CommandLine.CommandGenerator.csproj", "{B0D00128-E41B-4648-9D22-9B91F8F6BF0C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostingPlayground", "samples\HostingPlayground\HostingPlayground.csproj", "{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostingPlayground", "samples\HostingPlayground\HostingPlayground.csproj", "{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}"
EndProject
@@ -78,30 +61,6 @@ Global
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -82,30 +62,6 @@ Global
{0BE8E56E-7580-4526-BE24-D304E1779724}.Release|x64.Build.0 = Release|Any CPU
{0BE8E56E-7580-4526-BE24-D304E1779724}.Release|x86.ActiveCfg = Release|Any CPU
{0BE8E56E-7580-4526-BE24-D304E1779724}.Release|x86.Build.0 = Release|Any CPU
Expand Down Expand Up @@ -77,7 +81,7 @@ index ec97010..102aefe 100644
{EEC30462-078F-45EB-AA70-12E3170CD51E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EEC30462-078F-45EB-AA70-12E3170CD51E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EEC30462-078F-45EB-AA70-12E3170CD51E}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -114,54 +73,6 @@ Global
@@ -118,54 +74,6 @@ Global
{EEC30462-078F-45EB-AA70-12E3170CD51E}.Release|x64.Build.0 = Release|Any CPU
{EEC30462-078F-45EB-AA70-12E3170CD51E}.Release|x86.ActiveCfg = Release|Any CPU
{EEC30462-078F-45EB-AA70-12E3170CD51E}.Release|x86.Build.0 = Release|Any CPU
Expand Down Expand Up @@ -132,7 +136,7 @@ index ec97010..102aefe 100644
{27E3BFFC-4412-4E4C-A656-B9D35B8A0F3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27E3BFFC-4412-4E4C-A656-B9D35B8A0F3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27E3BFFC-4412-4E4C-A656-B9D35B8A0F3E}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -174,30 +85,6 @@ Global
@@ -178,30 +86,6 @@ Global
{27E3BFFC-4412-4E4C-A656-B9D35B8A0F3E}.Release|x64.Build.0 = Release|Any CPU
{27E3BFFC-4412-4E4C-A656-B9D35B8A0F3E}.Release|x86.ActiveCfg = Release|Any CPU
{27E3BFFC-4412-4E4C-A656-B9D35B8A0F3E}.Release|x86.Build.0 = Release|Any CPU
Expand Down Expand Up @@ -163,7 +167,7 @@ index ec97010..102aefe 100644
{644C4B4A-4A32-4307-9F71-C3BF901FFB66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{644C4B4A-4A32-4307-9F71-C3BF901FFB66}.Debug|Any CPU.Build.0 = Debug|Any CPU
{644C4B4A-4A32-4307-9F71-C3BF901FFB66}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -210,48 +97,27 @@ Global
@@ -214,18 +98,6 @@ Global
{644C4B4A-4A32-4307-9F71-C3BF901FFB66}.Release|x64.Build.0 = Release|Any CPU
{644C4B4A-4A32-4307-9F71-C3BF901FFB66}.Release|x86.ActiveCfg = Release|Any CPU
{644C4B4A-4A32-4307-9F71-C3BF901FFB66}.Release|x86.Build.0 = Release|Any CPU
Expand All @@ -182,15 +186,22 @@ index ec97010..102aefe 100644
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Debug|x64.ActiveCfg = Debug|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Debug|x64.Build.0 = Debug|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Debug|x86.ActiveCfg = Debug|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Debug|x86.Build.0 = Debug|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|Any CPU.Build.0 = Release|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x64.ActiveCfg = Release|Any CPU
@@ -238,38 +110,16 @@ Global
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x64.Build.0 = Release|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x86.ActiveCfg = Release|Any CPU
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906}.Release|x86.Build.0 = Release|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x64.ActiveCfg = Debug|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x64.Build.0 = Debug|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Debug|x86.Build.0 = Debug|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|Any CPU.Build.0 = Release|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x64.ActiveCfg = Release|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x64.Build.0 = Release|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x86.ActiveCfg = Release|Any CPU
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -210,20 +221,7 @@ index ec97010..102aefe 100644
{644C4B4A-4A32-4307-9F71-C3BF901FFB66} = {E5B1EC71-0FC4-4FAA-9C65-32D5016FBC45}
- {39483140-BC26-4CAD-BBAE-3DC76C2F16CF} = {E5B1EC71-0FC4-4FAA-9C65-32D5016FBC45}
{0BF6958D-9EE3-4623-B3D6-4DA77EAC1906} = {6749FB3E-39DE-4321-A39E-525278E9408D}
- {B0D00128-E41B-4648-9D22-9B91F8F6BF0C} = {E5B1EC71-0FC4-4FAA-9C65-32D5016FBC45}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
diff --git a/src/System.CommandLine.Suggest/dotnet-suggest.csproj b/src/System.CommandLine.Suggest/dotnet-suggest.csproj
index f529484..ef9c3bb 100644
--- a/src/System.CommandLine.Suggest/dotnet-suggest.csproj
+++ b/src/System.CommandLine.Suggest/dotnet-suggest.csproj
@@ -13,6 +13,7 @@
<DotnetSuggestBuildNumber Condition="'$(VersionSuffixDateStamp)' != ''">.$(VersionSuffixDateStamp).$(VersionSuffixBuildOfTheDay)</DotnetSuggestBuildNumber>
<VersionPrefix>1.1$(DotnetSuggestBuildNumber)</VersionPrefix>
<VersionSuffix></VersionSuffix>
+ <ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
</PropertyGroup>

<PropertyGroup>
--
2.18.0

SolutionGuid = {5C159F93-800B-49E7-9905-EE09F8B8434A}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,30 @@ rest of source-build: runtime and roslyn.

Includes a code fix for ref nullability with the new framework.
---
.../System.CommandLine.DragonFruit.csproj | 2 +-
.../System.CommandLine.Hosting.csproj | 2 +-
.../System.CommandLine.Rendering.csproj | 2 +-
src/System.CommandLine/Binding/BindingContext.cs | 2 +-
src/System.CommandLine/System.CommandLine.csproj | 7 +------
5 files changed, 5 insertions(+), 10 deletions(-)
.../System.CommandLine.CommandGenerator.csproj | 4 ++--
.../System.CommandLine.DragonFruit.csproj | 2 +-
src/System.CommandLine.Hosting/System.CommandLine.Hosting.csproj | 2 +-
.../System.CommandLine.Rendering.csproj | 2 +-
src/System.CommandLine/Binding/BindingContext.cs | 2 +-
src/System.CommandLine/System.CommandLine.csproj | 7 +------
6 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/src/System.CommandLine.CommandGenerator/System.CommandLine.CommandGenerator.csproj b/src/System.CommandLine.CommandGenerator/System.CommandLine.CommandGenerator.csproj
index d419906e..8644194a 100644
--- a/src/System.CommandLine.CommandGenerator/System.CommandLine.CommandGenerator.csproj
+++ b/src/System.CommandLine.CommandGenerator/System.CommandLine.CommandGenerator.csproj
@@ -1,7 +1,7 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
- <TargetFramework>netstandard2.0</TargetFramework>
+ <TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>9.0</LangVersion>
<IsPackable>true</IsPackable>
diff --git a/src/System.CommandLine.DragonFruit/System.CommandLine.DragonFruit.csproj b/src/System.CommandLine.DragonFruit/System.CommandLine.DragonFruit.csproj
index b3a542fd..06167997 100644
index b3a542fd..0e49d818 100644
--- a/src/System.CommandLine.DragonFruit/System.CommandLine.DragonFruit.csproj
+++ b/src/System.CommandLine.DragonFruit/System.CommandLine.DragonFruit.csproj
@@ -1,7 +1,7 @@
Expand All @@ -29,7 +44,7 @@ index b3a542fd..06167997 100644
</Description>
</PropertyGroup>
diff --git a/src/System.CommandLine.Hosting/System.CommandLine.Hosting.csproj b/src/System.CommandLine.Hosting/System.CommandLine.Hosting.csproj
index 1d00cff2..7342c1c5 100644
index bed1b893..913edb72 100644
--- a/src/System.CommandLine.Hosting/System.CommandLine.Hosting.csproj
+++ b/src/System.CommandLine.Hosting/System.CommandLine.Hosting.csproj
@@ -2,7 +2,7 @@
Expand All @@ -42,7 +57,7 @@ index 1d00cff2..7342c1c5 100644
<Description>This package provides support for using System.CommandLine with Microsoft.Extensions.Hosting.</Description>
</PropertyGroup>
diff --git a/src/System.CommandLine.Rendering/System.CommandLine.Rendering.csproj b/src/System.CommandLine.Rendering/System.CommandLine.Rendering.csproj
index d552286e..84026ebe 100644
index bd5ce1d7..762481d9 100644
--- a/src/System.CommandLine.Rendering/System.CommandLine.Rendering.csproj
+++ b/src/System.CommandLine.Rendering/System.CommandLine.Rendering.csproj
@@ -2,7 +2,7 @@
Expand All @@ -55,10 +70,10 @@ index d552286e..84026ebe 100644
<Description>This package provides support for structured command line output rendering. Write code once that renders correctly in multiple output modes, including System.Console, virtual terminal (using ANSI escape sequences), and plain text.
</Description>
diff --git a/src/System.CommandLine/Binding/BindingContext.cs b/src/System.CommandLine/Binding/BindingContext.cs
index b942ba6a..bbb83891 100644
index a80a4172..305a95ab 100644
--- a/src/System.CommandLine/Binding/BindingContext.cs
+++ b/src/System.CommandLine/Binding/BindingContext.cs
@@ -55,7 +55,7 @@ namespace System.CommandLine.Binding
@@ -56,7 +56,7 @@ namespace System.CommandLine.Binding

public ModelBinder GetModelBinder(IValueDescriptor valueDescriptor)
{
Expand All @@ -68,7 +83,7 @@ index b942ba6a..bbb83891 100644
return binder;
}
diff --git a/src/System.CommandLine/System.CommandLine.csproj b/src/System.CommandLine/System.CommandLine.csproj
index aaa2c4a3..5e875a73 100644
index 125e9c78..3a10c14d 100644
--- a/src/System.CommandLine/System.CommandLine.csproj
+++ b/src/System.CommandLine/System.CommandLine.csproj
@@ -3,7 +3,7 @@
Expand All @@ -79,8 +94,8 @@ index aaa2c4a3..5e875a73 100644
+ <TargetFramework>net5.0</TargetFramework>
<LangVersion>9</LangVersion>
<Nullable>enable</Nullable>
<Description>This package includes a powerful command line parser and other tools for building command line applications, including:
@@ -18,9 +18,4 @@

@@ -26,11 +26,6 @@
<Compile Include="..\System.Diagnostics.CodeAnalysis.cs" Link="System.Diagnostics.CodeAnalysis.cs" />
</ItemGroup>

Expand All @@ -90,6 +105,5 @@ index aaa2c4a3..5e875a73 100644
- </ItemGroup>
-
<ItemGroup>
--
2.25.2

<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"tools": {
"dotnet": "5.0.100",
"dotnet": "5.0.300",
"vs": {
"version": "16.8"
},
Expand Down
122 changes: 122 additions & 0 deletions src/System.CommandLine.CommandGenerator/CommandHandlerGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using Microsoft.CodeAnalysis;
using System.Linq;
using System.Text;

namespace System.CommandLine.CommandGenerator
{
[Generator]
public class CommandHandlerGenerator : ISourceGenerator
{
private const string ICommandHandlerType = "System.CommandLine.Invocation.ICommandHandler";

public void Execute(GeneratorExecutionContext context)
{
SyntaxReceiver rx = (SyntaxReceiver)context.SyntaxContextReceiver!;

StringBuilder builder = new();
builder.AppendLine(@"
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#nullable disable
using System.CommandLine.Binding;
using System.Reflection;
using System.Threading.Tasks;

namespace System.CommandLine.Invocation
{
public static partial class CommandHandlerGeneratorExtensions_Generated
{
");
int count = 1;
foreach (var invocation in rx.Invocations)
{
var methodParamters = invocation.Parameters
.Select(x => x.GetMethodParameter())
.Where(x => !string.IsNullOrWhiteSpace(x.Name))
.ToList();

builder.AppendLine(@$"public static {ICommandHandlerType} Generate<{string.Join(", ", Enumerable.Range(1, invocation.NumberOfGenerericParameters).Select(x => $"Unused{x}"))}>(this CommandHandlerGenerator handler,");
builder.AppendLine($"{invocation.DelegateType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)} method");
if (methodParamters.Count > 0)
{
builder.AppendLine(",");
builder.AppendLine(string.Join($", ", methodParamters.Select(x => $"{x.Type} {x.Name}")));
}
builder.AppendLine(")");
builder.AppendLine("{");
builder.Append($"return new GeneratedHandler_{count}(method");
if (methodParamters.Count > 0)
{
builder.Append(", ");
builder.Append(string.Join(", ", methodParamters.Select(x => x.Name)));
}
builder.AppendLine(");");

builder.AppendLine("}");


//TODO: fully qualify type names
builder.AppendLine($@"
private class GeneratedHandler_{count} : {ICommandHandlerType}
{{
public GeneratedHandler_{count}({invocation.DelegateType} method");

if (methodParamters.Count > 0)
{
builder.AppendLine(",");
builder.AppendLine(string.Join($", ", methodParamters.Select(x => $"{x.Type} {x.Name}")));
}

builder.AppendLine($@")
{{
Method = method;");
foreach (var propertyAssignment in invocation.Parameters
.Select(x => x.GetPropertyAssignment())
.Where(x => !string.IsNullOrWhiteSpace(x)))
{
builder.AppendLine(propertyAssignment);
}
builder.AppendLine($@"
}}

public {invocation.DelegateType} Method {{ get; }}");

foreach (var propertyDeclaration in invocation.Parameters
.Select(x => x.GetPropertyDeclaration())
.Where(x => !string.IsNullOrWhiteSpace(x)))
{
builder.AppendLine(propertyDeclaration);
}

builder.AppendLine($@"
public async Task<int> InvokeAsync(InvocationContext context)
{{");
builder.AppendLine(invocation.InvokeContents());
builder.AppendLine($@"
}}
}}");
count++;
}

builder.AppendLine(@"
}
}
#nullable restore");

context.AddSource("CommandHandlerGeneratorExtensions_Generated.g.cs", builder.ToString());
}

public void Initialize(GeneratorInitializationContext context)
{
#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
{
//System.Diagnostics.Debugger.Launch();
}
#endif

context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
}
}
}
Loading