Skip to content

Commit 9f8f9c3

Browse files
committed
Stabilize span normalization in expression evaluation
1 parent a585d61 commit 9f8f9c3

1 file changed

Lines changed: 6 additions & 34 deletions

File tree

src/SharpAssert.Runtime/Features/Shared/ExpressionValueEvaluator.cs

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace SharpAssert.Features.Shared;
99

1010
static class ExpressionValueEvaluator
1111
{
12-
static readonly MethodInfo? ToArrayMethod = ResolveToArrayMethod();
12+
static readonly MethodInfo SpanToArrayMethod = typeof(ExpressionValueEvaluator).GetMethod(nameof(SpanToArray), BindingFlags.NonPublic | BindingFlags.Static)!;
1313
static readonly Func<object> NullEvaluator = () => null!;
1414

1515
public static object? Evaluate(Expression expression) => Compile(expression)();
@@ -30,31 +30,6 @@ public static Func<object> Compile(Expression expression)
3030
return () => new EvaluationUnavailable("Evaluation failed");
3131
}
3232

33-
static MethodInfo? ResolveToArrayMethod()
34-
{
35-
foreach (var method in typeof(MemoryExtensions).GetMethods(BindingFlags.Public | BindingFlags.Static))
36-
{
37-
if (method.Name != "ToArray" || !method.IsGenericMethodDefinition)
38-
continue;
39-
40-
var parameters = method.GetParameters();
41-
if (parameters.Length != 1)
42-
continue;
43-
44-
if (IsReadOnlySpan(parameters[0].ParameterType))
45-
return method;
46-
}
47-
48-
return null;
49-
}
50-
51-
static bool IsReadOnlySpan(Type type)
52-
{
53-
return type.IsByRefLike &&
54-
type.IsGenericType &&
55-
type.GetGenericTypeDefinition() == typeof(ReadOnlySpan<>);
56-
}
57-
5833
static Expression Normalize(Expression expression)
5934
{
6035
if (!expression.Type.IsByRefLike)
@@ -70,14 +45,9 @@ static Expression Normalize(Expression expression)
7045
? expression
7146
: Expression.Convert(expression, readOnlySpanType);
7247

73-
if (ToArrayMethod != null)
74-
{
75-
var toArray = ToArrayMethod.MakeGenericMethod(elementType);
76-
var call = Expression.Call(toArray, spanExpression);
77-
return Expression.Convert(call, typeof(object));
78-
}
79-
80-
return Expression.Constant(new EvaluationUnavailable("Span conversion unavailable"), typeof(object));
48+
var toArray = SpanToArrayMethod.MakeGenericMethod(elementType);
49+
var call = Expression.Call(toArray, spanExpression);
50+
return Expression.Convert(call, typeof(object));
8151
}
8252

8353
static bool TryInterpret(Expression expression, out Func<object> result)
@@ -201,4 +171,6 @@ static bool TryEvaluateMember(MemberExpression member, out object value)
201171

202172
static object? TargetOrNull(object? targetValue) => targetValue is EvaluationUnavailable ? null : targetValue;
203173
}
174+
175+
static T[] SpanToArray<T>(ReadOnlySpan<T> span) => span.ToArray();
204176
}

0 commit comments

Comments
 (0)