110 lines
4.7 KiB
C#
110 lines
4.7 KiB
C#
using MonoFN.Cecil;
|
|
using System.Linq;
|
|
|
|
namespace FishNet.CodeGenerating.Helping.Extension
|
|
{
|
|
internal static class CustomAttributeExtensions
|
|
{
|
|
private static IGenericParameterProvider GetSafeContext(CodegenSession session, IGenericParameterProvider context)
|
|
{
|
|
return (context != null && context.Module == session.Module) ? context : null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clones an attribute into the current session module.
|
|
/// </summary>
|
|
internal static CustomAttribute CloneImported(this CustomAttribute customAttr, CodegenSession session, IGenericParameterProvider context = null)
|
|
{
|
|
IGenericParameterProvider safeContext = GetSafeContext(session, context);
|
|
MethodReference ctor = (safeContext == null) ? session.ImportReference(customAttr.Constructor) : session.ImportReference(customAttr.Constructor, safeContext);
|
|
CustomAttribute result = new(ctor);
|
|
|
|
foreach (CustomAttributeArgument item in customAttr.ConstructorArguments)
|
|
result.ConstructorArguments.Add(item.CloneImported(session, safeContext));
|
|
|
|
foreach (CustomAttributeNamedArgument item in customAttr.Fields)
|
|
result.Fields.Add(item.CloneImported(session, safeContext));
|
|
|
|
foreach (CustomAttributeNamedArgument item in customAttr.Properties)
|
|
result.Properties.Add(item.CloneImported(session, safeContext));
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clones an attribute argument into the current session module.
|
|
/// </summary>
|
|
internal static CustomAttributeArgument CloneImported(this CustomAttributeArgument customAttrArg, CodegenSession session, IGenericParameterProvider context = null)
|
|
{
|
|
IGenericParameterProvider safeContext = GetSafeContext(session, context);
|
|
TypeReference typeRef = safeContext == null ? session.ImportReference(customAttrArg.Type) : session.ImportReference(customAttrArg.Type, safeContext);
|
|
object value = customAttrArg.Value;
|
|
|
|
if (value is TypeReference tr)
|
|
{
|
|
value = (safeContext == null) ? session.ImportReference(tr) : session.ImportReference(tr, safeContext);
|
|
}
|
|
else if (value is CustomAttributeArgument[] arguments)
|
|
{
|
|
CustomAttributeArgument[] clonedArguments = new CustomAttributeArgument[arguments.Length];
|
|
for (int i = 0; i < arguments.Length; i++)
|
|
clonedArguments[i] = arguments[i].CloneImported(session, safeContext);
|
|
|
|
value = clonedArguments;
|
|
}
|
|
|
|
return new(typeRef, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clones a named attribute argument into the current session module.
|
|
/// </summary>
|
|
internal static CustomAttributeNamedArgument CloneImported(this CustomAttributeNamedArgument customAttrNamedArg, CodegenSession session, IGenericParameterProvider context = null)
|
|
{
|
|
return new(customAttrNamedArg.Name, customAttrNamedArg.Argument.CloneImported(session, context));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds a field within an attribute.
|
|
/// </summary>
|
|
/// <typeparam name = "T"></typeparam>
|
|
/// <param name = "customAttr"></param>
|
|
/// <param name = "field"></param>
|
|
/// <param name = "defaultValue"></param>
|
|
/// <returns></returns>
|
|
internal static T GetField<T>(this CustomAttribute customAttr, string field, T defaultValue)
|
|
{
|
|
foreach (CustomAttributeNamedArgument customField in customAttr.Fields)
|
|
{
|
|
if (customField.Name == field)
|
|
{
|
|
return (T)customField.Argument.Value;
|
|
}
|
|
}
|
|
|
|
return defaultValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns if any of the attributes match IAtrribute.
|
|
/// </summary>
|
|
/// <typeparam name = "TAttribute"></typeparam>
|
|
/// <param name = "attributeProvider"></param>
|
|
/// <returns></returns>
|
|
internal static bool HasCustomAttribute<TAttribute>(this ICustomAttributeProvider attributeProvider)
|
|
{
|
|
return attributeProvider.CustomAttributes.Any(attr => attr.AttributeType.Is<TAttribute>());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns if ca is of type target.
|
|
/// </summary>
|
|
/// <param name = "ca"></param>
|
|
/// <param name = "targetFullName"></param>
|
|
/// <returns></returns>
|
|
internal static bool Is(this CustomAttribute ca, string targetFullName)
|
|
{
|
|
return ca.AttributeType.FullName == targetFullName;
|
|
}
|
|
}
|
|
} |