コード例 #1
0
ファイル: DmdType.CanCastTo.cs プロジェクト: xi4oyu/dnSpy
        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]));
        }
コード例 #2
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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        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();
        }
コード例 #6
0
ファイル: DmdType.CanCastTo.cs プロジェクト: xi4oyu/dnSpy
        __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);
            }
        }
コード例 #7
0
ファイル: DmdType.CanCastTo.cs プロジェクト: xi4oyu/dnSpy
        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);
            }
        }