private static Expression ValidateOneArgument(ParameterInfo parameter, Expression expression)
        {
            RequiresCanRead(expression, nameof(expression));

            var pType = parameter.ParameterType;

            // NB: No writeability check is performed; LINQ doesn't either, so you can pass e.g.
            //     a constant by ref, causing the write-back to be discarded. We're just being
            //     consistent here.
            if (pType.IsByRef)
            {
                pType = pType.GetElementType();
            }

            TypeUtils.ValidateType(pType);

            if (!TypeUtils.AreReferenceAssignable(pType, expression.Type))
            {
                if (!TryQuote(pType, ref expression))
                {
                    throw Error.ExpressionTypeDoesNotMatchParameter(expression.Type, pType);
                }
            }

            return(expression);
        }
Example #2
0
        private static BlockExpression BlockCore(Type type, ReadOnlyCollection <ParameterExpression> variableList, ReadOnlyCollection <Expression> expressionList)
        {
            ContractUtils.RequiresNotEmpty(expressionList, "expressions");
            RequiresCanRead(expressionList, "expressions");
            ValidateVariables(variableList, "variables");

            Expression last = expressionList.Last();

            if (type != typeof(void))
            {
                if (!TypeUtils.AreReferenceAssignable(type, last.Type))
                {
                    throw Error.ArgumentTypesMustMatch();
                }
            }

            if (!TypeUtils.AreEquivalent(type, last.Type))
            {
                return(new ScopeWithType(variableList, expressionList, type));
            }
            else
            {
                if (expressionList.Count == 1)
                {
                    return(new Scope1(variableList, expressionList[0]));
                }
                else
                {
                    return(new ScopeN(variableList, expressionList));
                }
            }
        }
Example #3
0
        private void EmitBinaryMethod(BinaryExpression b, CompilationFlags flags)
        {
            if (b.IsLifted)
            {
                ParameterExpression  p1 = Expression.Variable(b.Left.Type.GetNonNullableType(), name: null);
                ParameterExpression  p2 = Expression.Variable(b.Right.Type.GetNonNullableType(), name: null);
                MethodCallExpression mc = Expression.Call(null, b.Method, p1, p2);
                Type resultType;
                if (b.IsLiftedToNull)
                {
                    resultType = mc.Type.GetNullableType();
                }
                else
                {
                    Debug.Assert(mc.Type == typeof(bool));
                    Debug.Assert(b.NodeType == ExpressionType.Equal ||
                                 b.NodeType == ExpressionType.NotEqual ||
                                 b.NodeType == ExpressionType.LessThan ||
                                 b.NodeType == ExpressionType.LessThanOrEqual ||
                                 b.NodeType == ExpressionType.GreaterThan ||
                                 b.NodeType == ExpressionType.GreaterThanOrEqual);

                    resultType = typeof(bool);
                }

                Debug.Assert(TypeUtils.AreReferenceAssignable(p1.Type, b.Left.Type.GetNonNullableType()));
                Debug.Assert(TypeUtils.AreReferenceAssignable(p2.Type, b.Right.Type.GetNonNullableType()));
                EmitLift(b.NodeType, resultType, mc, new[] { p1, p2 }, new[] { b.Left, b.Right });
            }
            else
            {
                EmitMethodCallExpression(Expression.Call(null, b.Method, b.Left, b.Right), flags);
            }
        }
Example #4
0
        internal ComInvokeBinder(
            CallInfo callInfo,
            DynamicMetaObject[] args,
            bool[] isByRef,
            BindingRestrictions restrictions,
            Expression method,
            Expression dispatch,
            ComMethodDesc methodDesc
            )
        {
            Debug.Assert(callInfo != null, "arguments");
            Debug.Assert(args != null, "args");
            Debug.Assert(isByRef != null, "isByRef");
            Debug.Assert(method != null, "method");
            Debug.Assert(dispatch != null, "dispatch");

            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(ComMethodDesc), method.Type), "method");
            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(IDispatch), dispatch.Type), "dispatch");

            _method     = method;
            _dispatch   = dispatch;
            _methodDesc = methodDesc;

            _callInfo     = callInfo;
            _args         = args;
            _isByRef      = isByRef;
            _restrictions = restrictions;

            // Set Instance to some value so that CallBinderHelper has the right number of parameters to work with
            _instance = dispatch;
        }
