This commit is contained in:
Tyrrrz
2022-01-10 23:41:28 +02:00
parent 8e96d2701d
commit 4ff1e1d3e1
30 changed files with 184 additions and 165 deletions

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(null)] [CommandOption(null)]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -38,7 +38,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -57,7 +57,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Bar { get; set; } public string Bar { get; set; }
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption(""bar"")] [CommandOption(""bar"")]
public string Bar { get; set; } public string Bar { get; set; }
@@ -63,7 +63,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption('f')] [CommandOption('f')]
public string Bar { get; set; } public string Bar { get; set; }
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public string Bar { get; set; } public string Bar { get; set; }
@@ -63,7 +63,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption('F')] [CommandOption('F')]
public string Bar { get; set; } public string Bar { get; set; }
@@ -85,7 +85,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -24,7 +24,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"", Converter = typeof(MyConverter))] [CommandOption(""foo"", Converter = typeof(MyConverter))]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -48,7 +48,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"", Converter = typeof(MyConverter))] [CommandOption(""foo"", Converter = typeof(MyConverter))]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -67,7 +67,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""f"")] [CommandOption(""f"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -38,7 +38,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""1foo"")] [CommandOption(""1foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -57,7 +57,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -76,7 +76,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('1')] [CommandOption('1')]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -38,7 +38,7 @@ public class MyCommand : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -57,7 +57,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -24,7 +24,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"", Validators = new[] {typeof(MyValidator)})] [CommandOption(""foo"", Validators = new[] {typeof(MyValidator)})]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -48,7 +48,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"", Validators = new[] {typeof(MyValidator)})] [CommandOption(""foo"", Validators = new[] {typeof(MyValidator)})]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -67,7 +67,7 @@ public class MyCommand : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -9,7 +9,7 @@ public class ParameterMustBeLastIfNonScalarAnalyzerSpecs
private static DiagnosticAnalyzer Analyzer { get; } = new ParameterMustBeLastIfNonScalarAnalyzer(); private static DiagnosticAnalyzer Analyzer { get; } = new ParameterMustBeLastIfNonScalarAnalyzer();
[Fact] [Fact]
public void Analyzer_reports_an_error_if_a_non_scalar_parameter_is_not_last_in_order() public void Analyzer_reports_an_error_if_a_non_scalar_parameter_is_not_the_last_in_order()
{ {
// Arrange // Arrange
// language=cs // language=cs
@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string[] Foo { get; set; } public string[] Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }
@@ -31,7 +31,7 @@ public class MyCommand : ICommand
} }
[Fact] [Fact]
public void Analyzer_does_not_report_an_error_if_a_non_scalar_parameter_is_last_in_order() public void Analyzer_does_not_report_an_error_if_a_non_scalar_parameter_is_the_last_in_order()
{ {
// Arrange // Arrange
// language=cs // language=cs
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string[] Bar { get; set; } public string[] Bar { get; set; }
@@ -63,7 +63,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }

View File

@@ -9,7 +9,7 @@ public class ParameterMustBeLastIfNotRequiredAnalyzerSpecs
private static DiagnosticAnalyzer Analyzer { get; } = new ParameterMustBeLastIfNotRequiredAnalyzer(); private static DiagnosticAnalyzer Analyzer { get; } = new ParameterMustBeLastIfNotRequiredAnalyzer();
[Fact] [Fact]
public void Analyzer_reports_an_error_if_a_parameter_is_not_required_and_is_not_last_parameter() public void Analyzer_reports_an_error_if_a_non_required_parameter_is_not_the_last_in_order()
{ {
// Arrange // Arrange
// language=cs // language=cs
@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Name = ""foo"", IsRequired = false)] [CommandParameter(0, Name = ""foo"", IsRequired = false)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1, Name = ""bar"", IsRequired = false)] [CommandParameter(1, Name = ""bar"", IsRequired = false)]
public string Bar { get; set; } public string Bar { get; set; }
@@ -31,7 +31,7 @@ public class MyCommand : ICommand
} }
[Fact] [Fact]
public void Analyzer_does_not_report_an_error_if_isRequired_is_false_on_last_parameter() public void Analyzer_does_not_report_an_error_if_a_non_required_parameter_is_the_last_in_order()
{ {
// Arrange // Arrange
// language=cs // language=cs
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Name = ""foo"", IsRequired = true)] [CommandParameter(0, Name = ""foo"", IsRequired = true)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1, Name = ""bar"", IsRequired = false)] [CommandParameter(1, Name = ""bar"", IsRequired = false)]
public string Bar { get; set; } public string Bar { get; set; }
@@ -53,7 +53,7 @@ public class MyCommand : ICommand
} }
[Fact] [Fact]
public void Analyzer_does_not_report_an_error_on_a_property_when_isRequired_is_not_set() public void Analyzer_does_not_report_an_error_if_no_non_required_parameters_are_defined()
{ {
// Arrange // Arrange
// language=cs // language=cs
@@ -63,8 +63,8 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Name = ""foo"")] [CommandParameter(0, Name = ""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1, Name = ""bar"")] [CommandParameter(1, Name = ""bar"", IsRequired = true)]
public string Bar { get; set; } public string Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
@@ -73,4 +73,22 @@ public class MyCommand : ICommand
// Act & assert // Act & assert
Analyzer.Should().NotProduceDiagnostics(code); Analyzer.Should().NotProduceDiagnostics(code);
} }
[Fact]
public void Analyzer_does_not_report_an_error_on_a_property_that_is_not_a_parameter()
{
// Arrange
// language=cs
const string code = @"
[Command]
public class MyCommand : ICommand
{
public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default;
}";
// Act & assert
Analyzer.Should().NotProduceDiagnostics(code);
}
} }

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string[] Foo { get; set; } public string[] Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string[] Bar { get; set; } public string[] Bar { get; set; }
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string[] Bar { get; set; } public string[] Bar { get; set; }
@@ -63,7 +63,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Name = ""foo"")] [CommandParameter(0, Name = ""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1, Name = ""foo"")] [CommandParameter(1, Name = ""foo"")]
public string Bar { get; set; } public string Bar { get; set; }
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Name = ""foo"")] [CommandParameter(0, Name = ""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1, Name = ""bar"")] [CommandParameter(1, Name = ""bar"")]
public string Bar { get; set; } public string Bar { get; set; }

