private AqlExpression VisitUnary(UnaryExpression node) { AqlExpression operand = Visit(node.Operand); switch (node.NodeType) { case ExpressionType.Convert: case ExpressionType.ConvertChecked: // ignore the cast, because AQL does not support casts return(operand); case ExpressionType.UnaryPlus: return(new AqlUnaryOperator( operand, AqlExpressionType.UnaryPlus )); case ExpressionType.Negate: case ExpressionType.NegateChecked: return(new AqlUnaryOperator( operand, AqlExpressionType.UnaryMinus )); case ExpressionType.Not: return(new AqlUnaryOperator( operand, AqlExpressionType.Not )); } throw new AqlParsingException( $"Cannot parse node {node.NodeType} - not implemented" ); }
public AqlBinaryOperator( AqlExpression left, AqlExpression right, AqlExpressionType type ) { if ( type != AqlExpressionType.Add && type != AqlExpressionType.Subtract && type != AqlExpressionType.Multiply && type != AqlExpressionType.Divide && type != AqlExpressionType.Modulo && type != AqlExpressionType.Equal && type != AqlExpressionType.NotEqual && type != AqlExpressionType.GreaterThan && type != AqlExpressionType.GreaterThanOrEqual && type != AqlExpressionType.LessThan && type != AqlExpressionType.LessThanOrEqual && type != AqlExpressionType.And && type != AqlExpressionType.Or ) { throw new ArgumentException( $"Provided expression type {type} is not a binary operation" ); } ExpressionType = type; Left = left; Right = right; Parameters = new ReadOnlyCollection <string>( left.Parameters.Union(right.Parameters).ToList() ); }
/// <summary> /// Parse an expression tree directly, without the lambda wrapper /// </summary> public AqlExpression ParseExpression(Expression expression) { // simplify parts that have no parameters Expression demungified = demungifier.Demungify(expression); // convert to AQL expression AqlExpression converted = converter.Convert(demungified); return(converted); }
public AqlJsonObjectExpression Add(string key, AqlExpression expression) { if (expression.Parameters.Count > 0) { parameters = new ReadOnlyCollection <string>( parameters.Union(expression.Parameters).ToList() ); } Items.Add(key, expression); return(this); }
public AqlMemberAccessExpression( AqlExpression subject, AqlExpression member ) { Subject = subject; Member = member; Parameters = new ReadOnlyCollection <string>( Subject.Parameters.Union(Member.Parameters).ToList() ); }
public AqlUnaryOperator(AqlExpression operand, AqlExpressionType type) { if ( type != AqlExpressionType.UnaryPlus && type != AqlExpressionType.UnaryMinus && type != AqlExpressionType.Not ) { throw new ArgumentException( $"Provided expression type {type} is not an unary operation" ); } ExpressionType = type; Operand = operand; }
private AqlExpression VisitCall(MethodCallExpression node) { AqlExpression instance = Visit(node.Object); List <AqlExpression> args = node.Arguments .Select(Visit) .ToList(); // === handle arango functions === ArangoFunctionAttribute attribute = node.Method .GetCustomAttribute <ArangoFunctionAttribute>(); if (attribute != null) { return(new AqlFunctionExpression(attribute, args)); } // === intercept indexing on JSON objects and arrays === if (possibleIndexerMethods.Contains(node.Method) && args.Count == 1) { return(new AqlMemberAccessExpression( instance, args[0] )); } // === handle JSON object construction === // if we call .Add on a JsonObject instance if (node.Object?.Type == typeof(JsonObject) && node.Method.Name == "Add") { // start construction if (instance is AqlConstantExpression constant) { instance = new AqlJsonObjectExpression(constant.Value); } // continue construction if (instance is AqlJsonObjectExpression obj) { return(obj.CallAddViaArgs(args)); } } // === handle JSON array construction === // if we call .Add on a JsonArray instance if (node.Object?.Type == typeof(JsonArray) && node.Method.Name == "Add") { // start construction if (instance is AqlConstantExpression constant) { instance = new AqlJsonArrayExpression(constant.Value); } // continue construction if (instance is AqlJsonArrayExpression arr) { return(arr.CallAddViaArgs(args)); } } // === expression is invalid === throw new AqlParsingException( $"Expression uses parameters in method '{node.Method}'" + ", but this method cannot be translated to AQL" ); }
private AqlExpression VisitBinary(BinaryExpression node) { AqlExpression left = Visit(node.Left); AqlExpression right = Visit(node.Right); switch (node.NodeType) { case ExpressionType.Add: case ExpressionType.AddChecked: if (node.Left.Type == typeof(string) || node.Right.Type == typeof(string)) { return(new AqlFunctionExpression( "CONCAT", left, right )); } return(new AqlBinaryOperator( left, right, AqlExpressionType.Add )); case ExpressionType.Subtract: case ExpressionType.SubtractChecked: return(new AqlBinaryOperator( left, right, AqlExpressionType.Subtract )); case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: return(new AqlBinaryOperator( left, right, AqlExpressionType.Multiply )); case ExpressionType.Divide: return(new AqlBinaryOperator( left, right, AqlExpressionType.Divide )); case ExpressionType.Modulo: return(new AqlBinaryOperator( left, right, AqlExpressionType.Modulo )); case ExpressionType.Equal: return(new AqlBinaryOperator( left, right, AqlExpressionType.Equal )); case ExpressionType.NotEqual: return(new AqlBinaryOperator( left, right, AqlExpressionType.NotEqual )); case ExpressionType.GreaterThan: return(new AqlBinaryOperator( left, right, AqlExpressionType.GreaterThan )); case ExpressionType.GreaterThanOrEqual: return(new AqlBinaryOperator( left, right, AqlExpressionType.GreaterThanOrEqual )); case ExpressionType.LessThan: return(new AqlBinaryOperator( left, right, AqlExpressionType.LessThan )); case ExpressionType.LessThanOrEqual: return(new AqlBinaryOperator( left, right, AqlExpressionType.LessThanOrEqual )); case ExpressionType.And: case ExpressionType.AndAlso: return(new AqlBinaryOperator( left, right, AqlExpressionType.And )); case ExpressionType.Or: case ExpressionType.OrElse: return(new AqlBinaryOperator( left, right, AqlExpressionType.Or )); } throw new AqlParsingException( $"Cannot convert node {node.NodeType} - not implemented" ); }