Example #5
0
        public static MemberExpression Field(Expression expression, FieldInfo field)
        {
            ContractUtils.RequiresNotNull(field, "field");

            if (field.IsStatic)
            {
                if (expression != null)
                {
                    throw new ArgumentException(Strings.OnlyStaticFieldsHaveNullInstance, "expression");
                }
            }
            else
            {
                if (expression == null)
                {
                    throw new ArgumentException(Strings.OnlyStaticFieldsHaveNullInstance, "field");
                }
                RequiresCanRead(expression, "expression");
                if (!TypeUtils.AreReferenceAssignable(field.DeclaringType, expression.Type))
                {
                    throw Error.FieldInfoNotDefinedForType(field.DeclaringType, field.Name, expression.Type);
                }
            }
            return(MemberExpression.Make(expression, field));
        }
        /// <inheritdoc/>
        public override void GenerateCode(Emit.MethodBodyGenerator generator, Emit.MethodCompileOption options)
        {
            Type = VariableType != null?VariableType.ResolveType(generator.Context) : TypeProvider.AnyType;

            if (Value != null)
            {
                var defValue = Value.Accept(generator);
                defValue.GenerateCode(generator, AssignOption);
                if (VariableType == null)
                {
                    Type = defValue.Type;
                }
                else if (!TypeUtils.AreReferenceAssignable(Type, defValue.Type) && defValue.Type.TryImplicitConvert(Type, out System.Reflection.MethodInfo opConvert))
                {
                    // When converting value type to Any, must do Box
                    if (defValue.Type.IsValueType && opConvert.GetParameters()[0].ParameterType.IsValueType == false)
                    {
                        generator.Box(defValue.Type);
                    }
                    generator.CallStatic(opConvert);
                }
                else if (defValue.Type.IsValueType && !Type.IsValueType)
                {
                    generator.Box(defValue.Type);
                }
            }
            //initialize
            var variable = generator.DeclareVariable(Type, Name);

            generator.StoreVariable(variable);
            return;
        }
Example #7
0
 private static Expression Convert(Expression arg, Type type)
 {
     if (TypeUtils.AreReferenceAssignable(type, arg.Type))
     {
         return(arg);
     }
     return(Expression.Convert(arg, type));
 }
