예제 #1
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);
                            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)
                {
                    CompiledFragment originalFragment = argFrag;
                    argFrag = TryCast(method, argFrag, paramType);
                    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);
            }
        }
예제 #2
0
        /// <summary>Gets the ToString method of the given type, being called on the given fragment.</summary>
        /// <param name="method">The function this operation is occuring in.</param>
        /// <param name="frag">The object that the ToString method is being called on.</param>
        /// <param name="type">The type that fragment contains and the one that the ToString operation must be found on.</param>
        /// <returns>A methodOperation representing the ToString call. Throws an error if frag is null.</returns>
        public static MethodOperation ToStringMethod(CompiledMethod method, CompiledFragment frag, Type type)
        {
            if (type == null)
            {
                frag.Error("Unable to convert null to a string.");
            }
            MethodOperation mo = new MethodOperation(method, type.GetMethod("ToString", new Type[0]));

            mo.CalledOn         = frag;
            frag.ParentFragment = mo;
            return(mo);
        }
예제 #3
0
		/// <summary>Gets the ToString method of the given type, being called on the given fragment.</summary>
		/// <param name="method">The function this operation is occuring in.</param>
		/// <param name="frag">The object that the ToString method is being called on.</param>
		/// <param name="type">The type that fragment contains and the one that the ToString operation must be found on.</param>
		/// <returns>A methodOperation representing the ToString call. Throws an error if frag is null.</returns>
		public static MethodOperation ToStringMethod(CompiledMethod method,CompiledFragment frag,Type type){
			if(type==null){
				frag.Error("Unable to convert null to a string.");
			}
			MethodOperation mo=new MethodOperation(method,type.GetMethod("ToString",new Type[0]));
			mo.CalledOn=frag;
			frag.ParentFragment=mo;
			return mo;
		}
예제 #4
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);
            }
        }