//-----------------------------------------------------------------------
//
// 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;
}
}
}