Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
 /// <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);
Exemplo n.º 4
0
 static bool IsShortNameType(DmdType type) => type.IsPrimitive || type == type.AppDomain.System_Void || type == type.AppDomain.System_TypedReference;
Exemplo n.º 5
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();
        }
Exemplo n.º 6
0
 public static string FormatFullName(DmdType type) => Format(type, serializable: true);
Exemplo n.º 7
0
 string FormatNameCore(DmdType type)
 {
     WriteName(type, GetTypeFlags(shortTypeNames: false) | TypeFlags.FnPtrIsIntPtr);
     return(writer.ToString());
 }
Exemplo n.º 8
0
#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);
Exemplo n.º 9
0
 /// <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);
Exemplo n.º 10
0
 static bool IsDelegate(DmdType td) => td.BaseType == td.AppDomain.System_MulticastDelegate;
Exemplo n.º 11
0
 /// <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);
Exemplo n.º 12
0
 /// <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;
 }
Exemplo n.º 13
0
 /// <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);
Exemplo n.º 14
0
 /// <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);
Exemplo n.º 15
0
 DmdMarshalType(VarEnum safeArraySubType, DmdType safeArrayUserDefinedSubType)
 {
     Value                       = UnmanagedType.SafeArray;
     SafeArraySubType            = safeArraySubType;
     SafeArrayUserDefinedSubType = safeArrayUserDefinedSubType;
 }
Exemplo n.º 16
0
 /// <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);
Exemplo n.º 17
0
 /// <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;
 }
Exemplo n.º 18
0
 /// <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);
Exemplo n.º 19
0
 string FormatCore(DmdType type)
 {
     Write(type);
     return(writer.ToString());
 }
Exemplo n.º 20
0
 /// <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);
Exemplo n.º 21
0
 void Write(DmdType type) => Write(type, GetTypeFlags(false) | TypeFlags.FnPtrIsIntPtr);
Exemplo n.º 22
0
 /// <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);
Exemplo n.º 23
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.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();
        }
Exemplo n.º 24
0
 /// <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);
Exemplo n.º 25
0
        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();
            }
        }
Exemplo n.º 26
0
 /// <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;
 }
Exemplo n.º 27
0
        __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);
            }
        }
Exemplo n.º 28
0
 /// <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;
Exemplo n.º 29
0
 /// <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);
Exemplo n.º 30
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);
        }