public static bool TryGetDelegateMethod(Type type, Type[] args, out MethodInfo method, out ArgumentConversions conversions)
 {
     conversions = new ArgumentConversions(args.Length);
     method      = type.GetMethod(InvokeMethod, PublicInstance);
     // only static method can allowed
     return(method.MatchesArgumentTypes(args, conversions));
 }
Beispiel #2
0
 public static MethodInfo FindSetIndexer(this System.Type type, System.Type[] args, out ArgumentConversions conversions)
 {
     conversions = new ArgumentConversions(args.Length);
     if (type.IsArray)
     {
         var m = type.GetMethod("Set", TypeUtils.PublicInstance);
         //for array no indexer we have to use Set Method
         if (m.MatchesArgumentTypes(args, conversions))
         {
             return(m);
         }
         return(null);
     }
     foreach (var item in type.GetDefaultMembers())
     {
         if (item.MemberType == MemberTypes.Property)
         {
             var p = (PropertyInfo)item;
             if (p.CanWrite)
             {
                 var m = p.GetSetMethod(true);
                 if (m.MatchesArgumentTypes(args, conversions))
                 {
                     return(m);
                 }
             }
         }
     }
     return(null);
 }
Beispiel #3
0
        static void PrepareLogicalBoolean(int index, Type type, ArgumentConversions conversions)
        {
            if (type == TypeProvider.BooleanType)
            {
                return;
            }
            else if (type.IsPrimitive && type == typeof(bool))
            {
                conversions.Append(index, new ParamConversion(index, TypeProvider.BooleanType.GetMethod(TypeUtils.ImplicitConversionName, TypeUtils.PublicStatic, null, new Type[1] {
                    type
                }, null)));
                return;
            }
            else if (type.GetInterface(ReflectionUtils.ConvertibleType, false) != null)
            {
                if (type.IsValueType)
                {
                    conversions.Append(index, new BoxConversion(index, type));
                }
                conversions.Append(index, new ParamConversion(index, ReflectionHelpers.ToBoolean));
                return;
            }
            var methods = type.GetMember(TypeUtils.ImplicitConversionName, System.Reflection.MemberTypes.Method, TypeUtils.PublicStatic);
            var types   = new Type[] { type };

            foreach (System.Reflection.MethodInfo method in methods)
            {
                if (method.MatchesArgumentTypes(types, conversions) && method.ReturnType == TypeProvider.BooleanType)
                {
                    return;
                }
            }
            throw new Exception(string.Concat("can't convert from ", type, " to type Boolean"));
        }
Beispiel #4
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);
        }
Beispiel #5
0
        /// <inheritdoc/>
        Expression IExpressionVisitor <Expression> .VisitBinary(BinaryExpression node)
        {
            //todo like rutime compiler
            var left  = node.Left.Accept(this);
            var right = node.Right.Accept(this);
            ArgumentConversions conversions = new ArgumentConversions(2);

            System.Reflection.MethodInfo method;
            switch (node.NodeType)
            {
            case ExpressionType.Plus:
                method = VisitAddition(left, right, conversions);
                break;

            case ExpressionType.AndAnd:
            case ExpressionType.OrOr:
                PrepareLogicalBoolean(0, left.Type, conversions);
                PrepareLogicalBoolean(1, right.Type, conversions);
                method = node.NodeType == ExpressionType.AndAnd ? ReflectionHelpers.LogicalAnd : ReflectionHelpers.LogicalOr;
                break;

            case ExpressionType.StarStar:
                method = VisitPow(node, left, right, conversions);
                break;

            default:
                method = VisitBinary(left, right, node.MethodName, conversions);
                break;
            }
            node.Conversions = conversions;
            node.Method      = method ?? throw new OperationCanceledException(string.Concat("Invalid Operation ", node.ToString()));
            node.Type        = method.ReturnType;
            return(node);
        }
 internal static bool TryGetDelegateMethod(object obj, object[] args, out MethodInfo method, out ArgumentConversions conversions)
 {
     conversions = new ArgumentConversions(args.Length);
     method      = obj.GetType().GetMethod(InvokeMethod, PublicInstance);
     // only static method can allowed
     return(method.MatchesArguments(args, conversions));
 }
 public static TMethod BindToMethod <TMethod>(TMethod[] methods, Type[] types, out ArgumentConversions bindings) where TMethod : MethodBase
 {
     bindings = new ArgumentConversions(types.Length);
     foreach (var m in methods)
     {
         if (m.MatchesArgumentTypes(types, bindings))
         {
             return(m);
         }
     }
     return(null);
 }
 public static TMethod BindToMethod <TMethod>(TMethod[] methods, object[] args, out ArgumentConversions conversions) where TMethod : MethodBase
 {
     conversions = new ArgumentConversions(args.Length);
     foreach (var m in methods)
     {
         if (m.MatchesArguments(args, conversions))
         {
             return(m);
         }
     }
     return(null);
 }
