示例#1
0
        public override bool Equals(object o)
        {
            IReturnType rt = o as IReturnType;

            if (rt == null || !rt.IsArrayReturnType)
            {
                return(false);
            }
            ArrayReturnType art = rt.CastToArrayReturnType();

            if (art.ArrayDimensions != dimensions)
            {
                return(false);
            }
            return(elementType.Equals(art.ArrayElementType));
        }
示例#2
0
 public static IReturnType TranslateType(IReturnType input, IList <IReturnType> typeParameters, bool convertForMethod)
 {
     if (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);
 }
        static IReturnType[] InferTypeArguments(IMethod method, IReturnType[] arguments)
        {
            // §25.6.4 Inference of type arguments
            int count = method.TypeParameters.Count;

            if (count == 0)
            {
                return(null);
            }
            IReturnType[]      result     = new IReturnType[count];
            IList <IParameter> parameters = method.Parameters;

            for (int i = 0; i < arguments.Length; i++)
            {
                if (i >= parameters.Count)
                {
                    break;
                }
                if (!InferTypeArgument(parameters[i].ReturnType, arguments[i], result))
                {
                    // inferring failed: maybe this is a params parameter that must be expanded?
                    if (parameters[i].IsParams && parameters[i].ReturnType.IsArrayReturnType)
                    {
                        ArrayReturnType art = parameters[i].ReturnType.CastToArrayReturnType();
                        if (art.ArrayDimensions == 1)
                        {
                            InferTypeArgument(art.ArrayElementType, arguments[i], result);
                        }
                    }
                }
            }
            // only return the result array when there something was inferred
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] != null)
                {
                    return(result);
                }
            }
            return(null);
        }
        /// <summary>
        /// Checks if an implicit conversion exists from <paramref name="from"/> to <paramref name="to"/>.
        /// </summary>
        public static bool ConversionExists(IReturnType from, IReturnType to)
        {
            // ECMA-334, § 13.1 Implicit conversions

            // Identity conversion:
            if (from == to)
            {
                return(true);
            }
            if (from == null || to == null)
            {
                return(false);
            }
            if (from.Equals(to))
            {
                return(true);
            }

            bool fromIsDefault = from.IsDefaultReturnType;
            bool toIsDefault   = to.IsDefaultReturnType;

            if (fromIsDefault && toIsDefault)
            {
                // Implicit numeric conversions:
                int f = GetPrimitiveType(from);
                int t = GetPrimitiveType(to);
                if (f == SByte && (t == Short || t == Int || t == Long || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == Byte && (t == Short || t == UShort || t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == Short && (t == Int || t == Long || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == UShort && (t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == Int && (t == Long || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == UInt && (t == Long || t == ULong || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if ((f == Long || f == ULong) && (t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == Char && (t == UShort || t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal))
                {
                    return(true);
                }
                if (f == Float && t == Double)
                {
                    return(true);
                }
            }
            // Implicit reference conversions:

            if (toIsDefault && to.FullyQualifiedName == "System.Object")
            {
                return(true);                // from any type to object
            }
            if (toIsDefault && (fromIsDefault || from.IsArrayReturnType))
            {
                IClass c1 = from.GetUnderlyingClass();
                IClass c2 = to.GetUnderlyingClass();
                if (c1 != null && c1.IsTypeInInheritanceTree(c2))
                {
                    return(true);
                }
            }
            if (from.IsArrayReturnType && to.IsArrayReturnType)
            {
                ArrayReturnType fromArt = from.CastToArrayReturnType();
                ArrayReturnType toArt   = to.CastToArrayReturnType();
                // from array to other array type
                if (fromArt.ArrayDimensions == toArt.ArrayDimensions)
                {
                    return(ConversionExists(fromArt.ArrayElementType, toArt.ArrayElementType));
                }
            }

            if (from.IsConstructedReturnType && to.IsConstructedReturnType)
            {
                if (from.FullyQualifiedName == to.FullyQualifiedName)
                {
                    IList <IReturnType> fromTypeArguments = from.CastToConstructedReturnType().TypeArguments;
                    IList <IReturnType> toTypeArguments   = to.CastToConstructedReturnType().TypeArguments;
                    if (fromTypeArguments.Count == toTypeArguments.Count)
                    {
                        for (int i = 0; i < fromTypeArguments.Count; i++)
                        {
                            if (fromTypeArguments[i] == toTypeArguments[i])
                            {
                                continue;
                            }
                            if (object.Equals(fromTypeArguments[i], toTypeArguments[i]))
                            {
                                continue;
                            }
                            if (!(toTypeArguments[i].IsGenericReturnType))
                            {
                                return(false);
                            }
                        }
                        return(true);
                    }
                }
            }

            return(false);
        }