Пример #1
0
 /// <summary>
 /// Performs an assignment variable = value
 /// </summary>
 public static BoundAssignment Assign(Variable variable, Expression value)
 {
     Contract.RequiresNotNull(variable, "variable");
     Contract.RequiresNotNull(value, "value");
     Contract.Requires(TypeUtils.CanAssign(variable.Type, value.Type));
     return(new BoundAssignment(variable, value));
 }
Пример #2
0
        private static void ValidateCallArguments(IList <ParameterInfo> parameters, IList <Expression> arguments)
        {
            Contract.Requires(parameters.Count == arguments.Count, "arguments", "Argument count must match parameter count");

            int count = parameters.Count;

            for (int index = 0; index < count; index++)
            {
                Type pt = parameters[index].ParameterType;
                Contract.Requires(!TypeUtils.IsGeneric(pt), "arguments");
                if (pt.IsByRef)
                {
                    pt = pt.GetElementType();
                }
                if (!TypeUtils.CanAssign(pt, arguments[index].Type))
                {
                    throw new ArgumentException(
                              String.Format(
                                  "Invalid type for argument {0}. Expected {1}, got {2}.",
                                  index, pt.Name, arguments[index].Type.Name
                                  ),
                              "arguments"
                              );
                }
            }
        }
Пример #3
0
 public static CatchBlock Catch(SourceSpan span, SourceLocation header, Type type, Variable target, Statement body)
 {
     Contract.RequiresNotNull(type, "type");
     Contract.Requires(target == null || TypeUtils.CanAssign(target.Type, type), "target");
     Contract.RequiresNotNull(body, "body");
     return(new CatchBlock(span, header, type, target, body));
 }
Пример #4
0
        public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments)
        {
            Contract.RequiresNotNull(method, "method");
            Contract.Requires(!method.IsGenericMethodDefinition, "method");
            Contract.Requires(!method.ContainsGenericParameters, "method");
            if (method.IsStatic)
            {
                Contract.Requires(instance == null, "instance", "Instance must be null for static method");
            }
            else
            {
                Contract.RequiresNotNull(instance, "instance");
                if (!TypeUtils.CanAssign(method.DeclaringType, instance.Type))
                {
                    throw new ArgumentException(
                              String.Format(
                                  "Invalid instance type for {0}.{1}. Expected {0}, got {2}.",
                                  method.DeclaringType.Name,
                                  method.Name,
                                  instance.Type.Name
                                  ),
                              "instance"
                              );
                }
            }

            Contract.RequiresNotNullItems(arguments, "arguments");
            ParameterInfo[] parameters = method.GetParameters();

            ValidateCallArguments(parameters, arguments);

            return(new MethodCallExpression(method, instance, CollectionUtils.ToReadOnlyCollection(arguments), parameters));
        }
Пример #5
0
        public static NewArrayExpression NewArrayHelper(Type type, IList <Expression> initializers)
        {
            Contract.RequiresNotNullItems(initializers, "initializers");
            Contract.RequiresNotNull(type, "type");
            Contract.Requires(type.IsArray, "type", "Not an array type");

            Type element = type.GetElementType();

            Expression[] clone = null;
            for (int i = 0; i < initializers.Count; i++)
            {
                Expression initializer = initializers[i];
                if (!TypeUtils.CanAssign(element, initializer.Type))
                {
                    if (clone == null)
                    {
                        clone = new Expression[initializers.Count];
                        for (int j = 0; j < i; j++)
                        {
                            clone[j] = initializers[j];
                        }
                    }
                    initializer = Ast.Convert(initializer, element);
                }
                if (clone != null)
                {
                    clone[i] = initializer;
                }
            }

            return(NewArray(type, clone ?? initializers));
        }
Пример #6
0
 internal static void CheckField(FieldInfo info, Expression instance, Expression rightValue)
 {
     Contract.RequiresNotNull(info, "field");
     Contract.Requires((instance == null) == info.IsStatic, "expression",
                       "Static field requires null expression, non-static field requires non-null expression.");
     Contract.Requires(instance == null || TypeUtils.CanAssign(info.DeclaringType, instance.Type), "expression", "Incorrect instance type for the property");
     Contract.Requires(rightValue == null || TypeUtils.CanAssign(info.FieldType, rightValue.Type), "value", "Incorrect value type for the field");
 }
Пример #7
0
        public static ScopeStatement Scope(SourceSpan span, Expression scope, Statement body)
        {
            Contract.RequiresNotNull(scope, "scope");
            Contract.RequiresNotNull(body, "body");
            Contract.Requires(TypeUtils.CanAssign(typeof(IAttributesCollection), scope.Type), "scope", "Scope must be IAttributesCollection");

            return(new ScopeStatement(span, scope, body));
        }
Пример #8
0
 public static ThrowStatement Throw(SourceSpan span, Expression value)
 {
     if (value != null)
     {
         Contract.Requires(TypeUtils.CanAssign(typeof(Exception), value.Type));
     }
     return(new ThrowStatement(span, value));
 }
Пример #9
0
        public static CodeBlock Generator(SourceSpan span, string name, Type generator, Type next)
        {
            Contract.RequiresNotNull(name, "name");
            Contract.RequiresNotNull(generator, "generator");
            Contract.RequiresNotNull(next, "next");
            Contract.Requires(TypeUtils.CanAssign(typeof(Generator), generator), "generator", "The generator type must inherit from Generator");

            return(new GeneratorCodeBlock(span, name, generator, next));
        }
