private static void TestAssignability(Type a, Type b, MetadataResolutionContext context) { var aData = a.IsGenericParameter ? context.GetGenericTypeParameterData(a) : context.GetTypeData(a); var bData = b.IsGenericParameter ? context.GetGenericTypeParameterData(b) : context.GetTypeData(b); if (aData == null || bData == null) { AssertX.Inconclusive("Unable to get one of the types"); } if (a.IsImplicitlyAssignableFrom(b)) { Assert.True(aData.IsAssignableFromNew(bData), string.Format("The type should be assignable: {0} <- {1}", aData.Name, bData.Name)); } else { Assert.False(aData.IsAssignableFromNew(bData), string.Format("The type should not be assignable: {0} <- {1}", aData.Name, bData.Name)); } if (b.IsImplicitlyAssignableFrom(a)) { Assert.True(bData.IsAssignableFromNew(aData), string.Format("The type should be assignable: {0} <- {1}", bData.Name, aData.Name)); } else { Assert.False(bData.IsAssignableFromNew(aData), string.Format("The type should not be assignable: {0} <- {1}", bData.Name, aData.Name)); } }
/// <summary> /// Gets the <see cref="TypeData"/> instance containing the metadata for externally visible types and members of the specified <see cref="Type"/>. /// </summary> /// <param name="typeSymbol">The type for which of corresponding to the TypeData to get.</param> /// <returns>The TypeData instance containing the metadata for externally visible types and members of the specified Type.</returns> internal TypeData GetTypeData(ITypeSymbol typeSymbol) { Debug.Assert( Context.GetDeclaringAssemblySymbol(typeSymbol).ToDisplayString() == FullName, "The type belongs to another assembly."); if (typeSymbol is ITypeParameterSymbol typeParameterSymbol) { return(GetGenericTypeParameterData(typeParameterSymbol)); } if (!typeSymbol.DeclaredAccessibility.IsPublicOrProtected()) { return(null); } if (typeSymbol is INamedTypeSymbol namedTypeSymbol) { // TODO: I think this may be a bug. Report if so: ValueTuple<T1> doesn't report its fully qualified name correctly unless we do this. // However, this is needed anyway to get the proper type info for tuple types. if (namedTypeSymbol.IsTupleType) { namedTypeSymbol = namedTypeSymbol.TupleUnderlyingType; } if (namedTypeSymbol.IsConstructed()) { return(Context.GetTypeDefinitionData(namedTypeSymbol.ConstructedFrom).GetConstructedGenericTypeData(namedTypeSymbol.TypeArguments.Select(a => Context.GetTypeData(a)))); } return(GetTypeDefinitionData(namedTypeSymbol.GetFullName())); } DeclaringTypeData declaringType = null; if (typeSymbol.ContainingType != null) { declaringType = (DeclaringTypeData)GetTypeData(typeSymbol.ContainingType); } if (typeSymbol is IArrayTypeSymbol arrayType) { Debug.Assert(declaringType == null, "Types with elements should not be declared within other types."); var elementType = Context.GetTypeData(arrayType.ElementType); return(elementType.GetArrayType((byte)arrayType.Rank)); } if (typeSymbol is IPointerTypeSymbol pointerTypeSymbol) { return(Context.GetTypeData(pointerTypeSymbol.PointedAtType).GetPointerType()); } if (typeSymbol is IDynamicTypeSymbol dynamicTypeSymbol) { // TODO: Not sure if this is the right thing to do return(GetTypeDefinitionData(Utilities.ObjectTypeName)); } Debug.Fail("Unknown kind of type."); return(Context.GetTypeData(typeSymbol)); }