Beispiel #9
0
 public void EmitArguments(INodeList <Expression> arguments, ArgumentConversions conversions)
 {
     if (arguments.Count > 0)
     {
         for (int i = 0; i < arguments.Count; i++)
         {
             var arg  = arguments[i];
             var conv = conversions[i];
             if (conv != null)
             {
                 if (conv.ConversionType == ConversionType.Normal)
                 {
                     arg.GenerateCode(this, Expression.AssignOption);
                     EmitConvert(conv);
                 }
                 else if (conv.ConversionType == ConversionType.ParamArray)
                 {
                     var args = new Expression[arguments.Count - i];
                     arguments.CopyTo(args, conv.Index);
                     EmitConvert((ParamArrayConversion)conv, args);
                     break;
                 }
             }
             else
             {
                 arg.GenerateCode(this, Expression.AssignOption);
             }
         }
     }
     // remaing Conversions like optional or param array
     if (arguments.Count < conversions.Count)
     {
         for (var i = arguments.Count; i < conversions.Count; i++)
         {
             Conversion conv = conversions[i];
             if (conv.ConversionType == ConversionType.Normal)
             {
                 arguments[i].GenerateCode(this, Expression.AssignOption);
                 EmitConvert(conv);
             }
             else if (conv.ConversionType == ConversionType.ParamArray)
             {
                 // remaining arguments
                 var args = new Expression[arguments.Count - i];
                 arguments.CopyTo(args, conv.Index);
                 EmitConvert((ParamArrayConversion)conv, args);
                 break;
             }
         }
     }
 }
 public static MethodInfo GetOperatorOverload(string name, ArgumentConversions conversions, params Type[] types)
 {
     for (int i = 0; i < types.Length; i++)
     {
         var members = types[i].GetMember(name, PublicStatic);
         foreach (MethodInfo m in members)
         {
             if (MethodExtensions.MatchesArgumentTypes(m, types, conversions))
             {
                 return(m);
             }
         }
     }
     return(null);
 }
 public static MethodInfo BindToMethod(MemberInfo[] members, Type[] types, out ArgumentConversions bindings)
 {
     bindings = new ArgumentConversions(types.Length);
     foreach (var m in members)
     {
         if (m.MemberType == MemberTypes.Method)
         {
             if (MethodExtensions.MatchesArgumentTypes((MethodInfo)m, types, bindings))
             {
                 return((MethodInfo)m);
             }
         }
     }
     return(null);
 }
 public static MethodInfo BindToMethod(MemberInfo[] members, object[] args, out ArgumentConversions conversions)
 {
     conversions = new ArgumentConversions(args.Length);
     foreach (var m in members)
     {
         if (m.MemberType == MemberTypes.Method)
         {
             if (ReflectionExtensions.MatchesArguments((MethodInfo)m, args, conversions))
             {
                 return((MethodInfo)m);
             }
         }
     }
     return(null);
 }
