1
Fork 0
mirror of https://github.com/Steffo99/better-tee.git synced 2024-11-23 07:44:19 +00:00
better-tee/Assets/Packages/Mirror/Editor/Weaver/Extensions.cs
2019-09-17 17:43:32 +02:00

151 lines
4.9 KiB
C#

using System;
using Mono.CecilX;
namespace Mirror.Weaver
{
public static class Extensions
{
public static bool IsDerivedFrom(this TypeDefinition td, TypeReference baseClass)
{
if (!td.IsClass)
return false;
// are ANY parent classes of baseClass?
TypeReference parent = td.BaseType;
while (parent != null)
{
string parentName = parent.FullName;
// strip generic parameters
int index = parentName.IndexOf('<');
if (index != -1)
{
parentName = parentName.Substring(0, index);
}
if (parentName == baseClass.FullName)
{
return true;
}
try
{
parent = parent.Resolve().BaseType;
}
catch (AssemblyResolutionException)
{
// this can happen for plugins.
//Console.WriteLine("AssemblyResolutionException: "+ ex.ToString());
break;
}
}
return false;
}
public static TypeReference GetEnumUnderlyingType(this TypeDefinition td)
{
foreach (FieldDefinition field in td.Fields)
{
if (!field.IsStatic)
return field.FieldType;
}
throw new ArgumentException($"Invalid enum {td.FullName}");
}
public static bool ImplementsInterface(this TypeDefinition td, TypeReference baseInterface)
{
TypeDefinition typedef = td;
while (typedef != null)
{
foreach (InterfaceImplementation iface in typedef.Interfaces)
{
if (iface.InterfaceType.FullName == baseInterface.FullName)
return true;
}
try
{
TypeReference parent = typedef.BaseType;
typedef = parent?.Resolve();
}
catch (AssemblyResolutionException)
{
// this can happen for pluins.
//Console.WriteLine("AssemblyResolutionException: "+ ex.ToString());
break;
}
}
return false;
}
public static bool IsArrayType(this TypeReference tr)
{
if ((tr.IsArray && ((ArrayType)tr).ElementType.IsArray) || // jagged array
(tr.IsArray && ((ArrayType)tr).Rank > 1)) // multidimensional array
return false;
return true;
}
public static bool CanBeResolved(this TypeReference parent)
{
while (parent != null)
{
if (parent.Scope.Name == "Windows")
{
return false;
}
if (parent.Scope.Name == "mscorlib")
{
TypeDefinition resolved = parent.Resolve();
return resolved != null;
}
try
{
parent = parent.Resolve().BaseType;
}
catch
{
return false;
}
}
return true;
}
// Given a method of a generic class such as ArraySegment<T>.get_Count,
// and a generic instance such as ArraySegment<int>
// Creates a reference to the specialized method ArraySegment<int>.get_Count;
// Note that calling ArraySegment<T>.get_Count directly gives an invalid IL error
public static MethodReference MakeHostInstanceGeneric(this MethodReference self, GenericInstanceType instanceType)
{
MethodReference reference = new MethodReference(self.Name, self.ReturnType, instanceType)
{
CallingConvention = self.CallingConvention,
HasThis = self.HasThis,
ExplicitThis = self.ExplicitThis
};
foreach (ParameterDefinition parameter in self.Parameters)
reference.Parameters.Add(new ParameterDefinition(parameter.ParameterType));
foreach (GenericParameter generic_parameter in self.GenericParameters)
reference.GenericParameters.Add(new GenericParameter(generic_parameter.Name, reference));
return Weaver.CurrentAssembly.MainModule.ImportReference(reference);
}
public static CustomAttribute GetCustomAttribute(this MethodDefinition method, string attributeName)
{
foreach (CustomAttribute ca in method.CustomAttributes)
{
if (ca.AttributeType.FullName == attributeName)
return ca;
}
return null;
}
}
}