Example #1
0
        static bool ParamArrayMatchs(Type[] types, int index, Type dest, ArgumentConversions conversions)
        {
            var binder = new ArgumentConversions(types.Length - index);

            // check first parameter type matches
            for (int i = 0, current = index; current < types.Length; i++, current++)
            {
                var src = types[current];
                if (src is null)
                {
                    if (dest.IsValueType && !dest.IsNullableType())
                    {
                        return(false);
                    }
                }
                else if (!TypeUtils.AreReferenceAssignable(dest, src))
                {
                    if (src.TryImplicitConvert(dest, out MethodInfo opImplict) == false)
                    {
                        return(false);
                    }
                    if (src.IsValueType && opImplict.GetParameters()[0].ParameterType.IsValueType == false)
                    {
                        binder.Add(new BoxConversion(i, src));
                    }
                    binder.Add(new ParamConversion(i, opImplict));
                }
                else if (src.IsValueType && dest.IsValueType == false)
                {
                    conversions.Add(new BoxConversion(i, src));
                }
            }
            conversions.Add(new ParamArrayConversion(index, dest, binder));
            return(true);
        }
Example #2
0
 static System.Reflection.MethodInfo VisitAddition(Expression left, Expression right, ArgumentConversions conversions)
 {
     if (left.Type.Name.Equals(TypeProvider.String))
     {
         if (right.Type.Name.Equals(TypeProvider.String))
         {
             return(VisitBinary(left, right, Operators.Addition, conversions));
         }
         if (right.Type.IsValueType)
         {
             conversions.Add(new BoxConversion(1, right.Type));
         }
         conversions.Add(new ParamConversion(1, ReflectionHelpers.AnyToString));
         right.Type = TypeProvider.StringType;
         return(VisitBinary(left, right, Operators.Addition, conversions));
     }
     if (right.Type.Name.Equals(TypeProvider.String))
     {
         if (left.Type.Name.Equals(TypeProvider.String))
         {
             return(VisitBinary(left, right, Operators.Addition, conversions));
         }
         if (right.Type.IsValueType)
         {
             conversions.Add(new BoxConversion(1, left.Type));
         }
         conversions.Add(new ParamConversion(0, ReflectionHelpers.AnyToString));
         left.Type = TypeProvider.StringType;
         return(VisitBinary(left, right, Operators.Addition, conversions));
     }
     return(VisitBinary(left, right, Operators.Addition, conversions));
 }
Example #3
0
        public static bool MatchesArgumentTypes(this MethodBase method, Type[] types, ArgumentConversions conversions)
        {
            var parameters = method.GetParameters();
            var length     = types.Length;

            if (parameters.Length < length)
            {
                return(false);
            }
            int i;

            for (i = 0; i < parameters.Length; i++)
            {
                var param = parameters[i];
                var dest  = param.ParameterType;
                if (param.IsDefined(typeof(ParamArrayAttribute), false))
                {
                    // parameters is extra example print(string, params string[] args) and print('hello')
                    // in this case 2 and 1
                    if (parameters.Length > length)
                    {
                        conversions.Add(new ParamArrayConversion(i, dest.GetElementType()));
                        return(true);
                    }
                    //No further check required if matchs
                    return(ParamArrayMatchs(types, i, dest.GetElementType(), conversions));
                }
                // matches current index
                if (i >= length)
                {
                    return(conversions.Recycle());
                }
                var src = types[i];
                if (src is null)
                {
                    if (dest.IsValueType && !dest.IsNullableType())
                    {
                        return(conversions.Recycle());
                    }
                }
                else if (!TypeUtils.AreReferenceAssignable(dest, src))
                {
                    if (src.TryImplicitConvert(dest, out MethodInfo m) == false)
                    {
                        return(conversions.Recycle());
                    }
                    if (src.IsValueType && m.GetParameters()[0].ParameterType.IsValueType == false)
                    {
                        conversions.Add(new BoxConversion(i, src));
                    }
                    conversions.Add(new ParamConversion(i, m));
                }
                if (src.IsValueType && dest.IsValueType == false)
                {
                    conversions.Add(new BoxConversion(i, src));
                }
            }
            if (i == length)
            {
                return(true);
            }
            return(conversions.Recycle());
        }