public override Expression VisitBinaryExpression(BinaryExpression binaryExpression){ if (binaryExpression == null) return null; binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2); binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1); if (binaryExpression.Type == null) binaryExpression.Type = binaryExpression.Operand1.Type; //Hack: need proper inferencing return binaryExpression; }
public static void CompileBinaryExpression(BinaryExpression expression, bool useInterpreter, bool expected) { Expression<Func<bool>> e = Expression.Lambda<Func<bool>>(expression, Enumerable.Empty<ParameterExpression>()); Func<bool> f = e.Compile(useInterpreter); Assert.Equal(expected, f()); }
public bool Match(BinaryExpression exp) { if (exp.Operator != Operator.IAdd) return false; id = exp.Left as Identifier; bin = exp.Right as BinaryExpression; if ((id == null || bin == null) && exp.Operator == Operator.IAdd) { id = exp.Right as Identifier; bin = exp.Left as BinaryExpression; } if (id == null || bin == null) return false; if (bin.Operator != Operator.SMul && bin.Operator != Operator.UMul && bin.Operator != Operator.IMul) return false; Identifier idInner = bin.Left as Identifier; cInner = bin.Right as Constant; if (idInner == null ||cInner == null) return false; if (idInner != id) return false; return true; }
public void TestComplexExpression() { const string VAR_X = "x"; const string VAR_Y = "y"; const string VAR_Z = "z"; var ctx = new Context(); ctx.SetValue(VAR_X, true); ctx.SetValue(VAR_Y, true); ctx.SetValue(VAR_Z, false); var constExp = new ConstExpression(TRUE_TOKEN); var unaryExp = new UnaryExpression(constExp); Assert.AreEqual(false, unaryExp.Interpret(ctx)); var binaryExp = new BinaryExpression( new BinaryExpression(VAR_X, BinaryOp.And, unaryExp), BinaryOp.Or, new BinaryExpression(new UnaryExpression(VAR_Y), BinaryOp.And, VAR_Z)); Assert.AreEqual(false, binaryExp.Interpret(ctx)); }
//CONFORMING private void EmitBinaryMethod(BinaryExpression b) { if (b.IsLifted) { ParameterExpression p1 = Expression.Variable(TypeUtils.GetNonNullableType(b.Left.Type), null); ParameterExpression p2 = Expression.Variable(TypeUtils.GetNonNullableType(b.Right.Type), null); MethodCallExpression mc = Expression.Call(null, b.Method, p1, p2); Type resultType = null; if (b.IsLiftedToNull) { resultType = TypeUtils.GetNullableType(mc.Type); } else { switch (b.NodeType) { case ExpressionType.Equal: case ExpressionType.NotEqual: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: if (mc.Type != typeof(bool)) { throw Error.ArgumentMustBeBoolean(); } resultType = typeof(bool); break; default: resultType = TypeUtils.GetNullableType(mc.Type); break; } } IList<ParameterExpression> variables = new ParameterExpression[] { p1, p2 }; IList<Expression> arguments = new Expression[] { b.Left, b.Right }; ValidateLift(variables, arguments); EmitLift(b.NodeType, resultType, mc, variables, arguments); } else { EmitMethodCallExpression(Expression.Call(null, b.Method, b.Left, b.Right)); } }
public void Exs_OrWithSelf() { BuildExpressionSimplifier(); var expr = new BinaryExpression(Operator.Or, foo.DataType, foo, foo); var result = expr.Accept(simplifier); Assert.AreSame(foo, result); }
public bool MatchMul(BinaryExpression b) { if (b.Operator == Operator.SMul || b.Operator == Operator.UMul || b.Operator == Operator.IMul) { Constant c = b.Left as Constant; Expression e = b.Right; if (c == null) { c = b.Right as Constant; e = b.Left; } if (c != null) { elemSize = c; Index = e; return true; } } if (b.Operator == Operator.Shl) { Constant c = b.Right as Constant; if (c != null) { elemSize = b.Operator.ApplyConstants(Constant.Create(b.Left.DataType, 1), c); Index = b.Left; return true; } } return false; }
protected Expression GetResultIndexExpression() { var resultVarIndex = ReadWord(); Expression resultVarIndexExp = resultVarIndex.ToLiteral(); if ((resultVarIndex & 0x2000) == 0x2000) { int a = ReadWord(); if ((a & 0x2000) == 0x2000) { var variableExp = ReadVariable(a & ~0x2000); var literalExp = variableExp as IntegerLiteralExpression; if (literalExp != null) { resultVarIndex += Convert.ToInt32(literalExp.Value); resultVarIndex &= ~0x2000; resultVarIndexExp = resultVarIndex.ToLiteral(); } else { resultVarIndexExp = new BinaryExpression( new BinaryExpression(resultVarIndexExp, Operator.Add, variableExp), Operator.And, new UnaryExpression(0x2000.ToLiteral(), Operator.Not)); } } else { resultVarIndex = resultVarIndex + (a & 0xFFF); resultVarIndex &= ~0x2000; resultVarIndexExp = resultVarIndex.ToLiteral(); } } return resultVarIndexExp; }
private void AddressOf(BinaryExpression node, Type type) { Debug.Assert(node.NodeType == ExpressionType.ArrayIndex && node.Method == null); if (TypeUtils.AreEquivalent(type, node.Type)) { EmitExpression(node.Left); EmitExpression(node.Right); Type rightType = node.Right.Type; if (TypeUtils.IsNullableType(rightType)) { LocalBuilder loc = GetLocal(rightType); _ilg.Emit(OpCodes.Stloc, loc); _ilg.Emit(OpCodes.Ldloca, loc); _ilg.EmitGetValue(rightType); FreeLocal(loc); } Type indexType = TypeUtils.GetNonNullableType(rightType); if (indexType != typeof(int)) { _ilg.EmitConvertToType(indexType, typeof(int), isChecked: true); } _ilg.Emit(OpCodes.Ldelema, node.Type); } else { EmitExpressionAddress(node, type); } }
public void EvcBinaryExpression() { Identifier a = new Identifier("a", PrimitiveType.Word32, new TemporaryStorage("a", 1, PrimitiveType.Word32)); BinaryExpression a1 = new BinaryExpression(Operator.IAdd, PrimitiveType.Word32, a, a); BinaryExpression a2 = new BinaryExpression(Operator.IAdd, PrimitiveType.Word32, a, a); Assert.IsTrue(eq.Equals(a1, a2)); Assert.AreEqual(eq.GetHashCode(a1), eq.GetHashCode(a2)); }
public override Expression VisitBinaryExpression(BinaryExpression be) { be.Operand1 = this.VisitExpression(be.Operand1); bool hcr = this.hasContextReference; this.hasContextReference = false; be.Operand2 = this.VisitExpression(be.Operand2); this.hasContextReference |= hcr; return (Expression) this.Compose(be, this.GetComposer(be.Operand1), this.GetComposer(be.Operand2)); }
public void ExsConstants() { BuildExpressionSimplifier(); Expression expr = new BinaryExpression(Operator.IAdd, PrimitiveType.Word32, Constant.Word32(1), Constant.Word32(2)); Constant c = (Constant) expr.Accept(simplifier); Assert.AreEqual(3, c.ToInt32()); }
/// <summary> /// Extends an effective address ''id'' to ''id'' + 0. /// </summary> /// <remarks> /// The purpose here is to extend the effective address to avoid premature typing of id. /// If later in the type inference process [[id]] is discovered to be a signed integer, the /// decompiler can accomodate that by having the added 0 be [[pointer]] or [[member pointer]]. /// This is not possible if all we have is the id. /// </remarks> /// <param name="ea"></param> /// <returns></returns> private Expression AddZeroToEffectiveAddress(Expression ea) { BinaryExpression bin = new BinaryExpression( Operator.IAdd, PrimitiveType.CreateWord(ea.DataType.Size), ea, Constant.Create(PrimitiveType.CreateWord(ea.DataType.Size), 0)); return bin; }
void EmitBinaryExpression(BinaryExpression expr, MethodInfo method) { // Compute the operands VisitExpression(expr.Left); VisitExpression(expr.Right); // Call the operator method IL.Emit(OpCodes.Call, method); }
public bool Match(Identifier id) { this.id = id; bin = ctx.GetValue(id) as BinaryExpression; if (bin == null) return false; if (ctx.IsUsedInPhi(id)) return false; return (bin.Left is Identifier) && (bin.Right is Constant); }
public bool Match(BinaryExpression binExp) { idLeft = binExp.Left as Identifier; if (idLeft == null) return false; idRight = binExp.Right as Identifier; if (idRight == null) return false; return (idLeft == idRight && binExp.Operator == Operator.IAdd); }
public bool Match(UnaryExpression unary) { if (unary.Operator == Operator.Neg) { bin = unary.Expression as BinaryExpression; if (bin != null && bin.Operator == Operator.ISub) return true; } return false; }
public void VpAddZero() { Identifier r = Reg32("r"); Identifier s = Reg32("s"); var sub = new BinaryExpression(Operator.ISub, PrimitiveType.Word32, new MemoryAccess(MemoryIdentifier.GlobalMemory, r, PrimitiveType.Word32), Constant.Word32(0)); var vp = new ExpressionSimplifier(new SsaEvaluationContext(arch, ssaIds)); var exp = sub.Accept(vp); Assert.AreEqual("Mem0[r:word32]", exp.ToString()); }
private void PrintResolvedBinaryExpression(BinaryExpression node, int indent) { AppendLine(indent, "Type = " + node.Type); AppendLine(indent, "CommonType = " + node.CommonType); AppendLine(indent, "ExpressionType = " + node.ExpressionType); AppendLine(indent, "Left ="); PrintNode(node.Left, indent + 1); AppendLine(indent, "Right ="); PrintNode(node.Right, indent + 1); }
public bool Match(BinaryExpression binExp) { if (binExp.Operator != Operator.ISub && binExp.Operator != Operator.Xor && binExp.Operator != Operator.And && binExp.Operator != Operator.Or) return false; this.binExp = binExp; id = binExp.Left as Identifier; return (id != null && binExp.Left == binExp.Right); }
// Assumes that the operators are left associative. private Expression DoCreateBinary(List<Result> results) { Expression result = results[0].Value; for (int i = 1; i < results.Count; i += 2) { result = new BinaryExpression(result, results[i + 1].Value, results[i].Text); } return result; }
/// <summary> /// Constructor /// </summary> /// <param name="listExpression"></param> /// <param name="condition"></param> /// <param name="expression"></param> /// <param name="root">the root element for which this expression should be parsed</param> public SumExpression(ModelElement root, Expression listExpression, Expression condition, Expression expression) : base(root, listExpression, condition, expression) { AccumulatorVariable = (Variables.Variable)Generated.acceptor.getFactory().createVariable(); AccumulatorVariable.Enclosing = this; AccumulatorVariable.Name = "RESULT"; Utils.ISubDeclaratorUtils.AppendNamable(this, AccumulatorVariable); Accumulator = new BinaryExpression(root, expression, BinaryExpression.OPERATOR.ADD, new UnaryExpression(root, new Term(root, new Designator(root, "RESULT")))); Accumulator.Enclosing = this; }
public void CfAddMul() { Identifier id1 = new Identifier("v1", PrimitiveType.Word16, null); Identifier id2 = new Identifier("v2", PrimitiveType.Word16, null); Expression e = new BinaryExpression( Operator.IAdd, PrimitiveType.Word16, new BinaryExpression( Operator.IMul, PrimitiveType.Word16, id1, id2), Constant.Word16(2)); e.Accept(cf); Assert.AreEqual("v1 * v2 + 0x0002", sw.ToString()); }
public override Expression VisitBinaryExpression(BinaryExpression binaryExpression) { if (binaryExpression.Operand2 != null) { binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2); } if (binaryExpression.Operand1 != null) { binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1); } return binaryExpression; }
private void RewriteBranch0(MipsInstruction instr, BinaryOperator condOp, bool link) { if (!link) { var reg = RewriteOperand(instr.op1); var addr = (Address)RewriteOperand(instr.op2); var cond = new BinaryExpression(condOp, PrimitiveType.Bool, reg, Constant.Zero(reg.DataType)); cluster.Class = RtlClass.ConditionalTransfer; emitter.Branch(cond, addr, RtlClass.ConditionalTransfer | RtlClass.Delay); } else throw new NotImplementedException("Linked branches not implemented yet."); }
public bool Match(BinaryExpression binExp) { cLeft = binExp.Left as Constant; cRight = binExp.Right as Constant; if (cLeft != null && cRight != null && binExp.Operator != Operator.Eq) { if (!cLeft.IsReal && !cRight.IsReal) { op = binExp.Operator; return true; } } return false; }
/// <summary> /// 获取简单表达式 /// </summary> /// <param name="binaryExpression">二元表达式</param> /// <returns>简单表达式</returns> private static Expression getSimpleOrElse(BinaryExpression binaryExpression) { if (binaryExpression.Left.NodeType == ExpressionType.LogicConstant) { if (((logicConstantExpression)binaryExpression.Left).Value) return binaryExpression.Left; return binaryExpression.Right; } if (binaryExpression.Right.NodeType == ExpressionType.LogicConstant) { if (((logicConstantExpression)binaryExpression.Right).Value) return binaryExpression.Right; return binaryExpression.Left; } return binaryExpression; }
protected BinaryExpression UpdateBinary(BinaryExpression b, Expression left, Expression right, Expression conversion, bool isLiftedToNull, MethodInfo method) { if (left != b.Left || right != b.Right || conversion != b.Conversion || method != b.Method || isLiftedToNull != b.IsLiftedToNull) { if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null) { return Expression.Coalesce(left, right, conversion as LambdaExpression); } else { return Expression.MakeBinary(b.NodeType, left, right, isLiftedToNull, method); } } return b; }
public void ExsAddPositiveConstantToNegative() { BuildExpressionSimplifier(); var expr = new BinaryExpression( Operator.IAdd, foo.DataType, new BinaryExpression( Operator.ISub, foo.DataType, foo, Constant.Word32(4)), Constant.Word32(1)); var result = expr.Accept(simplifier); Assert.AreEqual("foo_0 - 0x00000003", result.ToString()); }
public bool Match(BinaryExpression binExp, Expression left, Expression right) { bin = binExp; binLeft = left as BinaryExpression; if (binLeft == null) return false; cLeftRight = binLeft.Right as Constant; if (cLeftRight == null) return false; cRight = right as Constant; if (cRight == null) return false; if (!IsAddOrSub(binExp.Operator)) return false; return (!cRight.IsReal && !cRight.IsReal); }
public object Visit(BinaryExpression binary) { return(null); }
static bool LessThanOrEqualUseIndex <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { SessionBase session = sourceCollection.Session; CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; Expression leftSide = binExp.Left; Expression rightSide = binExp.Right; object rightValue = GetRightValue(leftSide, rightSide); if (leftSide.NodeType == ExpressionType.Parameter) { Key key = (Key)rightValue; if (key != null) { if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); } } else { if (comparer != null) { //if we were able to create a hash from the right side (likely) MemberExpression returnedEx = null; if (comparer.FieldsToCompare == null) { comparer.SetupFieldsToCompare(); } DataMember dataMember = comparer.FieldsToCompare[0]; if (rightValue != null && HasIndexablePropertyOnLeft <Key>(leftSide, sourceCollection, dataMember, out returnedEx)) { if (session.TraceIndexUsage) { Trace.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " Index used with " + sourceCollection.ToString()); } return(true); } else if (leftSide.NodeType == ExpressionType.Call) { // don't know yet how to handle TODO /*MethodCallExpression expression = leftSide as MethodCallExpression; * Trace.Out.WriteLine("Method: " + expression.Method.Name); * Trace.Out.WriteLine("Args: "); * foreach (var exp in expression.Arguments) * sourceCollection where */ } } } return(false); }
static public IEnumerable <Key> Where <Key>(this BTreeBase <Key, Key> sourceCollection, Expression <Func <Key, bool> > expr) #if WINDOWS_PHONE where Key : new() #endif { if (sourceCollection != null) { bool noIndex = true; SessionBase session = sourceCollection.Session; CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; BinaryExpression binExp = expr.Body as BinaryExpression; if (binExp != null && canUseIndex <Key>(sourceCollection, binExp, comparer)) { session.WaitForIndexUpdates(); switch (expr.Body.NodeType) { case ExpressionType.AndAlso: { noIndex = AndUseIndex(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in And <Key>(sourceCollection, binExp)) { yield return(x); } } else { BinaryExpression leftExpr = (BinaryExpression)binExp.Left; binExp = leftExpr; switch (binExp.NodeType) { case ExpressionType.Equal: { noIndex = EqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> equal = Equal <Key>(sourceCollection, binExp); IEnumerable <Key> result = equal.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.LessThan: { noIndex = LessThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> lessThan = LessThan <Key>(sourceCollection, binExp); IEnumerable <Key> result = lessThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.LessThanOrEqual: { noIndex = LessThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> lessThan = LessThanOrEqual <Key>(sourceCollection, binExp); IEnumerable <Key> result = lessThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.GreaterThan: { noIndex = GreaterThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> greaterThan = GreaterThan <Key>(sourceCollection, binExp); IEnumerable <Key> result = greaterThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } case ExpressionType.GreaterThanOrEqual: { noIndex = GreaterThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { IEnumerable <Key> greaterThan = GreaterThanOrEqual <Key>(sourceCollection, binExp); IEnumerable <Key> result = greaterThan.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } yield break; } } ; } } break; case ExpressionType.Equal: { noIndex = EqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in Equal <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.GreaterThan: { noIndex = GreaterThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in GreaterThan <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.GreaterThanOrEqual: { noIndex = GreaterThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in GreaterThanOrEqual <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.LessThan: { noIndex = LessThanUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in LessThan <Key>(sourceCollection, binExp)) { yield return(x); } } } break; case ExpressionType.LessThanOrEqual: { noIndex = LessThanOrEqualUseIndex <Key>(sourceCollection, binExp) == false; if (noIndex == false) { foreach (var x in LessThanOrEqual <Key>(sourceCollection, binExp)) { yield return(x); } } } break; } } if (noIndex) //no index? just do it the normal slow way then... { IEnumerable <Key> sourceEnum; if (sourceCollection.UsesOidShort) { BTreeSetOidShort <Key> c = (BTreeSetOidShort <Key>)sourceCollection; sourceEnum = c.AsEnumerable <Key>(); } else { BTreeSet <Key> c = (BTreeSet <Key>)sourceCollection; sourceEnum = c.AsEnumerable <Key>(); } IEnumerable <Key> result = sourceEnum.Where <Key>(expr.Compile()); foreach (Key resultItem in result) { yield return(resultItem); } } } }
protected virtual void PVisitBinary(BinaryExpression b) { }
protected override Expression VisitBinary(BinaryExpression binaryExpression) { if (binaryExpression.NodeType == ExpressionType.ArrayIndex) { if (TranslationFailed(binaryExpression.Left, Visit(TryRemoveImplicitConvert(binaryExpression.Left)), out var sqlLeft) || TranslationFailed(binaryExpression.Right, Visit(TryRemoveImplicitConvert(binaryExpression.Right)), out var sqlRight)) { return(QueryCompilationContext.NotTranslatedExpression); } if (binaryExpression.Left.Type == typeof(byte[])) { var left = Visit(binaryExpression.Left); var right = Visit(binaryExpression.Right); if (left is SqlExpression leftSql && right is SqlExpression rightSql) { return(_sqlExpressionFactory.NullableFunction( "ASCII", new[] { _sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { leftSql, Dependencies.SqlExpressionFactory.Add( Dependencies.SqlExpressionFactory.ApplyDefaultTypeMapping(rightSql), Dependencies.SqlExpressionFactory.Constant(1)), Dependencies.SqlExpressionFactory.Constant(1) }, typeof(byte[])) }, typeof(byte))); } } // Try translating ArrayIndex inside json column var expression = _jsonPocoTranslator?.TranslateMemberAccess( sqlLeft, _sqlExpressionFactory.JsonArrayIndex(sqlRight), binaryExpression.Type); if (expression is not null) { return(expression); } } var visitedExpression = base.VisitBinary(binaryExpression); if (visitedExpression is SqlBinaryExpression visitedBinaryExpression) { // TODO: Is this still true in .NET Core 3.0? switch (visitedBinaryExpression.OperatorType) { case ExpressionType.Add: case ExpressionType.Subtract: case ExpressionType.Multiply: case ExpressionType.Divide: case ExpressionType.Modulo: return(IsDateTimeBasedOperation(visitedBinaryExpression) ? QueryCompilationContext.NotTranslatedExpression : visitedBinaryExpression); } } return(visitedExpression); }
protected override Expression VisitBinaryExpression(BinaryExpression expression) { SqlExpression.Append(" "); foreach (var candidate in QueryParts.ExpressionMatchers) { if (candidate.TryMatch(expression, SqlExpression, exp => VisitExpression(exp), Context)) { return(expression); } } switch (expression.NodeType) { case ExpressionType.Coalesce: SqlExpression.Append(" COALESCE("); VisitExpression(expression.Left); SqlExpression.Append(", "); VisitExpression(expression.Right); SqlExpression.Append(")"); return(expression); case ExpressionType.Modulo: SqlExpression.Append(" MOD("); VisitExpression(expression.Left); SqlExpression.Append(", "); VisitExpression(expression.Right); SqlExpression.Append(")"); return(expression); } SqlExpression.Append("("); var nullLeft = IsNullExpression(expression.Left); var nullRight = IsNullExpression(expression.Right); if ((expression.NodeType == ExpressionType.NotEqual || expression.NodeType == ExpressionType.Equal) && (nullLeft || nullRight)) { if (expression.NodeType == ExpressionType.NotEqual) { SqlExpression.Append("(NOT "); } if (nullRight) { VisitExpression(expression.Left); } else { VisitExpression(expression.Right); } SqlExpression.Append(" IS NULL)"); if (expression.NodeType == ExpressionType.NotEqual) { SqlExpression.Append(")"); } return(expression); } if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { BinaryLevel = Level; } VisitExpression(expression.Left); // In production code, handle this via lookup tables. switch (expression.NodeType) { case ExpressionType.Equal: SqlExpression.Append(" = "); break; case ExpressionType.NotEqual: SqlExpression.Append(" <> "); break; case ExpressionType.AndAlso: case ExpressionType.And: SqlExpression.Append(" AND "); break; case ExpressionType.OrElse: case ExpressionType.Or: SqlExpression.Append(" OR "); break; case ExpressionType.Add: if (expression.Type == typeof(string)) { SqlExpression.Append(" || "); } else { SqlExpression.Append(" + "); } break; case ExpressionType.Subtract: SqlExpression.Append(" - "); break; case ExpressionType.Multiply: SqlExpression.Append(" * "); break; case ExpressionType.Divide: SqlExpression.Append(" / "); break; case ExpressionType.GreaterThan: SqlExpression.Append(" > "); break; case ExpressionType.GreaterThanOrEqual: SqlExpression.Append(" >= "); break; case ExpressionType.LessThan: SqlExpression.Append(" < "); break; case ExpressionType.LessThanOrEqual: SqlExpression.Append(" <= "); break; default: base.VisitBinaryExpression(expression); break; } VisitExpression(expression.Right); if (expression.NodeType == ExpressionType.NotEqual) { SqlExpression.Append(" OR ("); if (expression.Left is ConstantExpression || expression.Left is PartialEvaluationExceptionExpression) { VisitExpression(expression.Right); } else { VisitExpression(expression.Left); } SqlExpression.Append(" IS NULL)"); } SqlExpression.Append(")"); return(expression); }
public static bool tester <T>(BinaryExpression CC) { return(true); }
protected override Expression VisitBinary(BinaryExpression node) { var left = Visit(node.Left).UnwrapInnerExpression(); var right = Visit(node.Right).UnwrapInnerExpression(); var leftConstant = left as ConstantExpression; var rightConstant = right as ConstantExpression; switch (node.NodeType) { case ExpressionType.AndAlso: { if (leftConstant != null && rightConstant != null) { if (false.Equals(leftConstant.Value) || false.Equals(rightConstant.Value)) { return(Expression.Constant(false)); } else if (true.Equals(leftConstant.Value) && true.Equals(rightConstant.Value)) { return(Expression.Constant(true)); } } else if (leftConstant != null) { if (false.Equals(leftConstant.Value)) { return(left); } else if (true.Equals(leftConstant.Value)) { return(right); } } else if (rightConstant != null) { if (false.Equals(rightConstant.Value)) { return(right); } else if (true.Equals(rightConstant.Value)) { return(left); } } break; } case ExpressionType.OrElse: { if (leftConstant != null && rightConstant != null) { if (true.Equals(leftConstant.Value) || true.Equals(rightConstant.Value)) { return(Expression.Constant(true)); } else if (false.Equals(leftConstant.Value) && false.Equals(rightConstant.Value)) { return(Expression.Constant(false)); } } else if (leftConstant != null) { if (true.Equals(leftConstant.Value)) { return(left); } else if (false.Equals(leftConstant.Value)) { return(right); } } else if (rightConstant != null) { if (true.Equals(rightConstant.Value)) { return(right); } else if (false.Equals(rightConstant.Value)) { return(left); } } break; } case ExpressionType.Equal: { if (leftConstant != null && rightConstant != null && leftConstant.Type.IsBooleanType() && rightConstant.Type.IsBooleanType()) { if (leftConstant.Value.Equals(rightConstant.Value)) { return(Expression.Constant(true)); } else { return(Expression.Constant(false)); } } else if (leftConstant != null && !right.Type.IsNullableType()) { if (true.Equals(leftConstant.Value)) { return(right); } else if (false.Equals(leftConstant.Value)) { return(Expression.Not(right)); } } else if (rightConstant != null && !left.Type.IsNullableType()) { if (true.Equals(rightConstant.Value)) { return(left); } else if (false.Equals(rightConstant.Value)) { return(Expression.Not(left)); } } else if (left.NodeType == ExpressionType.Not && right.NodeType == ExpressionType.Not) { left = ((UnaryExpression)left).Operand; right = ((UnaryExpression)right).Operand; ExpressionExtensions.MatchNullableTypes(ref left, ref right); return(Visit(Expression.Equal(left, right))); } else if (left.NodeType == ExpressionType.Not && !left.Type.IsNullableType() && !right.Type.IsNullableType()) { left = ((UnaryExpression)left).Operand; ExpressionExtensions.MatchNullableTypes(ref left, ref right); return(Visit(Expression.NotEqual(left, right))); } else if (right.NodeType == ExpressionType.Not && !left.Type.IsNullableType() && !right.Type.IsNullableType()) { right = ((UnaryExpression)right).Operand; ExpressionExtensions.MatchNullableTypes(ref left, ref right); return(Visit(Expression.NotEqual(left, right))); } break; } case ExpressionType.NotEqual: { if (leftConstant != null && rightConstant != null && leftConstant.Type.IsBooleanType() && rightConstant.Type.IsBooleanType()) { if (leftConstant.Value.Equals(rightConstant.Value)) { return(Expression.Constant(false)); } else { return(Expression.Constant(true)); } } else if (leftConstant != null && !right.Type.IsNullableType()) { if (false.Equals(leftConstant.Value)) { return(right); } else if (true.Equals(leftConstant.Value)) { return(Expression.Not(right)); } } else if (rightConstant != null && !left.Type.IsNullableType()) { if (false.Equals(rightConstant.Value)) { return(left); } else if (true.Equals(rightConstant.Value)) { return(Expression.Not(left)); } } else if (left.NodeType == ExpressionType.Not && right.NodeType == ExpressionType.Not) { left = ((UnaryExpression)left).Operand; right = ((UnaryExpression)right).Operand; ExpressionExtensions.MatchNullableTypes(ref left, ref right); return(Visit(Expression.NotEqual(left, right))); } else if (left.NodeType == ExpressionType.Not && !left.Type.IsNullableType() && !right.Type.IsNullableType()) { left = ((UnaryExpression)left).Operand; ExpressionExtensions.MatchNullableTypes(ref left, ref right); return(Visit(Expression.Equal(left, right))); } else if (right.NodeType == ExpressionType.Not && !left.Type.IsNullableType() && !right.Type.IsNullableType()) { right = ((UnaryExpression)right).Operand; ExpressionExtensions.MatchNullableTypes(ref left, ref right); return(Visit(Expression.Equal(left, right))); } break; } } return(node.UpdateWithConversion(left, right)); }
public static LoopExpression buildWhileExpression(BinaryExpression whileCondition, Expression loop) { LabelTarget label = Expression.Label(); return(Expression.Loop(Expression.IfThenElse(whileCondition, loop, Expression.Break(label)), label)); }
protected virtual T VisitBinary_Modulo(BinaryExpression exp) { throw new NotImplementedException(exp.ToString()); }
protected override Expression VisitBinaryExpression([NotNull] BinaryExpression binaryExpression) { Check.NotNull(binaryExpression, "binaryExpression"); _binaryExpression = binaryExpression; if (binaryExpression.IsLogicalOperation()) { _sql.Append("("); } VisitExpression(binaryExpression.Left); string op; switch (binaryExpression.NodeType) { case ExpressionType.Equal: op = " = "; break; case ExpressionType.NotEqual: op = " <> "; break; case ExpressionType.GreaterThan: op = " > "; break; case ExpressionType.GreaterThanOrEqual: op = " >= "; break; case ExpressionType.LessThan: op = " < "; break; case ExpressionType.LessThanOrEqual: op = " <= "; break; case ExpressionType.AndAlso: op = " AND "; break; case ExpressionType.OrElse: op = " OR "; break; case ExpressionType.Add: op = " " + ConcatOperator + " "; break; default: throw new ArgumentOutOfRangeException(); } _sql.Append(op); VisitExpression(binaryExpression.Right); if (binaryExpression.IsLogicalOperation()) { _sql.Append(")"); } _binaryExpression = null; return(binaryExpression); }
private object EvaluteBinaryExpression(BinaryExpression e, VariableContext context, out bool isEvaluated) { isEvaluated = false; bool isTupleValue = e.Right.Type.Name.Contains("Tuple"); if (e.Operator == BinaryOperator.Assign && (e.Left is MultipleVariableExpression || isTupleValue)) { isEvaluated = true; object rightValue = Evaluate(e.Right, context); if (e.Left is MultipleVariableExpression) { MultipleVariableExpression mv = e.Left as MultipleVariableExpression; if (isTupleValue) { int count = mv.Type.GenericTypeArguments.Length; for (int i = 0; i <= count - 1; i++) { context.Set(mv.Variables[i], rightValue.GetType().GetProperty("Item" + (i + 1)).GetValue(rightValue)); } } else { context.Set(mv.Variables[0], rightValue); } } else { context.Set((e.Left as VariableExpression).VariableName, rightValue.GetType().GetProperty("Item1").GetValue(rightValue)); } return(rightValue); } else if (e.Operator == BinaryOperator.Add) { if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Add(Evaluate(e.Right, context) as Matrix)); } else if (e.Left.Type == typeof(Matrix) && Types.IsNumberType(e.Right.Type)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Add(Types.ConvertValue <double>(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Matrix) && Types.IsNumberType(e.Left.Type)) { isEvaluated = true; return((Evaluate(e.Right, context) as Matrix).Add(Types.ConvertValue <double>(Evaluate(e.Left, context)))); } else if (e.Left.Type == typeof(Vector) && Types.IsNumberType(e.Right.Type)) { isEvaluated = true; return((Evaluate(e.Left, context) as Vector).Add(Types.ConvertValue <double>(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Vector) && Types.IsNumberType(e.Left.Type)) { isEvaluated = true; return((Evaluate(e.Right, context) as Vector).Add(Types.ConvertValue <double>(Evaluate(e.Left, context)))); } } else if (e.Operator == BinaryOperator.Subtract) { if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Add((Evaluate(e.Right, context) as Matrix).ToNegative())); } else if (e.Left.Type == typeof(Matrix) && Types.IsNumberType(e.Right.Type)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Subtract(Types.ConvertValue <double>(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Matrix) && Types.IsNumberType(e.Left.Type)) { isEvaluated = true; return((Evaluate(e.Right, context) as Matrix).Subtract(Types.ConvertValue <double>(Evaluate(e.Left, context))).GetNegative()); } else if (e.Left.Type == typeof(Vector) && Types.IsNumberType(e.Right.Type)) { isEvaluated = true; return((Evaluate(e.Left, context) as Vector).Subtract(Types.ConvertValue <double>(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Vector) && Types.IsNumberType(e.Left.Type)) { isEvaluated = true; return((Evaluate(e.Right, context) as Vector).Subtract(Types.ConvertValue <double>(Evaluate(e.Left, context))).GetNegative()); } } else if (e.Operator == BinaryOperator.Multiply) { if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Multiply(Evaluate(e.Right, context) as Matrix)); } else if (e.Left.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Multiply(Convert.ToDouble(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Right, context) as Matrix).Multiply(Convert.ToDouble(Evaluate(e.Left, context)))); } else if (e.Left.Type == typeof(Vector) && Types.IsNumberType(e.Right.Type)) { isEvaluated = true; return((Evaluate(e.Left, context) as Vector).Multiply(Types.ConvertValue <double>(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Vector) && Types.IsNumberType(e.Left.Type)) { isEvaluated = true; return((Evaluate(e.Right, context) as Vector).Multiply(Types.ConvertValue <double>(Evaluate(e.Left, context))).GetNegative()); } } else if (e.Operator == BinaryOperator.Divide) { if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Divide((Evaluate(e.Right, context) as Matrix))); } else if (e.Left.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Left, context) as Matrix).Multiply(1 / Convert.ToDouble(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Matrix)) { isEvaluated = true; return((Evaluate(e.Right, context) as Matrix).ElementInvert().Multiply(Convert.ToDouble(Evaluate(e.Left, context)))); } if (e.Left.Type == typeof(Vector)) { isEvaluated = true; return((Evaluate(e.Left, context) as Vector).Multiply(1 / Convert.ToDouble(Evaluate(e.Right, context)))); } else if (e.Right.Type == typeof(Vector)) { isEvaluated = true; return((Evaluate(e.Right, context) as Vector).ElementInvert().Multiply(Convert.ToDouble(Evaluate(e.Left, context)))); } } return(null); }
public virtual void VisitLogicalExpression(BinaryExpression binaryExpression) { VisitBinaryExpression(binaryExpression); }
private string AndAlso(BinaryExpression exp) => Base(exp.Left) + " AND " + Secondary.Serialize(exp.Right);
private void EmitNullableCoalesce(BinaryExpression b) { Debug.Assert(b.Method == null); var loc = GetLocal(b.Left.Type); var labIfNull = _ilg.DefineLabel(); var labEnd = _ilg.DefineLabel(); EmitExpression(b.Left); _ilg.Emit(OpCodes.Stloc, loc); _ilg.Emit(OpCodes.Ldloca, loc); _ilg.EmitHasValue(b.Left.Type); _ilg.Emit(OpCodes.Brfalse, labIfNull); var nnLeftType = b.Left.Type.GetNonNullableType(); if (b.Conversion != null) { Debug.Assert(b.Conversion.Parameters.Count == 1); var p = b.Conversion.Parameters[0]; Debug.Assert(p.Type.IsAssignableFrom(b.Left.Type) || p.Type.IsAssignableFrom(nnLeftType)); // emit the delegate instance EmitLambdaExpression(b.Conversion); // emit argument if (!p.Type.IsAssignableFrom(b.Left.Type)) { _ilg.Emit(OpCodes.Ldloca, loc); _ilg.EmitGetValueOrDefault(b.Left.Type); } else { _ilg.Emit(OpCodes.Ldloc, loc); } // emit call to invoke _ilg.Emit(OpCodes.Callvirt, b.Conversion.Type.GetMethod("Invoke")); } else if (b.Type != nnLeftType) { _ilg.Emit(OpCodes.Ldloca, loc); _ilg.EmitGetValueOrDefault(b.Left.Type); _ilg.EmitConvertToType(nnLeftType, b.Type, true); } else { _ilg.Emit(OpCodes.Ldloca, loc); _ilg.EmitGetValueOrDefault(b.Left.Type); } FreeLocal(loc); _ilg.Emit(OpCodes.Br, labEnd); _ilg.MarkLabel(labIfNull); EmitExpression(b.Right); if (b.Right.Type != b.Type) { _ilg.EmitConvertToType(b.Right.Type, b.Type, true); } _ilg.MarkLabel(labEnd); }
public BinaryExpression(BinaryExpression left, BinaryExpression right, Operator op) { Left = left; Right = right; Operator = op; }
protected override Expression VisitBinaryExpression(BinaryExpression expression) { SqlExpression.Append(" "); foreach (var candidate in QueryParts.ExpressionMatchers) { if (candidate.TryMatch(expression, SqlExpression, exp => VisitExpression(exp))) { return(expression); } } var left = expression.Left; var right = expression.Right; if (left.Type == typeof(int) && right.Type == typeof(int) && (left.NodeType == ExpressionType.Convert && right.NodeType == ExpressionType.Constant || left.NodeType == ExpressionType.Constant && right.NodeType == ExpressionType.Convert)) { var ual = left as UnaryExpression; var uar = right as UnaryExpression; if (ual != null) { var ce = ConvertToEnum(ual, right as ConstantExpression); if (ce != null) { right = ce; } } else if (uar != null) { var ce = ConvertToEnum(uar, left as ConstantExpression); if (ce != null) { left = ce; } } } switch (expression.NodeType) { case ExpressionType.Coalesce: SqlExpression.Append(" (COALESCE("); VisitExpression(left); SqlExpression.Append(", "); VisitExpression(right); SqlExpression.Append("))"); return(expression); } SqlExpression.Append("("); var nullLeft = IsNullExpression(left); var nullRight = IsNullExpression(right); if ((expression.NodeType == ExpressionType.NotEqual || expression.NodeType == ExpressionType.Equal) && (nullLeft || nullRight)) { if (expression.NodeType == ExpressionType.NotEqual) { SqlExpression.Append("(NOT "); } if (nullRight) { VisitExpression(left); } else { VisitExpression(right); } SqlExpression.Append(" IS NULL)"); if (expression.NodeType == ExpressionType.NotEqual) { SqlExpression.Append(")"); } return(expression); } VisitExpression(left); // In production code, handle this via lookup tables. switch (expression.NodeType) { case ExpressionType.Equal: SqlExpression.Append(" = "); break; case ExpressionType.NotEqual: SqlExpression.Append(" <> "); break; case ExpressionType.AndAlso: case ExpressionType.And: SqlExpression.Append(" AND "); break; case ExpressionType.OrElse: case ExpressionType.Or: SqlExpression.Append(" OR "); break; case ExpressionType.Add: if (expression.Type == typeof(string)) { SqlExpression.Append(" || "); } else { SqlExpression.Append(" + "); } break; case ExpressionType.Subtract: SqlExpression.Append(" - "); break; case ExpressionType.Multiply: SqlExpression.Append(" * "); break; case ExpressionType.Divide: SqlExpression.Append(" / "); break; case ExpressionType.GreaterThan: SqlExpression.Append(" > "); break; case ExpressionType.GreaterThanOrEqual: SqlExpression.Append(" >= "); break; case ExpressionType.LessThan: SqlExpression.Append(" < "); break; case ExpressionType.LessThanOrEqual: SqlExpression.Append(" <= "); break; case ExpressionType.Modulo: SqlExpression.Append(" % "); break; default: base.VisitBinaryExpression(expression); break; } VisitExpression(right); if (expression.NodeType == ExpressionType.NotEqual) { SqlExpression.Append(" OR ("); if (left is ConstantExpression || left is PartialEvaluationExceptionExpression) { VisitExpression(right); } else { VisitExpression(left); } SqlExpression.Append(" IS NULL)"); } SqlExpression.Append(")"); return(expression); }
// < protected override DbExpression VisitBinary_LessThan(BinaryExpression exp) { return(DbExpression.LessThan(this.Visit(exp.Left), this.Visit(exp.Right))); }
Expression BuildExpr <T>(Rule r, ParameterExpression OrderType) { Expression propertyOnOrder = null; Type propType = null; ExpressionType tBinary; if (string.IsNullOrEmpty(r.MemberName))//check is against the object itself { propertyOnOrder = OrderType; propType = propertyOnOrder.Type; } else if (r.MemberName.Contains('.'))//Child property { String[] childProperties = r.MemberName.Split('.'); var property = typeof(T).GetProperty(childProperties[0]); var paramExp = Expression.Parameter(typeof(T), "SomeObject"); propertyOnOrder = Expression.PropertyOrField(OrderType, childProperties[0]); for (int i = 1; i < childProperties.Length; i++) { var orig = property; property = property.PropertyType.GetProperty(childProperties[i]); if (property != null) { propertyOnOrder = Expression.PropertyOrField(propertyOnOrder, childProperties[i]); } } propType = propertyOnOrder.Type; } else//Property { propertyOnOrder = Expression.PropertyOrField(OrderType, r.MemberName); propType = propertyOnOrder.Type; } // is the operator a known .NET operator? if (ExpressionType.TryParse(r.Operator, out tBinary) || r.Operator == "Function") { //no repetition of error message,action or setter found Expression right = null; BinaryExpression binary = null; MethodCallExpression ErrorMessage = Expression.Call(OrderType, "AddMessage", null, new Expression[] { Expression.Constant(r.ErrorMessage) }); if (r.Operator != "Function") { right = this.StringToExpression(r.TargetValue, propType); binary = Expression.MakeBinary(tBinary, propertyOnOrder, right); } //function if (!string.IsNullOrEmpty(r.Function)) { // var firstexp = Expression.MakeBinary(tBinary, propertyOnOrder, right); Expression[] functionParams = new Expression[] { Expression.Constant(r.ErrorMessage) }; Expression FunctionCall = Expression.Call(OrderType, r.Function, null, r.Inputs.Select(x => Expression.Constant(x)).ToArray()); if (r.Operator == "Function") { //call functon and if the function returns false, set error message //Expression.IfThenElse(FunctionCall, Expression.Constant(true) return(Expression.Condition(FunctionCall, Expression.Constant(true), Expression.Block(ErrorMessage, Expression.Condition(Expression.Constant(r.ReturnTue), Expression.Constant(true), Expression.Constant(true))))); } return(Expression.Block(Expression.IfThenElse(binary, FunctionCall, ErrorMessage), Expression.Condition(Expression.Constant(r.ReturnTue), Expression.Condition(binary, binary, Expression.Not(binary)), binary) ));//need fix-u dont // } //setter else if (!string.IsNullOrEmpty(r.Setter)) { //no repetition of error message,action or setter found var prop1 = Expression.PropertyOrField(OrderType, r.Setter.Split('=')[0]); var prop2 = Expression.Constant(r.Setter.Split('=')[1]); return(Expression.Block(Expression.IfThenElse(binary, Expression.Assign(prop1, prop2), ErrorMessage), Expression.Condition(Expression.Constant(r.ReturnTue), Expression.Condition(binary, binary, Expression.Not(binary)), binary) )); // } // else { return(Expression.Block(Expression.IfThen(Expression.Not(binary), ErrorMessage), Expression.Condition(Expression.Constant(r.ReturnTue), Expression.Condition(binary, binary, Expression.Not(binary)), binary) )); //var ifthen = Expression.IfThen(Expression.Not(binary), ErrorMessage); //return Expression.Block(ifthen, binary); } } else if (r.Operator == "IsMatch") { var tester = Expression.Call( typeof(Regex).GetMethod("IsMatch", new[] { typeof(string), typeof(string), typeof(RegexOptions) }), propertyOnOrder, Expression.Constant(r.TargetValue, typeof(string)), Expression.Constant(RegexOptions.IgnoreCase, typeof(RegexOptions)) ); return(Expression.Block(Expression.IfThen(tester, Expression.Call(OrderType, "AddMessage", null, new Expression[] { Expression.Constant(r.MemberName) })), tester)); } else //Invoke a method on the Property { Type[] parameterTypes = r.Inputs.Select(x => x.GetType()).ToArray(); var methodInfo = propType.GetMethod(r.Operator, parameterTypes); if (!methodInfo.IsGenericMethod) { parameterTypes = null;//Only pass in type information to a Generic Method } Expression[] prametersAsArray = r.Inputs.Select(x => Expression.Constant(x)).ToArray(); var firstcall = Expression.Call(propertyOnOrder, r.Operator, parameterTypes, prametersAsArray); var message = Expression.Call(OrderType, "AddMessage", null, new Expression[] { Expression.Constant(r.MemberName) }); var ifthen = Expression.IfThen(Expression.Not(firstcall), message); return(Expression.Block(ifthen, firstcall)); } }
// % protected override DbExpression VisitBinary_Modulo(BinaryExpression exp) { return(DbExpression.Modulo(this.Visit(exp.Left), this.Visit(exp.Right), exp.Type)); }
protected Expression Compare(BinaryExpression bop) { var e1 = this.SkipConvert(bop.Left); var e2 = this.SkipConvert(bop.Right); OuterJoinedExpression oj1 = e1 as OuterJoinedExpression; OuterJoinedExpression oj2 = e2 as OuterJoinedExpression; EntityExpression entity1 = oj1 != null ? oj1.Expression as EntityExpression : e1 as EntityExpression; EntityExpression entity2 = oj2 != null ? oj2.Expression as EntityExpression : e2 as EntityExpression; bool negate = bop.NodeType == ExpressionType.NotEqual; // check for outer-joined entity comparing against null. These are special because outer joins have // a test expression specifically desgined to be tested against null to determine if the joined side exists. if (oj1 != null && e2.NodeType == ExpressionType.Constant && ((ConstantExpression)e2).Value == null) { return(MakeIsNull(oj1.Test, negate)); } else if (oj2 != null && e1.NodeType == ExpressionType.Constant && ((ConstantExpression)e1).Value == null) { return(MakeIsNull(oj2.Test, negate)); } // if either side is an entity construction expression then compare using its primary key members if (entity1 != null) { return(this.MakePredicate(e1, e2, this.mapping.GetPrimaryKeyMembers(entity1.Entity), negate)); } else if (entity2 != null) { return(this.MakePredicate(e1, e2, this.mapping.GetPrimaryKeyMembers(entity2.Entity), negate)); } // check for comparison of user constructed type projections var dm1 = this.GetDefinedMembers(e1); var dm2 = this.GetDefinedMembers(e2); if (dm1 == null && dm2 == null) { // neither are constructed types return(bop); } if (dm1 != null && dm2 != null) { // both are constructed types, so they'd better have the same members declared HashSet <string> names1 = new HashSet <string>(dm1.Select(m => m.Name)); HashSet <string> names2 = new HashSet <string>(dm2.Select(m => m.Name)); if (names1.IsSubsetOf(names2) && names2.IsSubsetOf(names1)) { return(MakePredicate(e1, e2, dm1, negate)); } } else if (dm1 != null) { return(MakePredicate(e1, e2, dm1, negate)); } else if (dm2 != null) { return(MakePredicate(e1, e2, dm2, negate)); } throw new InvalidOperationException("Cannot compare two constructed types with different sets of members assigned."); }
// - protected override DbExpression VisitBinary_Subtract(BinaryExpression exp) { return(DbExpression.Subtract(this.Visit(exp.Left), this.Visit(exp.Right), exp.Type)); }
public override void Visit(BinaryExpression node) { CannotOptimize(node); }
// + protected override DbExpression VisitBinary_Add(BinaryExpression exp) { return(DbExpression.Add(this.Visit(exp.Left), this.Visit(exp.Right), exp.Type, exp.Method)); }
// a??b protected override DbExpression VisitBinary_Coalesce(BinaryExpression exp) { DbExpression dbExp = new DbCoalesceExpression(this.Visit(exp.Left), this.Visit(exp.Right)); return(dbExp); }
// >= protected override DbExpression VisitBinary_GreaterThanOrEqual(BinaryExpression exp) { return(DbExpression.GreaterThanOrEqual(this.Visit(exp.Left), this.Visit(exp.Right))); }
static IEnumerable <Key> LessThan <Key>(BTreeBase <Key, Key> sourceCollection, BinaryExpression binExp) #if WINDOWS_PHONE where Key : new() #endif { SessionBase session = sourceCollection.Session; Expression leftSide = binExp.Left; Expression rightSide = binExp.Right; object rightValue = GetRightValue(leftSide, rightSide); CompareByField <Key> comparer = sourceCollection.Comparer as CompareByField <Key>; if (leftSide.NodeType == ExpressionType.Parameter) { Key key = (Key)rightValue; if (key != null) { BTreeSetIterator <Key> itr = sourceCollection.Iterator(); if (itr.GoTo(key)) { while (itr.Previous() != null) { yield return(itr.Current()); } } } } else { if (comparer != null) { //if we were able to create a hash from the right side (likely) MemberExpression returnedEx = null; #if WINDOWS_PHONE || WINDOWS_UWP || NET_CORE Key key = (Key)Activator.CreateInstance(typeof(Key)); #else Key key = (Key)FormatterServices.GetUninitializedObject(typeof(Key)); #endif if (comparer.FieldsToCompare == null) { comparer.SetupFieldsToCompare(); } DataMember dataMember = comparer.FieldsToCompare[0]; if (rightValue != null && HasIndexablePropertyOnLeft <Key>(leftSide, sourceCollection, dataMember, out returnedEx)) { //cast to MemberExpression - it allows us to get the property MemberExpression propExp = (MemberExpression)returnedEx; MemberInfo property = propExp.Member; foreach (DataMember member in comparer.FieldsToCompare.Skip(1)) { if (member.GetTypeCode == TypeCode.String) { member.SetMemberValue(key, ""); } } dataMember.SetMemberValueWithPossibleConvert(key, rightValue); BTreeSetIterator <Key> itr = sourceCollection.Iterator(); itr.GoTo(key); var v = itr.Current(); if (v == null) { v = itr.Previous(); } while (v != null && comparer.CompareField(dataMember, key, v, 0) == 0) { v = itr.Previous(); } while (v != null) { yield return(v); v = itr.Previous(); } } else if (leftSide.NodeType == ExpressionType.Call) { // don't know yet how to handle TODO /*MethodCallExpression expression = leftSide as MethodCallExpression; * Trace.Out.WriteLine("Method: " + expression.Method.Name); * Trace.Out.WriteLine("Args: "); * foreach (var exp in expression.Arguments) * sourceCollection where */ } } } }
private void EmitBranchComparison(bool branch, BinaryExpression node, Label label) { Debug.Assert(node.NodeType == ExpressionType.Equal || node.NodeType == ExpressionType.NotEqual); Debug.Assert(!node.IsLiftedToNull); // To share code paths, we want to treat NotEqual as an inverted Equal var branchWhenEqual = branch == (node.NodeType == ExpressionType.Equal); if (node.Method != null) { EmitBinaryMethod(node, CompilationFlags.EmitAsNoTail); // EmitBinaryMethod takes into account the Equal/NotEqual // node kind, so use the original branch value EmitBranchOp(branch, label); } else if (ConstantCheck.IsNull(node.Left)) { if (node.Right.Type.IsNullableType()) { EmitAddress(node.Right, node.Right.Type); _ilg.EmitHasValue(node.Right.Type); } else { Debug.Assert(!node.Right.Type.IsValueType); EmitExpression(GetEqualityOperand(node.Right)); } EmitBranchOp(!branchWhenEqual, label); } else if (ConstantCheck.IsNull(node.Right)) { if (node.Left.Type.IsNullableType()) { EmitAddress(node.Left, node.Left.Type); _ilg.EmitHasValue(node.Left.Type); } else { Debug.Assert(!node.Left.Type.IsValueType); EmitExpression(GetEqualityOperand(node.Left)); } EmitBranchOp(!branchWhenEqual, label); } else if (node.Left.Type.IsNullableType() || node.Right.Type.IsNullableType()) { EmitBinaryExpression(node); // EmitBinaryExpression takes into account the Equal/NotEqual // node kind, so use the original branch value EmitBranchOp(branch, label); } else { EmitExpression(GetEqualityOperand(node.Left)); EmitExpression(GetEqualityOperand(node.Right)); if (branchWhenEqual) { _ilg.Emit(OpCodes.Beq, label); } else { _ilg.Emit(OpCodes.Ceq); _ilg.Emit(OpCodes.Brfalse, label); } } }
private static void BuildBranches(Expression expression, PropertyAccessTree tree, Stack <PropertyAccessTreeNode> currentNodeBranch, Predicate <Type> typeFilter) { BinaryExpression binaryExpression = expression as BinaryExpression; if (binaryExpression != null) { BuildBranches(binaryExpression.Left, tree, currentNodeBranch, typeFilter); BuildBranches(binaryExpression.Right, tree, currentNodeBranch, typeFilter); return; } UnaryExpression unaryExpression = expression as UnaryExpression; if (unaryExpression != null) { BuildBranches(unaryExpression.Operand, tree, currentNodeBranch, typeFilter); return; } MethodCallExpression methodCallExpression = expression as MethodCallExpression; if (methodCallExpression != null) { foreach (Expression argument in methodCallExpression.Arguments) { BuildBranches(argument, tree, currentNodeBranch, typeFilter); } return; } ConditionalExpression conditionalExpression = expression as ConditionalExpression; if (conditionalExpression != null) { BuildBranches(conditionalExpression.Test, tree, currentNodeBranch, typeFilter); BuildBranches(conditionalExpression.IfTrue, tree, currentNodeBranch, typeFilter); BuildBranches(conditionalExpression.IfFalse, tree, currentNodeBranch, typeFilter); return; } InvocationExpression invocationExpression = expression as InvocationExpression; if (invocationExpression != null) { foreach (Expression argument in invocationExpression.Arguments) { BuildBranches(argument, tree, currentNodeBranch, typeFilter); } BuildBranches(invocationExpression.Expression, tree, currentNodeBranch, typeFilter); return; } switch (expression.NodeType) { case ExpressionType.MemberAccess: MemberExpression memberExpression = (MemberExpression)expression; PropertyInfo property = memberExpression.Member as PropertyInfo; FieldInfo fieldInfo = memberExpression.Member as FieldInfo; if (property != null) { PropertyAccessNode node = new PropertyAccessNode(memberExpression); currentNodeBranch.Push(node); BuildBranches(memberExpression.Expression, tree, currentNodeBranch, typeFilter); } else if (fieldInfo != null) { if (typeFilter(fieldInfo.FieldType)) { ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression; if (constantExpression.Value != null) { object value = fieldInfo.GetValue(constantExpression.Value); ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)value); currentNodeBranch.Push(constantNode); AddBranch(tree, currentNodeBranch); } } else { currentNodeBranch.Clear(); } } else { BuildBranches(memberExpression.Expression, tree, currentNodeBranch, typeFilter); } break; case ExpressionType.Parameter: ParameterExpression parameterExpression = (ParameterExpression)expression; ParameterNode parameterNode = new ParameterNode(expression.Type, parameterExpression.Name); currentNodeBranch.Push(parameterNode); AddBranch(tree, currentNodeBranch); break; case ExpressionType.Constant: { ConstantExpression constantExpression = (ConstantExpression)expression; if (typeFilter(constantExpression.Type) && constantExpression.Value != null) { ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)constantExpression.Value); currentNodeBranch.Push(constantNode); AddBranch(tree, currentNodeBranch); } else { currentNodeBranch.Clear(); } } break; case ExpressionType.New: { NewExpression newExpression = (NewExpression)expression; foreach (Expression argument in newExpression.Arguments) { BuildBranches(argument, tree, currentNodeBranch, typeFilter); } } break; case ExpressionType.MemberInit: { MemberInitExpression memberInitExpression = (MemberInitExpression)expression; BuildBranches(memberInitExpression.NewExpression, tree, currentNodeBranch, typeFilter); foreach (var memberBinding in memberInitExpression.Bindings) { MemberAssignment assignment = memberBinding as MemberAssignment; if (assignment != null) { BuildBranches(assignment.Expression, tree, currentNodeBranch, typeFilter); } } } break; default: throw new InvalidProgramException(string.Format("CLINQ does not support expressions of type: {0}", expression.NodeType)); } }
public virtual void VisitBinaryExpression(BinaryExpression binaryExpression) { VisitExpression(binaryExpression.Left.As <Expression>()); VisitExpression(binaryExpression.Right.As <Expression>()); }