View File

@@ -19,7 +19,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(0)] [CommandParameter(0)]
public string Bar { get; set; } public string Bar { get; set; }
@@ -41,7 +41,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }

View File

@@ -24,7 +24,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Converter = typeof(MyConverter))] [CommandParameter(0, Converter = typeof(MyConverter))]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -48,7 +48,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Converter = typeof(MyConverter))] [CommandParameter(0, Converter = typeof(MyConverter))]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -67,7 +67,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -24,7 +24,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Validators = new[] {typeof(MyValidator)})] [CommandParameter(0, Validators = new[] {typeof(MyValidator)})]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -48,7 +48,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0, Validators = new[] {typeof(MyValidator)})] [CommandParameter(0, Validators = new[] {typeof(MyValidator)})]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";
@@ -67,7 +67,7 @@ public class MyCommand : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"; }";

View File

@@ -71,10 +71,9 @@ internal partial class CommandOptionSymbol
{ {
var attribute = TryGetOptionAttribute(property); var attribute = TryGetOptionAttribute(property);
if (attribute is null) return attribute is not null
return null; ? FromAttribute(attribute)
: null;
return FromAttribute(attribute);
} }
public static bool IsOptionProperty(IPropertySymbol property) => public static bool IsOptionProperty(IPropertySymbol property) =>

View File

