static bool ParamArrayMatchs(object[] args, int index, Type dest, ArgumentConversions conversions)
        {
            var argConversions = new ArgumentConversions(args.Length - index);

            // check first parameter type matches
            for (int i = 0, current = index; current < args.Length; i++, current++)
            {
                var arg = args[current];
                if (arg is null)
                {
                    if (dest.IsValueType && !IsNullableType(dest))
                    {
                        return(false);
                    }
                }
                else
                {
                    var src = arg.GetType();
                    if (!TypeUtils.AreReferenceAssignable(dest, src))
                    {
                        if (TryImplicitConvert(src, dest, out MethodInfo opImplict) == false)
                        {
                            return(false);
                        }
                        argConversions.Add(new ParamConversion(i, opImplict));
                    }
                }
            }
            conversions.Add(new ParamArrayConversion(index, dest, argConversions));
            return(true);
        }
 public static MethodInfo FindSetIndexer(this Type type, object[] 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 (MatchesArguments(m, 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 (MatchesArguments(m, args, conversions))
                 {
                     return(m);
                 }
             }
         }
     }
     return(null);
 }
 public static bool TryFindMethod(this Type type, string name, object[] args, out MethodInfo method, out ArgumentConversions conversions)
 {
     conversions = new ArgumentConversions(args.Length);
     return(type.IsInterface
         ? TryFindInterfaceMethod(type, name, args, out method, conversions)
         : type.IsDefined(typeof(RegisterAttribute), false)
         ? FindMethods(type, name, TypeUtils.AnyPublic, args, out method, conversions)
         : TryFindSystemMethod(name, type, TypeUtils.AnyPublic, args, out method, conversions));
 }
        Any IDynamicInvocable.Invoke(string name, params Any[] args)
        {
            var actualArgs = Any.GetArgs(args);
            var i          = FindEntry(name);

            if (i >= 0 && entries[i].Value is System.Delegate del)
            {
                var conversions = new ArgumentConversions(args.Length);
                var method      = del.GetType().GetMethod(nameof(System.Action.Invoke));
                if (method.MatchesArguments(actualArgs, conversions))
                {
                    return(Any.op_Implicit(del.DynamicInvoke(actualArgs)));
                }
            }
            return(default(Any));
        }
Example #5
0
 public MethodInvoker(object target, MethodInfo method, ArgumentConversions conversions)
 {
     Target      = target;
     Method      = method;
     Conversions = conversions;
 }
Example #6
0
 public ParamArrayConversion(int index, Type type, ArgumentConversions conversions) : base(index)
 {
     Type        = type;
     Conversions = conversions;
 }
        public static bool MatchesArguments(this MethodBase method, object[] args, ArgumentConversions conversions)
        {
            var parameters = method.GetParameters();
            // arg length
            var length = args.Length;
            // no arg
            int argCount = parameters.Length;

            if (argCount == 0 && length > 0)
            {
                return(false);
            }
            int i;

            for (i = 0; i < argCount; 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 (argCount > length)
                    {
                        conversions.Add(new ParamArrayConversion(i, dest.GetElementType()));
                        return(true);
                    }
                    //No further check required if matchs
                    return(ParamArrayMatchs(args, i, dest.GetElementType(), conversions));
                }
                // matches current index
                if (i >= length)
                {
                    // method has one more parameter so skip
                    return(conversions.Recycle());
                }

                var arg = args[i];
                if (arg is null)
                {
                    if (dest.IsValueType && !IsNullableType(dest))
                    {
                        return(conversions.Recycle());
                    }
                }
                else
                {
                    var src = arg.GetType();
                    if (!TypeUtils.AreReferenceAssignable(dest, src))
                    {
                        if (TryImplicitConvert(src, dest, out MethodInfo opImplict) == false)
                        {
                            return(conversions.Recycle());
                        }
                        conversions.Add(new ParamConversion(i, opImplict));
                    }
                }
            }
            if (i == length)
            {
                return(true);
            }
            return(conversions.Recycle());
        }
        /// Current Declared Indexer can get
        public static MethodInfo FindSetIndexer(this Type type, object[] indices, object value, out ArgumentConversions conversions, out object[] args)
        {
            int length = indices.Length;

            args = new object[length + 1];
            indices.CopyTo(args, 0);
            args[length] = value;
            return(FindSetIndexer(type, args, out conversions));
        }
        private static bool TryFindSystemMethod(string name, Type type, BindingFlags flags, object[] args, out MethodInfo method, ArgumentConversions conversions)
        {
            if (type != null)
            {
                foreach (MethodInfo m in type.GetMethods(flags))
                {
                    if (m.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && MatchesArguments(m, args, conversions))
                    {
                        method = m;
                        return(true);
                    }
                }
            }

            method = null;
            return(false);
        }
        static bool TryFindInterfaceMethod(this Type type, string name, object[] args, out MethodInfo method, ArgumentConversions conversions)
        {
            if (TryFindSystemMethod(name, type, TypeUtils.PublicInstance, args, out method, conversions))
            {
                return(true);
            }
            var types = type.GetInterfaces();

            for (int i = 0; i < types.Length; i++)
            {
                type = types[i];
                if (TryFindSystemMethod(name, type, TypeUtils.PublicInstance, args, out method, conversions))
                {
                    return(true);
                }
            }
            return(false);
        }
 static bool FindMethods(this Type type, string name, BindingFlags flags, object[] args, out MethodInfo method, ArgumentConversions conversions)
 {
     if (type != null)
     {
         var methods = type.GetMethods(flags);
         for (int i = 0; i < methods.Length; i++)
         {
             var m     = methods[i];
             var attrs = (RegisterAttribute[])m.GetCustomAttributes(typeof(RegisterAttribute), false);
             if (attrs.Length > 0 && attrs[0].Match(name) &&
                 MatchesArguments(m, args, conversions))
             {
                 method = m;
                 return(true);
             }
         }
         return(FindMethods(type.BaseType, name, TypeUtils.PublicStatic, args, out method, conversions));
     }
     method = null;
     return(false);
 }