Exemple #1
0
        private IExpression Index(IAstNode operand, AstNodeCollection arguments)
        {
            var resolvedArguments = ResolveArguments(arguments);

            var resolvedOperand = operand.Accept(this);

            if (resolvedOperand.Type.IsArray)
            {
                if (resolvedArguments.Length != resolvedOperand.Type.GetArrayRank())
                {
                    throw new ExpressionsException(
                              "Invalid array index rank",
                              ExpressionsExceptionType.TypeMismatch
                              );
                }

                foreach (var argument in resolvedArguments)
                {
                    if (!TypeUtil.IsCastAllowed(argument.Type, typeof(int)))
                    {
                        throw new ExpressionsException(
                                  "Argument of array index must be convertable to integer",
                                  ExpressionsExceptionType.TypeMismatch
                                  );
                    }
                }

                if (resolvedArguments.Length == 1)
                {
                    return(new Expressions.Index(resolvedOperand, resolvedArguments[0], resolvedOperand.Type.GetElementType()));
                }
                else
                {
                    return(_resolver.ResolveMethod(resolvedOperand, "Get", resolvedArguments));
                }
            }

            var defaultMemberAttributes = resolvedOperand.Type.GetCustomAttributes(typeof(DefaultMemberAttribute), true);

            if (defaultMemberAttributes.Length != 1)
            {
                throw new ExpressionsException(
                          "Operand does not support indexing",
                          ExpressionsExceptionType.TypeMismatch
                          );
            }

            var result = _resolver.ResolveMethod(resolvedOperand, "get_" + ((DefaultMemberAttribute)defaultMemberAttributes[0]).MemberName, resolvedArguments);

            if (result == null)
            {
                throw new ExpressionsException(
                          "Unresolved index method",
                          ExpressionsExceptionType.UnresolvedMethod
                          );
            }

            return(result);
        }
Exemple #2
0
        public override IExpression BinaryExpression(BinaryExpression binaryExpression)
        {
            var left  = binaryExpression.Left.Accept(this);
            var right = binaryExpression.Right.Accept(this);

            if (
                (
                    binaryExpression.ExpressionType == ExpressionType.Add &&
                    (left.Type == typeof(string) || right.Type == typeof(string))
                ) ||
                binaryExpression.ExpressionType == ExpressionType.Concat
                )
            {
                return(_resolver.ResolveMethod(
                           new TypeAccess(typeof(string)),
                           "Concat",
                           FlattenConcatArguments(binaryExpression.Left, binaryExpression.Right)
                           ));
            }
            else if (binaryExpression.ExpressionType == ExpressionType.Power)
            {
                return(_resolver.ResolveMethod(
                           new TypeAccess(typeof(Math)),
                           "Pow",
                           new[] { left, right }
                           ));
            }

            if (left == binaryExpression.Left && right == binaryExpression.Right)
            {
                return(binaryExpression);
            }
            else
            {
                return(new BinaryExpression(left, right, binaryExpression.ExpressionType, binaryExpression.Type));
            }
        }
Exemple #3
0
        public override IExpression BinaryExpression(BinaryExpression binaryExpression)
        {
            var left  = binaryExpression.Left.Accept(this);
            var right = binaryExpression.Right.Accept(this);

            if (
                (
                    binaryExpression.ExpressionType == ExpressionType.Add &&
                    (left.Type == typeof(string) || right.Type == typeof(string))
                ) ||
                binaryExpression.ExpressionType == ExpressionType.Concat
                )
            {
                return(_resolver.ResolveMethod(
                           new TypeAccess(typeof(string)),
                           "Concat",
                           FlattenConcatArguments(binaryExpression.Left, binaryExpression.Right)
                           ));
            }
            else if (binaryExpression.ExpressionType == ExpressionType.Power)
            {
                return(_resolver.ResolveMethod(
                           new TypeAccess(typeof(Math)),
                           "Pow",
                           new[] { left, right }
                           ));
            }
            else if (_resolver.DynamicExpression.Language == ExpressionLanguage.VisualBasic)
            {
                // Special handling for Visual Basic.

                string methodName = null;

                switch (binaryExpression.ExpressionType)
                {
                case ExpressionType.Compares: methodName = "CompareObjectEqual"; break;

                case ExpressionType.NotCompares: methodName = "CompareObjectNotEqual"; break;

                case ExpressionType.Greater: methodName = "CompareObjectGreater"; break;

                case ExpressionType.GreaterOrEquals: methodName = "CompareObjectGreaterEqual"; break;

                case ExpressionType.Less: methodName = "CompareObjectLess"; break;

                case ExpressionType.LessOrEquals: methodName = "CompareObjectLessEqual"; break;
                }

                // Is this an operator for which we have a method?

                if (methodName != null)
                {
                    // Should we output a normal comparison anyway?

                    if (TypeUtil.IsConvertible(left.Type) && TypeUtil.IsConvertible(right.Type))
                    {
                        var expressionType = binaryExpression.ExpressionType;

                        // Coerce Compares/NotCompares to Equals/NotEquals.

                        if (expressionType == ExpressionType.Compares)
                        {
                            expressionType = ExpressionType.Equals;
                        }
                        else if (expressionType == ExpressionType.NotCompares)
                        {
                            expressionType = ExpressionType.NotEquals;
                        }

                        if (
                            left == binaryExpression.Left &&
                            right == binaryExpression.Right &&
                            expressionType == binaryExpression.ExpressionType
                            )
                        {
                            return(binaryExpression);
                        }
                        else
                        {
                            return(new BinaryExpression(left, right, expressionType, binaryExpression.Type, binaryExpression.CommonType));
                        }
                    }
                    else
                    {
                        var method = typeof(Operators).GetMethod(methodName);

                        Debug.Assert(method.ReturnType == typeof(object));

                        return(new Cast(
                                   new MethodCall(
                                       new TypeAccess(typeof(Operators)),
                                       method,
                                       new[]
                        {
                            left,
                            right,
                            new Constant(false)
                        }
                                       ),
                                   typeof(bool)
                                   ));
                    }
                }
            }

            if (left == binaryExpression.Left && right == binaryExpression.Right)
            {
                return(binaryExpression);
            }
            else
            {
                return(new BinaryExpression(left, right, binaryExpression.ExpressionType, binaryExpression.Type));
            }
        }