@@ -10,9 +10,9 @@ internal partial class CommandParameterSymbol
public int Order { get; } public int Order { get; }
public string? Name { get; } public string? Name { get; }
public bool? IsRequired { get; } public bool? IsRequired { get; }
public ITypeSymbol? ConverterType { get; } public ITypeSymbol? ConverterType { get; }
public IReadOnlyList<ITypeSymbol> ValidatorTypes { get; } public IReadOnlyList<ITypeSymbol> ValidatorTypes { get; }
@@ -41,7 +41,7 @@ internal partial class CommandParameterSymbol
private static CommandParameterSymbol FromAttribute(AttributeData attribute) private static CommandParameterSymbol FromAttribute(AttributeData attribute)
{ {
var order = (int) attribute var order = (int)attribute
.ConstructorArguments .ConstructorArguments
.Select(a => a.Value) .Select(a => a.Value)
.First()!; .First()!;
@@ -51,7 +51,7 @@ internal partial class CommandParameterSymbol
.Where(a => a.Key == "Name") .Where(a => a.Key == "Name")
.Select(a => a.Value.Value) .Select(a => a.Value.Value)
.FirstOrDefault() as string; .FirstOrDefault() as string;
var isRequired = attribute var isRequired = attribute
.NamedArguments .NamedArguments
.Where(a => a.Key == "IsRequired") .Where(a => a.Key == "IsRequired")

View File

@@ -12,8 +12,8 @@ public class ParameterMustBeLastIfNonScalarAnalyzer : AnalyzerBase
{ {
public ParameterMustBeLastIfNonScalarAnalyzer() public ParameterMustBeLastIfNonScalarAnalyzer()
: base( : base(
"Parameters of non-scalar types must be last in order", "Parameters of non-scalar types must be the last in order",
"This parameter has a non-scalar type so it must be last in order (its order must be highest within the command).") "This parameter has a non-scalar type so it must be the last in order (its order must be highest within the command).")
{ {
} }

View File

@@ -1,5 +1,4 @@
using System; using System.Linq;
using System.Linq;
using CliFx.Analyzers.ObjectModel; using CliFx.Analyzers.ObjectModel;
using CliFx.Analyzers.Utils.Extensions; using CliFx.Analyzers.Utils.Extensions;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
@@ -13,8 +12,8 @@ public class ParameterMustBeLastIfNotRequiredAnalyzer : AnalyzerBase
{ {
public ParameterMustBeLastIfNotRequiredAnalyzer() public ParameterMustBeLastIfNotRequiredAnalyzer()
: base( : base(
"Only last parameter can be optional", "Parameters marked as non-required must be the last in order",
"IsRequired can only be set to false on the last parameter.") "This parameter is non-required so it must be the last in order (its order must be highest within the command).")
{ {
} }
@@ -27,10 +26,12 @@ public class ParameterMustBeLastIfNotRequiredAnalyzer : AnalyzerBase
return; return;
var parameter = CommandParameterSymbol.TryResolve(property); var parameter = CommandParameterSymbol.TryResolve(property);
if (parameter is null)
if (parameter is null || parameter.IsRequired != false)
return; return;
if (parameter.IsRequired != false)
return;
var otherProperties = property var otherProperties = property
.ContainingType .ContainingType
.GetMembers() .GetMembers()
@@ -44,7 +45,7 @@ public class ParameterMustBeLastIfNotRequiredAnalyzer : AnalyzerBase
if (otherParameter is null) if (otherParameter is null)
continue; continue;
if (parameter.IsRequired is false && parameter.Order < otherParameter.Order) if (otherParameter.Order > parameter.Order)
{ {
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
} }

View File

@@ -103,7 +103,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public bool Foo { get; set; } public bool Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public bool Bar { get; set; } public bool Bar { get; set; }
@@ -379,7 +379,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public int? Foo { get; set; } public int? Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public int? Bar { get; set; } public int? Bar { get; set; }
@@ -427,7 +427,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public CustomEnum? Foo { get; set; } public CustomEnum? Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public CustomEnum? Bar { get; set; } public CustomEnum? Bar { get; set; }
@@ -471,7 +471,7 @@ public class Command : ICommand
public class CustomType public class CustomType
{ {
public string Value { get; } public string Value { get; }
public CustomType(string value) => Value = value; public CustomType(string value) => Value = value;
} }
@@ -480,7 +480,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public CustomType Foo { get; set; } public CustomType Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo.Value); console.Output.WriteLine(Foo.Value);
@@ -516,9 +516,9 @@ public class Command : ICommand
public class CustomTypeA public class CustomTypeA
{ {
public string Value { get; } public string Value { get; }
private CustomTypeA(string value) => Value = value; private CustomTypeA(string value) => Value = value;
public static CustomTypeA Parse(string value) => public static CustomTypeA Parse(string value) =>
new CustomTypeA(value); new CustomTypeA(value);
} }
@@ -526,9 +526,9 @@ public class CustomTypeA
public class CustomTypeB public class CustomTypeB
{ {
public string Value { get; } public string Value { get; }
private CustomTypeB(string value) => Value = value; private CustomTypeB(string value) => Value = value;
public static CustomTypeB Parse(string value, IFormatProvider formatProvider) => public static CustomTypeB Parse(string value, IFormatProvider formatProvider) =>
new CustomTypeB(value); new CustomTypeB(value);
} }
@@ -538,10 +538,10 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public CustomTypeA Foo { get; set; } public CustomTypeA Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public CustomTypeB Bar { get; set; } public CustomTypeB Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(""Foo = "" + Foo.Value); console.Output.WriteLine(""Foo = "" + Foo.Value);
@@ -590,7 +590,7 @@ public class Command : ICommand
{ {
[CommandOption('f', Converter = typeof(CustomConverter))] [CommandOption('f', Converter = typeof(CustomConverter))]
public int Foo { get; set; } public int Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -628,7 +628,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string[] Foo { get; set; } public string[] Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -672,7 +672,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -716,7 +716,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public List<string> Foo { get; set; } public List<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -760,7 +760,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public int[] Foo { get; set; } public int[] Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -804,7 +804,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public int Foo { get; set; } public int Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -840,7 +840,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public CustomType Foo { get; set; } public CustomType Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -872,7 +872,7 @@ public class Command : ICommand
public class CustomType : IEnumerable<object> public class CustomType : IEnumerable<object>
{ {
public IEnumerator<object> GetEnumerator() => Enumerable.Empty<object>().GetEnumerator(); public IEnumerator<object> GetEnumerator() => Enumerable.Empty<object>().GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
} }
@@ -881,7 +881,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public CustomType Foo { get; set; } public CustomType Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -925,7 +925,7 @@ public class Command : ICommand
{ {
[CommandOption('f', Validators = new[] {typeof(ValidatorA), typeof(ValidatorB)})] [CommandOption('f', Validators = new[] {typeof(ValidatorA), typeof(ValidatorB)})]
public int Foo { get; set; } public int Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -957,9 +957,9 @@ public class Command : ICommand
public class CustomType public class CustomType
{ {
public string Value { get; } public string Value { get; }
private CustomType(string value) => Value = value; private CustomType(string value) => Value = value;
public static CustomType Parse(string value) => throw new Exception(""Hello world""); public static CustomType Parse(string value) => throw new Exception(""Hello world"");
} }
@@ -968,7 +968,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public CustomType Foo { get; set; } public CustomType Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");

View File

@@ -31,7 +31,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", IsRequired = true, EnvironmentVariable = ""ENV_FOO"")] [CommandOption(""foo"", IsRequired = true, EnvironmentVariable = ""ENV_FOO"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -73,7 +73,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")] [CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -115,12 +115,12 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")] [CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.Output.WriteLine(i);
return default; return default;
} }
} }
@@ -162,7 +162,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")] [CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -204,7 +204,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")] [CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);

View File

@@ -339,13 +339,13 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }
[CommandParameter(2)] [CommandParameter(2)]
public IReadOnlyList<string> Baz { get; set; } public IReadOnlyList<string> Baz { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -396,7 +396,7 @@ public class Command : CommandBase
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }
public override ValueTask ExecuteAsync(IConsole console) => default; public override ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -434,13 +434,13 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", IsRequired = true)] [CommandOption(""foo"", IsRequired = true)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption(""bar"")] [CommandOption(""bar"")]
public string Bar { get; set; } public string Bar { get; set; }
[CommandOption(""baz"", IsRequired = true)] [CommandOption(""baz"", IsRequired = true)]
public IReadOnlyList<string> Baz { get; set; } public IReadOnlyList<string> Baz { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -478,10 +478,10 @@ public class Command : ICommand
{ {
[CommandParameter(0, Name = ""foo"", Description = ""Description of foo."")] [CommandParameter(0, Name = ""foo"", Description = ""Description of foo."")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption(""bar"", Description = ""Description of bar."")] [CommandOption(""bar"", Description = ""Description of bar."")]
public string Bar { get; set; } public string Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -597,10 +597,10 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public CustomEnum Foo { get; set; } public CustomEnum Foo { get; set; }
[CommandOption(""bar"")] [CommandOption(""bar"")]
public CustomEnum Bar { get; set; } public CustomEnum Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -732,10 +732,10 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")] [CommandOption(""foo"", EnvironmentVariable = ""ENV_FOO"")]
public CustomEnum Foo { get; set; } public CustomEnum Foo { get; set; }
[CommandOption(""bar"", EnvironmentVariable = ""ENV_BAR"")] [CommandOption(""bar"", EnvironmentVariable = ""ENV_BAR"")]
public CustomEnum Bar { get; set; } public CustomEnum Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");
@@ -794,10 +794,10 @@ public class Command : ICommand
[CommandOption(""lol"")] [CommandOption(""lol"")]
public CustomEnum Lol { get; set; } = CustomEnum.Two; public CustomEnum Lol { get; set; } = CustomEnum.Two;
[CommandOption(""hmm"", IsRequired = true)] [CommandOption(""hmm"", IsRequired = true)]
public string Hmm { get; set; } = ""not printed""; public string Hmm { get; set; } = ""not printed"";
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
} }
"); ");

View File

@@ -28,7 +28,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public bool Foo { get; set; } public bool Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -66,7 +66,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public bool Foo { get; set; } public bool Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -104,10 +104,10 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption(""bar"")] [CommandOption(""bar"")]
public string Bar { get; set; } public string Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(""Foo = "" + Foo); console.Output.WriteLine(""Foo = "" + Foo);
@@ -150,10 +150,10 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public string Bar { get; set; } public string Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(""Foo = "" + Foo); console.Output.WriteLine(""Foo = "" + Foo);
@@ -196,10 +196,10 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption('b')] [CommandOption('b')]
public string Bar { get; set; } public string Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(""Foo = "" + Foo); console.Output.WriteLine(""Foo = "" + Foo);
@@ -242,7 +242,7 @@ public class Command : ICommand
{ {
[CommandOption(""Foo"")] [CommandOption(""Foo"")]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -286,7 +286,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -330,7 +330,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -374,7 +374,7 @@ public class Command : ICommand
{ {
[CommandOption('f')] [CommandOption('f')]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -418,7 +418,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", 'f')] [CommandOption(""foo"", 'f')]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
@@ -462,10 +462,10 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
[CommandOption(""bar"")] [CommandOption(""bar"")]
public string Bar { get; set; } = ""hello""; public string Bar { get; set; } = ""hello"";
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(""Foo = "" + Foo); console.Output.WriteLine(""Foo = "" + Foo);
@@ -506,7 +506,7 @@ public class Command : ICommand
public static class SharedContext public static class SharedContext
{ {
public static int Foo { get; set; } public static int Foo { get; set; }
public static bool Bar { get; set; } public static bool Bar { get; set; }
} }
@@ -585,7 +585,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.Output.WriteLine(Foo);
@@ -624,7 +624,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", IsRequired = true)] [CommandOption(""foo"", IsRequired = true)]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"); }");
@@ -658,7 +658,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", IsRequired = true)] [CommandOption(""foo"", IsRequired = true)]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"); }");
@@ -692,7 +692,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"", IsRequired = true)] [CommandOption(""foo"", IsRequired = true)]
public IReadOnlyList<string> Foo { get; set; } public IReadOnlyList<string> Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"); }");
@@ -726,7 +726,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"); }");
@@ -760,7 +760,7 @@ public class Command : ICommand
{ {
[CommandOption(""foo"")] [CommandOption(""foo"")]
public string Foo { get; set; } public string Foo { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"); }");

View File

@@ -27,7 +27,7 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }
@@ -35,7 +35,7 @@ public class Command : ICommand
{ {
console.Output.WriteLine(""Foo = "" + Foo); console.Output.WriteLine(""Foo = "" + Foo);
console.Output.WriteLine(""Bar = "" + Bar); console.Output.WriteLine(""Bar = "" + Bar);
return default; return default;
} }
}"); }");
@@ -73,13 +73,13 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }
[CommandParameter(2)] [CommandParameter(2)]
public IReadOnlyList<string> Baz { get; set; } public IReadOnlyList<string> Baz { get; set; }
[CommandOption(""boo"")] [CommandOption(""boo"")]
public string Boo { get; set; } public string Boo { get; set; }
@@ -87,10 +87,10 @@ public class Command : ICommand
{ {
console.Output.WriteLine(""Foo = "" + Foo); console.Output.WriteLine(""Foo = "" + Foo);
console.Output.WriteLine(""Bar = "" + Bar); console.Output.WriteLine(""Bar = "" + Bar);
foreach (var i in Baz) foreach (var i in Baz)
console.Output.WriteLine(""Baz = "" + i); console.Output.WriteLine(""Baz = "" + i);
return default; return default;
} }
}"); }");
@@ -131,7 +131,7 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }
@@ -168,10 +168,10 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public IReadOnlyList<string> Bar { get; set; } public IReadOnlyList<string> Bar { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default; public ValueTask ExecuteAsync(IConsole console) => default;
}"); }");
@@ -205,7 +205,7 @@ public class Command : ICommand
{ {
[CommandParameter(0)] [CommandParameter(0)]
public string Foo { get; set; } public string Foo { get; set; }
[CommandParameter(1)] [CommandParameter(1)]
public string Bar { get; set; } public string Bar { get; set; }

View File

@@ -29,7 +29,7 @@ public sealed class CommandOptionAttribute : Attribute
public char? ShortName { get; } public char? ShortName { get; }
/// <summary> /// <summary>
/// Whether this option is required. /// Whether this option is required (default: <c>false</c>).
/// If an option is required, the user will get an error if they don't set it. /// If an option is required, the user will get an error if they don't set it.
/// </summary> /// </summary>
public bool IsRequired { get; set; } public bool IsRequired { get; set; }

View File

@@ -11,23 +11,24 @@ public sealed class CommandParameterAttribute : Attribute
{ {
/// <summary> /// <summary>
/// Parameter order. /// Parameter order.
/// </summary>
/// <remarks>
/// Higher order means the parameter appears later, lower order means /// Higher order means the parameter appears later, lower order means
/// it appears earlier. /// it appears earlier.
/// /// </summary>
/// <remarks>
/// All parameters in a command must have unique order. /// All parameters in a command must have unique order.
///
/// Parameter whose type is a non-scalar (e.g. array), must always be the last in order. /// Parameter whose type is a non-scalar (e.g. array), must always be the last in order.
/// Only one non-scalar parameter is allowed in a command. /// Only one non-scalar parameter is allowed in a command.
/// </remarks> /// </remarks>
public int Order { get; } public int Order { get; }
/// <summary> /// <summary>
/// Whether this parameter is required. (default: true) /// Whether this parameter is required (default: <c>true</c>).
/// If a parameter is required, the user will get an error if they don't set it. /// If a parameter is required, the user will get an error if they don't set it.
/// Only the last parameter in order can be optional.
/// </summary> /// </summary>
/// <remarks>
/// Parameter marked as non-required must always be the last in order.
/// Only one non-required parameter is allowed in a command.
/// </remarks>
public bool IsRequired { get; set; } = true; public bool IsRequired { get; set; } = true;
/// <summary> /// <summary>

View File

@@ -82,7 +82,7 @@ public interface IConsole
/// </para> /// </para>
/// </remarks> /// </remarks>
CancellationToken RegisterCancellationHandler(); CancellationToken RegisterCancellationHandler();
/// <summary> /// <summary>
/// Clears the console buffer and corresponding console window of display information. /// Clears the console buffer and corresponding console window of display information.
/// </summary> /// </summary>

View File

@@ -33,7 +33,7 @@ internal class BindablePropertyDescriptor : IPropertyDescriptor
return type; return type;
} }
var underlyingType = GetUnderlyingType(Type); var underlyingType = GetUnderlyingType(Type);
// We can only get valid values for enums // We can only get valid values for enums

View File

@@ -13,27 +13,28 @@ internal partial class ParameterSchema : IMemberSchema
public string Name { get; } public string Name { get; }
public string? Description { get; }
public bool IsRequired { get; } public bool IsRequired { get; }
public string? Description { get; }
public Type? ConverterType { get; } public Type? ConverterType { get; }
public IReadOnlyList<Type> ValidatorTypes { get; } public IReadOnlyList<Type> ValidatorTypes { get; }
public ParameterSchema(IPropertyDescriptor property, public ParameterSchema(
IPropertyDescriptor property,
int order, int order,
string name, string name,
string? description,
bool isRequired, bool isRequired,
string? description,
Type? converterType, Type? converterType,
IReadOnlyList<Type> validatorTypes) IReadOnlyList<Type> validatorTypes)
{ {
Property = property; Property = property;
Order = order; Order = order;
Name = name; Name = name;
Description = description;
IsRequired = isRequired; IsRequired = isRequired;
Description = description;
ConverterType = converterType; ConverterType = converterType;
ValidatorTypes = validatorTypes; ValidatorTypes = validatorTypes;
} }
@@ -58,8 +59,8 @@ internal partial class ParameterSchema
new BindablePropertyDescriptor(property), new BindablePropertyDescriptor(property),
attribute.Order, attribute.Order,
name, name,
description,
attribute.IsRequired, attribute.IsRequired,
description,
attribute.Converter, attribute.Converter,
attribute.Validators attribute.Validators
); );

View File

@@ -32,7 +32,6 @@ internal static partial class PolyfillExtensions
stream.Write(buffer, 0, buffer.Length); stream.Write(buffer, 0, buffer.Length);
} }
namespace System.Linq namespace System.Linq
{ {
internal static class PolyfillExtensions internal static class PolyfillExtensions

View File

@@ -226,7 +226,7 @@ Similarly, unseparated arguments in the form of `myapp -ofile` will be treated a
Because of these rules, order of arguments is semantically important and must always follow this pattern: Because of these rules, order of arguments is semantically important and must always follow this pattern:
```ini ```txt
[directives] [command name] [parameters] [options] [directives] [command name] [parameters] [options]
``` ```
@@ -596,7 +596,7 @@ public async Task ConcatCommand_executes_successfully()
// Act // Act
await command.ExecuteAsync(console); await command.ExecuteAsync(console);
var stdOut = console.ReadOutputString(); var stdOut = console.ReadOutputString();
// Assert // Assert
@@ -624,7 +624,7 @@ public async Task ConcatCommand_executes_successfully()
// Act // Act
await app.RunAsync(args, envVars); await app.RunAsync(args, envVars);
var stdOut = console.ReadOutputString(); var stdOut = console.ReadOutputString();
// Assert // Assert