55using System ;
66using System . Collections . Generic ;
77using System . CommandLine ;
8- using System . CommandLine . Builder ;
9- using System . CommandLine . Invocation ;
10- using System . CommandLine . Parsing ;
118#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
129using System . Diagnostics . CodeAnalysis ;
1310#endif
1613using System . Reflection ;
1714using System . Runtime . Versioning ;
1815using System . Text ;
16+ using System . Threading ;
1917using System . Threading . Tasks ;
2018
2119using Microsoft . Extensions . DependencyInjection ;
2725
2826namespace Smdn . Reflection . ReverseGenerating . ListApi ;
2927
30- public sealed class RootCommandImplementation : ICommandHandler {
28+ public sealed class RootCommandImplementation {
3129 public static readonly string DefaultBuildConfiguration = "Release" ;
3230
33- private static readonly Argument < FileSystemInfo > ArgumentInput = new Argument < FileSystemInfo > (
34- name : "input" ,
31+ private static readonly Argument < FileSystemInfo > ArgumentInput = new Argument < FileSystemInfo > ( "input" ) {
3532#if FEATURE_BUILD_PROJ
36- description : "Path to project/solution/assembly file to generate the API list. The command will search for an project file from the current directory if not specified, or search from the directory if a directory is specified." ,
33+ Description = "Path to project/solution/assembly file to generate the API list. The command will search for an project file from the current directory if not specified, or search from the directory if a directory is specified." ,
3734#else
38- description : "Path to an assembly file to generate the API list." ,
35+ Description = "Path to an assembly file to generate the API list." ,
3936#endif
40- getDefaultValue: static ( ) => new DirectoryInfo( Environment . CurrentDirectory )
41- ) {
37+ DefaultValueFactory = static _ => new DirectoryInfo ( Environment . CurrentDirectory ) ,
4238 // Arity = ArgumentArity.OneOrMore
4339 Arity = ArgumentArity . ExactlyOne ,
4440 }
45- . ExistingOnly ( ) ;
41+ . AcceptExistingOnly ( ) ;
4642
4743#if FEATURE_BUILD_PROJ
48- private static readonly Option < string ? > OptionConfiguration = new (
49- aliases : new [ ] { "-c" , "--configuration" } ,
50- description : "The 'build configuration' option passed to `Build` target when the project will be built." ,
51- getDefaultValue : static ( ) => DefaultBuildConfiguration
52- ) ;
53- private static readonly Option < string ? > OptionTargetFramework = new (
54- aliases : new [ ] { "-f" , "--framework" } ,
55- description : "The 'target framework' option passed to `Build` target when the project will be built." ,
56- getDefaultValue : static ( ) => null
57- ) ;
58- private static readonly Option < string ? > OptionRuntimeIdentifier = new (
59- aliases : new [ ] { "-r" , "--runtime" } ,
60- description : "The 'target runtime' option passed to `Build` target when the project will be built." ,
61- getDefaultValue : static ( ) => null
62- ) ;
44+ private static readonly Option < string ? > OptionConfiguration = new ( "--configuration" , "-c" ) {
45+ Description = "The 'build configuration' option passed to `Build` target when the project will be built." ,
46+ DefaultValueFactory = static _ => DefaultBuildConfiguration ,
47+ } ;
48+ private static readonly Option < string ? > OptionTargetFramework = new ( "--framework" , "-f" ) {
49+ Description = "The 'target framework' option passed to `Build` target when the project will be built." ,
50+ DefaultValueFactory = static _ => null ,
51+ } ;
52+ private static readonly Option < string ? > OptionRuntimeIdentifier = new ( "--runtime" , "-r" ) {
53+ Description = "The 'target runtime' option passed to `Build` target when the project will be built." ,
54+ DefaultValueFactory = static _ => null ,
55+ } ;
6356#if false
6457 private static readonly Option < string ? > OptionOS = new (
6558 aliases : new [ ] { "--os" } ,
6659 description : "The 'target operating system' option passed to `Build` target when the project will be built." ,
67- getDefaultValue : static ( ) => null
60+ DefaultValueFactory = static _ => null ,
6861 ) ;
6962#endif
7063#endif // FEATURE_BUILD_PROJ
71- private static readonly Option < DirectoryInfo > OptionOutputDirectory = new (
72- aliases : new [ ] { "-o" , "--output-directory" } ,
73- description : "Path to output directory." ,
74- getDefaultValue : static ( ) => new DirectoryInfo ( Environment . CurrentDirectory )
75- ) ;
76- private static readonly Option < bool > OptionLoadAssemblyIntoReflectionOnlyContext = new (
77- aliases : new [ ] { "--load-reflection-only" } ,
78- description : "Loads and processes input assemblies in the reflection-only context." ,
79- getDefaultValue : static ( ) =>
64+ private static readonly Option < DirectoryInfo > OptionOutputDirectory = new ( "--output-directory" , "-o" ) {
65+ Description = "Path to output directory." ,
66+ DefaultValueFactory = static _ => new DirectoryInfo ( Environment . CurrentDirectory ) ,
67+ } ;
68+ private static readonly Option < bool > OptionLoadAssemblyIntoReflectionOnlyContext = new ( "--load-reflection-only" ) {
69+ Description = "Loads and processes input assemblies in the reflection-only context." ,
70+ DefaultValueFactory = static _ =>
8071#if NETFRAMEWORK
81- true
72+ true ,
8273#else
83- false
74+ false ,
8475#endif
85- ) ;
76+ } ;
8677 // cSpell:disable
87- private static readonly Option < bool > OptionGenerateFullTypeName = new (
88- aliases : new [ ] { "--generate-fulltypename" } ,
89- description : "Generates declarations with full type name." ,
90- getDefaultValue : static ( ) => false
91- ) ;
92- private static readonly Option < MethodBodyOption > OptionGenerateMethodBody = new (
93- aliases : new [ ] { "--generate-methodbody" } ,
94- description : "Generates method body with specified type of implementation." ,
95- getDefaultValue : static ( ) => MethodBodyOption . EmptyImplementation
96- ) ;
97- private static readonly Option < bool > OptionGenerateStaticMembersFirst = new (
98- aliases : new [ ] { "--generate-staticmembersfirst" } ,
99- description : "Generates member declarations in the order of the static members first." ,
100- getDefaultValue : static ( ) => false
101- ) ;
102- private static readonly Option < bool > OptionGenerateNullableAnnotations = new (
103- aliases : new [ ] { "--generate-nullableannotations" } ,
104- description : "Generates declarations with nullable annotations." ,
105- getDefaultValue : static ( ) => true
106- ) ;
107- private static readonly Option < bool > OptionGenerateRecords = new (
108- aliases : new [ ] { "--generate-records" } ,
109- description : "Generates record type declarations and hides compiler-generated mebers." ,
110- getDefaultValue : static ( ) => true
111- ) ;
78+ private static readonly Option < bool > OptionGenerateFullTypeName = new ( "--generate-fulltypename" ) {
79+ Description = "Generates declarations with full type name." ,
80+ DefaultValueFactory = static _ => false ,
81+ } ;
82+ private static readonly Option < MethodBodyOption > OptionGenerateMethodBody = new ( "--generate-methodbody" ) {
83+ Description = "Generates method body with specified type of implementation." ,
84+ DefaultValueFactory = static _ => MethodBodyOption . EmptyImplementation ,
85+ } ;
86+ private static readonly Option < bool > OptionGenerateStaticMembersFirst = new ( "--generate-staticmembersfirst" ) {
87+ Description = "Generates member declarations in the order of the static members first." ,
88+ DefaultValueFactory = static _ => false ,
89+ } ;
90+ private static readonly Option < bool > OptionGenerateNullableAnnotations = new ( "--generate-nullableannotations" ) {
91+ Description = "Generates declarations with nullable annotations." ,
92+ DefaultValueFactory = static _ => true ,
93+ } ;
94+ private static readonly Option < bool > OptionGenerateRecords = new ( "--generate-records" ) {
95+ Description = "Generates record type declarations and hides compiler-generated mebers." ,
96+ DefaultValueFactory = static _ => true ,
97+ } ;
11298 // cSpell:enable
11399
114100 private readonly Microsoft . Extensions . Logging . ILogger ? logger ;
@@ -138,13 +124,13 @@ internal Command CreateCommand()
138124 OptionGenerateRecords ,
139125 } ;
140126
141- rootCommand . Handler = this ;
127+ rootCommand . SetAction ( RunAsync ) ;
142128
143129 return rootCommand ;
144130 }
145131
146132 private ParseResult ParseCommandLineArgs ( string [ ] args )
147- => new CommandLineBuilder ( CreateCommand ( ) ) . UseDefaults ( ) . Build ( ) . Parse ( args ) ;
133+ => CreateCommand ( ) . Parse ( args ) ;
148134
149135 // <remarks>This method is for testing purposes.</remarks>
150136 public ApiListWriterOptions GetApiListWriterOptions ( string [ ] args )
@@ -155,21 +141,21 @@ private static ApiListWriterOptions GetApiListWriterOptions(ParseResult parseRes
155141 var options = new ApiListWriterOptions ( ) ;
156142
157143#pragma warning disable IDE0055
158- options . TypeDeclaration . WithNamespace = parseResult . GetValueForOption ( OptionGenerateFullTypeName ) ;
159- options . MemberDeclaration . WithNamespace = parseResult . GetValueForOption ( OptionGenerateFullTypeName ) ;
160- options . AttributeDeclaration . WithNamespace = parseResult . GetValueForOption ( OptionGenerateFullTypeName ) ;
144+ options . TypeDeclaration . WithNamespace = parseResult . GetValue ( OptionGenerateFullTypeName ) ;
145+ options . MemberDeclaration . WithNamespace = parseResult . GetValue ( OptionGenerateFullTypeName ) ;
146+ options . AttributeDeclaration . WithNamespace = parseResult . GetValue ( OptionGenerateFullTypeName ) ;
161147
162- var methodBody = parseResult . GetValueForOption ( OptionGenerateMethodBody ) ;
148+ var methodBody = parseResult . GetValue ( OptionGenerateMethodBody ) ;
163149
164150 options . MemberDeclaration . MethodBody = methodBody ;
165151 options . MemberDeclaration . AccessorBody = methodBody ;
166152
167- options . Writer . OrderStaticMembersFirst = parseResult . GetValueForOption ( OptionGenerateStaticMembersFirst ) ;
168- options . Writer . WriteNullableAnnotationDirective = parseResult . GetValueForOption ( OptionGenerateNullableAnnotations ) ;
153+ options . Writer . OrderStaticMembersFirst = parseResult . GetValue ( OptionGenerateStaticMembersFirst ) ;
154+ options . Writer . WriteNullableAnnotationDirective = parseResult . GetValue ( OptionGenerateNullableAnnotations ) ;
169155
170156 options . TypeDeclaration . EnableRecordTypes =
171157 options . TypeDeclaration . OmitRecordImplicitInterface =
172- options . Writer . OmitCompilerGeneratedRecordEqualityMethods = parseResult . GetValueForOption ( OptionGenerateRecords ) ;
158+ options . Writer . OmitCompilerGeneratedRecordEqualityMethods = parseResult . GetValue ( OptionGenerateRecords ) ;
173159
174160 options . AttributeDeclaration . TypeFilter = AttributeFilter . Default ;
175161
@@ -180,17 +166,13 @@ private static ApiListWriterOptions GetApiListWriterOptions(ParseResult parseRes
180166 }
181167
182168 private static DirectoryInfo GetOutputDirectory ( ParseResult parseResult )
183- => parseResult . GetValueForOption ( OptionOutputDirectory ) ?? new ( Environment . CurrentDirectory ) ;
169+ => parseResult . GetValue ( OptionOutputDirectory ) ?? new ( Environment . CurrentDirectory ) ;
184170
185- Task < int > ICommandHandler . InvokeAsync ( InvocationContext invocationContext )
186- #pragma warning disable CA1849
187- => Task . FromResult ( ( this as ICommandHandler ) . Invoke ( invocationContext ) ) ;
188- #pragma warning restore CA1849
171+ private Task < int > RunAsync ( ParseResult parseResult , CancellationToken cancellationToken )
172+ => Task . FromResult ( Run ( parseResult , cancellationToken ) ) ;
189173
190- int ICommandHandler . Invoke ( InvocationContext invocationContext )
174+ private int Run ( ParseResult parseResult , CancellationToken cancellationToken )
191175 {
192- var parseResult = invocationContext . ParseResult ;
193-
194176#pragma warning disable CA2254
195177 logger ? . LogDebug ( parseResult . ToString ( ) ) ;
196178#pragma warning restore CA2254
@@ -206,8 +188,8 @@ int ICommandHandler.Invoke(InvocationContext invocationContext)
206188
207189 var options = GetApiListWriterOptions ( parseResult ) ;
208190 var outputDirectory = GetOutputDirectory ( parseResult ) ;
209- var loadAssemblyIntoReflectionOnlyContext = parseResult . GetValueForOption ( OptionLoadAssemblyIntoReflectionOnlyContext ) ;
210- var enableNullabilityAnnotations = parseResult . GetValueForOption ( OptionGenerateNullableAnnotations ) ;
191+ var loadAssemblyIntoReflectionOnlyContext = parseResult . GetValue ( OptionLoadAssemblyIntoReflectionOnlyContext ) ;
192+ var enableNullabilityAnnotations = parseResult . GetValue ( OptionGenerateNullableAnnotations ) ;
211193 var hasError = false ;
212194
213195 foreach ( var inputAssemblyFile in GetInputAssemblyFiles ( parseResult ) ) {
@@ -385,7 +367,7 @@ public IEnumerable<FileInfo> GetInputAssemblyFiles(string[] args)
385367
386368 private IEnumerable < FileInfo > GetInputAssemblyFiles ( ParseResult parseResult )
387369 {
388- var input = parseResult . GetValueForArgument ( ArgumentInput ) ;
370+ var input = parseResult . GetRequiredValue ( ArgumentInput ) ;
389371 FileInfo inputFile ;
390372
391373 if ( input is null )
@@ -432,10 +414,10 @@ private IEnumerable<FileInfo> GetInputAssemblyFiles(ParseResult parseResult)
432414 inputAssemblyFiles = ProjectBuilder . Build (
433415 inputFile ,
434416 options : new ( ) {
435- Configuration = parseResult . GetValueForOption ( OptionConfiguration ) ,
436- TargetFramework = parseResult . GetValueForOption ( OptionTargetFramework ) ,
437- // OS: parseResult.GetValueForOption (OptionOS),
438- RuntimeIdentifier = parseResult . GetValueForOption ( OptionRuntimeIdentifier ) ,
417+ Configuration = parseResult . GetValue ( OptionConfiguration ) ,
418+ TargetFramework = parseResult . GetValue ( OptionTargetFramework ) ,
419+ // OS: parseResult.GetValue (OptionOS),
420+ RuntimeIdentifier = parseResult . GetValue ( OptionRuntimeIdentifier ) ,
439421 LoggerVerbosity = VerbosityOption . ParseLoggerVerbosity ( parseResult ) ,
440422 } ,
441423 logger : logger
0 commit comments