diff --git a/src/CommandLine/CommandLine.csproj b/src/CommandLine/CommandLine.csproj
index 8f829c9f..b445db7c 100644
--- a/src/CommandLine/CommandLine.csproj
+++ b/src/CommandLine/CommandLine.csproj
@@ -169,8 +169,16 @@
-
-
+
+
+
+ ..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll
+ True
+ True
+
+
+
+
..\..\packages\FSharp.Core\lib\portable-net45+netcore45\FSharp.Core.dll
diff --git a/src/CommandLine/Core/InstanceBuilder.cs b/src/CommandLine/Core/InstanceBuilder.cs
index 0c24fddd..fd9ac4d7 100644
--- a/src/CommandLine/Core/InstanceBuilder.cs
+++ b/src/CommandLine/Core/InstanceBuilder.cs
@@ -80,22 +80,23 @@ public static ParserResult Build(
var specPropsWithValue =
optionSpecPropsResult.SucceededWith().Concat(valueSpecPropsResult.SucceededWith());
- Func buildMutable = () =>
+ var setPropertyErrors = new List();
+
+ Func buildMutable = () =>
{
var mutable = factory.MapValueOrDefault(f => f(), Activator.CreateInstance());
- mutable =
- mutable.SetProperties(specPropsWithValue, sp => sp.Value.IsJust(), sp => sp.Value.FromJustOrFail())
- .SetProperties(
- specPropsWithValue,
- sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(),
- sp => sp.Specification.DefaultValue.FromJustOrFail())
- .SetProperties(
- specPropsWithValue,
- sp =>
- sp.Value.IsNothing() && sp.Specification.TargetType == TargetType.Sequence
- && sp.Specification.DefaultValue.MatchNothing(),
- sp => sp.Property.PropertyType.GetTypeInfo().GetGenericArguments().Single().CreateEmptyArray());
- return mutable;
+ setPropertyErrors.AddRange(mutable.SetProperties(specPropsWithValue, sp => sp.Value.IsJust(), sp => sp.Value.FromJustOrFail()));
+ setPropertyErrors.AddRange(mutable.SetProperties(
+ specPropsWithValue,
+ sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(),
+ sp => sp.Specification.DefaultValue.FromJustOrFail()));
+ setPropertyErrors.AddRange(mutable.SetProperties(
+ specPropsWithValue,
+ sp =>
+ sp.Value.IsNothing() && sp.Specification.TargetType == TargetType.Sequence
+ && sp.Specification.DefaultValue.MatchNothing(),
+ sp => sp.Property.PropertyType.GetTypeInfo().GetGenericArguments().Single().CreateEmptyArray()));
+ return mutable;
};
Func buildImmutable = () =>
@@ -121,6 +122,7 @@ join sp in specPropsWithValue on prms.Name.ToLower() equals sp.Property.Name.ToL
.Concat(optionSpecPropsResult.SuccessfulMessages())
.Concat(valueSpecPropsResult.SuccessfulMessages())
.Concat(validationErrors)
+ .Concat(setPropertyErrors)
.Memorize();
var warnings = from e in allErrors where nonFatalErrors.Contains(e.Tag) select e;
diff --git a/src/CommandLine/Core/ReflectionExtensions.cs b/src/CommandLine/Core/ReflectionExtensions.cs
index 068b3034..0e8811ca 100644
--- a/src/CommandLine/Core/ReflectionExtensions.cs
+++ b/src/CommandLine/Core/ReflectionExtensions.cs
@@ -80,51 +80,30 @@ public static TargetType ToTargetType(this Type type)
: TargetType.Scalar;
}
- public static T SetProperties(
+ public static IEnumerable SetProperties(
this T instance,
IEnumerable specProps,
Func predicate,
Func selector)
{
- return specProps.Where(predicate).Aggregate(
- instance,
- (current, specProp) =>
- {
- specProp.Property.SetValue(current, selector(specProp));
- return instance;
- });
- }
-
- private static T SetValue(this PropertyInfo property, T instance, object value)
- {
- Action fail = inner => {
- throw new InvalidOperationException("Cannot set value to target instance.", inner);
- };
-
- try
- {
- property.SetValue(instance, value, null);
- }
-#if !PLATFORM_DOTNET
- catch (TargetException e)
- {
- fail(e);
- }
-#endif
- catch (TargetParameterCountException e)
- {
- fail(e);
- }
- catch (MethodAccessException e)
- {
- fail(e);
- }
- catch (TargetInvocationException e)
- {
- fail(e);
- }
-
- return instance;
+ return specProps.Where(predicate).SelectMany(specProp => specProp.Property.SetValue(instance, selector(specProp)));
+ }
+
+ private static IEnumerable SetValue(this PropertyInfo property, T instance, object value)
+ {
+ try
+ {
+ property.SetValue(instance, value, null);
+ return Enumerable.Empty();
+ }
+ catch (TargetInvocationException e)
+ {
+ return new[] { new SetValueExceptionError(e.InnerException) };
+ }
+ catch (Exception e)
+ {
+ return new[] { new SetValueExceptionError(e) };
+ }
}
public static object CreateEmptyArray(this Type type)
diff --git a/src/CommandLine/Error.cs b/src/CommandLine/Error.cs
index 475ac8e3..0cbf4938 100644
--- a/src/CommandLine/Error.cs
+++ b/src/CommandLine/Error.cs
@@ -60,7 +60,11 @@ public enum ErrorType
///
/// Value of type.
///
- VersionRequestedError
+ VersionRequestedError,
+ ///
+ /// Value of type.
+ ///
+ SetValueExceptionError
}
///
@@ -471,4 +475,26 @@ internal VersionRequestedError()
{
}
}
+
+ ///
+ /// Models as error generated when exception is thrown at Property.SetValue
+ ///
+ public sealed class SetValueExceptionError : Error
+ {
+ private readonly Exception exception;
+
+ internal SetValueExceptionError(Exception exception)
+ : base(ErrorType.SetValueExceptionError)
+ {
+ this.exception = exception;
+ }
+
+ ///
+ /// The expection thrown from Property.SetValue
+ ///
+ public Exception Exception
+ {
+ get { return exception; }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/CommandLine/Text/SentenceBuilder.cs b/src/CommandLine/Text/SentenceBuilder.cs
index 1c28e959..44ca5b8f 100644
--- a/src/CommandLine/Text/SentenceBuilder.cs
+++ b/src/CommandLine/Text/SentenceBuilder.cs
@@ -137,6 +137,8 @@ public override Func FormatError
case ErrorType.RepeatedOptionError:
return "Option '".JoinTo(((RepeatedOptionError)error).NameInfo.NameText,
"' is defined multiple times.");
+ case ErrorType.SetValueExceptionError:
+ return "Error setting option value: ".JoinTo(((SetValueExceptionError)error).Exception.Message);
}
throw new InvalidOperationException();
};