Beispiel #13
0
        /// <inheritdoc/>
        Expression IExpressionVisitor <Expression> .VisitArrayLiteral(ArrayListExpression node)
        {
            var type = node.ArrayType != null?node.ArrayType.ResolveType(Context) : TypeProvider.AnyType;

            node.Type        = typeof(Collections.List <>).MakeGenericType(type);
            node.ElementType = type;
            if (node.Arguments != null)
            {
                var types = node.Arguments.Map(arg => arg.Accept(this).Type);
                if (node.Constructor == null)
                {
                    var ctors = node.Type.GetConstructors(ReflectionUtils.PublicInstance);
                    var ctor  = ReflectionUtils.BindToMethod(ctors, types, out ArgumentConversions conversions);
                    if (ctor == null)
                    {
                        ExecutionException.ThrowMissingMethod(node.Type, "ctor", node);
                    }
                    node.Constructor         = ctor;
                    node.ArgumentConversions = conversions;
                }
            }
            else if (node.Constructor == null)
            {
                node.Constructor = node.Type.GetConstructor(ReflectionUtils.PublicInstance, null, new Type[0], null);
            }
            var items = node.Expressions;

            if (items.Count > 0)
            {
                var arrayConversions = new ArgumentConversions(items.Count);
                for (int index = 0; index < items.Count; index++)
                {
                    var expression = items[index].Accept(this);
                    if (!TypeUtils.AreReferenceAssignable(type, expression.Type) && expression.Type.TryImplicitConvert(type, out System.Reflection.MethodInfo implicitCall))
                    {
                        if (expression.Type.IsValueType &&
                            implicitCall.GetParameters()[0].ParameterType == TypeProvider.ObjectType)
                        {
                            arrayConversions.Append(index, new BoxConversion(index, expression.Type));
                        }
                        arrayConversions.Append(index, new ParamConversion(index, implicitCall));
                    }
                }
                node.ArrayConversions = arrayConversions;
            }
            return(node);
        }
        static object Invoke(BinaryExpression node, string opName, object left, object right)
        {
            if (left is null)
            {
                ExecutionException.ThrowNullError(node.Left, node);
            }
            if (right is null)
            {
                ExecutionException.ThrowNullError(node.Right, node);
            }

            if (node.Method is null)
            {
                var leftType  = left.GetType();
                var rightType = right.GetType();
                var types     = new Type[2] {
                    leftType, rightType
                };
                ArgumentConversions          conversions = new ArgumentConversions(2);
                System.Reflection.MethodInfo method;
                if (leftType.IsPrimitive || rightType.IsPrimitive)
                {
                    var initial = (ReflectionUtils.FromSystemType(ref types));
                    method = ReflectionUtils.
                             GetOperatorOverload(opName, conversions, types);
                    conversions.SetInitial(initial);
                }
                else
                {
                    method = ReflectionUtils.
                             GetOperatorOverload(opName, conversions, types);
                }
                if (method is null)
                {
                    ExecutionException.ThrowInvalidOp(node);
                }
                node.Method      = method;
                node.Type        = method.ReturnType;
                node.Conversions = conversions;
            }
            object[] args = new object[2] {
                left, right
            };
            node.Conversions.Invoke(ref args);
            // operator overload invoke
            return(node.Method.Invoke(null, System.Reflection.BindingFlags.Default, null, args, null));
        }
