Skip to content

Commit b2c13b7

Browse files
Rolled back ValueAnnotationExtensions. NotNullWhen to ValueSource.TryGet...
1 parent 993ea1e commit b2c13b7

File tree

2 files changed

+136
-22
lines changed

2 files changed

+136
-22
lines changed

src/System.CommandLine.Subsystems/ValueAnnotationExtensions.cs

Lines changed: 133 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace System.CommandLine;
1010

1111
public static class ValueAnnotationExtensions
1212
{
13-
1413
/// <summary>
1514
/// Get the default value annotation for the <paramref name="option"/>
1615
/// </summary>
@@ -34,6 +33,31 @@ public static bool TryGetDefaultValueSource(this CliValueSymbol valueSymbol, [No
3433
public static void SetDefaultValueSource(this CliValueSymbol valueSymbol, ValueSource defaultValue)
3534
=> valueSymbol.SetAnnotation(ValueAnnotations.DefaultValue, defaultValue);
3635

36+
37+
/// <summary>
38+
/// Sets the default value annotation on the <paramref name="option"/>
39+
/// </summary>
40+
/// <typeparam name="TValue">The type of the option value</typeparam>
41+
/// <param name="option">The option</param>
42+
/// <param name="defaultValue">The default value for the option</param>
43+
/// <returns>The <paramref name="option">, to enable fluent construction of symbols with annotations.</returns>
44+
public static CliOption<TValue> WithDefaultValue<TValue>(this CliOption<TValue> option, TValue defaultValue)
45+
{
46+
option.SetDefaultValue(defaultValue);
47+
return option;
48+
}
49+
50+
/// <summary>
51+
/// Sets the default value annotation on the <paramref name="option"/>
52+
/// </summary>
53+
/// <typeparam name="TValue">The type of the option value</typeparam>
54+
/// <param name="option">The option</param>
55+
/// <param name="defaultValue">The default value for the option</param>
56+
public static void SetDefaultValue<TValue>(this CliOption<TValue> option, TValue defaultValue)
57+
{
58+
option.SetAnnotation(ValueAnnotations.DefaultValue, defaultValue);
59+
}
60+
3761
/// <summary>
3862
/// Get the default value annotation for the <paramref name="option"/>
3963
/// </summary>
@@ -45,17 +69,27 @@ public static void SetDefaultValueSource(this CliValueSymbol valueSymbol, ValueS
4569
/// which calculates the actual default value, based on the default value annotation and default value calculation,
4670
/// whether directly stored on the symbol or from the subsystem's <see cref="IAnnotationProvider"/>.
4771
/// </remarks>
48-
public static bool TryGetDefaultValueAnnotation<TValue>(this CliValueSymbol valueSymbol, out TValue? defaultValue)
49-
=> valueSymbol.TryGetAnnotation(ValueAnnotations.DefaultValue, out defaultValue);
72+
public static TValue? GetDefaultValueAnnotation<TValue>(this CliOption<TValue> option)
73+
{
74+
if (option.TryGetAnnotation(ValueAnnotations.DefaultValue, out TValue? defaultValue))
75+
{
76+
return defaultValue;
77+
}
78+
return default;
79+
}
5080

5181
/// <summary>
52-
/// Sets the default value annotation on the <paramref name="option"/>
82+
/// Sets the default value annotation on the <paramref name="argument"/>
5383
/// </summary>
54-
/// <typeparam name="TValue">The type of the option value</typeparam>
55-
/// <param name="option">The option</param>
56-
/// <param name="defaultValue">The default value for the option</param>
57-
public static void SetDefaultValue<TValue>(this CliOption<TValue> option, TValue defaultValue)
58-
=> option.SetAnnotation(ValueAnnotations.DefaultValue, defaultValue);
84+
/// <typeparam name="TValue">The type of the argument value</typeparam>
85+
/// <param name="argument">The argument</param>
86+
/// <param name="defaultValue">The default value for the argument</param>
87+
/// <returns>The <paramref name="argument">, to enable fluent construction of symbols with annotations.</returns>
88+
public static CliArgument<TValue> WithDefaultValue<TValue>(this CliArgument<TValue> argument, TValue defaultValue)
89+
{
90+
argument.SetDefaultValue(defaultValue);
91+
return argument;
92+
}
5993

6094
/// <summary>
6195
/// Sets the default value annotation on the <paramref name="argument"/>
@@ -64,22 +98,43 @@ public static void SetDefaultValue<TValue>(this CliOption<TValue> option, TValue
6498
/// <param name="argument">The argument</param>
6599
/// <param name="defaultValue">The default value for the argument</param>
66100
/// <returns>The <paramref name="argument">, to enable fluent construction of symbols with annotations.</returns>
67-
public static void SetDefaultValue<TValue>(this CliArgument<TValue> argument, TValue defaultValue)
68-
=> argument.SetAnnotation(ValueAnnotations.DefaultValue, defaultValue);
101+
public static void SetDefaultValue<TValue>(this CliArgument<TValue> argument, TValue defaultValue)
102+
{
103+
argument.SetAnnotation(ValueAnnotations.DefaultValue, defaultValue);
104+
}
69105

70106
/// <summary>
71-
/// Get the default value calculation for the <paramref name="option"/>
107+
/// Get the default value annotation for the <paramref name="argument"/>
72108
/// </summary>
73-
/// <typeparam name="TValue">The type of the option value</typeparam>
74-
/// <param name="option">The option</param>
75-
/// <returns>The option's default value calculation if any, otherwise <see langword="null"/></returns>
109+
/// <typeparam name="TValue">The type of the argument value</typeparam>
110+
/// <param name="argument">The argument</param>
111+
/// <returns>The argument's default value annotation if any, otherwise <see langword="null"/></returns>
76112
/// <remarks>
77-
/// This is intended to be called by CLI authors. Subsystems should instead call <see cref="PipelineResult.GetValue{T}(CliOption)"/>,
113+
/// This is intended to be called by CLI authors. Subsystems should instead call <see cref="PipelineResult.GetValue{T}(CliArgument)"/>,
78114
/// which calculates the actual default value, based on the default value annotation and default value calculation,
79115
/// whether directly stored on the symbol or from the subsystem's <see cref="IAnnotationProvider"/>.
80116
/// </remarks>
81-
public static bool TryGetDefaultValueCalculation<TValue>(this CliValueSymbol valueSymbol, out Func<TValue?>? calculation)
82-
=> valueSymbol.TryGetAnnotation(ValueAnnotations.DefaultValueCalculation, out calculation);
117+
public static TValue? GetDefaultValueAnnotation<TValue>(this CliArgument<TValue> argument)
118+
{
119+
if (argument.TryGetAnnotation(ValueAnnotations.DefaultValue, out TValue? defaultValue))
120+
{
121+
return (TValue?)defaultValue;
122+
}
123+
return default;
124+
}
125+
126+
/// <summary>
127+
/// Sets the default value calculation for the <paramref name="option"/>
128+
/// </summary>
129+
/// <typeparam name="TValue">The type of the option value</typeparam>
130+
/// <param name="option">The option</param>
131+
/// <param name="defaultValueCalculation">The default value calculation for the option</param>
132+
/// <returns>The <paramref name="option">, to enable fluent construction of symbols with annotations.</returns>
133+
public static CliOption<TValue> WithDefaultValueCalculation<TValue>(this CliOption<TValue> option, Func<TValue?> defaultValueCalculation)
134+
{
135+
option.SetDefaultValueCalculation(defaultValueCalculation);
136+
return option;
137+
}
83138

84139
/// <summary>
85140
/// Sets the default value calculation for the <paramref name="option"/>
@@ -88,7 +143,29 @@ public static bool TryGetDefaultValueCalculation<TValue>(this CliValueSymbol va
88143
/// <param name="option">The option</param>
89144
/// <param name="defaultValueCalculation">The default value calculation for the option</param>
90145
public static void SetDefaultValueCalculation<TValue>(this CliOption<TValue> option, Func<TValue?> defaultValueCalculation)
91-
=> option.SetAnnotation(ValueAnnotations.DefaultValueCalculation, defaultValueCalculation);
146+
{
147+
option.SetAnnotation(ValueAnnotations.DefaultValueCalculation, defaultValueCalculation);
148+
}
149+
150+
/// <summary>
151+
/// Get the default value calculation for the <paramref name="option"/>
152+
/// </summary>
153+
/// <typeparam name="TValue">The type of the option value</typeparam>
154+
/// <param name="option">The option</param>
155+
/// <returns>The option's default value calculation if any, otherwise <see langword="null"/></returns>
156+
/// <remarks>
157+
/// This is intended to be called by CLI authors. Subsystems should instead call <see cref="PipelineResult.GetValue{T}(CliOption)"/>,
158+
/// which calculates the actual default value, based on the default value annotation and default value calculation,
159+
/// whether directly stored on the symbol or from the subsystem's <see cref="IAnnotationProvider"/>.
160+
/// </remarks>
161+
public static Func<TValue?>? GetDefaultValueCalculation<TValue>(this CliOption<TValue> option)
162+
{
163+
if (option.TryGetAnnotation(ValueAnnotations.DefaultValueCalculation, out Func<TValue?>? defaultValueCalculation))
164+
{
165+
return defaultValueCalculation;
166+
}
167+
return default;
168+
}
92169

93170
/// <summary>
94171
/// Sets the default value calculation for the <paramref name="argument"/>
@@ -97,6 +174,41 @@ public static void SetDefaultValueCalculation<TValue>(this CliOption<TValue> opt
97174
/// <param name="argument">The argument</param>
98175
/// <param name="defaultValueCalculation">The default value calculation for the argument</param>
99176
/// <returns>The <paramref name="option">, to enable fluent construction of symbols with annotations.</returns>
100-
public static void SetDefaultValueCalculation<TValue>(this CliArgument<TValue> argument, Func<TValue?> defaultValueCalculation)
101-
=> argument.SetAnnotation(ValueAnnotations.DefaultValueCalculation, defaultValueCalculation);
177+
public static CliArgument<TValue> WithDefaultValueCalculation<TValue>(this CliArgument<TValue> argument, Func<TValue?> defaultValueCalculation)
178+
{
179+
argument.SetDefaultValueCalculation(defaultValueCalculation);
180+
return argument;
181+
}
182+
183+
/// <summary>
184+
/// Sets the default value calculation for the <paramref name="argument"/>
185+
/// </summary>
186+
/// <typeparam name="TValue">The type of the argument value</typeparam>
187+
/// <param name="argument">The argument</param>
188+
/// <param name="defaultValueCalculation">The default value calculation for the argument</param>
189+
/// <returns>The <paramref name="option">, to enable fluent construction of symbols with annotations.</returns>
190+
public static void SetDefaultValueCalculation<TValue>(this CliArgument<TValue> argument, Func<TValue?> defaultValueCalculation)
191+
{
192+
argument.SetAnnotation(ValueAnnotations.DefaultValueCalculation, defaultValueCalculation);
193+
}
194+
195+
/// <summary>
196+
/// Get the default value calculation for the <paramref name="argument"/>
197+
/// </summary>
198+
/// <typeparam name="TValue">The type of the argument value</typeparam>
199+
/// <param name="argument">The argument</param>
200+
/// <returns>The argument's default value calculation if any, otherwise <see langword="null"/></returns>
201+
/// <remarks>
202+
/// This is intended to be called by CLI authors. Subsystems should instead call <see cref="PipelineResult.GetValue{T}(CliArgument)"/>,
203+
/// which calculates the actual default value, based on the default value annotation and default value calculation,
204+
/// whether directly stored on the symbol or from the subsystem's <see cref="IAnnotationProvider"/>.
205+
/// </remarks>
206+
public static Func<TValue?>? GetDefaultValueCalculation<TValue>(this CliArgument<TValue> argument)
207+
{
208+
if (argument.TryGetAnnotation(ValueAnnotations.DefaultValueCalculation, out Func<TValue?>? defaultValueCalculation))
209+
{
210+
return defaultValueCalculation;
211+
}
212+
return default;
213+
}
102214
}

src/System.CommandLine.Subsystems/ValueSources/ValueSource.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using System.Diagnostics.CodeAnalysis;
5+
46
namespace System.CommandLine.ValueSources;
57

68
public abstract class ValueSource
@@ -38,7 +40,7 @@ public abstract class ValueSource<T> : ValueSource
3840
{
3941
public abstract bool TryGetTypedValue(PipelineResult pipelineResult, out T? value);
4042

41-
public override bool TryGetValue(PipelineResult pipelineResult, out object? value)
43+
public override bool TryGetValue(PipelineResult pipelineResult, [NotNullWhen(true)]out object? value)
4244
{
4345

4446
if (TryGetTypedValue(pipelineResult, out T? newValue))

0 commit comments

Comments
 (0)