bool __ArraySupportsBizarreInterface(DmdType arrayType, DmdType @interface) { if (arrayType.__GetInternalCorElementType() != DDN.ElementType.SZArray) { return(false); } if (!__IsImplicitInterfaceOfSZArray(@interface)) { return(false); } return(__CanCastParam(arrayType.GetElementType(), @interface.GetGenericArguments()[0])); }
/// <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); }
/// <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); }
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(); }
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.MetadataNamespace 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(); }
__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); } }
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); } }