Example #1
0
        private static TypeReference ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance declaringGenericInstanceType, TypeReference parameterType)
        {
            ByReferenceType byRefType = parameterType as ByReferenceType;

            if (byRefType != null)
            {
                return(ResolveIfNeeded(genericInstanceMethod, declaringGenericInstanceType, byRefType));
            }

            ArrayType arrayType = parameterType as ArrayType;

            if (arrayType != null)
            {
                return(ResolveIfNeeded(genericInstanceMethod, declaringGenericInstanceType, arrayType));
            }

            GenericInstanceType genericInstanceType = parameterType as GenericInstanceType;

            if (genericInstanceType != null)
            {
                return(ResolveIfNeeded(genericInstanceMethod, declaringGenericInstanceType, genericInstanceType));
            }

            GenericParameter genericParameter = parameterType as GenericParameter;

            if (genericParameter != null)
            {
                return(ResolveIfNeeded(genericInstanceMethod, declaringGenericInstanceType, genericParameter));
            }

            RequiredModifierType requiredModifierType = parameterType as RequiredModifierType;

            if (requiredModifierType != null && ContainsGenericParameters(requiredModifierType))
            {
                return(ResolveIfNeeded(genericInstanceMethod, declaringGenericInstanceType, requiredModifierType.ElementType));
            }

            if (ContainsGenericParameters(parameterType))
            {
                throw new Exception("Unexpected generic parameter.");
            }

            return(parameterType);
        }
        public static int GetHashCodeFor(TypeReference obj)
        {
            // a very good prime number
            const int hashCodeMultiplier = 486187739;
            // prime numbers
            const int genericInstanceTypeMultiplier = 31;
            const int byReferenceMultiplier         = 37;
            const int pointerMultiplier             = 41;
            const int requiredModifierMultiplier    = 43;
            const int optionalModifierMultiplier    = 47;
            const int pinnedMultiplier   = 53;
            const int sentinelMultiplier = 59;

            MetadataType metadataType = obj.MetadataType;

            if (metadataType == MetadataType.GenericInstance)
            {
                GenericInstanceType genericInstanceType = (GenericInstanceType)obj;
                int hashCode = GetHashCodeFor(genericInstanceType.ElementType) * hashCodeMultiplier + genericInstanceTypeMultiplier;
                for (int i = 0; i < genericInstanceType.GenericArguments.Count; i++)
                {
                    hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(genericInstanceType.GenericArguments[i]);
                }

                return(hashCode);
            }

            if (metadataType == MetadataType.Array)
            {
                ArrayType arrayType = (ArrayType)obj;
                return(GetHashCodeFor(arrayType.ElementType) * hashCodeMultiplier + arrayType.Rank.GetHashCode());
            }

            if (metadataType == MetadataType.Var || metadataType == MetadataType.MVar)
            {
                GenericParameter genericParameter = (GenericParameter)obj;
                int hashCode = genericParameter.Position.GetHashCode() * hashCodeMultiplier + ((int)metadataType).GetHashCode();

                TypeReference ownerTypeReference = genericParameter.Owner as TypeReference;
                if (ownerTypeReference != null)
                {
                    return(hashCode * hashCodeMultiplier + GetHashCodeFor(ownerTypeReference));
                }

                MethodReference ownerMethodReference = genericParameter.Owner as MethodReference;
                if (ownerMethodReference != null)
                {
                    return(hashCode * hashCodeMultiplier + MethodReferenceComparer.GetHashCodeFor(ownerMethodReference));
                }

                throw new InvalidOperationException("Generic parameter encountered with invalid owner");
            }

            if (metadataType == MetadataType.ByReference)
            {
                ByReferenceType byReferenceType = (ByReferenceType)obj;
                return(GetHashCodeFor(byReferenceType.ElementType) * hashCodeMultiplier * byReferenceMultiplier);
            }

            if (metadataType == MetadataType.Pointer)
            {
                PointerType pointerType = (PointerType)obj;
                return(GetHashCodeFor(pointerType.ElementType) * hashCodeMultiplier * pointerMultiplier);
            }

            if (metadataType == MetadataType.RequiredModifier)
            {
                RequiredModifierType requiredModifierType = (RequiredModifierType)obj;
                int hashCode = GetHashCodeFor(requiredModifierType.ElementType) * requiredModifierMultiplier;
                hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(requiredModifierType.ModifierType);
                return(hashCode);
            }

            if (metadataType == MetadataType.OptionalModifier)
            {
                OptionalModifierType optionalModifierType = (OptionalModifierType)obj;
                int hashCode = GetHashCodeFor(optionalModifierType.ElementType) * optionalModifierMultiplier;
                hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(optionalModifierType.ModifierType);
                return(hashCode);
            }

            if (metadataType == MetadataType.Pinned)
            {
                PinnedType pinnedType = (PinnedType)obj;
                return(GetHashCodeFor(pinnedType.ElementType) * hashCodeMultiplier * pinnedMultiplier);
            }

            if (metadataType == MetadataType.Sentinel)
            {
                SentinelType sentinelType = (SentinelType)obj;
                return(GetHashCodeFor(sentinelType.ElementType) * hashCodeMultiplier * sentinelMultiplier);
            }

            if (metadataType == MetadataType.FunctionPointer)
            {
                throw new NotImplementedException("We currently don't handle function pointer types.");
            }

            return(obj.Namespace.GetHashCode() * hashCodeMultiplier + obj.FullName.GetHashCode());
        }
        public static bool AreEqual(TypeReference a, TypeReference b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact)
        {
            if (ReferenceEquals(a, b))
            {
                return(true);
            }

            if (a == null || b == null)
            {
                return(false);
            }

            MetadataType aMetadataType = a.MetadataType;
            MetadataType bMetadataType = b.MetadataType;

            if (aMetadataType == MetadataType.GenericInstance || bMetadataType == MetadataType.GenericInstance)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual((GenericInstanceType)a, (GenericInstanceType)b, comparisonMode));
            }

            if (aMetadataType == MetadataType.Array || bMetadataType == MetadataType.Array)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                ArrayType a1 = (ArrayType)a;
                ArrayType b1 = (ArrayType)b;
                if (a1.Rank != b1.Rank)
                {
                    return(false);
                }

                return(AreEqual(a1.ElementType, b1.ElementType, comparisonMode));
            }

            if (aMetadataType == MetadataType.Var || bMetadataType == MetadataType.Var)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual((GenericParameter)a, (GenericParameter)b, comparisonMode));
            }

            if (aMetadataType == MetadataType.MVar || bMetadataType == MetadataType.MVar)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual((GenericParameter)a, (GenericParameter)b, comparisonMode));
            }

            if (aMetadataType == MetadataType.ByReference || bMetadataType == MetadataType.ByReference)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual(((ByReferenceType)a).ElementType, ((ByReferenceType)b).ElementType, comparisonMode));
            }

            if (aMetadataType == MetadataType.Pointer || bMetadataType == MetadataType.Pointer)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual(((PointerType)a).ElementType, ((PointerType)b).ElementType, comparisonMode));
            }

            if (aMetadataType == MetadataType.RequiredModifier || bMetadataType == MetadataType.RequiredModifier)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                RequiredModifierType a1 = (RequiredModifierType)a;
                RequiredModifierType b1 = (RequiredModifierType)b;

                return(AreEqual(a1.ModifierType, b1.ModifierType, comparisonMode) && AreEqual(a1.ElementType, b1.ElementType, comparisonMode));
            }

            if (aMetadataType == MetadataType.OptionalModifier || bMetadataType == MetadataType.OptionalModifier)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                OptionalModifierType a1 = (OptionalModifierType)a;
                OptionalModifierType b1 = (OptionalModifierType)b;

                return(AreEqual(a1.ModifierType, b1.ModifierType, comparisonMode) && AreEqual(a1.ElementType, b1.ElementType, comparisonMode));
            }

            if (aMetadataType == MetadataType.Pinned || bMetadataType == MetadataType.Pinned)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual(((PinnedType)a).ElementType, ((PinnedType)b).ElementType, comparisonMode));
            }

            if (aMetadataType == MetadataType.Sentinel || bMetadataType == MetadataType.Sentinel)
            {
                if (aMetadataType != bMetadataType)
                {
                    return(false);
                }

                return(AreEqual(((SentinelType)a).ElementType, ((SentinelType)b).ElementType, comparisonMode));
            }

            if (!a.Name.Equals(b.Name) || !a.Namespace.Equals(b.Namespace))
            {
                return(false);
            }

            TypeDefinition xDefinition = a.Resolve();
            TypeDefinition yDefinition = b.Resolve();

            // For loose signature the types could be in different assemblies, as long as the type names match we will consider them equal
            if (comparisonMode == TypeComparisonMode.SignatureOnlyLoose)
            {
                if (xDefinition.Module.Name != yDefinition.Module.Name)
                {
                    return(false);
                }

                if (xDefinition.Module.Assembly.Name.Name != yDefinition.Module.Assembly.Name.Name)
                {
                    return(false);
                }

                return(xDefinition.FullName == yDefinition.FullName);
            }

            return(xDefinition == yDefinition);
        }
