Exemplo n.º 1
0
        /// <summary>
        /// If the type if UnknownType, it will search all the dependencies for the specified type.
        /// If the type is not unknown type it will just return the type directly.
        /// This gets around the problem that types are only known for the assembly they are included in.
        /// </summary>
        /// <param name="type">The type to check.</param>
        /// <param name="compilation">The compilation which contains all the assemblies and dependencies.</param>
        /// <returns>The concrete type if one can be found.</returns>
        public static IType GetRealType(this IType type, ICompilation compilation)
        {
            // If the type is UnknownType, check other assemblies we have as dependencies first,
            // since UnknownType is only if it's unknown in the current assembly only.
            // This scenario is fairly common with types in the netstandard libraries, eg System.EventHandler.
            var newType = type;

            if (newType is UnknownType || newType.Kind == TypeKind.Unknown)
            {
                if (newType.TypeParameterCount == 0)
                {
                    newType = compilation.GetReferenceTypeDefinitionsWithFullName(newType.ReflectionName).FirstOrDefault();
                }
                else if (newType is ParameterizedType paramType)
                {
                    var genericType = compilation.GetReferenceTypeDefinitionsWithFullName(paramType.GenericType.ReflectionName).FirstOrDefault();

                    var typeArguments = newType.TypeArguments.Select(x => GetRealType(x, compilation));

                    newType = new ParameterizedType(genericType, typeArguments);
                }
            }

            return(newType ?? type);
        }