Exemple #1
0
        /// <summary>Looks for the use of the given property within this operation. E.g. this.hello=this.hello+1;</summary>
        /// <param name="cfrag">The fragment to look in, e.g. this.Input1.</param>
        /// <param name="findingProp">The property being searched for.</param>
        /// <returns>True if it was found in there, false otherwise.</returns>
        public bool LookFor(CompiledFragment cfrag, PropertyOperation findingProp)
        {
            if (cfrag == null)
            {
                return(false);
            }

            // Try as operation:
            Operation op = cfrag as Operation;

            if (op != null)
            {
                // Specifically a property operation?
                PropertyOperation prop = op as PropertyOperation;

                if (prop != null && prop.Equals(findingProp))
                {
                    // Got a match!
                    return(true);
                }

                if (LookFor(op.Input0, findingProp))
                {
                    return(true);
                }

                if (LookFor(op.Input1, findingProp))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #2
0
        /// <summary>Is the object in I0 mentioned anywhere in I1? Used to distinguish incrementals from straight sets.</summary>
        /// <returns>True if it is, false otherwise.</returns>
        public bool SelfReferencing()
        {
            if (Input1 == null || Input0 == null)
            {
                return(false);
            }

            // Try getting it as a variable:
            Variable variable = Input0.Value as Variable;

            if (variable != null)
            {
                // Great it's a variable!
                return(LookFor(Input1, variable));
            }
            else
            {
                // Try as a property instead.
                PropertyOperation property = Input0 as PropertyOperation;

                if (property != null)
                {
                    // it's a property - try searching that instead!
                    return(LookFor(Input1, property));
                }
            }

            return(false);
        }
Exemple #3
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.");
            }
        }
        /// <summary>Does this property operation equal the given one? Compares value names.</summary>
        public bool Equals(PropertyOperation prop)
        {
            if (Name == prop.Name)
            {
                // So far so good! Match for Of's too?
                if (Of == null && prop.Of == null)
                {
                    return(true);
                }

                if (Of != null && prop.Of != null)
                {
                    // Compare those:
                    if (Of.GetType() == prop.Of.GetType())
                    {
                        return(Of.ToString() == prop.Of.ToString());
                    }
                }
            }

            return(false);
        }
        /// <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.");
            }
        }
Exemple #6
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);
            }
        }