Ejemplo n.º 1
0
 private bool AreCompatible(Type paramType, Type argType)
 {
     if (paramType.GetTypeInfo().IsAssignableFrom(argType.GetTypeInfo()))
     {
         return(true);
     }
     else
     {
         return(PyNetConverter.CanConvert(argType, paramType));
     }
 }
Ejemplo n.º 2
0
        public object[] Inject(MethodBase methodBase, object[] args, object thisReference = null)
        {
            var methodParams = methodBase.GetParameters();

            // If there's a params field then we have to cram an array into there.
            bool hasParamsField    = methodParams.Length >= 1 && methodParams[methodParams.Length - 1].IsDefined(typeof(ParamArrayAttribute), false);
            bool isExtensionMethod = methodBase.IsExtensionMethod();

            // Transform all arguments except for any in the params field.
            object[] outParams;
            int      in_param_i   = 0; // Keep an eye on this for later to determine if we have stuff for a params field!
            int      out_param_i  = 0;
            int      methodInfo_i = 0;

            outParams = new object[methodParams.Length];

            // Extension method; there's the "this object" parameter in the first position that we need to insert.
            if (isExtensionMethod)
            {
                outParams[0] = thisReference;
                out_param_i  = 1;
                methodInfo_i = 1;
            }

            for (; out_param_i < (hasParamsField ? outParams.Length - 1 : outParams.Length); ++out_param_i, ++methodInfo_i)
            {
                var paramInfo = methodParams[methodInfo_i];
                if (paramInfo.ParameterType == typeof(IInterpreter))
                {
                    outParams[out_param_i] = Interpreter;
                }
                else if (paramInfo.ParameterType == typeof(FrameContext))
                {
                    outParams[out_param_i] = Context;
                }
                else if (paramInfo.ParameterType == typeof(IScheduler))
                {
                    outParams[out_param_i] = Scheduler;
                }
                else
                {
                    if (in_param_i < args.Length)
                    {
                        outParams[out_param_i] = PyNetConverter.Convert(args[in_param_i], paramInfo.ParameterType);
                        ++in_param_i;
                    }
                    else
                    {
                        // Might be an optional parameter. If so, we use the default:
                        if (paramInfo.HasDefaultValue)
                        {
                            outParams[out_param_i] = paramInfo.DefaultValue == null ? null : PyNetConverter.Convert(paramInfo.DefaultValue, paramInfo.ParameterType);
                        }
                        else
                        {
                            throw new ArgumentException("Not enough arguments for " + methodBase.Name + " to satisfy the call");
                        }
                    }
                }
            }

            // If there's a params field and we don't have enough stuff to fill it, then we need to
            // give it a null or else we'll run into a TargetParameterCountException
            // If we *can* fill it in, we need to convert to the params array type.
            //
            if (hasParamsField)
            {
                if (in_param_i >= args.Length)
                {
                    outParams[outParams.Length - 1] = null;
                }
                else
                {
                    var elementType = methodParams[methodParams.Length - 1].ParameterType.GetElementType();
                    var paramsArray = Array.CreateInstance(elementType, args.Length - in_param_i);
                    for (int i = 0; i < paramsArray.Length; ++i)
                    {
                        paramsArray.SetValue(PyNetConverter.Convert(args[in_param_i + i], elementType), i);
                    }

                    outParams[outParams.Length - 1] = paramsArray;
                }
            }

            return(outParams);
        }
Ejemplo n.º 3
0
        public object[] Inject(MethodBase methodBase, object[] args)
        {
            var methodParams = methodBase.GetParameters();

            // If there's a params field then we have to cram an array into there.
            bool hasParamsField = methodParams.Length >= 1 && methodParams[methodParams.Length - 1].IsDefined(typeof(ParamArrayAttribute), false);

            // Transform all arguments except for any in the params field.
            object[] outParams  = new object[methodParams.Length];
            int      in_param_i = 0; // Keep an eye on this for later to determine if we have stuff for a params field!

            for (int out_param_i = 0; out_param_i < (hasParamsField ? methodParams.Length - 1 : methodParams.Length); ++out_param_i)
            {
                var paramInfo = methodParams[out_param_i];
                if (paramInfo.ParameterType == typeof(IInterpreter))
                {
                    outParams[out_param_i] = Interpreter;
                }
                else if (paramInfo.ParameterType == typeof(FrameContext))
                {
                    outParams[out_param_i] = Context;
                }
                else if (paramInfo.ParameterType == typeof(IScheduler))
                {
                    outParams[out_param_i] = Scheduler;
                }
                else
                {
                    if (in_param_i >= args.Length)
                    {
                        // We have a missing parameter
                        if (paramInfo.HasDefaultValue)
                        {
                            // But it has a default
                            outParams[out_param_i] = paramInfo.DefaultValue == null ? null : PyNetConverter.Convert(paramInfo.DefaultValue, paramInfo.ParameterType);
                        }
                        else
                        {
                            throw new Exception("Missing parameter.");
                        }
                    }
                    else
                    {
                        outParams[out_param_i] = PyNetConverter.Convert(args[in_param_i], paramInfo.ParameterType);
                    }

                    ++in_param_i;
                }
            }

            // If there's a params field and we don't have enough stuff to fill it, then we need to
            // give it a null or else we'll run into a TargetParameterCountException
            // If we *can* fill it in, we need to convert to the params array type.
            //
            if (hasParamsField)
            {
                if (in_param_i >= args.Length)
                {
                    outParams[outParams.Length - 1] = null;
                }
                else
                {
                    var elementType = methodParams[methodParams.Length - 1].ParameterType.GetElementType();
                    var paramsArray = Array.CreateInstance(elementType, args.Length - in_param_i);
                    for (int i = 0; i < paramsArray.Length; ++i)
                    {
                        paramsArray.SetValue(PyNetConverter.Convert(args[in_param_i + i], elementType), i);
                    }

                    outParams[outParams.Length - 1] = paramsArray;
                }
            }

            return(outParams);
        }