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); }
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)); } }
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)); } }