Skip to content

Commit

Permalink
Use correct property in expression tree
Browse files Browse the repository at this point in the history
  • Loading branch information
stakx committed Oct 22, 2020
1 parent aacdcb8 commit c57c6ab
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
36 changes: 30 additions & 6 deletions src/Moq/ExpressionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,21 @@ void Split(Expression e, out Expression r /* remainder */, out InvocationShape p
var parameter = Expression.Parameter(r.Type, r is ParameterExpression ope ? ope.Name : ParameterName);
var indexer = indexExpression.Indexer;
var arguments = indexExpression.Arguments;
var method = !assignment && indexer.CanRead(out var getter) ? getter
: indexer.CanWrite(out var setter) ? setter
: null;
MethodInfo method;
if (!assignment && indexer.CanRead(out var getter, out var getterIndexer))
{
method = getter;
indexer = getterIndexer;
}
else if (indexer.CanWrite(out var setter, out var setterIndexer))
{
method = setter;
indexer = setterIndexer;
}
else // This should be unreachable.
{
method = null;
}
p = new InvocationShape(
expression: Expression.Lambda(
Expression.MakeIndex(parameter, indexer, arguments),
Expand Down Expand Up @@ -281,9 +293,21 @@ void Split(Expression e, out Expression r /* remainder */, out InvocationShape p
r = memberAccessExpression.Expression;
var parameter = Expression.Parameter(r.Type, r is ParameterExpression ope ? ope.Name : ParameterName);
var property = memberAccessExpression.GetReboundProperty();
var method = !assignment && property.CanRead(out var getter) ? getter
: property.CanWrite(out var setter) ? setter
: null;
MethodInfo method;
if (!assignment && property.CanRead(out var getter, out var getterProperty))
{
method = getter;
property = getterProperty;
}
else if (property.CanWrite(out var setter, out var setterProperty))
{
method = setter;
property = setterProperty;
}
else // This should be unreachable.
{
method = null;
}
p = new InvocationShape(
expression: Expression.Lambda(
Expression.MakeMemberAccess(parameter, property),
Expand Down
18 changes: 16 additions & 2 deletions src/Moq/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ public static bool CanCreateInstance(this Type type)
}

public static bool CanRead(this PropertyInfo property, out MethodInfo getter)
{
return property.CanRead(out getter, out _);
}

public static bool CanRead(this PropertyInfo property, out MethodInfo getter, out PropertyInfo getterProperty)
{
if (property.CanRead)
{
// The given `PropertyInfo` should be able to provide a getter:
getter = property.GetGetMethod(nonPublic: true);
getterProperty = property;
Debug.Assert(getter != null);
return true;
}
Expand All @@ -47,20 +53,27 @@ public static bool CanRead(this PropertyInfo property, out MethodInfo getter)
.GetMember(property.Name, MemberTypes.Property, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Cast<PropertyInfo>()
.First(p => p.GetSetMethod(nonPublic: true) == baseSetter);
return baseProperty.CanRead(out getter);
return baseProperty.CanRead(out getter, out getterProperty);
}
}

getter = null;
getterProperty = null;
return false;
}

public static bool CanWrite(this PropertyInfo property, out MethodInfo setter)
{
return property.CanWrite(out setter, out _);
}

public static bool CanWrite(this PropertyInfo property, out MethodInfo setter, out PropertyInfo setterProperty)
{
if (property.CanWrite)
{
// The given `PropertyInfo` should be able to provide a setter:
setter = property.GetSetMethod(nonPublic: true);
setterProperty = property;
Debug.Assert(setter != null);
return true;
}
Expand All @@ -83,11 +96,12 @@ public static bool CanWrite(this PropertyInfo property, out MethodInfo setter)
.GetMember(property.Name, MemberTypes.Property, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Cast<PropertyInfo>()
.First(p => p.GetGetMethod(nonPublic: true) == baseGetter);
return baseProperty.CanWrite(out setter);
return baseProperty.CanWrite(out setter, out setterProperty);
}
}

setter = null;
setterProperty = null;
return false;
}

Expand Down

0 comments on commit c57c6ab

Please sign in to comment.