Skip to content

Commit

Permalink
C# 8 Nullable reference types (dotnet#856)
Browse files Browse the repository at this point in the history
  • Loading branch information
Keboo authored May 11, 2020
1 parent 65f9a03 commit 750fdd1
Show file tree
Hide file tree
Showing 86 changed files with 568 additions and 451 deletions.
20 changes: 20 additions & 0 deletions src/System.CommandLine.Tests/ArgumentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ public void When_there_is_no_default_value_then_GetDefaultValue_throws()
.Be("Argument \"the-arg\" does not have a default value");
}

[Fact]
public void When_argument_type_is_set_to_null_then_it_throws()
{
var argument = new Argument();

argument.Invoking(a => a.ArgumentType = null)
.Should()
.Throw<ArgumentNullException>();
}

[Fact]
public void By_default_the_argument_type_is_void()
{
var argument = new Argument();

argument.ArgumentType
.Should()
.Be(typeof(void));
}

public class CustomParsing
{
[Fact]
Expand Down
49 changes: 27 additions & 22 deletions src/System.CommandLine/Argument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,34 @@ namespace System.CommandLine
{
public class Argument : Symbol, IArgument
{
private Func<ArgumentResult, object> _defaultValueFactory;
private Func<ArgumentResult, object?>? _defaultValueFactory;
private readonly List<string> _suggestions = new List<string>();
private readonly List<ISuggestionSource> _suggestionSources = new List<ISuggestionSource>();
private IArgumentArity _arity;
private TryConvertArgument _convertArguments;
private IArgumentArity? _arity;
private TryConvertArgument? _convertArguments;
private Type _argumentType = typeof(void);

public Argument()
{
}

public Argument(string name)
public Argument(string? name)
{
if (!string.IsNullOrWhiteSpace(name))
{
Name = name;
Name = name!;
}
}

internal HashSet<string> AllowedValues { get; private set; }
internal HashSet<string>? AllowedValues { get; private set; }

public IArgumentArity Arity
{
get
{
if (_arity == null)
if (_arity is null)
{
if (ArgumentType != null)
if (ArgumentType != typeof(void))
{
return ArgumentArity.Default(ArgumentType, this, Parents.FirstOrDefault());
}
Expand All @@ -52,19 +53,19 @@ public IArgumentArity Arity
set => _arity = value;
}

internal TryConvertArgument ConvertArguments
internal TryConvertArgument? ConvertArguments
{
get
{
if (_convertArguments == null &&
ArgumentType != null)
ArgumentType != typeof(void))
{
if (ArgumentType.CanBeBoundFromScalarValue())
{
if (Arity.MaximumNumberOfValues == 1 &&
ArgumentType == typeof(bool))
{
_convertArguments = (ArgumentResult symbol, out object value) =>
_convertArguments = (ArgumentResult symbol, out object? value) =>
{
value = ArgumentConverter.ConvertObject(
this,
Expand Down Expand Up @@ -108,18 +109,22 @@ bool DefaultConvert(SymbolResult symbol, out object value)
set => _convertArguments = value;
}

public Type ArgumentType { get; set; }
public Type ArgumentType
{
get => _argumentType;
set => _argumentType = value ?? throw new ArgumentNullException(nameof(value));
}

internal List<ValidateSymbol<ArgumentResult>> Validators { get; } = new List<ValidateSymbol<ArgumentResult>>();

public void AddValidator(ValidateSymbol<ArgumentResult> validator) => Validators.Add(validator);

public object GetDefaultValue()
public object? GetDefaultValue()
{
return GetDefaultValue(new ArgumentResult(this, null));
}

internal object GetDefaultValue(ArgumentResult argumentResult)
internal object? GetDefaultValue(ArgumentResult argumentResult)
{
if (_defaultValueFactory is null)
{
Expand All @@ -134,17 +139,17 @@ public void SetDefaultValue(object value)
SetDefaultValueFactory(() => value);
}

public void SetDefaultValueFactory(Func<object> getDefaultValue)
public void SetDefaultValueFactory(Func<object?> getDefaultValue)
{
if (getDefaultValue == null)
if (getDefaultValue is null)
{
throw new ArgumentNullException(nameof(getDefaultValue));
}

SetDefaultValueFactory(_ => getDefaultValue());
}

public void SetDefaultValueFactory(Func<ArgumentResult, object> getDefaultValue)
public void SetDefaultValueFactory(Func<ArgumentResult, object?> getDefaultValue)
{
_defaultValueFactory = getDefaultValue ?? throw new ArgumentNullException(nameof(getDefaultValue));
}
Expand All @@ -155,7 +160,7 @@ public void SetDefaultValueFactory(Func<ArgumentResult, object> getDefaultValue)

public void AddSuggestions(IReadOnlyCollection<string> suggestions)
{
if (suggestions == null)
if (suggestions is null)
{
throw new ArgumentNullException(nameof(suggestions));
}
Expand All @@ -165,7 +170,7 @@ public void AddSuggestions(IReadOnlyCollection<string> suggestions)

public void AddSuggestionSource(ISuggestionSource suggest)
{
if (suggest == null)
if (suggest is null)
{
throw new ArgumentNullException(nameof(suggest));
}
Expand All @@ -175,7 +180,7 @@ public void AddSuggestionSource(ISuggestionSource suggest)

public void AddSuggestionSource(Suggest suggest)
{
if (suggest == null)
if (suggest is null)
{
throw new ArgumentNullException(nameof(suggest));
}
Expand All @@ -185,15 +190,15 @@ public void AddSuggestionSource(Suggest suggest)

internal void AddAllowedValues(IEnumerable<string> values)
{
if (AllowedValues == null)
if (AllowedValues is null)
{
AllowedValues = new HashSet<string>();
}

AllowedValues.UnionWith(values);
}

public override IEnumerable<string> GetSuggestions(string textToMatch = null)
public override IEnumerable<string?> GetSuggestions(string? textToMatch = null)
{
var fixedSuggestions = _suggestions;

Expand Down
15 changes: 10 additions & 5 deletions src/System.CommandLine/ArgumentArity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ public ArgumentArity(int minimumNumberOfValues, int maximumNumberOfValues)

public int MaximumNumberOfValues { get; set; }

internal static FailedArgumentConversionArityResult Validate(
SymbolResult symbolResult,
internal static FailedArgumentConversionArityResult? Validate(
SymbolResult? symbolResult,
IArgument argument,
int minimumNumberOfValues,
int maximumNumberOfValues)
{
var argumentResult = symbolResult switch
{
CommandResult commandResult => commandResult.Root.FindResultFor(argument),
CommandResult commandResult => commandResult.Root?.FindResultFor(argument),
OptionResult optionResult => optionResult.Children.ResultFor(argument),
_ => symbolResult
};
Expand All @@ -46,7 +46,7 @@ internal static FailedArgumentConversionArityResult Validate(

if (tokenCount < minimumNumberOfValues)
{
if (symbolResult.UseDefaultValueFor(argument))
if (symbolResult!.UseDefaultValueFor(argument))
{
return null;
}
Expand All @@ -60,7 +60,7 @@ internal static FailedArgumentConversionArityResult Validate(
{
return new TooManyArgumentsConversionResult(
argument,
symbolResult.ValidationMessages.ExpectsOneArgument(symbolResult));
symbolResult!.ValidationMessages.ExpectsOneArgument(symbolResult));
}

return null;
Expand Down Expand Up @@ -98,6 +98,11 @@ internal static IArgumentArity Default(Type type, Argument argument, ISymbol par
return ZeroOrOne;
}

if (type == typeof(void))
{
return Zero;
}

return ExactlyOne;
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/System.CommandLine/Argument{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public Argument() : base(null)

public Argument(
string name,
string description = null) : base(name)
string? description = null) : base(name)
{
ArgumentType = typeof(T);
Description = description;
Expand All @@ -23,9 +23,9 @@ public Argument(
public Argument(
string name,
Func<T> getDefaultValue,
string description = null) : this(name)
string? description = null) : this(name)
{
if (getDefaultValue == null)
if (getDefaultValue is null)
{
throw new ArgumentNullException(nameof(getDefaultValue));
}
Expand All @@ -37,7 +37,7 @@ public Argument(

public Argument(Func<T> getDefaultValue) : this()
{
if (getDefaultValue == null)
if (getDefaultValue is null)
{
throw new ArgumentNullException(nameof(getDefaultValue));
}
Expand All @@ -46,16 +46,16 @@ public Argument(Func<T> getDefaultValue) : this()
}

public Argument(
string name,
ParseArgument<T> parse,
string? name,
ParseArgument<T> parse,
bool isDefault = false) : this()
{
if (!string.IsNullOrWhiteSpace(name))
{
Name = name;
Name = name!;
}

if (parse == null)
if (parse is null)
{
throw new ArgumentNullException(nameof(parse));
}
Expand All @@ -65,7 +65,7 @@ public Argument(
SetDefaultValueFactory(argumentResult => parse(argumentResult));
}

ConvertArguments = (ArgumentResult argumentResult, out object value) =>
ConvertArguments = (ArgumentResult argumentResult, out object? value) =>
{
var result = parse(argumentResult);

Expand All @@ -76,7 +76,7 @@ public Argument(
}
else
{
value = default(T);
value = default(T)!;
return false;
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/System.CommandLine/Binding/ArgumentConversionResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ private protected ArgumentConversionResult(IArgument argument)

public IArgument Argument { get; }

internal string ErrorMessage { get; set; }
internal string? ErrorMessage { get; set; }

internal static FailedArgumentConversionResult Failure(IArgument argument, string error) => new FailedArgumentConversionResult(argument, error);

public static SuccessfulArgumentConversionResult Success(IArgument argument, object value) => new SuccessfulArgumentConversionResult(argument, value);
public static SuccessfulArgumentConversionResult Success(IArgument argument, object? value) => new SuccessfulArgumentConversionResult(argument, value);

internal static NoArgumentConversionResult None(IArgument argument) => new NoArgumentConversionResult(argument);
}
Expand Down
Loading

0 comments on commit 750fdd1

Please sign in to comment.