//----------------------------------------------------------------------- // // Copyright (c) 2018 Sirenix IVS // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //----------------------------------------------------------------------- namespace VRC.Udon.Serialization.OdinSerializer.Utilities { using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Globalization; /// /// MemberInfo method extensions. /// public static class MemberInfoExtensions { /// /// Returns true if the attribute whose type is specified by the generic argument is defined on this member /// public static bool IsDefined(this ICustomAttributeProvider member, bool inherit) where T : Attribute { try { return member.IsDefined(typeof(T), inherit); } catch { return false; } } /// /// Returns true if the attribute whose type is specified by the generic argument is defined on this member /// public static bool IsDefined(this ICustomAttributeProvider member) where T : Attribute { return IsDefined(member, false); } /// /// Returns the first found custom attribute of type T on this member /// Returns null if none was found /// public static T GetAttribute(this ICustomAttributeProvider member, bool inherit) where T : Attribute { var all = GetAttributes(member, inherit).ToArray(); return (all == null || all.Length == 0) ? null : all[0]; } /// /// Returns the first found non-inherited custom attribute of type T on this member /// Returns null if none was found /// public static T GetAttribute(this ICustomAttributeProvider member) where T : Attribute { return GetAttribute(member, false); } /// /// Gets all attributes of the specified generic type. /// /// The member. public static IEnumerable GetAttributes(this ICustomAttributeProvider member) where T : Attribute { return GetAttributes(member, false); } /// /// Gets all attributes of the specified generic type. /// /// The member. /// If true, specifies to also search the ancestors of element for custom attributes. public static IEnumerable GetAttributes(this ICustomAttributeProvider member, bool inherit) where T : Attribute { try { return member.GetCustomAttributes(typeof(T), inherit).Cast(); } catch { return new T[0]; } } /// /// Gets all attribute instances defined on a MemeberInfo. /// /// The member. public static Attribute[] GetAttributes(this ICustomAttributeProvider member) { try { return member.GetAttributes().ToArray(); } catch { return new Attribute[0]; } } /// /// Gets all attribute instances on a MemberInfo. /// /// The member. /// If true, specifies to also search the ancestors of element for custom attributes. public static Attribute[] GetAttributes(this ICustomAttributeProvider member, bool inherit) { try { return member.GetAttributes(inherit).ToArray(); } catch { return new Attribute[0]; } } /// /// If this member is a method, returns the full method name (name + params) otherwise the member name paskal splitted /// public static string GetNiceName(this MemberInfo member) { var method = member as MethodBase; string result; if (method != null) { result = method.GetFullName(); } else { result = member.Name; } return result.ToTitleCase(); } /// /// Determines whether a FieldInfo, PropertyInfo or MethodInfo is static. /// /// The member. /// /// true if the specified member is static; otherwise, false. /// /// public static bool IsStatic(this MemberInfo member) { var field = member as FieldInfo; if (field != null) { return field.IsStatic; } var property = member as PropertyInfo; if (property != null) { return property.CanRead ? property.GetGetMethod(true).IsStatic : property.GetSetMethod(true).IsStatic; } var method = member as MethodBase; if (method != null) { return method.IsStatic; } var @event = member as EventInfo; if (@event != null) { return @event.GetRaiseMethod(true).IsStatic; } var type = member as Type; if (type != null) { return type.IsSealed && type.IsAbstract; } string message = string.Format( CultureInfo.InvariantCulture, "Unable to determine IsStatic for member {0}.{1}" + "MemberType was {2} but only fields, properties and methods are supported.", member.DeclaringType.FullName, member.Name, member.GetType().FullName); throw new NotSupportedException(message); } /// /// Determines whether the specified member is an alias. /// /// The member to check. /// /// true if the specified member is an alias; otherwise, false. /// public static bool IsAlias(this MemberInfo memberInfo) { return memberInfo is MemberAliasFieldInfo || memberInfo is MemberAliasPropertyInfo || memberInfo is MemberAliasMethodInfo; } /// /// Returns the original, backing member of an alias member if the member is an alias. /// /// The member to check. /// /// if set to true an exception will be thrown if the member is not aliased. /// /// The member was not aliased; this only occurs if throwOnNotAliased is true. public static MemberInfo DeAlias(this MemberInfo memberInfo, bool throwOnNotAliased = false) { MemberAliasFieldInfo aliasFieldInfo = memberInfo as MemberAliasFieldInfo; if (aliasFieldInfo != null) { return aliasFieldInfo.AliasedField; } MemberAliasPropertyInfo aliasPropertyInfo = memberInfo as MemberAliasPropertyInfo; if (aliasPropertyInfo != null) { return aliasPropertyInfo.AliasedProperty; } MemberAliasMethodInfo aliasMethodInfo = memberInfo as MemberAliasMethodInfo; if (aliasMethodInfo != null) { return aliasMethodInfo.AliasedMethod; } if (throwOnNotAliased) { throw new ArgumentException("The member " + memberInfo.GetNiceName() + " was not aliased."); } return memberInfo; } } }