Skip to content

Commit b92f20e

Browse files
Alxandrnatemcmaster
authored andcommitted
feature: add support for private base type options (#288)
Resolves #287
1 parent b5f1af3 commit b92f20e

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

src/CommandLineUtils/Internal/ReflectionHelper.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.ComponentModel.DataAnnotations;
67
using System.Linq;
78
using System.Reflection;
@@ -35,25 +36,25 @@ public static SetPropertyDelegate GetPropertySetter(PropertyInfo prop)
3536

3637
public static MethodInfo[] GetPropertyOrMethod(Type type, string name)
3738
{
38-
const BindingFlags binding = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
39-
return type.GetTypeInfo()
40-
.GetMethods(binding)
39+
var members = GetAllMembers(type.GetTypeInfo()).ToList();
40+
return members
41+
.OfType<MethodInfo>()
4142
.Where(m => m.Name == name)
42-
.Concat(type.GetTypeInfo().GetProperties(binding).Where(m => m.Name == name).Select(p => p.GetMethod))
43+
.Concat(members.OfType<PropertyInfo>().Where(m => m.Name == name).Select(p => p.GetMethod))
4344
.Where(m => m.ReturnType == typeof(string) && m.GetParameters().Length == 0)
4445
.ToArray();
4546
}
4647

4748
public static PropertyInfo[] GetProperties(Type type)
4849
{
49-
const BindingFlags binding = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
50-
return type.GetTypeInfo().GetProperties(binding);
50+
return GetAllMembers(type.GetTypeInfo())
51+
.OfType<PropertyInfo>()
52+
.ToArray();
5153
}
5254

5355
public static MemberInfo[] GetMembers(Type type)
5456
{
55-
const BindingFlags binding = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
56-
return type.GetTypeInfo().GetMembers(binding);
57+
return GetAllMembers(type.GetTypeInfo()).ToArray();
5758
}
5859

5960
public static object[] BindParameters(MethodInfo method, CommandLineApplication command, CancellationToken cancellationToken)
@@ -102,5 +103,21 @@ public static bool IsNullableType(TypeInfo typeInfo, out Type? wrappedType)
102103

103104
return result;
104105
}
106+
107+
static IEnumerable<MemberInfo> GetAllMembers(TypeInfo typeInfo)
108+
{
109+
const BindingFlags binding = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly;
110+
111+
while (typeInfo != null)
112+
{
113+
var members = typeInfo.GetMembers(binding);
114+
foreach (var member in members)
115+
{
116+
yield return member;
117+
}
118+
119+
typeInfo = typeInfo.BaseType?.GetTypeInfo();
120+
}
121+
}
105122
}
106123
}

test/CommandLineUtils.Tests/OptionAttributeTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,25 @@ public void BindsToStaticPropertiesWithSetterMethod()
259259
Assert.Equal(2, PrivateSetterProgram.StaticValue);
260260
}
261261

262+
abstract class PrivateBaseType
263+
{
264+
[Option]
265+
int Count { get; }
266+
267+
public int GetCount() => Count;
268+
}
269+
270+
class WithPrivateBaseTypeApplication : PrivateBaseType
271+
{
272+
}
273+
274+
[Fact]
275+
public void BindsToPrivateBaseTypeProperty()
276+
{
277+
var parsed = CommandLineParser.ParseArgs<WithPrivateBaseTypeApplication>("--count", "42");
278+
Assert.Equal(42, parsed.GetCount());
279+
}
280+
262281
[Theory]
263282
[InlineData("Option123", "o", "option123", "OPTION123")]
264283
[InlineData("dWORD", "d", "d-word", "D_WORD")]

0 commit comments

Comments
 (0)