예제 #1
0
        private ArrayTypeSymbol SubstituteArrayType(ArrayTypeSymbol t)
        {
            var oldElement = t.ElementType;
            TypeSymbolWithAnnotations element = oldElement.SubstituteTypeWithTupleUnification(this);

            if (element.IsSameAs(oldElement))
            {
                return(t);
            }

            ImmutableArray <NamedTypeSymbol> interfaces = t.InterfacesNoUseSiteDiagnostics();

            Debug.Assert(0 <= interfaces.Length && interfaces.Length <= 2);

            if (interfaces.Length == 1)
            {
                Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T>
                interfaces = ImmutableArray.Create <NamedTypeSymbol>(SubstituteNamedType(interfaces[0]));
            }
            else if (interfaces.Length == 2)
            {
                Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T>
                interfaces = ImmutableArray.Create <NamedTypeSymbol>(SubstituteNamedType(interfaces[0]), SubstituteNamedType(interfaces[1]));
            }
            else if (interfaces.Length != 0)
            {
                throw ExceptionUtilities.Unreachable;
            }

            var arrayType = t.BaseTypeNoUseSiteDiagnostics.Construct(element.TypeSymbol);

            return(ArrayTypeSymbol.CreateArray(
                       element,
                       arrayType,
                       interfaces));
        }
예제 #2
0
        /// <summary>
        /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly
        /// its referenced assemblies.
        /// </summary>
        /// <param name="type">The type to resolve.</param>
        /// <param name="includeReferences">Use referenced assemblies for resolution.</param>
        /// <returns>The resolved symbol if successful or null on failure.</returns>
        internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences)
        {
            System.Reflection.TypeInfo typeInfo = type.GetTypeInfo();

            Debug.Assert(!typeInfo.IsByRef);

            // not supported (we don't accept open types as submission results nor host types):
            Debug.Assert(!typeInfo.ContainsGenericParameters);

            if (typeInfo.IsArray)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                int rank = typeInfo.GetArrayRank();
                if (rank != 1)
                {
                    throw new NotSupportedException($"An array of rank {rank} is not supported in stark via reflection");
                }

                return(ArrayTypeSymbol.CreateArray(this, TypeSymbolWithAnnotations.Create(symbol)));
            }
            else if (typeInfo.IsPointer)
            {
                TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                return(new PointerTypeSymbol(TypeSymbolWithAnnotations.Create(symbol)));
            }
            else if (typeInfo.DeclaringType != null)
            {
                Debug.Assert(!typeInfo.IsArray);

                // consolidated generic arguments (includes arguments of all declaring types):
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                int    typeArgumentIndex = 0;

                var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo;
                var nestedTypes     = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance();

                while (true)
                {
                    Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType);

                    nestedTypes.Add(currentTypeInfo);
                    if (currentTypeInfo.DeclaringType == null)
                    {
                        break;
                    }

                    currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo();
                }

                int i      = nestedTypes.Count - 1;
                var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences);
                if ((object)symbol == null)
                {
                    return(null);
                }

                while (--i >= 0)
                {
                    int forcedArity         = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length;
                    MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity);

                    symbol = symbol.LookupMetadataType(ref mdName);
                    if ((object)symbol == null || symbol.IsErrorType())
                    {
                        return(null);
                    }

                    symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                    if ((object)symbol == null)
                    {
                        return(null);
                    }
                }

                nestedTypes.Free();
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
            else
            {
                AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly);

                MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName(
                    typeInfo.Namespace ?? string.Empty,
                    typeInfo.Name,
                    forcedArity: typeInfo.GenericTypeArguments.Length);

                NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false, conflicts: out var _);

                if ((object)symbol == null || symbol.IsErrorType())
                {
                    return(null);
                }

                int    typeArgumentIndex = 0;
                Type[] genericArguments  = typeInfo.GenericTypeArguments;
                symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences);
                Debug.Assert(typeArgumentIndex == genericArguments.Length);
                return(symbol);
            }
        }