Skip to content

Commit 68c8460

Browse files
committed
😤 Correct fix for immutable handling
1 parent a5fad0d commit 68c8460

4 files changed

Lines changed: 34 additions & 1 deletion

File tree

src/CommandLine.Tests/Unit/ParserTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,5 +200,21 @@ public void Explicit_help_request_with_immutable_instance_generates_help_request
200200
result.Errors.Should().ContainSingle(e => e.Equals(expectedError));
201201
// Teardown
202202
}
203+
204+
[Fact]
205+
public void Explicit_help_request_with_immutable_instance_generates_help_screen()
206+
{
207+
// Fixture setup
208+
var help = new StringWriter();
209+
var sut = new Parser(config => config.HelpWriter = help);
210+
211+
// Exercize system
212+
sut.ParseArguments<FakeImmutableOptions>(new[] { "--help" });
213+
var result = help.ToString();
214+
215+
// Verify outcome
216+
result.Length.Should().BeGreaterThan(0);
217+
// Teardown
218+
}
203219
}
204220
}

src/CommandLine/Core/InstanceBuilder.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,17 @@ public static ParserResult<T> Build<T>(
5050
.ThrowingValidate(SpecificationGuards.Lookup)
5151
.OfType<OptionSpecification>();
5252

53+
Func<T> makeDefault = () =>
54+
typeof(T).IsMutable()
55+
? factory.Return(f => f(), Activator.CreateInstance<T>())
56+
: ReflectionHelper.CreateDefaultImmutableInstance<T>(
57+
(from p in specProps select p.Specification.ConversionType).ToArray());
58+
5359
if (arguments.Any() && nameComparer.Equals("--help", arguments.First()))
5460
{
5561
return ParserResult.Create(
5662
ParserResultType.Options,
57-
factory.Return(f => f(), default(T)),
63+
makeDefault(),
5864
new[] { new HelpRequestedError() });
5965
}
6066

src/CommandLine/Infrastructure/ReflectionHelper.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Linq;
55
using System.Reflection;
6+
using CommandLine.Core;
67

78
namespace CommandLine.Infrastructure
89
{
@@ -36,5 +37,14 @@ public static bool IsFSharpOptionType(Type type)
3637
return type.FullName.StartsWith(
3738
"Microsoft.FSharp.Core.FSharpOption`1", StringComparison.Ordinal);
3839
}
40+
41+
public static T CreateDefaultImmutableInstance<T>(Type[] constructorTypes)
42+
{
43+
var t = typeof(T);
44+
var ctor = t.GetConstructor(constructorTypes);
45+
var values = (from prms in ctor.GetParameters()
46+
select prms.ParameterType.CreateDefaultForImmutable()).ToArray();
47+
return (T)ctor.Invoke(values);
48+
}
3949
}
4050
}

src/CommandLine/ParserResult.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ public static ParserResult<T> Create<T>(ParserResultType tag, T instance, IEnume
105105

106106
public static ParserResult<T> Create<T>(ParserResultType tag, T instance, IEnumerable<Error> errors, Maybe<IEnumerable<Type>> verbTypes)
107107
{
108+
if (Equals(instance, default(T))) throw new ArgumentNullException("instance");
108109
if (errors == null) throw new ArgumentNullException("errors");
109110
if (verbTypes == null) throw new ArgumentNullException("verbTypes");
110111

0 commit comments

Comments
 (0)