Exemple #1
0
        public override bool Equals(IReturnType rt)
        {
            if (rt == null || !rt.IsGenericReturnType)
            {
                return(false);
            }
            GenericReturnType grt = rt.CastToGenericReturnType();

            if ((typeParameter.Method == null) != (grt.typeParameter.Method == null))
            {
                return(false);
            }
            return(typeParameter.Index == grt.typeParameter.Index);
        }
 public static IReturnType TranslateType(IReturnType input, IList <IReturnType> typeParameters, bool convertForMethod)
 {
     if (input == null || typeParameters == null || typeParameters.Count == 0)
     {
         return(input);                // nothing to do when there are no type parameters specified
     }
     if (input.IsGenericReturnType)
     {
         GenericReturnType rt = input.CastToGenericReturnType();
         if (convertForMethod ? (rt.TypeParameter.Method != null) : (rt.TypeParameter.Method == null))
         {
             if (rt.TypeParameter.Index < typeParameters.Count)
             {
                 IReturnType newType = typeParameters[rt.TypeParameter.Index];
                 if (newType != null)
                 {
                     return(newType);
                 }
             }
         }
     }
     else if (input.IsArrayReturnType)
     {
         ArrayReturnType arInput = input.CastToArrayReturnType();
         IReturnType     e       = arInput.ArrayElementType;
         IReturnType     t       = TranslateType(e, typeParameters, convertForMethod);
         if (e != t && t != null)
         {
             return(new ArrayReturnType(arInput.ProjectContent, t, arInput.ArrayDimensions));
         }
     }
     else if (input.IsConstructedReturnType)
     {
         ConstructedReturnType cinput = input.CastToConstructedReturnType();
         List <IReturnType>    para   = new List <IReturnType>(cinput.TypeArguments.Count);
         foreach (IReturnType argument in cinput.TypeArguments)
         {
             para.Add(TranslateType(argument, typeParameters, convertForMethod));
         }
         return(new ConstructedReturnType(cinput.UnboundType, para));
     }
     return(input);
 }
Exemple #3
0
 void WriteType(IReturnType rt)
 {
     if (rt == null)
     {
         writer.Write(NullRTReferenceCode);
         return;
     }
     if (rt.IsDefaultReturnType)
     {
         string name = rt.FullyQualifiedName;
         if (name == "System.Void")
         {
             writer.Write(VoidRTCode);
         }
         else if (name == "dynamic")
         {
             writer.Write(DynamicRTCode);
         }
         else
         {
             writer.Write(classIndices[new ClassNameTypeCountPair(rt)]);
         }
     }
     else if (rt.IsGenericReturnType)
     {
         GenericReturnType grt = rt.CastToGenericReturnType();
         if (grt.TypeParameter.Method != null)
         {
             writer.Write(MethodGenericRTCode);
         }
         else
         {
             writer.Write(TypeGenericRTCode);
         }
         writer.Write(grt.TypeParameter.Index);
     }
     else if (rt.IsArrayReturnType)
     {
         writer.Write(ArrayRTCode);
         writer.Write(rt.CastToArrayReturnType().ArrayDimensions);
         WriteType(rt.CastToArrayReturnType().ArrayElementType);
     }
     else if (rt.IsConstructedReturnType)
     {
         ConstructedReturnType crt = rt.CastToConstructedReturnType();
         writer.Write(ConstructedRTCode);
         WriteType(crt.UnboundType);
         writer.Write((byte)crt.TypeArguments.Count);
         foreach (IReturnType typeArgument in crt.TypeArguments)
         {
             WriteType(typeArgument);
         }
     }
     else if (rt.IsDecoratingReturnType <PointerReturnType>())
     {
         writer.Write(PointerRTCode);
         WriteType(rt.CastToDecoratingReturnType <PointerReturnType>().BaseType);
     }
     else
     {
         writer.Write(NullRTReferenceCode);
         LoggingService.Warn("Unknown return type: " + rt.ToString());
     }
 }
Exemple #4
0
        /// <summary>
        /// Infers type arguments specified by passing expectedArgument as parameter where passedArgument
        /// was expected. The resulting type arguments are written to outputArray.
        /// Returns false when expectedArgument and passedArgument are incompatible, otherwise true
        /// is returned (true is used both for successful inferring and other kind of errors).
        ///
        /// Warning: This method for single-argument type inference doesn't support lambdas!
        /// </summary>
        /// <remarks>
        /// The C# spec (§ 25.6.4) has a bug: it says that type inference works if the passedArgument is IEnumerable{T}
        /// and the expectedArgument is an array; passedArgument and expectedArgument must be swapped here.
        /// </remarks>
        public static bool InferTypeArgument(IReturnType expectedArgument, IReturnType passedArgument, IReturnType[] outputArray)
        {
            if (expectedArgument == null)
            {
                return(true);
            }
            if (passedArgument == null || passedArgument == NullReturnType.Instance)
            {
                return(true);
            }

            if (passedArgument.IsArrayReturnType)
            {
                IReturnType passedArrayElementType = passedArgument.CastToArrayReturnType().ArrayElementType;
                if (expectedArgument.IsArrayReturnType && expectedArgument.CastToArrayReturnType().ArrayDimensions == passedArgument.CastToArrayReturnType().ArrayDimensions)
                {
                    return(InferTypeArgument(expectedArgument.CastToArrayReturnType().ArrayElementType, passedArrayElementType, outputArray));
                }
                else if (expectedArgument.IsConstructedReturnType)
                {
                    switch (expectedArgument.FullyQualifiedName)
                    {
                    case "System.Collections.Generic.IList":
                    case "System.Collections.Generic.ICollection":
                    case "System.Collections.Generic.IEnumerable":
                        return(InferTypeArgument(expectedArgument.CastToConstructedReturnType().TypeArguments[0], passedArrayElementType, outputArray));
                    }
                }
                // If P is an array type, and A is not an array type of the same rank,
                // or an instantiation of IList<>, ICollection<>, or IEnumerable<>, then
                // type inference fails for the generic method.
                return(false);
            }
            if (expectedArgument.IsGenericReturnType)
            {
                GenericReturnType methodTP = expectedArgument.CastToGenericReturnType();
                if (methodTP.TypeParameter.Method != null)
                {
                    if (methodTP.TypeParameter.Index < outputArray.Length)
                    {
                        outputArray[methodTP.TypeParameter.Index] = passedArgument;
                    }
                    return(true);
                }
            }
            if (expectedArgument.IsConstructedReturnType)
            {
                // The spec for this case is quite complex.
                // For our purposes, we can simplify enourmously:
                if (!passedArgument.IsConstructedReturnType)
                {
                    return(false);
                }

                IList <IReturnType> expectedTA = expectedArgument.CastToConstructedReturnType().TypeArguments;
                IList <IReturnType> passedTA   = passedArgument.CastToConstructedReturnType().TypeArguments;

                int count = Math.Min(expectedTA.Count, passedTA.Count);
                for (int i = 0; i < count; i++)
                {
                    InferTypeArgument(expectedTA[i], passedTA[i], outputArray);
                }
            }
            return(true);
        }