/// <summary> /// Gets the hash code of a type /// </summary> /// <param name="a">Type</param> /// <returns></returns> public int GetHashCode(DmdType a) { if ((object)a == null) { return(0); } if (!IncrementRecursionCounter()) { return(0); } int hc = CompareCustomModifiers ? GetHashCode(a.GetCustomModifiers()) : 0; switch (a.TypeSignatureKind) { case DmdTypeSignatureKind.Type: hc ^= (object)a.DeclaringType == null ? HASHCODE_MAGIC_TYPE : HASHCODE_MAGIC_NESTED_TYPE; hc ^= MemberNameGetHashCode(a.MetadataName); hc ^= MemberNameGetHashCode(a.MetadataNamespace); hc ^= GetHashCode(a.DeclaringType); // Don't include the type scope in the hash since it can be one of Module, ModuleRef, AssemblyRef // and we could only hash the common denominator which isn't much at all. break; case DmdTypeSignatureKind.Pointer: hc ^= HASHCODE_MAGIC_ET_PTR ^ GetHashCode(a.GetElementType()); break; case DmdTypeSignatureKind.ByRef: hc ^= HASHCODE_MAGIC_ET_BYREF ^ GetHashCode(a.GetElementType()); break; case DmdTypeSignatureKind.SZArray: hc ^= HASHCODE_MAGIC_ET_SZARRAY ^ GetHashCode(a.GetElementType()); break; case DmdTypeSignatureKind.TypeGenericParameter: hc ^= HASHCODE_MAGIC_ET_VAR ^ a.GenericParameterPosition; if (CompareGenericParameterDeclaringMember) { hc ^= GetHashCode(a.DeclaringType); } break; case DmdTypeSignatureKind.MethodGenericParameter: hc ^= HASHCODE_MAGIC_ET_MVAR ^ a.GenericParameterPosition; if (CompareGenericParameterDeclaringMember) { options &= ~DmdSigComparerOptions.CompareGenericParameterDeclaringMember; hc ^= GetHashCode(a.DeclaringMethod); options |= DmdSigComparerOptions.CompareGenericParameterDeclaringMember; } break; case DmdTypeSignatureKind.MDArray: hc ^= HASHCODE_MAGIC_ET_ARRAY; hc ^= a.GetArrayRank(); if (!IgnoreMultiDimensionalArrayLowerBoundsAndSizes) { hc ^= GetHashCode(a.GetArraySizes()); hc ^= GetHashCode(a.GetArrayLowerBounds()); } hc ^= GetHashCode(a.GetElementType()); break; case DmdTypeSignatureKind.GenericInstance: hc ^= HASHCODE_MAGIC_ET_GENERICINST; hc ^= GetHashCode(a.GetGenericTypeDefinition()); hc ^= GetHashCode(a.GetGenericArguments()); break; case DmdTypeSignatureKind.FunctionPointer: hc ^= HASHCODE_MAGIC_ET_FNPTR; hc ^= GetHashCode(a.GetFunctionPointerMethodSignature()); break; default: throw new InvalidOperationException(); } DecrementRecursionCounter(); return(hc); }
bool __TypeDesc_CanCastTo(DmdType toType) { if (this == toType) { return(true); } if (IsGenericParameter) { if (toType == AppDomain.System_Object) { return(true); } if (toType == AppDomain.System_ValueType) { if ((GenericParameterAttributes & DmdGenericParameterAttributes.NotNullableValueTypeConstraint) != 0) { return(true); } } foreach (var constraint in GetGenericParameterConstraints()) { if (constraint.__CanCastTo(toType)) { return(true); } } return(false); } if (!toType.__IsTypeDesc()) { if (!IsArray) { return(false); } if (__CanCastToClassOrInterface(toType)) { return(true); } if (toType.IsInterface) { if (__ArraySupportsBizarreInterface(this, toType)) { return(true); } } return(false); } var toKind = toType.__GetInternalCorElementType(); var fromKind = __GetInternalCorElementType(); if (!(toKind == fromKind || (toKind == DDN.ElementType.Array && fromKind == DDN.ElementType.SZArray))) { return(false); } switch (toKind) { case DDN.ElementType.Array: if (GetArrayRank() != toType.GetArrayRank()) { return(false); } goto case DDN.ElementType.SZArray; case DDN.ElementType.SZArray: case DDN.ElementType.ByRef: case DDN.ElementType.Ptr: return(__CanCastParam(GetElementType(), toType.GetElementType())); case DDN.ElementType.Var: case DDN.ElementType.MVar: case DDN.ElementType.FnPtr: return(false); default: return(true); } }
/// <summary> /// Checks if a custom attribute is present /// </summary> /// <param name="attributeType">Custom attribute type</param> /// <param name="inherit">true to check custom attributes in all base classes</param> /// <returns></returns> public virtual bool IsDefined(DmdType attributeType, bool inherit) => CustomAttributesHelper.IsDefined(GetCustomAttributesData(), attributeType);
static bool IsShortNameType(DmdType type) => type.IsPrimitive || type == type.AppDomain.System_Void || type == type.AppDomain.System_TypedReference;
void WriteName(DmdType type, TypeFlags flags) { if ((object)type == null) { writer.Append("???"); return; } if (!IncrementRecursionCounter()) { writer.Append("???"); return; } switch (type.TypeSignatureKind) { case DmdTypeSignatureKind.Type: WriteIdentifier(type.MetadataName); break; case DmdTypeSignatureKind.Pointer: WriteName(type.GetElementType(), flags); writer.Append('*'); break; case DmdTypeSignatureKind.ByRef: WriteName(type.GetElementType(), flags); writer.Append('&'); break; case DmdTypeSignatureKind.TypeGenericParameter: case DmdTypeSignatureKind.MethodGenericParameter: WriteIdentifier(type.MetadataName); break; case DmdTypeSignatureKind.SZArray: WriteName(type.GetElementType(), flags); writer.Append("[]"); break; case DmdTypeSignatureKind.MDArray: WriteName(type.GetElementType(), flags); writer.Append('['); var rank = type.GetArrayRank(); if (rank <= 0) { writer.Append("???"); } else if (rank == 1) { writer.Append('*'); } else { writer.Append(',', rank - 1); } writer.Append(']'); break; case DmdTypeSignatureKind.GenericInstance: WriteName(GetGenericTypeDefinition(type), flags); break; case DmdTypeSignatureKind.FunctionPointer: if ((flags & TypeFlags.FnPtrIsIntPtr) != 0) { WriteName(type.AppDomain.System_IntPtr, flags); } else { writer.Append("(fnptr)"); } break; default: throw new InvalidOperationException(); } DecrementRecursionCounter(); }
public static string FormatFullName(DmdType type) => Format(type, serializable: true);
string FormatNameCore(DmdType type) { WriteName(type, GetTypeFlags(shortTypeNames: false) | TypeFlags.FnPtrIsIntPtr); return(writer.ToString()); }
#pragma warning restore 1591 // Missing XML comment for publicly visible type or member /// <summary> /// Returns a cached type if present else the input type /// </summary> /// <param name="type">Type</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType Intern(DmdType type, MakeTypeOptions options = MakeTypeOptions.None);
/// <summary> /// Makes a SZ array type /// </summary> /// <param name="elementType">Element type</param> /// <param name="customModifiers">Custom modifiers or null</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType MakeArrayType(DmdType elementType, IList <DmdCustomModifier> customModifiers, MakeTypeOptions options = MakeTypeOptions.None);
static bool IsDelegate(DmdType td) => td.BaseType == td.AppDomain.System_MulticastDelegate;
/// <summary> /// Makes a by-ref type /// </summary> /// <param name="elementType">Element type</param> /// <param name="customModifiers">Custom modifiers or null</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType MakeByRefType(DmdType elementType, IList <DmdCustomModifier> customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
/// <summary> /// Constructor /// </summary> /// <param name="type">Type</param> /// <param name="isRequired">true if it's a required C modifier, false if it's an optional C modifier</param> public DmdCustomModifier(DmdType type, bool isRequired) { Type = type ?? throw new ArgumentNullException(nameof(type)); IsRequired = isRequired; }
/// <summary> /// Finds a custom attribute /// </summary> /// <param name="attributeType">Custom attribute type</param> /// <param name="inherit">true to check custom attributes in all base classes</param> /// <returns></returns> public sealed override DmdCustomAttributeData FindCustomAttribute(DmdType attributeType, bool inherit) => CustomAttributesHelper.Find(this, attributeType, inherit);
/// <summary> /// Checks if a custom attribute is present /// </summary> /// <param name="attributeType">Custom attribute type</param> /// <param name="inherit">true to check custom attributes in all base classes</param> /// <returns></returns> public sealed override bool IsDefined(DmdType attributeType, bool inherit) => CustomAttributesHelper.IsDefined(this, attributeType, inherit);
DmdMarshalType(VarEnum safeArraySubType, DmdType safeArrayUserDefinedSubType) { Value = UnmanagedType.SafeArray; SafeArraySubType = safeArraySubType; SafeArrayUserDefinedSubType = safeArrayUserDefinedSubType; }
/// <summary> /// Makes a multi-dimensional array type /// </summary> /// <param name="elementType">Element type</param> /// <param name="rank">Number of dimensions</param> /// <param name="sizes">Sizes</param> /// <param name="lowerBounds">Lower bounds</param> /// <param name="customModifiers">Custom modifiers or null</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType MakeArrayType(DmdType elementType, int rank, IList <int> sizes, IList <int> lowerBounds, IList <DmdCustomModifier> customModifiers, MakeTypeOptions options = MakeTypeOptions.None);
/// <summary> /// Constructor /// </summary> /// <param name="argumentType">Argument type</param> /// <param name="value">Argument value</param> public DmdCustomAttributeTypedArgument(DmdType argumentType, object?value) { VerifyValue(value); ArgumentType = argumentType ?? throw new ArgumentNullException(nameof(argumentType)); Value = value; }
/// <summary> /// Makes a generic type /// </summary> /// <param name="genericTypeDefinition">Generic type definition</param> /// <param name="typeArguments">Generic arguments</param> /// <param name="customModifiers">Custom modifiers or null</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType MakeGenericType(DmdType genericTypeDefinition, IList <DmdType> typeArguments, IList <DmdCustomModifier> customModifiers, MakeTypeOptions options = MakeTypeOptions.None);
string FormatCore(DmdType type) { Write(type); return(writer.ToString()); }
/// <summary> /// Makes a function pointer type /// </summary> /// <param name="flags">Flags</param> /// <param name="genericParameterCount">Number of generic parameters</param> /// <param name="returnType">Return type</param> /// <param name="parameterTypes">Parameter types</param> /// <param name="varArgsParameterTypes">VarArgs parameter types</param> /// <param name="customModifiers">Custom modifiers or null</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType MakeFunctionPointerType(DmdSignatureCallingConvention flags, int genericParameterCount, DmdType returnType, IList <DmdType> parameterTypes, IList <DmdType> varArgsParameterTypes, IList <DmdCustomModifier> customModifiers, MakeTypeOptions options = MakeTypeOptions.None);
void Write(DmdType type) => Write(type, GetTypeFlags(false) | TypeFlags.FnPtrIsIntPtr);
/// <summary> /// Makes a generic type parameter /// </summary> /// <param name="position">Position</param> /// <param name="declaringType">Declaring type</param> /// <returns></returns> public DmdType MakeGenericTypeParameter(int position, DmdType declaringType) => MakeGenericTypeParameter(position, declaringType, string.Empty, 0, null);
void Write(DmdType type, TypeFlags flags) { if ((object)type == null) { writer.Append("???"); return; } if (!IncrementRecursionCounter()) { writer.Append("???"); return; } switch (type.TypeSignatureKind) { case DmdTypeSignatureKind.Type: if ((flags & TypeFlags.NoDeclaringTypeNames) == 0 && type.DeclaringType is DmdType declType && !type.IsGenericParameter) { Write(declType, flags | (IsGenericTypeDefinition(type) ? TypeFlags.NoGenericDefParams : 0)); writer.Append('+'); } if (!type.IsNested && type.Namespace is string ns && ns.Length > 0) { if ((globalFlags & GlobalFlags.Serializable) != 0 || ((flags & TypeFlags.MethodGenericArgumentType) == 0 && ((flags & TypeFlags.ShortSpecialNames) == 0 || !IsShortNameType(type)))) { WriteIdentifier(ns); writer.Append('.'); } } WriteIdentifier(type.MetadataName); if ((flags & TypeFlags.NoGenericDefParams) == 0 && (globalFlags & GlobalFlags.Serializable) == 0) { WriteTypeGenericArguments(GetGenericArguments(type), flags & ~TypeFlags.NoGenericDefParams); } break; case DmdTypeSignatureKind.Pointer: Write(type.GetElementType(), flags); writer.Append('*'); break; case DmdTypeSignatureKind.ByRef: Write(type.GetElementType(), flags); writer.Append('&'); break; case DmdTypeSignatureKind.TypeGenericParameter: case DmdTypeSignatureKind.MethodGenericParameter: WriteIdentifier(type.MetadataName); break; case DmdTypeSignatureKind.SZArray: Write(type.GetElementType(), flags); writer.Append("[]"); break; case DmdTypeSignatureKind.MDArray: Write(type.GetElementType(), flags); writer.Append('['); var rank = type.GetArrayRank(); if (rank <= 0) { writer.Append("???"); } else if (rank == 1) { writer.Append('*'); } else { writer.Append(',', rank - 1); } writer.Append(']'); break; case DmdTypeSignatureKind.GenericInstance: Write(GetGenericTypeDefinition(type), flags | TypeFlags.NoGenericDefParams); if ((flags & TypeFlags.MethodGenericArgumentType) == 0) { WriteTypeGenericArguments(GetGenericArguments(type), flags); } break; case DmdTypeSignatureKind.FunctionPointer: if ((flags & TypeFlags.FnPtrIsIntPtr) != 0) { Write(type.AppDomain.System_IntPtr, flags); } else { writer.Append("(fnptr)"); } break; default: throw new InvalidOperationException(); } DecrementRecursionCounter(); }
/// <summary> /// Makes a generic type parameter /// </summary> /// <param name="position">Position</param> /// <param name="declaringType">Declaring type</param> /// <param name="name">Name</param> /// <param name="attributes">Attributes</param> /// <param name="customModifiers">Custom modifiers or null</param> /// <param name="options">Options</param> /// <returns></returns> public abstract DmdType MakeGenericTypeParameter(int position, DmdType declaringType, string name, DmdGenericParameterAttributes attributes, IList <DmdCustomModifier> customModifiers, MakeTypeOptions options = MakeTypeOptions.None);
bool TypeScopeEquals(DmdType a, DmdType b) { Debug.Assert(!(a is null) && !(b is null) && !a.HasElementType && !b.HasElementType); if (DontCompareTypeScope) { return(true); } if ((object?)a == b) { return(true); } var at = a.TypeScope; var bt = b.TypeScope; switch (at.Kind) { case DmdTypeScopeKind.Invalid: return(false); case DmdTypeScopeKind.Module: switch (bt.Kind) { case DmdTypeScopeKind.Invalid: return(false); case DmdTypeScopeKind.Module: return(at.Data == bt.Data); case DmdTypeScopeKind.ModuleRef: return(StringComparer.OrdinalIgnoreCase.Equals(((DmdModule)at.Data).ScopeName, (string)bt.Data) && Equals(((DmdModule)at.Data).Assembly.GetName(), (IDmdAssemblyName)bt.Data2)); case DmdTypeScopeKind.AssemblyRef: return(Equals(((DmdModule)at.Data).Assembly.GetName(), (IDmdAssemblyName)bt.Data)); default: throw new InvalidOperationException(); } case DmdTypeScopeKind.ModuleRef: switch (bt.Kind) { case DmdTypeScopeKind.Invalid: return(false); case DmdTypeScopeKind.Module: return(StringComparer.OrdinalIgnoreCase.Equals((string)at.Data, ((DmdModule)bt.Data).ScopeName) && Equals((IDmdAssemblyName)at.Data2, ((DmdModule)bt.Data).Assembly.GetName())); case DmdTypeScopeKind.ModuleRef: return(StringComparer.OrdinalIgnoreCase.Equals((string)at.Data, (string)bt.Data) && Equals((IDmdAssemblyName)at.Data2, (IDmdAssemblyName)bt.Data2)); case DmdTypeScopeKind.AssemblyRef: return(Equals((IDmdAssemblyName)at.Data2, (IDmdAssemblyName)bt.Data)); default: throw new InvalidOperationException(); } case DmdTypeScopeKind.AssemblyRef: switch (bt.Kind) { case DmdTypeScopeKind.Invalid: return(false); case DmdTypeScopeKind.Module: return(Equals((IDmdAssemblyName)at.Data, ((DmdModule)bt.Data).Assembly.GetName())); case DmdTypeScopeKind.ModuleRef: return(Equals((IDmdAssemblyName)at.Data, (IDmdAssemblyName)bt.Data2)); case DmdTypeScopeKind.AssemblyRef: return(Equals((IDmdAssemblyName)at.Data, (IDmdAssemblyName)bt.Data)); default: throw new InvalidOperationException(); } default: throw new InvalidOperationException(); } }
/// <summary> /// Constructor /// </summary> /// <param name="flags">Flags</param> /// <param name="tryOffset">Try offset</param> /// <param name="tryLength">Try length</param> /// <param name="handlerOffset">Handler offset</param> /// <param name="handlerLength">Handler length</param> /// <param name="filterOffset">Filter offset</param> /// <param name="catchType">Catch type</param> public DmdExceptionHandlingClause(DmdExceptionHandlingClauseOptions flags, int tryOffset, int tryLength, int handlerOffset, int handlerLength, int filterOffset, DmdType catchType) { Flags = flags; TryOffset = tryOffset; TryLength = tryLength; HandlerOffset = handlerOffset; HandlerLength = handlerLength; this.filterOffset = filterOffset; this.catchType = catchType; }
__CastResult __TypeDesc_CanCastToNoGC(DmdType toType) { Debug.Assert(this != toType); if (IsGenericParameter) { if (toType == AppDomain.System_Object) { return(__CastResult.CanCast); } if (toType == AppDomain.System_ValueType) { return(__CastResult.MaybeCast); } foreach (var constraint in GetGenericParameterConstraints()) { if (constraint.__CanCastToNoGC(toType) == __CastResult.CanCast) { return(__CastResult.CanCast); } } return(__CastResult.MaybeCast); } if (!toType.__IsTypeDesc()) { if (!IsArray) { return(__CastResult.CannotCast); } return(__CanCastToClassOrInterfaceNoGC(toType)); } var toKind = toType.__GetInternalCorElementType(); var fromKind = __GetInternalCorElementType(); if (!(toKind == fromKind || (toKind == DDN.ElementType.Array && fromKind == DDN.ElementType.SZArray))) { return(__CastResult.CannotCast); } switch (toKind) { case DDN.ElementType.Array: if (GetArrayRank() != toType.GetArrayRank()) { return(__CastResult.CannotCast); } goto case DDN.ElementType.SZArray; case DDN.ElementType.SZArray: case DDN.ElementType.ByRef: case DDN.ElementType.Ptr: return(__CanCastParamNoGC(GetElementType(), toType.GetElementType())); case DDN.ElementType.Var: case DDN.ElementType.MVar: case DDN.ElementType.FnPtr: return(__CastResult.CannotCast); default: return(__CastResult.CanCast); } }
/// <summary> /// Constructor /// </summary> /// <param name="type">Type that couldn't be resolved</param> public TypeResolveException(DmdType type) : base("Couldn't resolve type: " + type.ToString()) => Type = type;
/// <summary> /// Finds a custom attribute /// </summary> /// <param name="attributeType">Custom attribute type</param> /// <param name="inherit">true to check custom attributes in all base classes</param> /// <returns></returns> public virtual DmdCustomAttributeData FindCustomAttribute(DmdType attributeType, bool inherit) => CustomAttributesHelper.Find(GetCustomAttributesData(), attributeType);
/// <summary> /// Compares two types /// </summary> /// <param name="a">First type</param> /// <param name="b">Second type</param> /// <returns></returns> public bool Equals(DmdType a, DmdType b) { if ((object)a == b) { return(true); } if ((object)a == null || (object)b == null) { return(false); } if (!IncrementRecursionCounter()) { return(false); } bool result; var at = a.TypeSignatureKind; if (at != b.TypeSignatureKind) { result = false; } else if (CompareCustomModifiers && !Equals(a.GetCustomModifiers(), b.GetCustomModifiers())) { result = false; } else { switch (at) { case DmdTypeSignatureKind.Type: result = MemberNameEquals(a.MetadataName, b.MetadataName) && MemberNameEquals(a.MetadataNamespace, b.MetadataNamespace) && Equals(a.DeclaringType, b.DeclaringType); // Type scope only needs to be checked if it's a non-nested type if (result && !DontCompareTypeScope && (object)a.DeclaringType == null) { result = TypeScopeEquals(a, b); if (!result) { // One or both of the types could be exported types. We need to // resolve them and then compare again. var ra = a.ResolveNoThrow(); var rb = (object)ra == null ? null : b.ResolveNoThrow(); result = (object)ra != null && (object)rb != null && TypeScopeEquals(ra, rb); if (!result && CheckTypeEquivalence) { result = TIAHelper.Equivalent(ra, rb); } } } break; case DmdTypeSignatureKind.Pointer: case DmdTypeSignatureKind.ByRef: case DmdTypeSignatureKind.SZArray: result = Equals(a.GetElementType(), b.GetElementType()); break; case DmdTypeSignatureKind.TypeGenericParameter: result = a.GenericParameterPosition == b.GenericParameterPosition; if (result && CompareGenericParameterDeclaringMember) { result = Equals(a.DeclaringType, b.DeclaringType); } break; case DmdTypeSignatureKind.MethodGenericParameter: result = a.GenericParameterPosition == b.GenericParameterPosition; if (result && CompareGenericParameterDeclaringMember) { options &= ~DmdSigComparerOptions.CompareGenericParameterDeclaringMember; result = Equals(a.DeclaringMethod, b.DeclaringMethod); options |= DmdSigComparerOptions.CompareGenericParameterDeclaringMember; } break; case DmdTypeSignatureKind.MDArray: result = a.GetArrayRank() == b.GetArrayRank() && (IgnoreMultiDimensionalArrayLowerBoundsAndSizes || (Equals(a.GetArraySizes(), b.GetArraySizes()) && Equals(a.GetArrayLowerBounds(), b.GetArrayLowerBounds()))) && Equals(a.GetElementType(), b.GetElementType()); break; case DmdTypeSignatureKind.GenericInstance: result = Equals(a.GetGenericTypeDefinition(), b.GetGenericTypeDefinition()) && Equals(a.GetGenericArguments(), b.GetGenericArguments()); break; case DmdTypeSignatureKind.FunctionPointer: result = Equals(a.GetFunctionPointerMethodSignature(), b.GetFunctionPointerMethodSignature()); break; default: throw new InvalidOperationException(); } } DecrementRecursionCounter(); return(result); }