DatapointProvider
Provides data from fields marked with the DatapointAttribute or the
DatapointsAttribute.
using NUnit.Framework.Interfaces;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Internal.Builders
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class DatapointProvider : IParameterDataProvider
{
private readonly bool _searchInDeclaringTypes;
private static readonly ProviderCache ProviderCache = new ProviderCache();
public DatapointProvider(bool searchInDeclaringTypes)
{
_searchInDeclaringTypes = searchInDeclaringTypes;
}
public bool HasDataFor(IParameterInfo parameter)
{
IMethodInfo method = parameter.Method;
if (!method.IsDefined<TheoryAttribute>(true))
return false;
Type parameterType = parameter.ParameterType;
if (parameterType == typeof(bool) || parameterType.IsEnum)
return true;
Type type = method.TypeInfo.Type;
foreach (Tuple<MemberInfo, Type> item2 in GetMembersFromType(type)) {
MemberInfo item = item2.Item1;
if (item.IsDefined(typeof(DatapointAttribute), true) && GetTypeFromMemberInfo(item) == parameterType)
return true;
if (item.IsDefined(typeof(DatapointSourceAttribute), true) && GetElementTypeFromMemberInfo(item) == parameterType)
return true;
}
return false;
}
public IEnumerable GetDataFor(IParameterInfo parameter)
{
List<object> list = new List<object>();
Type type = parameter.ParameterType;
Type type2 = parameter.Method.TypeInfo.Type;
foreach (Tuple<MemberInfo, Type> item3 in GetMembersFromType(type2)) {
MemberInfo item = item3.Item1;
Type item2 = item3.Item2;
if (item.IsDefined(typeof(DatapointAttribute), true)) {
FieldInfo fieldInfo = item as FieldInfo;
if (GetTypeFromMemberInfo(item) == type && (object)fieldInfo != null) {
if (fieldInfo.IsStatic)
list.Add(fieldInfo.GetValue(null));
else
list.Add(fieldInfo.GetValue(ProviderCache.GetInstanceOf(item2)));
}
} else if (item.IsDefined(typeof(DatapointSourceAttribute), true) && GetElementTypeFromMemberInfo(item) == type) {
FieldInfo fieldInfo2 = item as FieldInfo;
PropertyInfo propertyInfo = item as PropertyInfo;
MethodInfo methodInfo = item as MethodInfo;
if ((object)fieldInfo2 != null) {
object obj = fieldInfo2.IsStatic ? null : ProviderCache.GetInstanceOf(item2);
foreach (object item4 in (IEnumerable)fieldInfo2.GetValue(obj)) {
list.Add(item4);
}
} else if ((object)propertyInfo != null) {
object obj = (propertyInfo.GetGetMethod(true)?.IsStatic ?? false) ? null : ProviderCache.GetInstanceOf(item2);
foreach (object item5 in (IEnumerable)propertyInfo.GetValue(obj, null)) {
list.Add(item5);
}
} else if ((object)methodInfo != null) {
object obj = methodInfo.IsStatic ? null : ProviderCache.GetInstanceOf(item2);
MethodInfo methodInfo2 = methodInfo;
object obj2 = obj;
object[] parameters = Array.Empty<Type>();
foreach (object item6 in (IEnumerable)methodInfo2.Invoke(obj2, parameters)) {
list.Add(item6);
}
}
}
}
if (list.Count == 0) {
Type underlyingType = Nullable.GetUnderlyingType(type);
if ((object)underlyingType != null)
type = underlyingType;
if (type == typeof(bool)) {
list.Add(true);
list.Add(false);
} else if (type.IsEnum) {
foreach (object value in Enum.GetValues(type)) {
list.Add(value);
}
}
if (list.Count > 0 && (object)underlyingType != null)
list.Add(null);
}
return list;
}
private IEnumerable<Tuple<MemberInfo, Type>> GetMembersFromType(Type type)
{
if (_searchInDeclaringTypes)
return GetNestedMembersFromType(type);
return GetDirectMembersOfType(type);
}
private static IEnumerable<Tuple<MemberInfo, Type>> GetNestedMembersFromType([System.Runtime.CompilerServices.Nullable(2)] Type type)
{
while ((object)type != null) {
foreach (Tuple<MemberInfo, Type> item in GetDirectMembersOfType(type)) {
yield return item;
}
type = type.DeclaringType;
}
}
private static IEnumerable<Tuple<MemberInfo, Type>> GetDirectMembersOfType(Type type)
{
MemberInfo[] members = type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
foreach (MemberInfo item in members) {
yield return new Tuple<MemberInfo, Type>(item, type);
}
}
[return: System.Runtime.CompilerServices.Nullable(2)]
private Type GetTypeFromMemberInfo(MemberInfo member)
{
FieldInfo fieldInfo = member as FieldInfo;
if ((object)fieldInfo != null)
return fieldInfo.FieldType;
PropertyInfo propertyInfo = member as PropertyInfo;
if ((object)propertyInfo != null)
return propertyInfo.PropertyType;
return (member as MethodInfo)?.ReturnType;
}
[return: System.Runtime.CompilerServices.Nullable(2)]
private Type GetElementTypeFromMemberInfo(MemberInfo member)
{
Type typeFromMemberInfo = GetTypeFromMemberInfo(member);
if ((object)typeFromMemberInfo == null)
return null;
if (typeFromMemberInfo.IsArray)
return typeFromMemberInfo.GetElementType();
if (typeFromMemberInfo.IsGenericType && typeFromMemberInfo.Name == "IEnumerable`1")
return typeFromMemberInfo.GetGenericArguments()[0];
return null;
}
}
}