Example #8
0
        private static void ValidateAccessorArgumentTypes(MethodInfo method, ParameterInfo[] indexes, ref ReadOnlyCollection <Expression> arguments)
        {
            if (indexes.Length > 0)
            {
                if (indexes.Length != arguments.Count)
                {
                    throw Error.IncorrectNumberOfMethodCallArguments(method);
                }
                Expression[] newArgs = null;
                for (int i = 0, n = indexes.Length; i < n; i++)
                {
                    Expression    arg = arguments[i];
                    ParameterInfo pi  = indexes[i];
                    RequiresCanRead(arg, "arguments");

                    Type pType = pi.ParameterType;
                    if (pType.IsByRef)
                    {
                        throw Error.AccessorsCannotHaveByRefArgs();
                    }
                    TypeUtils.ValidateType(pType);

                    if (!TypeUtils.AreReferenceAssignable(pType, arg.Type))
                    {
                        if (TypeUtils.IsSameOrSubclass(typeof(LambdaExpression), pType) && pType.IsAssignableFrom(arg.GetType()))
                        {
                            arg = Expression.Quote(arg);
                        }
                        else
                        {
                            throw Error.ExpressionTypeDoesNotMatchMethodParameter(arg.Type, pType, method);
                        }
                    }
                    if (newArgs == null && arg != arguments[i])
                    {
                        newArgs = new Expression[arguments.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newArgs[j] = arguments[j];
                        }
                    }
                    if (newArgs != null)
                    {
                        newArgs[i] = arg;
                    }
                }
                if (newArgs != null)
                {
                    arguments = new TrueReadOnlyCollection <Expression>(newArgs);
                }
            }
            else if (arguments.Count > 0)
            {
                throw Error.IncorrectNumberOfMethodCallArguments(method);
            }
        }
        internal Expression ReduceTypeEqual()
        {
            Type cType = Expression.Type;

            // For value types (including Void, but not nullables), we can
            // determine the result now
            if (cType.GetTypeInfo().IsValueType&& !cType.IsNullableType())
            {
                return(Expression.Block(Expression, Expression.Constant(cType == _typeOperand.GetNonNullableType())));
            }

            // Can check the value right now for constants.
            if (Expression.NodeType == ExpressionType.Constant)
            {
                return(ReduceConstantTypeEqual());
            }

            // If the expression type is a sealed reference type or a nullable
            // type, it will match if the value is not null and the type operand
            // either matches or one is a nullable type while the other is its
            // type argument (T to the other's T?).
            if (cType.GetTypeInfo().IsSealed)
            {
                if (cType.GetNonNullableType() != _typeOperand.GetNonNullableType())
                {
                    return(Expression.Block(Expression, Expression.Constant(false)));
                }
                else if (cType.IsNullableType())
                {
                    return(Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
                else
                {
                    return(Expression.ReferenceNotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
            }

            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(object), Expression.Type), "Expecting reference types only after this point.");

            // expression is a ByVal parameter. Can safely reevaluate.
            var parameter = Expression as ParameterExpression;

            if (parameter != null && !parameter.IsByRef)
            {
                return(ByValParameterTypeEqual(parameter));
            }

            // Create a temp so we only evaluate the left side once
            parameter = Expression.Parameter(typeof(object));

            return(Expression.Block(
                       new[] { parameter },
                       Expression.Assign(parameter, Expression),
                       ByValParameterTypeEqual(parameter)
                       ));
        }
Example #10
0
        internal Expression ReduceTypeEqual()
        {
            Type cType = Expression.Type;

            // For value types (including Void, but not nullables), we can
            // determine the result now
            if (cType.IsValueType && !cType.IsNullableType())
            {
                return(Expression.Block(Expression, Expression.Constant(cType == _typeOperand.GetNonNullableType())));
            }

            // Can check the value right now for constants.
            if (Expression.NodeType == ExpressionType.Constant)
            {
                return(ReduceConstantTypeEqual());
            }

            // If the operand type is a sealed reference type or a nullable
            // type, it will match if value is not null
            if (cType.IsSealed && (cType == _typeOperand))
            {
                if (cType.IsNullableType())
                {
                    return(Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
                else
                {
                    return(Expression.ReferenceNotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
            }

            // expression is a ByVal parameter. Can safely reevaluate.
            var parameter = Expression as ParameterExpression;

            if (parameter != null && !parameter.IsByRef)
            {
                return(ByValParameterTypeEqual(parameter));
            }

            // Create a temp so we only evaluate the left side once
            parameter = Expression.Parameter(typeof(object));

            // Convert to object if necessary
            var expression = Expression;

            if (!TypeUtils.AreReferenceAssignable(typeof(object), expression.Type))
            {
                expression = Expression.Convert(expression, typeof(object));
            }

            return(Expression.Block(
                       new[] { parameter },
                       Expression.Assign(parameter, expression),
                       ByValParameterTypeEqual(parameter)
                       ));
        }
        private void EmitExpressionAddress(Expression node, Type type)
        {
            Debug.Assert(TypeUtils.AreReferenceAssignable(type, node.Type));

            EmitExpression(node, CompilationFlags.EmitAsNoTail | CompilationFlags.EmitNoExpressionStart);
            LocalBuilder tmp = GetLocal(type);

            _ilg.Emit(OpCodes.Stloc, tmp);
            _ilg.Emit(OpCodes.Ldloca, tmp);
        }
        internal Expression ReduceTypeEqual()
        {
            Type cType = Expression.Type;

            if (cType.IsValueType || TypeOperand.IsPointer)
            {
                if (cType.IsNullableType())
                {
                    // If the expression type is a nullable type, it will match if
                    // the value is not null and the type operand
                    // either matches or is its type argument (T to its T?).
                    if (cType.GetNonNullableType() != TypeOperand.GetNonNullableType())
                    {
                        return(Expression.Block(Expression, Utils.Constant(value: false)));
                    }
                    else
                    {
                        return(Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)));
                    }
                }
                else
                {
                    // For other value types (including Void), we can
                    // determine the result now
                    return(Expression.Block(Expression, Utils.Constant(cType == TypeOperand.GetNonNullableType())));
                }
            }

            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(object), Expression.Type), "Expecting reference types only after this point.");

            // Can check the value right now for constants.
            if (Expression.NodeType == ExpressionType.Constant)
            {
                return(ReduceConstantTypeEqual());
            }

            // expression is a ByVal parameter. Can safely reevaluate.
            var parameter = Expression as ParameterExpression;

            if (parameter != null && !parameter.IsByRef)
            {
                return(ByValParameterTypeEqual(parameter));
            }

            // Create a temp so we only evaluate the left side once
            parameter = Expression.Parameter(typeof(object));

            return(Expression.Block(
                       new TrueReadOnlyCollection <ParameterExpression>(parameter),
                       new TrueReadOnlyCollection <Expression>(
                           Expression.Assign(parameter, Expression),
                           ByValParameterTypeEqual(parameter)
                           )
                       ));
        }
Example #13
0
        private void EmitSwitchExpression(Expression expr, CompilationFlags flags)
        {
            SwitchExpression node = (SwitchExpression)expr;

            // Try to emit it as an IL switch. Works for integer types.
            if (TryEmitSwitchInstruction(node, flags))
            {
                return;
            }

            // Try to emit as a hashtable lookup. Works for strings.
            if (TryEmitHashtableSwitch(node, flags))
            {
                return;
            }

            //
            // Fall back to a series of tests. We need to IL gen instead of
            // transform the tree to avoid stack overflow on a big switch.
            //

            var switchValue = Expression.Parameter(node.SwitchValue.Type, "switchValue");
            var testValue   = Expression.Parameter(GetTestValueType(node), "testValue");

            _scope.AddLocal(this, switchValue);
            _scope.AddLocal(this, testValue);

            EmitExpression(node.SwitchValue);
            _scope.EmitSet(switchValue);

            // Emit tests
            var labels = new Label[node.Cases.Count];
            var isGoto = new bool[node.Cases.Count];

            for (int i = 0, n = node.Cases.Count; i < n; i++)
            {
                DefineSwitchCaseLabel(node.Cases[i], out labels[i], out isGoto[i]);
                foreach (Expression test in node.Cases[i].TestValues)
                {
                    // Pull the test out into a temp so it runs on the same
                    // stack as the switch. This simplifies spilling.
                    EmitExpression(test);
                    _scope.EmitSet(testValue);
                    Debug.Assert(TypeUtils.AreReferenceAssignable(testValue.Type, test.Type));
                    EmitExpressionAndBranch(true, Expression.Equal(switchValue, testValue, false, node.Comparison), labels[i]);
                }
            }

            // Define labels
            Label end      = _ilg.DefineLabel();
            Label @default = (node.DefaultBody == null) ? end : _ilg.DefineLabel();

            // Emit the case and default bodies
            EmitSwitchCases(node, labels, isGoto, @default, end, flags);
        }
Example #14
0
        /// <summary>
        /// Creates a <see cref="NewArrayExpression"/> of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>A <see cref="NewArrayExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.NewArrayInit"/> and the <see cref="NewArrayExpression.Expressions"/> property set to the specified value.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(initializers, nameof(initializers));
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }

            TypeUtils.ValidateType(type, nameof(type));
            if (type.IsByRef)
            {
                throw Error.TypeMustNotBeByRef(nameof(type));
            }

            if (type.IsPointer)
            {
                throw Error.TypeMustNotBePointer(nameof(type));
            }

            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                Expression expr = initializerList[i];
                RequiresCanRead(expr, nameof(initializers), i);

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (!TryQuote(type, ref expr))
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
        private void EmitExpressionAddress(Expression node, Type type)
        {
            Debug.Assert(TypeUtils.AreReferenceAssignable(type, node.Type));

            EmitExpression(node, false);
            LocalBuilder tmp = _ilg.GetLocal(type);

            _ilg.Emit(OpCodes.Stloc, tmp);
            _ilg.Emit(OpCodes.Ldloca, tmp);
            _ilg.FreeLocal(tmp);
        }
Example #16
0
        /// <summary>
        /// Reduces this node to a simpler expression. If CanReduce returns
        /// true, this should return a valid expression. This method is
        /// allowed to return another node which itself must be reduced.
        ///
        /// Unlike Reduce, this method checks that the reduced node satisfies
        /// certain invaraints.
        /// </summary>
        /// <returns>the reduced expression</returns>
        public Expression ReduceAndCheck()
        {
            ContractUtils.Requires(CanReduce, "this", Strings.MustBeReducible);

            var newNode = Reduce();

            // 1. Reduction must return a new, non-null node
            // 2. Reduction must return a new node whose result type can be assigned to the type of the original node
            ContractUtils.Requires(newNode != null && newNode != this, "this", Strings.MustReduceToDifferent);
            ContractUtils.Requires(TypeUtils.AreReferenceAssignable(Type, newNode.Type), "this", Strings.ReducedNotCompatible);
            return(newNode);
        }
 // For optimized Equal/NotEqual, we can eliminate reference
 // conversions. IL allows comparing managed pointers regardless of
 // type. See ECMA-335 "Binary Comparison or Branch Operations", in
 // Partition III, Section 1.5 Table 4.
 private static Expression GetEqualityOperand(Expression expression)
 {
     if (expression.NodeType == ExpressionType.Convert)
     {
         var convert = (UnaryExpression)expression;
         if (TypeUtils.AreReferenceAssignable(convert.Type, convert.Operand.Type))
         {
             return(convert.Operand);
         }
     }
     return(expression);
 }
Example #18
0
        private Expression ReduceStaticAssign(Expression lhs)
        {
            lhs = MakeWriteable(lhs);
            var rhs = Right.Expression;

            if (!TypeUtils.AreReferenceAssignable(lhs.Type, rhs.Type))
            {
                rhs = DynamicConvert(rhs, lhs.Type, CSharpBinderFlags.None, Context);
            }

            return(Expression.Assign(lhs, rhs));
        }
        private static void ValidateAccessorArgumentTypes(MethodInfo method, ParameterInfo[] indexes, ref ReadOnlyCollection <Expression> arguments, string?paramName)
        {
            if (indexes.Length > 0)
            {
                if (indexes.Length != arguments.Count)
                {
                    throw Error.IncorrectNumberOfMethodCallArguments(method, paramName);
                }
                Expression[]? newArgs = null;
                for (int i = 0, n = indexes.Length; i < n; i++)
                {
                    Expression    arg = arguments[i];
                    ParameterInfo pi  = indexes[i];
                    ExpressionUtils.RequiresCanRead(arg, nameof(arguments), i);

                    Type pType = pi.ParameterType;
                    if (pType.IsByRef)
                    {
                        throw Error.AccessorsCannotHaveByRefArgs(nameof(indexes), i);
                    }
                    TypeUtils.ValidateType(pType, nameof(indexes), i);

                    if (!TypeUtils.AreReferenceAssignable(pType, arg.Type))
                    {
                        if (!TryQuote(pType, ref arg))
                        {
                            throw Error.ExpressionTypeDoesNotMatchMethodParameter(arg.Type, pType, method, nameof(arguments), i);
                        }
                    }
                    if (newArgs == null && arg != arguments[i])
                    {
                        newArgs = new Expression[arguments.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newArgs[j] = arguments[j];
                        }
                    }
                    if (newArgs != null)
                    {
                        newArgs[i] = arg;
                    }
                }
                if (newArgs != null)
                {
                    arguments = new TrueReadOnlyCollection <Expression>(newArgs);
                }
            }
            else if (arguments.Count > 0)
            {
                throw Error.IncorrectNumberOfMethodCallArguments(method, paramName);
            }
        }
Example #20
0
        public static MethodInfo GetImplicitConversion(this System.Type type, string name, System.Type returnType, params System.Type[] parameterTypes)
        {
            var results = type.GetMember(name, MemberTypes.Method, DeclaredStatic);

            foreach (MethodInfo method in results)
            {
                if (method.MatchesArgumentTypes(parameterTypes) && TypeUtils.AreReferenceAssignable(method.ReturnType, returnType))
                {
                    return(method);
                }
            }
            throw new System.InvalidOperationException(string.Format("the convertion method {0}.{1}({2})", type.FullName, name, StringHelpers.Join(Separator, parameterTypes)));
        }
Example #21
0
        public static bool MatchesArgumentTypes(this MethodBase method, Type[] types)
        {
            var parameters = method.GetParameters();
            var length     = types.Length;

            if (parameters.Length < length)
            {
                return(false);
            }
            int i;

            for (i = 0; i < parameters.Length; i++)
            {
                var param = parameters[i];
                var dest  = param.ParameterType;
                if (param.IsDefined(typeof(ParamArrayAttribute), false))
                {
                    // parameters is extra example print(string, params string[] args) and print('hello')
                    // in this case 2 and 1
                    if (parameters.Length > length)
                    {
                        return(true);
                    }
                    //No further check required if matchs
                    return(ParamArrayMatchs(types, i, dest.GetElementType()));
                }
                // matches current index
                if (i >= length)
                {
                    return(false);
                }
                var src = types[i];
                if (src is null)
                {
                    if (dest.IsValueType && !dest.IsNullableType())
                    {
                        return(false);
                    }
                }
                else if (!TypeUtils.AreReferenceAssignable(dest, src))
                {
                    return(false);
                }
            }
            if (i == length)
            {
                return(true);
            }
            return(false);
        }
Example #22
0
 // Standard argument validation, taken from ValidateArgumentTypes
 private static void ValidateGotoType(Type expectedType, ref Expression value, string paramName)
 {
     RequiresCanRead(value, paramName);
     if (!TypeUtils.AreReferenceAssignable(expectedType, value.Type))
     {
         // C# autoquotes return values, so we'll do that here
         if (TypeUtils.IsSameOrSubclass(typeof(Expression), expectedType) &&
             expectedType.IsAssignableFrom(value.GetType()))
         {
             value = Expression.Quote(value);
         }
         throw Error.ExpressionTypeDoesNotMatchLabel(value.Type, expectedType);
     }
 }
Example #23
0
 // Standard argument validation, taken from ValidateArgumentTypes
 private static void ValidateGotoType(Type expectedType, ref Expression value, string paramName)
 {
     ExpressionUtils.RequiresCanRead(value, paramName);
     if (expectedType != typeof(void))
     {
         if (!TypeUtils.AreReferenceAssignable(expectedType, value.Type))
         {
             // C# auto-quotes return values, so we'll do that here
             if (!TryQuote(expectedType, ref value))
             {
                 throw Error.ExpressionTypeDoesNotMatchLabel(value.Type, expectedType);
             }
         }
     }
 }
Example #24
0
        public static UnaryExpression Throw(Expression value, Type type)
        {
            ContractUtils.RequiresNotNull(type, "type");

            if (value != null)
            {
                RequiresCanRead(value, "value");
                ContractUtils.Requires(
                    TypeUtils.AreReferenceAssignable(typeof(Exception), value.Type),
                    "value",
                    Strings.ArgumentMustBeException
                    );
            }
            return(new UnaryExpression(ExpressionType.Throw, value, type, null));
        }
Example #25
0
        /// <summary>
        /// Creates a new array expression of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>An instance of the <see cref="NewArrayExpression"/>.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");
            if (type.Equals(typeof(void)))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                Expression expr = initializerList[i];
                RequiresCanRead(expr, "initializers");

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (TypeUtils.IsSameOrSubclass(typeof(LambdaExpression), type) && type.IsAssignableFrom(expr.GetType()))
                    {
                        expr = Expression.Quote(expr);
                    }
                    else
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
        private static bool IsCompatible(PropertyInfo pi, Expression[]?args)
        {
            MethodInfo?mi = pi.GetGetMethod(nonPublic: true);

            ParameterInfo[] parms;
            if (mi != null)
            {
                parms = mi.GetParametersCached();
            }
            else
            {
                mi = pi.GetSetMethod(nonPublic: true);
                if (mi == null)
                {
                    return(false);
                }
                //The setter has an additional parameter for the value to set,
                //need to remove the last type to match the arguments.
                parms = mi.GetParametersCached();
                if (parms.Length == 0)
                {
                    return(false);
                }
                parms = parms.RemoveLast();
            }

            if (args == null)
            {
                return(parms.Length == 0);
            }

            if (parms.Length != args.Length)
            {
                return(false);
            }
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == null)
                {
                    return(false);
                }
                if (!TypeUtils.AreReferenceAssignable(parms[i].ParameterType, args[i].Type))
                {
                    return(false);
                }
            }
            return(true);
        }
