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); }
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); }
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); }