static bool CheckArgument(ExpressionParser parser, MethodCallExpression methE, bool left, out string hint) { int ix1 = left ? 0 : 1; int ix2 = left ? 1 : 0; if (typeof (Delegate).IsAssignableFrom(methE.Arguments[ix1].Type)) { object leftR; try { leftR = parser.DynamicInvoke(Expression.Invoke(methE.Arguments[ix1])); } catch (InvalidOperationException) // delegate needs arguments { hint = null; return false; } if (Equals(leftR, parser.DynamicInvoke(methE.Arguments[ix2]))) { hint = string.Format(", but would have been True if you had invoked '{0}'", NodeFormatter.PrettyPrint(parser.Parse(methE.Arguments[ix1]))); return true; } } hint = null; return false; }
public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint) { var methE = expression as MethodCallExpression; if (methE != null) { if (methE.Method == ObjectEqualsMethodInfo) { var left = parser.DynamicInvoke(methE.Arguments[0]); var right = parser.DynamicInvoke(methE.Arguments[1]); if (left is Delegate || right is Delegate) { if (CheckArgument(parser, methE, true, out hint)) { return true; } if (CheckArgument(parser, methE, false, out hint)) { return true; } hint = ", this is a suspicious comparison"; return true; } } } hint = null; return false; }
public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint) { object left = null; object right = null; Type declaringType = null; var methE = expression as MethodCallExpression; if (methE != null) { if (methE.Method == ObjectEqualsMethodInfo) { left = parser.DynamicInvoke(methE.Object); right = parser.DynamicInvoke(methE.Arguments[0]); // methE.Method.DeclaringType doesn't work here, it will // always return the base class method declaringType = GetDerivedMethodInfo(methE.Object.Type, methE.Method).DeclaringType; } } var binE = expression as BinaryExpression; if (binE != null && binE.NodeType == ExpressionType.Equal) { left = parser.DynamicInvoke(binE.Left); right = parser.DynamicInvoke(binE.Right); if (binE.Method != null) { declaringType = binE.Method.DeclaringType; } else { declaringType = typeof (object); // this should never happen - the hints are only called when the assert fails } } if (left != null && left == right) { hint = ", type " + ExpressionParser.NameOfType(declaringType) + " has a broken equality implementation (both sides are the same object)"; return true; } hint = null; return false; }
public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint) { var methE = expression as MethodCallExpression; if (methE != null) { if (StringEqualsMethodInfo.Any(x => x == methE.Method)) { var obj = parser.DynamicInvoke(methE.Object); var arg = parser.DynamicInvoke(methE.Arguments.First()); var comparison = (StringComparison) (methE.Arguments.Select(parser.DynamicInvoke) .FirstOrDefault(x => x is StringComparison) ?? StringComparison.CurrentCulture); hint = HintUtils.GetStringDifferHint((string) obj, (string) arg, GetComparerFromComparison(comparison)); return hint != null; } } hint = null; return false; }
public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint) { var methE = expression as MethodCallExpression; if (methE != null) { if (methE.Method == ObjectInstanceEqualsMethodInfo) { var obj = parser.DynamicInvoke(methE.Object) as IEnumerable; var arg = parser.DynamicInvoke(methE.Arguments.First()) as IEnumerable; if (obj != null && arg != null) { if (obj.Cast<object>().SequenceEqual(arg.Cast<object>())) { hint = ", but would have been True with .SequenceEqual()"; return true; } } } } hint = null; return false; }
x.GetParameters().Count() == 2); // TODO: equality comparer support public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint) { var methE = expression as MethodCallExpression; if (methE != null) { var typeParams = methE.Method.GetGenericArguments(); if (typeParams.Count() == 1) { var instantiatedMethodInfo = SequenceEqualMethodInfo.MakeGenericMethod(typeParams); if (methE.Method == instantiatedMethodInfo) { var left = parser.DynamicInvoke(methE.Arguments[0]); var right = parser.DynamicInvoke(methE.Arguments[1]); var enumLeft = ((IEnumerable) left).GetEnumerator(); var enumRight = ((IEnumerable) right).GetEnumerator(); { int i = 0; while (enumLeft.MoveNext() && enumRight.MoveNext()) { if (!Equals(enumLeft.Current, enumRight.Current)) { hint = string.Format(", enumerables differ at index {0}, {1} != {2}", i, ObjectFormatter.FormatObject(enumLeft.Current), ObjectFormatter.FormatObject(enumRight.Current)); return true; } ++i; } } } } } hint = null; return false; }
public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint) { if (expression is BinaryExpression && expression.NodeType == ExpressionType.Equal) { var be = (BinaryExpression) expression; object left; object right; try { left = parser.DynamicInvoke(be.Left); right = parser.DynamicInvoke(be.Right); } catch (TargetInvocationException exception) { hint = ObjectFormatter.FormatTargetInvocationException(exception); return true; } return TryGetHint(parser, left, right, out hint); } hint = null; return false; }
string Parse(ExpressionParser parser, Type enumType, Expression expression) { return enumType.Name + "." + Enum.GetName(enumType, parser.DynamicInvoke(expression)); }