Example #27
0
        /// <inheritdoc/>
        Expression IExpressionVisitor <Expression> .VisitArrayLiteral(ArrayListExpression node)
        {
            var type = node.ArrayType != null?node.ArrayType.ResolveType(Context) : TypeProvider.AnyType;

            node.Type        = typeof(Collections.List <>).MakeGenericType(type);
            node.ElementType = type;
            if (node.Arguments != null)
            {
                var types = node.Arguments.Map(arg => arg.Accept(this).Type);
                if (node.Constructor == null)
                {
                    var ctors = node.Type.GetConstructors(ReflectionUtils.PublicInstance);
                    var ctor  = ReflectionUtils.BindToMethod(ctors, types, out ArgumentConversions conversions);
                    if (ctor == null)
                    {
                        ExecutionException.ThrowMissingMethod(node.Type, "ctor", node);
                    }
                    node.Constructor         = ctor;
                    node.ArgumentConversions = conversions;
                }
            }
            else if (node.Constructor == null)
            {
                node.Constructor = node.Type.GetConstructor(ReflectionUtils.PublicInstance, null, new Type[0], null);
            }
            var items = node.Expressions;

            if (items.Count > 0)
            {
                var arrayConversions = new ArgumentConversions(items.Count);
                for (int index = 0; index < items.Count; index++)
                {
                    var expression = items[index].Accept(this);
                    if (!TypeUtils.AreReferenceAssignable(type, expression.Type) && expression.Type.TryImplicitConvert(type, out System.Reflection.MethodInfo implicitCall))
                    {
                        if (expression.Type.IsValueType &&
                            implicitCall.GetParameters()[0].ParameterType == TypeProvider.ObjectType)
                        {
                            arrayConversions.Append(index, new BoxConversion(index, expression.Type));
                        }
                        arrayConversions.Append(index, new ParamConversion(index, implicitCall));
                    }
                }
                node.ArrayConversions = arrayConversions;
            }
            return(node);
        }
