Skip to content

Commit 3535d7a

Browse files
committed
Leave quoted exprs unchanged when evaluating captures
1 parent 37b24ad commit 3535d7a

File tree

8 files changed

+17
-19
lines changed

8 files changed

+17
-19
lines changed

src/Moq/Evaluator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ internal HashSet<Expression> Nominate(Expression expression)
102102

103103
public override Expression Visit(Expression expression)
104104
{
105-
if (expression != null)
105+
if (expression != null && expression.NodeType != ExpressionType.Quote)
106106
{
107107
bool saveCannotBeEvaluated = this.cannotBeEvaluated;
108108
this.cannotBeEvaluated = false;

src/Moq/ExpressionComparer.cs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ private ExpressionComparer()
1818
{
1919
}
2020

21+
public bool EqualsAfterCapturesEvaluated(Expression x, Expression y)
22+
{
23+
return this.Equals(x?.Apply(EvaluateCaptures.Rewriter), y?.Apply(EvaluateCaptures.Rewriter));
24+
}
25+
2126
public bool Equals(Expression x, Expression y)
2227
{
2328
if (object.ReferenceEquals(x, y))
@@ -30,19 +35,6 @@ public bool Equals(Expression x, Expression y)
3035
return false;
3136
}
3237

33-
// Before actually comparing two nodes, make sure that captures variables have been
34-
// evaluated to their current values (as we don't want to compare their identities):
35-
36-
if (x is MemberExpression)
37-
{
38-
x = x.Apply(EvaluateCaptures.Rewriter);
39-
}
40-
41-
if (y is MemberExpression)
42-
{
43-
y = y.Apply(EvaluateCaptures.Rewriter);
44-
}
45-
4638
if (x.NodeType == y.NodeType)
4739
{
4840
switch (x.NodeType)

src/Moq/ExpressionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ private static bool PartialMatcherAwareEval_ShouldEvaluate(Expression expression
448448
#pragma warning disable 618
449449
return expression.NodeType switch
450450
{
451+
ExpressionType.Quote => false,
451452
ExpressionType.Parameter => false,
452453
ExpressionType.Extension => !(expression is MatchExpression),
453454
ExpressionType.Call => !((MethodCallExpression)expression).Method.IsDefined(typeof(MatcherAttribute), true)

src/Moq/Expressions/Visitors/EvaluateCaptures.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,10 @@ protected override Expression VisitMember(MemberExpression node)
3131
return base.VisitMember(node);
3232
}
3333
}
34+
35+
protected override Expression VisitUnary(UnaryExpression node)
36+
{
37+
return node.NodeType == ExpressionType.Quote ? node : base.VisitUnary(node);
38+
}
3439
}
3540
}

src/Moq/Match.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public bool Equals(Match<T> other)
217217
}
218218
else if (!(this.RenderExpression is MethodCallExpression ce && ce.Method.DeclaringType == typeof(Match)))
219219
{
220-
return ExpressionComparer.Default.Equals(this.RenderExpression, other.RenderExpression);
220+
return ExpressionComparer.Default.EqualsAfterCapturesEvaluated(this.RenderExpression, other.RenderExpression);
221221
}
222222
else
223223
{

src/Moq/Matchers/ExpressionMatcher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public ExpressionMatcher(Expression expression)
1919
public bool Matches(object argument, Type parameterType)
2020
{
2121
return argument is Expression valueExpression
22-
&& ExpressionComparer.Default.Equals(this.expression, valueExpression);
22+
&& ExpressionComparer.Default.EqualsAfterCapturesEvaluated(this.expression, valueExpression);
2323
}
2424

2525
public void SetupEvaluatedSuccessfully(object argument, Type parameterType)

src/Moq/MethodExpectation.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public override bool Equals(Expectation obj)
240240
{
241241
for (int j = 0, nj = e1.Expressions.Count; j < nj; ++j)
242242
{
243-
if (!ExpressionComparer.Default.Equals(e1.Expressions[j], e2.Expressions[j]))
243+
if (!ExpressionComparer.Default.EqualsAfterCapturesEvaluated(e1.Expressions[j], e2.Expressions[j]))
244244
{
245245
return false;
246246
}
@@ -250,7 +250,7 @@ public override bool Equals(Expectation obj)
250250
}
251251
}
252252

253-
if (!ExpressionComparer.Default.Equals(this.partiallyEvaluatedArguments[i], other.partiallyEvaluatedArguments[i]))
253+
if (!ExpressionComparer.Default.EqualsAfterCapturesEvaluated(this.partiallyEvaluatedArguments[i], other.partiallyEvaluatedArguments[i]))
254254
{
255255
return false;
256256
}

src/Moq/StubbedPropertiesSetup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public PropertyAccessorExpectation(Mock mock)
9090

9191
public override bool Equals(Expectation other)
9292
{
93-
return other is PropertyAccessorExpectation pae && ExpressionComparer.Default.Equals(this.expression, pae.expression);
93+
return other is PropertyAccessorExpectation pae && ExpressionComparer.Default.EqualsAfterCapturesEvaluated(this.expression, pae.expression);
9494
}
9595

9696
public override int GetHashCode()

0 commit comments

Comments
 (0)