/// <summary> /// Deal with a special case for an index redirection where we are looking for /// an integer or some simply type. There is only one very special case where this /// shows up. Unlikely to be used by physics, actually. :-) The second case we /// handle is dealing with != for two object compares. /// </summary> /// <param name="expression"></param> /// <returns></returns> protected override Expression VisitBinary(BinaryExpression expression) { // // If we are comparing a "new" against a null, then we don't support that. // if (expression.Left.IsNull() || expression.Right.IsNull()) { Expression nonNull = expression.Left.IsNull() ? expression.Right : expression.Left; if (nonNull.NodeType == ExpressionType.New) { throw new InvalidOperationException(string.Format("Doing a null comparison to a temporary object created in the query is very likely to generate incorrect code - not supported ({0})", expression.ToString())); } } // If this is an array index, then... if (expression.NodeType == ExpressionType.ArrayIndex && expression.IsLeafType()) { var rootExpr = expression.Left as MemberExpression; if (rootExpr != null) { return Expression.ArrayIndex(VisitExpressionImplemented(rootExpr), expression.Right); } } // If this is a comparison, and these are objects that have indicies (in whatever we are looping through)... if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { // Are we pointing to something we can deal with? var indexLeft = ExtractIndexReference(expression.Left); if (indexLeft != null) { var indexRight = ExtractIndexReference(expression.Right); if (indexRight != null) { if (expression.NodeType == ExpressionType.NotEqual) { return Expression.NotEqual(indexLeft, indexRight); } else { return Expression.Equal(indexLeft, indexRight); } } } } return base.VisitBinary(expression); }