static bool IsGenericTypeDefinition(DmdType type) { if (!type.IsMetadataReference) { return(type.IsGenericTypeDefinition); } // It's a TypeRef, make sure it won't throw if it can't resolve the type var resolvedType = type.ResolveNoThrow(); if ((object)resolvedType != null) { return(resolvedType.IsGenericTypeDefinition); } // Guess based on name return(type is Impl.DmdTypeRef && type.MetadataName.LastIndexOf('`') >= 0); }
static bool ContainsGenericParameters(DmdType type) { if (!type.IsMetadataReference) { return(type.ContainsGenericParameters); } // It's a TypeRef, make sure it won't throw if it can't resolve the type var resolvedType = type.ResolveNoThrow(); if ((object)resolvedType != null) { return(resolvedType.ContainsGenericParameters); } if (type is Impl.DmdTypeRef) { return(type.MetadataName.LastIndexOf('`') >= 0); } return(type.ContainsGenericParameters); }
static ReadOnlyCollection <DmdType> GetGenericArguments(DmdType type) { if (!type.IsMetadataReference) { return(type.GetGenericArguments()); } var resolvedType = type.ResolveNoThrow(); if ((object)resolvedType != null) { return(resolvedType.GetGenericArguments()); } if (type is Impl.DmdGenericInstanceTypeRef) { return(type.GetGenericArguments()); } return(ReadOnlyCollectionHelpers.Empty <DmdType>()); }
static DmdType GetGenericTypeDefinition(DmdType type) { if (!type.IsMetadataReference) { return(type.GetGenericTypeDefinition()); } var resolvedType = type.ResolveNoThrow(); if ((object)resolvedType != null) { return(resolvedType.GetGenericTypeDefinition()); } if (type is Impl.DmdGenericInstanceTypeRef) { return(type.GetGenericTypeDefinition()); } if (type.MetadataName.LastIndexOf('`') >= 0) { return(type); } return(null); }
/// <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); }