Beispiel #15
0
        /// <inheritdoc/>
        Expression IExpressionVisitor <Expression> .VisitUnary(UnaryExpression node)
        {
            var operand = node.Operand.Accept(this);

            if (node.NodeType == ExpressionType.Parenthesized)
            {
                node.Type = operand.Type;
                return(operand);
            }
            ArgumentConversions conversions = new ArgumentConversions(2);
            var method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, operand.Type);

            node.Conversions = conversions;
            node.Method      = method;
            node.Type        = method.ReturnType;
            return(node);
        }
        private object VisitCompare(BinaryExpression node, string opName)
        {
            var left  = node.Left.Accept(this);
            var right = node.Right.Accept(this);

            if (left is null || right is null)
            {
                return(NullCompare(node, left, right));
            }
            if (node.Method is null)
            {
                var leftType  = left.GetType();
                var rightType = right.GetType();
                var types     = new Type[2] {
                    leftType, rightType
                };
                ArgumentConversions          conversions = new ArgumentConversions(2);
                System.Reflection.MethodInfo method;
                if (leftType.IsPrimitive || rightType.IsPrimitive)
                {
                    var initial = ReflectionUtils.FromSystemType(ref types);
                    method = ReflectionUtils.
                             GetOperatorOverload(opName, conversions, types);
                    conversions.SetInitial(initial);
                }
                else
                {
                    method = ReflectionUtils.
                             GetOperatorOverload(opName, conversions, types);
                }
                if (method is null)
                {
                    return(NullCompare(node, left, right));
                }
                node.Method      = method;
                node.Conversions = conversions;
                node.Type        = method.ReturnType;
            }
            // null method handled
            object[] args = new object[2] {
                left, right
            };
            node.Conversions.Invoke(ref args);
            return(node.Method.Invoke(null, args));
        }
Beispiel #17
0
        public static MethodInfo FindMethod(this System.Type type, string name, System.Type[] types, BindingFlags bindingAttr, out ArgumentConversions conversions)
        {
            conversions = new ArgumentConversions(types.Length);
            if (type.IsDefined(typeof(RegisterAttribute), false))
            {
                var methods = type.GetMethods(bindingAttr);
                for (int i = 0; i < methods.Length; i++)
                {
                    var m     = methods[i];
                    var attrs = (System.Attribute[])m.GetCustomAttributes(typeof(RegisterAttribute), false);
                    if (attrs.Length > 0 && attrs[0].Match(name) &&
                        m.MatchesArgumentTypes(types, conversions))
                    {
                        return(m);
                    }
                }
                return(null);
            }

            return(FindSystemMethod(type, name, types, bindingAttr, conversions));
        }
        private object VisitExponentiation(BinaryExpression node)
        {
            var left  = node.Left.Accept(this);
            var right = node.Right.Accept(this);

            if (left is null)
            {
                ExecutionException.ThrowNullError(node, node.Left);
            }
            if (right is null)
            {
                ExecutionException.ThrowNullError(node, node.Right);
            }
            object[] args = new object[2] {
                left, right
            };
            if (node.Method is null)
            {
                Type leftType    = left.GetType();
                Type rightType   = right.GetType();
                var  types       = new Type[] { leftType, rightType };
                var  conversions = new ArgumentConversions(2);
                if (leftType.IsPrimitive || rightType.IsPrimitive)
                {
                    conversions.SetInitial(ReflectionUtils.FromSystemType(ref types));
                }
                if (!ReflectionHelpers.MathPow.MatchesArgumentTypes(types, conversions))
                {
                    ExecutionException.ThrowArgumentMisMatch(node);
                }
                node.Conversions = conversions;
                node.Method      = ReflectionHelpers.MathPow;
                node.Type        = TypeProvider.DoubleType;
            }
            node.Conversions.Invoke(ref args);
            return(node.Method.Invoke(null, args));
        }
