Beispiel #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);
        }
Beispiel #2
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);
        }