Skip to content

Commit 750fdd1

Browse files
authored
C# 8 Nullable reference types (#856)
1 parent 65f9a03 commit 750fdd1

File tree

86 files changed

+568
-451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+568
-451
lines changed

src/System.CommandLine.Tests/ArgumentTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ public void When_there_is_no_default_value_then_GetDefaultValue_throws()
5656
.Be("Argument \"the-arg\" does not have a default value");
5757
}
5858

59+
[Fact]
60+
public void When_argument_type_is_set_to_null_then_it_throws()
61+
{
62+
var argument = new Argument();
63+
64+
argument.Invoking(a => a.ArgumentType = null)
65+
.Should()
66+
.Throw<ArgumentNullException>();
67+
}
68+
69+
[Fact]
70+
public void By_default_the_argument_type_is_void()
71+
{
72+
var argument = new Argument();
73+
74+
argument.ArgumentType
75+
.Should()
76+
.Be(typeof(void));
77+
}
78+
5979
public class CustomParsing
6080
{
6181
[Fact]

src/System.CommandLine/Argument.cs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,34 @@ namespace System.CommandLine
1111
{
1212
public class Argument : Symbol, IArgument
1313
{
14-
private Func<ArgumentResult, object> _defaultValueFactory;
14+
private Func<ArgumentResult, object?>? _defaultValueFactory;
1515
private readonly List<string> _suggestions = new List<string>();
1616
private readonly List<ISuggestionSource> _suggestionSources = new List<ISuggestionSource>();
17-
private IArgumentArity _arity;
18-
private TryConvertArgument _convertArguments;
17+
private IArgumentArity? _arity;
18+
private TryConvertArgument? _convertArguments;
19+
private Type _argumentType = typeof(void);
1920

2021
public Argument()
2122
{
2223
}
2324

24-
public Argument(string name)
25+
public Argument(string? name)
2526
{
2627
if (!string.IsNullOrWhiteSpace(name))
2728
{
28-
Name = name;
29+
Name = name!;
2930
}
3031
}
3132

32-
internal HashSet<string> AllowedValues { get; private set; }
33+
internal HashSet<string>? AllowedValues { get; private set; }
3334

3435
public IArgumentArity Arity
3536
{
3637
get
3738
{
38-
if (_arity == null)
39+
if (_arity is null)
3940
{
40-
if (ArgumentType != null)
41+
if (ArgumentType != typeof(void))
4142
{
4243
return ArgumentArity.Default(ArgumentType, this, Parents.FirstOrDefault());
4344
}
@@ -52,19 +53,19 @@ public IArgumentArity Arity
5253
set => _arity = value;
5354
}
5455

55-
internal TryConvertArgument ConvertArguments
56+
internal TryConvertArgument? ConvertArguments
5657
{
5758
get
5859
{
5960
if (_convertArguments == null &&
60-
ArgumentType != null)
61+
ArgumentType != typeof(void))
6162
{
6263
if (ArgumentType.CanBeBoundFromScalarValue())
6364
{
6465
if (Arity.MaximumNumberOfValues == 1 &&
6566
ArgumentType == typeof(bool))
6667
{
67-
_convertArguments = (ArgumentResult symbol, out object value) =>
68+
_convertArguments = (ArgumentResult symbol, out object? value) =>
6869
{
6970
value = ArgumentConverter.ConvertObject(
7071
this,
@@ -108,18 +109,22 @@ bool DefaultConvert(SymbolResult symbol, out object value)
108109
set => _convertArguments = value;
109110
}
110111

111-
public Type ArgumentType { get; set; }
112+
public Type ArgumentType
113+
{
114+
get => _argumentType;
115+
set => _argumentType = value ?? throw new ArgumentNullException(nameof(value));
116+
}
112117

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

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

117-
public object GetDefaultValue()
122+
public object? GetDefaultValue()
118123
{
119124
return GetDefaultValue(new ArgumentResult(this, null));
120125
}
121126

122-
internal object GetDefaultValue(ArgumentResult argumentResult)
127+
internal object? GetDefaultValue(ArgumentResult argumentResult)
123128
{
124129
if (_defaultValueFactory is null)
125130
{
@@ -134,17 +139,17 @@ public void SetDefaultValue(object value)
134139
SetDefaultValueFactory(() => value);
135140
}
136141

137-
public void SetDefaultValueFactory(Func<object> getDefaultValue)
142+
public void SetDefaultValueFactory(Func<object?> getDefaultValue)
138143
{
139-
if (getDefaultValue == null)
144+
if (getDefaultValue is null)
140145
{
141146
throw new ArgumentNullException(nameof(getDefaultValue));
142147
}
143148

144149
SetDefaultValueFactory(_ => getDefaultValue());
145150
}
146151

147-
public void SetDefaultValueFactory(Func<ArgumentResult, object> getDefaultValue)
152+
public void SetDefaultValueFactory(Func<ArgumentResult, object?> getDefaultValue)
148153
{
149154
_defaultValueFactory = getDefaultValue ?? throw new ArgumentNullException(nameof(getDefaultValue));
150155
}
@@ -155,7 +160,7 @@ public void SetDefaultValueFactory(Func<ArgumentResult, object> getDefaultValue)
155160

156161
public void AddSuggestions(IReadOnlyCollection<string> suggestions)
157162
{
158-
if (suggestions == null)
163+
if (suggestions is null)
159164
{
160165
throw new ArgumentNullException(nameof(suggestions));
161166
}
@@ -165,7 +170,7 @@ public void AddSuggestions(IReadOnlyCollection<string> suggestions)
165170

166171
public void AddSuggestionSource(ISuggestionSource suggest)
167172
{
168-
if (suggest == null)
173+
if (suggest is null)
169174
{
170175
throw new ArgumentNullException(nameof(suggest));
171176
}
@@ -175,7 +180,7 @@ public void AddSuggestionSource(ISuggestionSource suggest)
175180

176181
public void AddSuggestionSource(Suggest suggest)
177182
{
178-
if (suggest == null)
183+
if (suggest is null)
179184
{
180185
throw new ArgumentNullException(nameof(suggest));
181186
}
@@ -185,15 +190,15 @@ public void AddSuggestionSource(Suggest suggest)
185190

186191
internal void AddAllowedValues(IEnumerable<string> values)
187192
{
188-
if (AllowedValues == null)
193+
if (AllowedValues is null)
189194
{
190195
AllowedValues = new HashSet<string>();
191196
}
192197

193198
AllowedValues.UnionWith(values);
194199
}
195200

196-
public override IEnumerable<string> GetSuggestions(string textToMatch = null)
201+
public override IEnumerable<string?> GetSuggestions(string? textToMatch = null)
197202
{
198203
var fixedSuggestions = _suggestions;
199204

src/System.CommandLine/ArgumentArity.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ public ArgumentArity(int minimumNumberOfValues, int maximumNumberOfValues)
2929

3030
public int MaximumNumberOfValues { get; set; }
3131

32-
internal static FailedArgumentConversionArityResult Validate(
33-
SymbolResult symbolResult,
32+
internal static FailedArgumentConversionArityResult? Validate(
33+
SymbolResult? symbolResult,
3434
IArgument argument,
3535
int minimumNumberOfValues,
3636
int maximumNumberOfValues)
3737
{
3838
var argumentResult = symbolResult switch
3939
{
40-
CommandResult commandResult => commandResult.Root.FindResultFor(argument),
40+
CommandResult commandResult => commandResult.Root?.FindResultFor(argument),
4141
OptionResult optionResult => optionResult.Children.ResultFor(argument),
4242
_ => symbolResult
4343
};
@@ -46,7 +46,7 @@ internal static FailedArgumentConversionArityResult Validate(
4646

4747
if (tokenCount < minimumNumberOfValues)
4848
{
49-
if (symbolResult.UseDefaultValueFor(argument))
49+
if (symbolResult!.UseDefaultValueFor(argument))
5050
{
5151
return null;
5252
}
@@ -60,7 +60,7 @@ internal static FailedArgumentConversionArityResult Validate(
6060
{
6161
return new TooManyArgumentsConversionResult(
6262
argument,
63-
symbolResult.ValidationMessages.ExpectsOneArgument(symbolResult));
63+
symbolResult!.ValidationMessages.ExpectsOneArgument(symbolResult));
6464
}
6565

6666
return null;
@@ -98,6 +98,11 @@ internal static IArgumentArity Default(Type type, Argument argument, ISymbol par
9898
return ZeroOrOne;
9999
}
100100

101+
if (type == typeof(void))
102+
{
103+
return Zero;
104+
}
105+
101106
return ExactlyOne;
102107
}
103108
}

src/System.CommandLine/Argument{T}.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public Argument() : base(null)
1414

1515
public Argument(
1616
string name,
17-
string description = null) : base(name)
17+
string? description = null) : base(name)
1818
{
1919
ArgumentType = typeof(T);
2020
Description = description;
@@ -23,9 +23,9 @@ public Argument(
2323
public Argument(
2424
string name,
2525
Func<T> getDefaultValue,
26-
string description = null) : this(name)
26+
string? description = null) : this(name)
2727
{
28-
if (getDefaultValue == null)
28+
if (getDefaultValue is null)
2929
{
3030
throw new ArgumentNullException(nameof(getDefaultValue));
3131
}
@@ -37,7 +37,7 @@ public Argument(
3737

3838
public Argument(Func<T> getDefaultValue) : this()
3939
{
40-
if (getDefaultValue == null)
40+
if (getDefaultValue is null)
4141
{
4242
throw new ArgumentNullException(nameof(getDefaultValue));
4343
}
@@ -46,16 +46,16 @@ public Argument(Func<T> getDefaultValue) : this()
4646
}
4747

4848
public Argument(
49-
string name,
50-
ParseArgument<T> parse,
49+
string? name,
50+
ParseArgument<T> parse,
5151
bool isDefault = false) : this()
5252
{
5353
if (!string.IsNullOrWhiteSpace(name))
5454
{
55-
Name = name;
55+
Name = name!;
5656
}
5757

58-
if (parse == null)
58+
if (parse is null)
5959
{
6060
throw new ArgumentNullException(nameof(parse));
6161
}
@@ -65,7 +65,7 @@ public Argument(
6565
SetDefaultValueFactory(argumentResult => parse(argumentResult));
6666
}
6767

68-
ConvertArguments = (ArgumentResult argumentResult, out object value) =>
68+
ConvertArguments = (ArgumentResult argumentResult, out object? value) =>
6969
{
7070
var result = parse(argumentResult);
7171

@@ -76,7 +76,7 @@ public Argument(
7676
}
7777
else
7878
{
79-
value = default(T);
79+
value = default(T)!;
8080
return false;
8181
}
8282
};

src/System.CommandLine/Binding/ArgumentConversionResult.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ private protected ArgumentConversionResult(IArgument argument)
1212

1313
public IArgument Argument { get; }
1414

15-
internal string ErrorMessage { get; set; }
15+
internal string? ErrorMessage { get; set; }
1616

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

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

2121
internal static NoArgumentConversionResult None(IArgument argument) => new NoArgumentConversionResult(argument);
2222
}

0 commit comments

Comments
 (0)