public static List <CacheMember> GetCacheMembers(object inspectorTarget, Type _type, ReflectionInspector _inspector) { var list = new List <CacheMember>(); var cachedSigs = new HashSet <string>(); var types = ReflectionUtility.GetAllBaseTypes(_type); var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static; if (!_inspector.StaticOnly) { flags |= BindingFlags.Instance; } var infos = new List <MemberInfo>(); foreach (var declaringType in types) { var target = inspectorTarget; if (!_inspector.StaticOnly) { target = target.TryCast(declaringType); } infos.Clear(); infos.AddRange(declaringType.GetProperties(flags)); infos.AddRange(declaringType.GetFields(flags)); infos.AddRange(declaringType.GetMethods(flags)); foreach (var member in infos) { if (member.DeclaringType != declaringType) { continue; } TryCacheMember(member, list, cachedSigs, declaringType, _inspector); } } var typeList = types.ToList(); var sorted = new List <CacheMember>(); sorted.AddRange(list.Where(it => it is CacheProperty) .OrderBy(it => typeList.IndexOf(it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(list.Where(it => it is CacheField) .OrderBy(it => typeList.IndexOf(it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(list.Where(it => it is CacheMethod) .OrderBy(it => typeList.IndexOf(it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); return(sorted); }
public void CacheMembers(Type type) { var list = new List <CacheMember>(); var cachedSigs = new HashSet <string>(); var types = ReflectionUtility.GetAllBaseTypes(type); var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static; if (this is InstanceInspector) { flags |= BindingFlags.Instance; } foreach (var declaringType in types) { var target = Target; target = target.Cast(declaringType); IEnumerable <MemberInfo> infos = declaringType.GetMethods(flags); infos = infos.Concat(declaringType.GetProperties(flags)); infos = infos.Concat(declaringType.GetFields(flags)); foreach (var member in infos) { try { var sig = GetSig(member); //ExplorerCore.Log($"Trying to cache member {sig}..."); //ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name); var mi = member as MethodInfo; var pi = member as PropertyInfo; var fi = member as FieldInfo; if (IsBlacklisted(sig) || (mi != null && IsBlacklisted(mi))) { continue; } var args = mi?.GetParameters() ?? pi?.GetIndexParameters(); if (args != null) { if (!CacheMember.CanProcessArgs(args)) { continue; } sig += AppendArgsToSig(args); } if (cachedSigs.Contains(sig)) { continue; } cachedSigs.Add(sig); if (mi != null) { list.Add(new CacheMethod(mi, target, m_scrollContent)); } else if (pi != null) { list.Add(new CacheProperty(pi, target, m_scrollContent)); } else { list.Add(new CacheField(fi, target, m_scrollContent)); } list.Last().ParentInspector = this; } catch (Exception e) { ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!"); ExplorerCore.Log(e.ToString()); } } } var typeList = types.ToList(); var sorted = new List <CacheMember>(); sorted.AddRange(list.Where(it => it is CacheMethod) .OrderBy(it => typeList.IndexOf(it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(list.Where(it => it is CacheProperty) .OrderBy(it => typeList.IndexOf(it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(list.Where(it => it is CacheField) .OrderBy(it => typeList.IndexOf(it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); m_allMembers = sorted.ToArray(); }
public static List <CacheMember> GetCacheMembers(object inspectorTarget, Type type, ReflectionInspector inspector) { //var list = new List<CacheMember>(); HashSet <string> cachedSigs = new(); List <CacheMember> props = new(); List <CacheMember> fields = new(); List <CacheMember> ctors = new(); List <CacheMember> methods = new(); var types = ReflectionUtility.GetAllBaseTypes(type); var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static; if (!inspector.StaticOnly) { flags |= BindingFlags.Instance; } if (!type.IsAbstract) { // Get non-static constructors of the main type. // There's no reason to get the static cctor, it will be invoked when we inspect the class. // Also no point getting ctors on inherited types. foreach (var ctor in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { TryCacheMember(ctor, ctors, cachedSigs, type, inspector); } // structs always have a parameterless constructor if (type.IsValueType) { CacheConstructor cached = new(type); cached.SetFallbackType(type); cached.SetInspectorOwner(inspector, null); ctors.Add(cached); } } foreach (var declaringType in types) { var target = inspectorTarget; if (!inspector.StaticOnly) { target = target.TryCast(declaringType); } foreach (var prop in declaringType.GetProperties(flags)) { if (prop.DeclaringType == declaringType) { TryCacheMember(prop, props, cachedSigs, declaringType, inspector); } } foreach (var field in declaringType.GetFields(flags)) { if (field.DeclaringType == declaringType) { TryCacheMember(field, fields, cachedSigs, declaringType, inspector); } } foreach (var method in declaringType.GetMethods(flags)) { if (method.DeclaringType == declaringType) { TryCacheMember(method, methods, cachedSigs, declaringType, inspector); } } } var sorted = new List <CacheMember>(); sorted.AddRange(props.OrderBy(it => Array.IndexOf(types, it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(fields.OrderBy(it => Array.IndexOf(types, it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(ctors.OrderBy(it => Array.IndexOf(types, it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); sorted.AddRange(methods.OrderBy(it => Array.IndexOf(types, it.DeclaringType)) .ThenBy(it => it.NameForFiltering)); return(sorted); }