Пример #1
0
        /// <summary>Loads the MethodToCall value if it needs to.</summary>
        private void GetMethodInfo()
        {
            if (MethodToCall != null)
            {
                return;
            }
            if (Arguments != null)
            {
                for (int i = 0; i < Arguments.Length; i++)
                {
                    CompiledFragment p = Arguments[i];
                    p.OutputType(out p);
                    Arguments[i] = p;
                }
            }

            // Note: Most things go via a DynamicMethod here.
            // This is because CalledOn is mostly a PropertyOperation.
            // It's converted to a static singular MethodInfo with GetOverload below though.

            Type fragType          = CalledOn.OutputType(out CalledOn);
            PropertyOperation prop = CalledOn as PropertyOperation;

            if (prop != null && prop.MethodReturnType != null)
            {
                MethodToCall = prop.GetOverload(Arguments);
                if (MethodToCall == null)
                {
                    Error("Method " + prop.Name + " was not found.");
                }
                CalledOn = MethodToCall.IsStatic?null:prop.Of;
            }
            else
            {
                MethodToCall = Types.GetCallable(fragType);
            }

            if (MethodToCall == null)
            {
                Error("Unable to run '" + Name + "' as a method.");
            }
        }
Пример #2
0
        /// <summary>Loads the MethodToCall value if it needs to.</summary>
        private void GetMethodInfo()
        {
            if (MethodToCall != null)
            {
                return;
            }

            if (Arguments != null)
            {
                for (int i = 0; i < Arguments.Length; i++)
                {
                    CompiledFragment p = Arguments[i];
                    p.OutputType(out p);
                    Arguments[i] = p;
                }
            }

            // Note: Most things go via a DynamicMethod here.
            // This is because CalledOn is mostly a PropertyOperation.
            // It's converted to a static singular MethodInfo with GetOverload below though.

            CalledOn.OutputType(out CalledOn);

            PropertyOperation prop = CalledOn as PropertyOperation;

            if (prop != null && (prop.MethodReturnType != null || prop.Methods != null))
            {
                MethodToCall = prop.GetOverload(Arguments);

                if (MethodToCall == null)
                {
                    Error("Method " + prop.Name + " was not found.");
                }

                CalledOn = MethodToCall.IsStatic?null:prop.Of;

                if (prop.Methods != null)
                {
                    // Push the original called on into args set:
                    if (Arguments == null)
                    {
                        // Create empty set:
                        Arguments = new CompiledFragment[1];
                    }
                    else
                    {
                        // Create the new args set:
                        CompiledFragment[] args = new CompiledFragment[Arguments.Length + 1];

                        // Copy args into it:
                        Array.Copy(Arguments, 0, args, 1, Arguments.Length);

                        // Update it:
                        Arguments = args;
                    }

                    // First one (propertyOp always puts it in as arg 0, for get/set properties):
                    Arguments[0] = prop.Of;
                }
            }

            if (MethodToCall == null)
            {
                Error("Unable to run '" + Name + "' as a method.");
            }
        }
Пример #3
0
        /// <summary>Outputs the given argument set into the given IL stream.</summary>
        /// <param name="args">The compiled set of arguments to be outputted.</param>
        /// <param name="method">The method that they are being used in.</param>
        /// <param name="into">The IL stream to output the arguments into.</param>
        /// <param name="parameters">The parameter info used to correctly match the location of the parameters.</param>
        public static void OutputParameters(CompiledFragment[] args, CompiledMethod method, NitroIL into, ParameterInfo[] parameters)
        {
            int argID    = 0;
            int argCount = 0;

            if (args != null)
            {
                argCount = args.Length;
            }
            for (int paramID = 0; paramID < parameters.Length; paramID++)
            {
                ParameterInfo param     = parameters[paramID];
                Type          paramType = param.ParameterType;

                if (IsParams(param))
                {
                    // The rest are going into an array Operation.
                    // Get the type we want to cast them all to (because paramType at this stage must be an array):
                    paramType = paramType.GetElementType();

                    CompiledFragment[] ops = new CompiledFragment[argCount - argID];
                    int Index = 0;
                    for (int i = argID; i < argCount; i++)
                    {
                        CompiledFragment frag     = args[i];
                        Type             fragType = frag.OutputType(out frag);

                        if (fragType != paramType)
                        {
                            frag = TryCast(method, frag, paramType, fragType);

                            if (frag == null)
                            {
                                args[i].Error("Unable to box or cast " + fragType + " to " + paramType + " at parameter " + argID + ". Note that you can't null a value type.");
                            }
                        }
                        ops[Index++] = frag;
                    }
                    CompiledFragment arrayOp = new ArrayOperation(method, paramType, ops);
                    arrayOp.OutputType(out arrayOp);

                    arrayOp.OutputIL(into);
                    return;
                }

                CompiledFragment argFrag = args[argID++];
                Type             argType = argFrag.OutputType(out argFrag);

                if (argType != paramType)
                {
                    // Is the parameter a delegate?
                    if (typeof(Delegate).IsAssignableFrom(paramType) || typeof(MulticastDelegate).IsAssignableFrom(paramType))
                    {
                        // Get the method info - argFrag should be a PropertyOperation:
                        PropertyOperation propertyOp = (argFrag as PropertyOperation);

                        if (propertyOp == null || propertyOp.Method == null)
                        {
                            argFrag.Error("Unrecognised object being used where a method (to use as a delegate) was expected.");
                        }

                        // Get the required set of parameters for the delegate:
                        Type[] delegateTypes = SetToTypes(paramType.GetMethod("Invoke").GetParameters());

                        // Get the target method:
                        MethodInfo targetMethod = propertyOp.GetOverload(delegateTypes);

                        if (targetMethod == null)
                        {
                            argFrag.Error("Given method does not match delegate signature for " + paramType);
                        }

                        // Got a delegate. Delegate creation op:
                        argFrag = new DelegateOperation(method, targetMethod, paramType);
                    }
                    else
                    {
                        CompiledFragment originalFragment = argFrag;
                        argFrag = TryCast(method, argFrag, paramType, argType);

                        if (argFrag == null)
                        {
                            originalFragment.Error("Unable to box or cast " + argType + " to " + paramType + " at parameter " + argID + " of method call " + param.Member.Name + ". Note that you can't null a value type.");
                        }
                    }
                }

                argFrag.OutputIL(into);
            }
        }