Beispiel #19
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());
        }
        public object VisitUnary(UnaryExpression node)
        {
            var value = node.Operand.Accept(this);

            if (node.NodeType == ExpressionType.Parenthesized)
            {
                node.Type = node.Operand.Type;
                return(value);
            }
            //modified a++; updated new value
            bool modified = false, updated = true;

            switch (node.NodeType)
            {
            case ExpressionType.PostfixPlusPlus:
                modified = true;
                updated  = false;
                break;

            case ExpressionType.PrefixPlusPlus:
                modified = true;
                break;

            case ExpressionType.PostfixMinusMinus:
                modified = true;
                updated  = false;
                break;

            case ExpressionType.PrefixMinusMinus:
                modified = true;
                break;

            case ExpressionType.Bang:
                // here value is null it is as not defined
                if (value is null)
                {
                    return(Boolean.True);
                }
                break;
            }
            if (value is null)
            {
                ExecutionException.ThrowNullError(node.Operand, node);
            }
            // no primitive supported it should be wrapped

            //resolve call
            if (node.Method is null)
            {
                Type type = node.Operand.Type;
                ArgumentConversions          conversions = new ArgumentConversions(1);
                System.Reflection.MethodInfo method;
                if (type.IsPrimitive)
                {
                    type   = TypeProvider.Find(Type.GetTypeCode(type));
                    method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, type);
                    conversions.AddFirst(new ParamConversion(0, ReflectionHelpers.ToAny));
                }
                else
                {
                    method = ReflectionUtils.GetOperatorOverload(node.MethodName, conversions, type);
                }
                if (method is null)
                {
                    ExecutionException.ThrowInvalidOp(node);
                }
                node.Conversions = conversions;
                node.Method      = method;
                node.Type        = method.ReturnType;
            }
            object[] args = new object[1] {
                value
            };
            node.Conversions.Invoke(ref args);
            object obj = node.Method.Invoke(null, args);

            if (modified)
            {
                if (node.Operand.NodeType == ExpressionType.Literal)
                {
                    ExecutionException.ThrowNotSupported(node);
                }
                var exp = new AssignmentExpression(node.Operand, new LiteralExpression(obj));
                exp.Accept(this);
            }
            return(updated ? obj : value);
        }
Beispiel #21
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));
 }
Beispiel #22
0
        static System.Reflection.MethodInfo VisitPow(BinaryExpression node, Expression left, Expression right, ArgumentConversions conversions)
        {
            var types = new Type[2] {
                left.Type, right.Type
            };

            System.Reflection.MethodInfo method = ReflectionHelpers.MathPow;
            if (left.Type.IsPrimitive || right.Type.IsPrimitive)
            {
                var initial = ReflectionUtils.FromSystemType(ref types);
                if (!method.MatchesArgumentTypes(types, conversions))
                {
                    ExecutionException.ThrowArgumentMisMatch(node);
                }
                conversions.SetInitial(initial);
                return(method);
            }
            if (!method.MatchesArgumentTypes(types, conversions))
            {
                ExecutionException.ThrowArgumentMisMatch(node);
            }
            return(method);
        }
Beispiel #23
0
        static System.Reflection.MethodInfo VisitBinary(Expression left, Expression right, string opName, ArgumentConversions conversions)
        {
            var types = new Type[2] {
                left.Type, right.Type
            };

            System.Reflection.MethodInfo methodInfo;
            if (left.Type.IsPrimitive || right.Type.IsPrimitive)
            {
                Conversion[] initial = ReflectionUtils.FromSystemType(ref types);
                methodInfo = ReflectionUtils.
                             GetOperatorOverload(opName, conversions, types);
                // add initial conversion
                conversions.SetInitial(initial);
            }
            else
            {
                methodInfo = ReflectionUtils.
                             GetOperatorOverload(opName, conversions, types);
            }
            return(methodInfo);
        }
Beispiel #24
0
        public static MethodInfo FindSystemMethod(this System.Type type, string name, System.Type[] types, BindingFlags bindingAttr, ArgumentConversions conversions)
        {
            var members = type.GetMember(name, MemberTypes.Method, bindingAttr);

            // start from last ex: in Console.Write(String) no match at the beginning
            for (int i = members.Length - 1; i >= 0; i--)
            {
                MethodInfo m = (MethodInfo)members[i];
                if (m.MatchesArgumentTypes(types, conversions))
                {
                    return(m);
                }
            }
            return(null);
        }