< Summary

Class:GDX.Reflection
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Reflection.cs
Covered lines:120
Uncovered lines:3
Coverable lines:123
Total lines:333
Line coverage:97.5% (120 of 123)
Covered branches:0
Total branches:0
Covered methods:11
Total methods:12
Method coverage:91.6% (11 of 12)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Reflection()0%110100%
GetDefault(...)0%3.043083.33%
GetType(...)0%33092.86%
GetTypeQualifiedName(...)0%2100%
InvokeStaticMethod(...)0%4.14081.82%
InvokeMethod(...)0%440100%
SetFieldOrPropertyValue(...)0%4.74064.71%
SetFieldValue(...)0%3.053081.82%
SetPropertyValue(...)0%3.053081.82%
TryGetFieldValue[T](...)0%3.513061.54%
TryGetFieldOrPropertyValue(...)0%5.194057.89%
TryGetPropertyValue[T](...)0%3.513061.54%

File(s)

./Packages/com.dotbunny.gdx/GDX/Reflection.cs

#LineLine coverage
 1// Copyright (c) 2020-2024 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System;
 6using System.Reflection;
 7using Object = UnityEngine.Object;
 8
 9namespace GDX
 10{
 11    /// <summary>
 12    ///     A collection of reflection related helper utilities.
 13    /// </summary>
 14    /// <remarks>Torn about the existence of this utility class, yet alone the conditions dictating it.</remarks>
 15    public static class Reflection
 16    {
 17        /// <summary>
 18        ///     <see cref="BindingFlags" /> for a private field.
 19        /// </summary>
 20        public const BindingFlags PrivateFieldFlags = BindingFlags.Instance | BindingFlags.NonPublic;
 21
 22        /// <summary>
 23        ///     <see cref="BindingFlags" /> for a private static.
 24        /// </summary>
 25        public const BindingFlags PrivateStaticFlags = BindingFlags.Static | BindingFlags.NonPublic;
 26
 27        /// <summary>
 28        ///     <see cref="BindingFlags" /> for a public static.
 29        /// </summary>
 30        public const BindingFlags PublicStaticFlags = BindingFlags.Static | BindingFlags.Public;
 31
 32        /// <summary>
 33        ///     The assembly qualified name for <see cref="UnityEngine.Object" />
 34        /// </summary>
 235        public static readonly string UnityObjectName = typeof(Object).AssemblyQualifiedName;
 36
 37        /// <summary>
 38        ///     The assembly qualified name for <see cref="Serializable.SerializableTypes" />
 39        /// </summary>
 240        public static readonly string SerializedTypesName =
 41            typeof(Serializable.SerializableTypes).AssemblyQualifiedName;
 42
 43        /// <summary>
 44        ///     Returns the default value for a given type.
 45        /// </summary>
 46        /// <param name="type">A qualified type.</param>
 47        /// <returns>The default value.</returns>
 48        public static object GetDefault(this Type type)
 249        {
 250            if (type.IsClass || !type.IsValueType)
 151            {
 152                return null;
 53            }
 54
 155            return Activator.CreateInstance(type);
 256        }
 57
 58        /// <summary>
 59        ///     Returns a qualified type..
 60        /// </summary>
 61        /// <param name="type">The full name of a type.</param>
 62        /// <returns>A <see cref="System.Type" /> if found.</returns>
 63        public static Type GetType(string type)
 2964        {
 2965            Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
 2966            int loadedAssembliesCount = loadedAssemblies.Length;
 520667            for (int i = 0; i < loadedAssembliesCount; i++)
 260168            {
 260169                Type targetType = loadedAssemblies[i].GetType(type);
 260170                if (targetType != null)
 2771                {
 2772                    return targetType;
 73                }
 257474            }
 75
 276            return null;
 2977        }
 78
 79        /// <summary>
 80        ///     Returns a short form, non-versioned qualified name for the type.
 81        /// </summary>
 82        /// <param name="type">The <see cref="System.Type" /> to generate the qualified name for.</param>
 83        /// <returns>A qualified name</returns>
 84        public static string GetTypeQualifiedName(Type type)
 085        {
 086            return $"{type.FullName}, {type.Assembly.GetName().Name}";
 087        }
 88
 89        /// <summary>
 90        ///     Invokes a known static method.
 91        /// </summary>
 92        /// <param name="type">The explicit type of the static class.</param>
 93        /// <param name="method">The name of the method to invoke.</param>
 94        /// <param name="parameters">Any parameters that should be passed to the method?</param>
 95        /// <param name="flags">The <paramref name="method" />'s access flags.</param>
 96        /// <returns>An <see cref="object" /> of the return value. This can be null.</returns>
 97        public static object InvokeStaticMethod(string type, string method, object[] parameters = null,
 98            BindingFlags flags = PublicStaticFlags)
 699        {
 6100            Type targetType = GetType(type);
 6101            if (targetType != null)
 5102            {
 5103                MethodInfo targetMethod = targetType.GetMethod(method, flags);
 5104                if (targetMethod != null)
 4105                {
 4106                    return targetMethod.Invoke(null, parameters ?? Core.EmptyObjectArray);
 107                }
 1108            }
 109
 2110            return null;
 6111        }
 112
 113        /// <summary>
 114        ///     Invoke a known private method on an object.
 115        /// </summary>
 116        /// <param name="targetObject">The ambiguous object to invoke a method on.</param>
 117        /// <param name="method">The name of the method to invoke.</param>
 118        /// <param name="parameters">Any parameters that should be passed to the method?</param>
 119        /// <param name="flags">The <paramref name="method" />'s access flags.</param>
 120        /// <returns>An <see cref="object" /> of the return value. This can be null.</returns>
 121        public static object InvokeMethod(object targetObject, string method, object[] parameters = null,
 122            BindingFlags flags = PrivateFieldFlags)
 11123        {
 11124            Type targetType = targetObject.GetType();
 11125            MethodInfo targetMethod = targetType.GetMethod(method, flags);
 11126            return targetMethod != null ? targetMethod.Invoke(targetObject, parameters ?? Core.EmptyObjectArray) : null;
 11127        }
 128
 129        /// <summary>
 130        ///     Set the field or property value of a specific <paramref name="targetObject" />, which may not be
 131        ///     normally accessible.
 132        /// </summary>
 133        /// <param name="targetObject">The instanced object which will have it's field or property value set.</param>
 134        /// <param name="name">The field or property's name to set.</param>
 135        /// <param name="value">The value to set the field or property to.</param>
 136        /// <param name="fieldFlags">The field's access flags.</param>
 137        /// <param name="propertyFlags">The property's access flags.</param>
 138        /// <returns>true/false if the value was set.</returns>
 139        public static bool SetFieldOrPropertyValue(object targetObject, string name, object value,
 140            BindingFlags fieldFlags = PrivateFieldFlags, BindingFlags propertyFlags = PrivateFieldFlags)
 6141        {
 6142            if (targetObject == null)
 1143            {
 1144                return false;
 145            }
 146
 5147            Type type = targetObject.GetType();
 5148            FieldInfo f = type.GetField(name, fieldFlags);
 5149            if (f != null)
 2150            {
 2151                f.SetValue(targetObject, value);
 2152                return true;
 153            }
 154
 3155            PropertyInfo p = type.GetProperty(name, propertyFlags);
 3156            if (p != null)
 2157            {
 2158                p.SetValue(targetObject, value);
 2159                return true;
 160            }
 161
 1162            return false;
 6163        }
 164
 165        /// <summary>
 166        ///     Set the field value of a specific <paramref name="targetObject" />, which may not be normally accessible
 167        /// </summary>
 168        /// <param name="targetObject">
 169        ///     The instanced object which will have it's field value set; use a null value if this is a
 170        ///     static field.
 171        /// </param>
 172        /// <param name="type">The explicit type of the <paramref name="targetObject" />.</param>
 173        /// <param name="name">The field's name to set.</param>
 174        /// <param name="value">The value to set the field to.</param>
 175        /// <param name="flags">The field's access flags.</param>
 176        /// <returns>true/false if the value was set.</returns>
 177        public static bool SetFieldValue(object targetObject, Type type, string name, object value,
 178            BindingFlags flags = PrivateFieldFlags)
 6179        {
 6180            if (type != null)
 5181            {
 5182                FieldInfo field = type.GetField(name, flags);
 5183                if (field != null)
 4184                {
 4185                    field.SetValue(targetObject, value);
 4186                    return true;
 187                }
 1188            }
 189
 2190            return false;
 6191        }
 192
 193        /// <summary>
 194        ///     Set the property value of a specific <paramref name="targetObject" />, which may not be normally accessi
 195        /// </summary>
 196        /// <param name="targetObject">
 197        ///     The instanced object which will have it's property value set; use a null value if this is a
 198        ///     static property.
 199        /// </param>
 200        /// <param name="type">The type of the <paramref name="targetObject" />.</param>
 201        /// <param name="name">The property's name to set.</param>
 202        /// <param name="value">The value to set the property to.</param>
 203        /// <param name="flags">The property's access flags.</param>
 204        /// <returns>true/false if the value was set.</returns>
 205        public static bool SetPropertyValue(object targetObject, Type type, string name, object value,
 206            BindingFlags flags = PrivateFieldFlags)
 4207        {
 4208            if (type != null)
 3209            {
 3210                PropertyInfo property = type.GetProperty(name, flags);
 3211                if (property != null)
 2212                {
 2213                    property.SetValue(targetObject, value);
 2214                    return true;
 215                }
 1216            }
 217
 2218            return false;
 4219        }
 220
 221        /// <summary>
 222        ///     Try to access the field value of a specific <paramref name="targetObject" />, which may not be normally 
 223        /// </summary>
 224        /// <remarks></remarks>
 225        /// <param name="targetObject">
 226        ///     The instanced object which will have it's field value read; use a null value if this is a
 227        ///     static field.
 228        /// </param>
 229        /// <param name="type">The qualified type of the <paramref name="targetObject" />.</param>
 230        /// <param name="name">The field's name to read.</param>
 231        /// <param name="returnValue">The returned value from the field, the default value if the field was unable to be
 232        /// <param name="flags">The field's access flags.</param>
 233        /// <typeparam name="T">The type of data being read from the field.</typeparam>
 234        /// <returns>true/false if the process was successful.</returns>
 235        public static bool TryGetFieldValue<T>(object targetObject, Type type, string name, out T returnValue,
 236            BindingFlags flags = PrivateFieldFlags)
 7237        {
 7238            if (type == null)
 1239            {
 1240                returnValue = default;
 1241                return false;
 242            }
 243
 6244            FieldInfo fieldInfo = type.GetField(name, flags);
 6245            if (fieldInfo == null)
 1246            {
 1247                returnValue = default;
 1248                return false;
 249            }
 250
 5251            returnValue = (T)fieldInfo.GetValue(targetObject);
 5252            return true;
 7253        }
 254
 255        /// <summary>
 256        ///     Try to access the field or property value of a specific <paramref name="targetObject" />, which may not
 257        ///     be normally accessible.
 258        /// </summary>
 259        /// <remarks>Useful for when you really do not know the <see cref="System.Type" />.</remarks>
 260        /// <param name="targetObject">The instanced object which will have it's field or property value read.</param>
 261        /// <param name="name">The field or property's name to read.</param>
 262        /// <param name="returnValue">
 263        ///     The returned value from the field or property, the default value if the property was unable
 264        ///     to be read.
 265        /// </param>
 266        /// <param name="fieldFlags">The field's access flags.</param>
 267        /// <param name="propertyFlags">The property's access flags.</param>
 268        /// <returns>true/false if a value was found.</returns>
 269        public static bool TryGetFieldOrPropertyValue(object targetObject, string name, out object returnValue,
 270            BindingFlags fieldFlags = PrivateFieldFlags, BindingFlags propertyFlags = PrivateFieldFlags)
 7271        {
 7272            if (targetObject == null)
 1273            {
 1274                returnValue = null;
 1275                return false;
 276            }
 277
 6278            Type type = targetObject.GetType();
 6279            FieldInfo f = type.GetField(name, fieldFlags);
 6280            if (f != null)
 2281            {
 2282                returnValue = f.GetValue(targetObject);
 2283                return true;
 284            }
 285
 4286            PropertyInfo p = type.GetProperty(name, propertyFlags);
 4287            if (p != null)
 3288            {
 3289                returnValue = p.GetValue(targetObject);
 3290                return true;
 291            }
 292
 1293            returnValue = default;
 1294            return false;
 7295        }
 296
 297        /// <summary>
 298        ///     Try to get a property value from <paramref name="targetObject" />, which may not be normally accessible.
 299        /// </summary>
 300        /// <param name="targetObject">
 301        ///     The instanced object which will have it's property value read; use a null value if this is a
 302        ///     static property.
 303        /// </param>
 304        /// <param name="type">The explicit type of the <paramref name="targetObject" />.</param>
 305        /// <param name="name">The property's name to read.</param>
 306        /// <param name="returnValue">
 307        ///     The returned value from the property, the default value if the property was unable to be
 308        ///     read.
 309        /// </param>
 310        /// <param name="flags">The property's access flags.</param>
 311        /// <typeparam name="T">The type of data being read from the property.</typeparam>
 312        /// <returns>true/false if the process was successful.</returns>
 313        public static bool TryGetPropertyValue<T>(object targetObject, Type type, string name, out T returnValue,
 314            BindingFlags flags = PrivateFieldFlags)
 5315        {
 5316            if (type == null)
 1317            {
 1318                returnValue = default;
 1319                return false;
 320            }
 321
 4322            PropertyInfo propertyInfo = type.GetProperty(name, flags);
 4323            if (propertyInfo == null)
 1324            {
 1325                returnValue = default;
 1326                return false;
 327            }
 328
 3329            returnValue = (T)propertyInfo.GetValue(targetObject);
 3330            return true;
 5331        }
 332    }
 333}

Coverage by test methods















































































































































































































































































































































































































































































































































































































































































































Methods/Properties

Reflection()
GetDefault(System.Type)
GetType(System.String)
GetTypeQualifiedName(System.Type)
InvokeStaticMethod(System.String, System.String, System.Object[], System.Reflection.BindingFlags)
InvokeMethod(System.Object, System.String, System.Object[], System.Reflection.BindingFlags)
SetFieldOrPropertyValue(System.Object, System.String, System.Object, System.Reflection.BindingFlags, System.Reflection.BindingFlags)
SetFieldValue(System.Object, System.Type, System.String, System.Object, System.Reflection.BindingFlags)
SetPropertyValue(System.Object, System.Type, System.String, System.Object, System.Reflection.BindingFlags)
TryGetFieldValue[T](System.Object, System.Type, System.String, , System.Reflection.BindingFlags)
TryGetFieldOrPropertyValue(System.Object, System.String, System.Object&, System.Reflection.BindingFlags, System.Reflection.BindingFlags)
TryGetPropertyValue[T](System.Object, System.Type, System.String, , System.Reflection.BindingFlags)