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));
            }
        }
Пример #2
0
        /// <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));
        }