Example #4
0
        private static bool ContainsGenericParameters(TypeReference typeReference)
        {
            GenericParameter genericParameter = typeReference as GenericParameter;

            if (genericParameter != null)
            {
                return(true);
            }

            ArrayType arrayType = typeReference as ArrayType;

            if (arrayType != null)
            {
                return(ContainsGenericParameters(arrayType.ElementType));
            }

            PointerType pointerType = typeReference as PointerType;

            if (pointerType != null)
            {
                return(ContainsGenericParameters(pointerType.ElementType));
            }

            ByReferenceType byRefType = typeReference as ByReferenceType;

            if (byRefType != null)
            {
                return(ContainsGenericParameters(byRefType.ElementType));
            }

            SentinelType sentinelType = typeReference as SentinelType;

            if (sentinelType != null)
            {
                return(ContainsGenericParameters(sentinelType.ElementType));
            }

            PinnedType pinnedType = typeReference as PinnedType;

            if (pinnedType != null)
            {
                return(ContainsGenericParameters(pinnedType.ElementType));
            }

            RequiredModifierType requiredModifierType = typeReference as RequiredModifierType;

            if (requiredModifierType != null)
            {
                return(ContainsGenericParameters(requiredModifierType.ElementType));
            }

            GenericInstanceType genericInstance = typeReference as GenericInstanceType;

            if (genericInstance != null)
            {
                foreach (TypeReference genericArgument in genericInstance.GenericArguments)
                {
                    if (ContainsGenericParameters(genericArgument))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            if (typeReference is TypeSpecification)
            {
                throw new NotSupportedException();
            }

            return(false);
        }
Example #5
0
        public TypeReference Resolve(TypeReference typeReference, bool includeTypeDefinitions)
        {
            if (IsDummy())
            {
                return(typeReference);
            }

            if (_typeDefinitionContext != null && _typeDefinitionContext.GenericArguments.Contains(typeReference))
            {
                return(typeReference);
            }

            if (_methodDefinitionContext != null && _methodDefinitionContext.GenericArguments.Contains(typeReference))
            {
                return(typeReference);
            }

            GenericParameter genericParameter = typeReference as GenericParameter;

            if (genericParameter != null)
            {
                if (_typeDefinitionContext != null && _typeDefinitionContext.GenericArguments.Contains(genericParameter))
                {
                    return(genericParameter);
                }

                if (_methodDefinitionContext != null && _methodDefinitionContext.GenericArguments.Contains(genericParameter))
                {
                    return(genericParameter);
                }

                return(ResolveGenericParameter(genericParameter));
            }

            ArrayType arrayType = typeReference as ArrayType;

            if (arrayType != null)
            {
                return(new ArrayType(Resolve(arrayType.ElementType), arrayType.Rank));
            }

            PointerType pointerType = typeReference as PointerType;

            if (pointerType != null)
            {
                return(new PointerType(Resolve(pointerType.ElementType)));
            }

            ByReferenceType byReferenceType = typeReference as ByReferenceType;

            if (byReferenceType != null)
            {
                return(new ByReferenceType(Resolve(byReferenceType.ElementType)));
            }

            PinnedType pinnedType = typeReference as PinnedType;

            if (pinnedType != null)
            {
                return(new PinnedType(Resolve(pinnedType.ElementType)));
            }

            GenericInstanceType genericInstanceType = typeReference as GenericInstanceType;

            if (genericInstanceType != null)
            {
                GenericInstanceType newGenericInstanceType = new GenericInstanceType(genericInstanceType.ElementType);
                foreach (TypeReference genericArgument in genericInstanceType.GenericArguments)
                {
                    newGenericInstanceType.GenericArguments.Add(Resolve(genericArgument));
                }

                return(newGenericInstanceType);
            }

            RequiredModifierType requiredModType = typeReference as RequiredModifierType;

            if (requiredModType != null)
            {
                return(Resolve(requiredModType.ElementType, includeTypeDefinitions));
            }

            if (includeTypeDefinitions)
            {
                TypeDefinition typeDefinition = typeReference as TypeDefinition;
                if (typeDefinition != null && typeDefinition.HasGenericParameters)
                {
                    GenericInstanceType newGenericInstanceType = new GenericInstanceType(typeDefinition);
                    foreach (GenericParameter gp in typeDefinition.GenericParameters)
                    {
                        newGenericInstanceType.GenericArguments.Add(Resolve(gp));
                    }

                    return(newGenericInstanceType);
                }
            }

            if (typeReference is TypeSpecification)
            {
                throw new NotSupportedException(string.Format("The type {0} cannot be resolved correctly.", typeReference.FullName));
            }

            return(typeReference);
        }