Пример #10
0
        internal static void CheckProperty(PropertyInfo info, Expression instance, Expression rightValue)
        {
            Contract.RequiresNotNull(info, "property");
            MethodInfo mi = (rightValue != null) ? info.GetSetMethod() : info.GetGetMethod();

            Contract.Requires(mi != null, "Property is not readable");
            Contract.Requires((instance == null) == mi.IsStatic, "expression",
                              "Static property requires null expression, non-static property requires non-null expression.");
            Contract.Requires(instance == null || TypeUtils.CanAssign(info.DeclaringType, instance.Type), "expression", "Incorrect instance type for the property");
            Contract.Requires(rightValue == null || TypeUtils.CanAssign(info.PropertyType, rightValue.Type), "value", "Incorrect value type for the property");
        }
Пример #11
0
 public static ConstantExpression Constant(object value, Type type)
 {
     Contract.RequiresNotNull(type, "type");
     if (value == null)
     {
         Contract.Requires(!type.IsValueType, "type");
     }
     else
     {
         Contract.Requires(TypeUtils.CanAssign(type, value.GetType()), "type");
     }
     return(new ConstantExpression(value, type));
 }
Пример #12
0
        /// <summary>
        /// Creates a new array expression of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">The type of the array (e.g. object[]).</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        public static NewArrayExpression NewArray(Type type, IList <Expression> initializers)
        {
            Contract.RequiresNotNull(initializers, "initializers");
            Contract.RequiresNotNull(type, "type");
            Contract.Requires(type.IsArray, "type", "Not an array type");
            Contract.RequiresNotNullItems(initializers, "initializers");

            Type element = type.GetElementType();

            foreach (Expression expression in initializers)
            {
                Contract.Requires(TypeUtils.CanAssign(element, expression.Type), "initializers");
            }

            return(new NewArrayExpression(type, CollectionUtils.ToReadOnlyCollection(initializers)));
        }
Пример #13
0
        private static Expression CoalesceInternal(CodeBlock currentBlock, Expression left, Expression right, MethodInfo isTrue, bool isReverse)
        {
            Contract.RequiresNotNull(currentBlock, "currentBlock");
            Contract.RequiresNotNull(left, "left");
            Contract.RequiresNotNull(right, "right");

            // A bit too strict, but on a safe side.
            Contract.Requires(left.Type == right.Type, "Expression types must match");

            Variable tmp = currentBlock.CreateTemporaryVariable(SymbolTable.StringToId("tmp_left"), left.Type);

            Expression condition;

            if (isTrue != null)
            {
                Contract.Requires(isTrue.ReturnType == typeof(bool), "isTrue", "Predicate must return bool.");
                ParameterInfo[] parameters = isTrue.GetParameters();
                Contract.Requires(parameters.Length == 1, "isTrue", "Predicate must take one parameter.");
                Contract.Requires(isTrue.IsStatic && isTrue.IsPublic, "isTrue", "Predicate must be public and static.");

                Type pt = parameters[0].ParameterType;
                Contract.Requires(TypeUtils.CanAssign(pt, left.Type), "left", "Incorrect left expression type");
                condition = Call(isTrue, Assign(tmp, left));
            }
            else
            {
                Contract.Requires(TypeUtils.CanCompareToNull(left.Type), "left", "Incorrect left expression type");
                condition = Equal(Assign(tmp, left), Null(left.Type));
            }

            Expression t, f;

            if (isReverse)
            {
                t = Read(tmp);
                f = right;
            }
            else
            {
                t = right;
                f = Read(tmp);
            }

            return(Condition(condition, t, f));
        }
Пример #14
0
        private static Expression CoalesceInternal(Expression left, Expression right, MethodInfo isTrue, bool isReverse, out ParameterExpression temp)
        {
            ContractUtils.RequiresNotNull(left, "left");
            ContractUtils.RequiresNotNull(right, "right");

            // A bit too strict, but on a safe side.
            ContractUtils.Requires(left.Type == right.Type, "Expression types must match");

            temp = Expression.Variable(left.Type, "tmp_left");

            Expression condition;

            if (isTrue != null)
            {
                ContractUtils.Requires(isTrue.ReturnType == typeof(bool), "isTrue", "Predicate must return bool.");
                ParameterInfo[] parameters = isTrue.GetParameters();
                ContractUtils.Requires(parameters.Length == 1, "isTrue", "Predicate must take one parameter.");
                ContractUtils.Requires(isTrue.IsStatic && isTrue.IsPublic, "isTrue", "Predicate must be public and static.");

                Type pt = parameters[0].ParameterType;
                ContractUtils.Requires(TypeUtils.CanAssign(pt, left.Type), "left", "Incorrect left expression type");
                condition = Expression.Call(isTrue, Expression.Assign(temp, left));
            }
            else
            {
                ContractUtils.Requires(TypeUtils.CanCompareToNull(left.Type), "left", "Incorrect left expression type");
                condition = Expression.Equal(Expression.Assign(temp, left), AstUtils.Constant(null, left.Type));
            }

            Expression t, f;

            if (isReverse)
            {
                t = temp;
                f = right;
            }
            else
            {
                t = right;
                f = temp;
            }

            return(Expression.Condition(condition, t, f));
        }
Пример #15
0
 internal static Variable Create(SymbolId name, VariableKind kind, CodeBlock block, Type type, Expression defaultValue)
 {
     Contract.Requires(defaultValue == null || TypeUtils.CanAssign(type, defaultValue.Type));
     Contract.Requires(kind != VariableKind.Parameter, "kind");
     return(new Variable(name, kind, block, type, defaultValue));
 }