mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
9.0 KiB
224 lines
9.0 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Reflection; |
|
using System.Reflection.Metadata; |
|
using ICSharpCode.Decompiler.TypeSystem; |
|
using ICSharpCode.Decompiler.Util; |
|
|
|
namespace ICSharpCode.Decompiler |
|
{ |
|
public static partial class SRMExtensions |
|
{ |
|
public static bool HasFlag(this TypeDefinition typeDefinition, TypeAttributes attribute) => (typeDefinition.Attributes & attribute) == attribute; |
|
public static bool HasFlag(this MethodDefinition methodDefinition, MethodAttributes attribute) => (methodDefinition.Attributes & attribute) == attribute; |
|
public static bool HasFlag(this FieldDefinition fieldDefinition, FieldAttributes attribute) => (fieldDefinition.Attributes & attribute) == attribute; |
|
public static bool HasFlag(this PropertyDefinition propertyDefinition, PropertyAttributes attribute) => (propertyDefinition.Attributes & attribute) == attribute; |
|
public static bool HasFlag(this EventDefinition eventDefinition, EventAttributes attribute) => (eventDefinition.Attributes & attribute) == attribute; |
|
|
|
public static bool IsValueType(this TypeDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
return reader.GetTypeDefinition(handle).IsValueType(reader); |
|
} |
|
|
|
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader) |
|
{ |
|
if (typeDefinition.BaseType.IsNil) |
|
return false; |
|
var baseType = typeDefinition.BaseType.GetFullTypeName(reader).ToString(); |
|
if (baseType == "System.Enum") |
|
return true; |
|
var thisType = typeDefinition.GetFullTypeName(reader).ToString(); |
|
return baseType == "System.ValueType" && thisType != "System.Enum"; |
|
} |
|
|
|
public static bool IsEnum(this TypeDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
return reader.GetTypeDefinition(handle).IsEnum(reader); |
|
} |
|
|
|
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader) |
|
{ |
|
if (typeDefinition.BaseType.IsNil) |
|
return false; |
|
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum"; |
|
} |
|
|
|
public static bool IsEnum(this TypeDefinitionHandle handle, MetadataReader reader, out PrimitiveTypeCode underlyingType) |
|
{ |
|
return reader.GetTypeDefinition(handle).IsEnum(reader, out underlyingType); |
|
} |
|
|
|
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader, out PrimitiveTypeCode underlyingType) |
|
{ |
|
underlyingType = 0; |
|
if (typeDefinition.BaseType.IsNil) |
|
return false; |
|
if (typeDefinition.BaseType.GetFullTypeName(reader).ToString() != "System.Enum") |
|
return false; |
|
var field = reader.GetFieldDefinition(typeDefinition.GetFields().First()); |
|
var blob = reader.GetBlobReader(field.Signature); |
|
if (blob.ReadSignatureHeader().Kind != SignatureKind.Field) |
|
return false; |
|
underlyingType = (PrimitiveTypeCode)blob.ReadByte(); |
|
return true; |
|
} |
|
|
|
public static bool IsDelegate(this TypeDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
return reader.GetTypeDefinition(handle).IsDelegate(reader); |
|
} |
|
|
|
public static bool IsDelegate(this TypeDefinition typeDefinition, MetadataReader reader) |
|
{ |
|
var baseType = typeDefinition.BaseType; |
|
return !baseType.IsNil && baseType.GetFullTypeName(reader).ToString() == typeof(MulticastDelegate).FullName; |
|
} |
|
|
|
public static bool IsExtensionMethod(this MethodDefinition methodDefinition, MetadataReader reader) |
|
{ |
|
if (methodDefinition.HasFlag(MethodAttributes.Static)) { |
|
foreach (var attribute in methodDefinition.GetCustomAttributes()) { |
|
string typeName = reader.GetCustomAttribute(attribute).GetAttributeType(reader).GetFullTypeName(reader).ToString(); |
|
if (typeName == "System.Runtime.CompilerServices.ExtensionAttribute") |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
public static bool HasBody(this MethodDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
var methodDefinition = reader.GetMethodDefinition(handle); |
|
return (methodDefinition.Attributes & MethodAttributes.Abstract) == 0 && |
|
(methodDefinition.Attributes & MethodAttributes.PinvokeImpl) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.InternalCall) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.Native) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.Unmanaged) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.Runtime) == 0; |
|
} |
|
|
|
public static bool HasBody(this MethodDefinition methodDefinition) |
|
{ |
|
return (methodDefinition.Attributes & MethodAttributes.Abstract) == 0 && |
|
(methodDefinition.Attributes & MethodAttributes.PinvokeImpl) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.InternalCall) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.Native) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.Unmanaged) == 0 && |
|
(methodDefinition.ImplAttributes & MethodImplAttributes.Runtime) == 0; |
|
} |
|
|
|
public static MethodDefinitionHandle GetAny(this PropertyAccessors accessors) |
|
{ |
|
if (!accessors.Getter.IsNil) |
|
return accessors.Getter; |
|
return accessors.Setter; |
|
} |
|
|
|
public static MethodDefinitionHandle GetAny(this EventAccessors accessors) |
|
{ |
|
if (!accessors.Adder.IsNil) |
|
return accessors.Adder; |
|
if (!accessors.Remover.IsNil) |
|
return accessors.Remover; |
|
return accessors.Raiser; |
|
} |
|
|
|
/// <summary> |
|
/// Gets the type of the attribute. |
|
/// </summary> |
|
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader) |
|
{ |
|
switch (attribute.Constructor.Kind) { |
|
case HandleKind.MethodDefinition: |
|
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor); |
|
return md.GetDeclaringType(); |
|
case HandleKind.MemberReference: |
|
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor); |
|
return mr.Parent; |
|
default: |
|
throw new NotSupportedException(); |
|
} |
|
} |
|
|
|
public static TypeReferenceHandle GetDeclaringType(this TypeReference tr) |
|
{ |
|
switch (tr.ResolutionScope.Kind) { |
|
case HandleKind.TypeReference: |
|
return (TypeReferenceHandle)tr.ResolutionScope; |
|
default: |
|
return default(TypeReferenceHandle); |
|
} |
|
} |
|
|
|
public static FullTypeName GetFullTypeName(this EntityHandle handle, MetadataReader reader) |
|
{ |
|
if (handle.IsNil) |
|
throw new ArgumentNullException(nameof(handle)); |
|
switch (handle.Kind) { |
|
case HandleKind.TypeDefinition: |
|
return ((TypeDefinitionHandle)handle).GetFullTypeName(reader); |
|
case HandleKind.TypeReference: |
|
return ((TypeReferenceHandle)handle).GetFullTypeName(reader); |
|
case HandleKind.TypeSpecification: |
|
return ((TypeSpecificationHandle)handle).GetFullTypeName(reader); |
|
default: |
|
throw new NotSupportedException(); |
|
} |
|
} |
|
|
|
public static FullTypeName GetFullTypeName(this TypeSpecificationHandle handle, MetadataReader reader, bool omitGenericParamCount = false) |
|
{ |
|
if (handle.IsNil) |
|
throw new ArgumentNullException(nameof(handle)); |
|
var ts = reader.GetTypeSpecification(handle); |
|
return ts.DecodeSignature(new Metadata.FullTypeNameSignatureDecoder(reader), default(Unit)); |
|
} |
|
|
|
public static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader, bool omitGenericParamCount = false) |
|
{ |
|
if (handle.IsNil) |
|
throw new ArgumentNullException(nameof(handle)); |
|
var tr = reader.GetTypeReference(handle); |
|
TypeReferenceHandle declaringTypeHandle; |
|
if ((declaringTypeHandle = tr.GetDeclaringType()).IsNil) { |
|
string @namespace = tr.Namespace.IsNil ? "" : reader.GetString(tr.Namespace); |
|
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(tr.Name))); |
|
} else { |
|
return declaringTypeHandle.GetFullTypeName(reader, omitGenericParamCount).NestedType(reader.GetString(tr.Name), 0); |
|
} |
|
} |
|
|
|
public static FullTypeName GetFullTypeName(this TypeDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
if (handle.IsNil) |
|
throw new ArgumentNullException(nameof(handle)); |
|
return reader.GetTypeDefinition(handle).GetFullTypeName(reader); |
|
} |
|
|
|
public static FullTypeName GetFullTypeName(this TypeDefinition td, MetadataReader reader) |
|
{ |
|
TypeDefinitionHandle declaringTypeHandle; |
|
if ((declaringTypeHandle = td.GetDeclaringType()).IsNil) { |
|
string @namespace = td.Namespace.IsNil ? "" : reader.GetString(td.Namespace); |
|
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(td.Name))); |
|
} else { |
|
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), 0); |
|
} |
|
} |
|
|
|
public static TType DecodeSignature<TType, TGenericContext>(this EventDefinition ev, MetadataReader reader, ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext) |
|
{ |
|
switch (ev.Type.Kind) { |
|
case HandleKind.TypeDefinition: |
|
return provider.GetTypeFromDefinition(reader, (TypeDefinitionHandle)ev.Type, 0); |
|
case HandleKind.TypeReference: |
|
return provider.GetTypeFromReference(reader, (TypeReferenceHandle)ev.Type, 0); |
|
case HandleKind.TypeSpecification: |
|
return provider.GetTypeFromSpecification(reader, genericContext, (TypeSpecificationHandle)ev.Type, 0); |
|
default: |
|
throw new NotSupportedException(); |
|
} |
|
} |
|
} |
|
}
|
|
|