Even More Modifiers  1.0.0.0
A mod for rolling various bonus stats on items
ReflectUtils.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using Loot.Api.Attributes;
6 using Loot.ILEditing;
7 
8 namespace Loot.Ext
9 {
10  internal static class ReflectUtils
11  {
12  public static IEnumerable<Type> GetILEdits()
13  => GetLootNonAbstractClasses(t => t.IsSubclassOf(typeof(ILEdit)));
14 
15  public static IEnumerable<MemberInfo> GetStaticAssetTypes()
16  => GetStaticAssetTypesTailRec(Loot.Instance.Code.GetTypes(), typeof(StaticAssetAttribute));
17 
18  public static IEnumerable<Type> GetLootNonAbstractClasses(Func<Type, bool> fun = null)
19  => Loot.Instance.Code.GetTypes().Where(t => t.IsClass && !t.IsAbstract && (fun?.Invoke(t) ?? true));
20 
21  // Tailrecursive call to iterate over all nested types
22  private static IEnumerable<MemberInfo> GetStaticAssetTypesTailRec(Type[] arr, Type attr, IEnumerable<MemberInfo> list = null, IEnumerable<Type> toCheck = null)
23  {
24  bool HasAttr(MemberInfo i) => Attribute.IsDefined(i, attr);
25 
26  IEnumerable<MemberInfo> GetPropsWithAttr(IEnumerable<Type> col)
27  {
28  //const BindingFlags flags = BindingFlags.Static;
29  return col.SelectMany(t => t.GetFields()).Where(f => f.IsStatic).Where(HasAttr).Cast<MemberInfo>()
30  .Concat(col.SelectMany(t => t.GetProperties()).Where(p => p.GetAccessors().Any(a => a.IsStatic)).Where(HasAttr));
31  }
32 
33  var types = list ?? GetPropsWithAttr(arr);
34  var nested = (toCheck ?? arr).SelectMany(t => t.GetNestedTypes()).ToArray();
35  if (nested.Length > 0)
36  {
37  types = types.Union(GetPropsWithAttr(nested));
38  types = GetStaticAssetTypesTailRec(arr, attr, types, nested);
39  }
40 
41  return types;
42  }
43  }
44 }