Example #28
0
 //Validate that the body of the try expression must have the same type as the body of every try block.
 private static void ValidateTryAndCatchHaveSameType(Type type, Expression tryBody, ReadOnlyCollection <CatchBlock> handlers)
 {
     Debug.Assert(tryBody != null);
     // Type unification ... all parts must be reference assignable to "type"
     if (type != null)
     {
         if (type != typeof(void))
         {
             if (!TypeUtils.AreReferenceAssignable(type, tryBody.Type))
             {
                 throw Error.ArgumentTypesMustMatch();
             }
             foreach (CatchBlock cb in handlers)
             {
                 if (!TypeUtils.AreReferenceAssignable(type, cb.Body.Type))
                 {
                     throw Error.ArgumentTypesMustMatch();
                 }
             }
         }
     }
     else if (tryBody.Type == typeof(void))
     {
         //The body of every try block must be null or have void type.
         foreach (CatchBlock cb in handlers)
         {
             Debug.Assert(cb.Body != null);
             if (cb.Body.Type != typeof(void))
             {
                 throw Error.BodyOfCatchMustHaveSameTypeAsBodyOfTry();
             }
         }
     }
     else
     {
         //Body of every catch must have the same type of body of try.
         type = tryBody.Type;
         foreach (CatchBlock cb in handlers)
         {
             Debug.Assert(cb.Body != null);
             if (!TypeUtils.AreEquivalent(cb.Body.Type, type))
             {
                 throw Error.BodyOfCatchMustHaveSameTypeAsBodyOfTry();
             }
         }
     }
 }
        public object VisitInstanceOf(InstanceOfExpression node)
        {
            var value = node.Target.Accept(this);

            if (value is null && node.TypeSyntax is RefTypeSyntax refType && refType.Name.Equals("null"))
            {
                return(Boolean.True);
            }
            var type      = node.TypeSyntax.ResolveType(TypeContext);
            var valueType = value.GetType();

            if (TypeUtils.AreReferenceAssignable(type, valueType))
            {
                return(Boolean.True);
            }
            return(Boolean.False);
        }
        //CONFORMING
        internal static void ValidateLift(IList <ParameterExpression> variables, IList <Expression> arguments)
        {
            System.Diagnostics.Debug.Assert(variables != null);
            System.Diagnostics.Debug.Assert(arguments != null);

            if (variables.Count != arguments.Count)
            {
                throw Error.IncorrectNumberOfIndexes();
            }
            for (int i = 0, n = variables.Count; i < n; i++)
            {
                if (!TypeUtils.AreReferenceAssignable(variables[i].Type, TypeUtils.GetNonNullableType(arguments[i].Type)))
                {
                    throw Error.ArgumentTypesMustMatch();
                }
            }
        }