TaskResultBinder
using System;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace DotNext.Dynamic
{
internal sealed class TaskResultBinder : CallSiteBinder
{
private const string ResultPropertyName = "Result";
private const BindingFlags ResultPropertyFlags = BindingFlags.Instance | BindingFlags.Public;
[RequiresUnreferencedCode("Runtime binding may be incompatible with IL trimming")]
private static Expression BindProperty(PropertyInfo resultProperty, Expression target, out Expression restrictions)
{
restrictions = Expression.TypeIs(target, resultProperty.DeclaringType);
target = Expression.Call(typeof(Unsafe), "As", new Type[1] {
resultProperty.DeclaringType
}, target);
target = Expression.Property(target, resultProperty);
if (!target.Type.IsValueType)
return target;
return Expression.Convert(target, typeof(object));
}
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(Task<>))]
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(ValueTask<>))]
[RequiresUnreferencedCode("Runtime binding may be incompatible with IL trimming")]
private static Expression Bind(object targetValue, Expression target, LabelTarget returnLabel)
{
target = BindProperty(targetValue.GetType().GetProperty("Result", BindingFlags.Instance | BindingFlags.Public), target, out Expression restrictions);
target = Expression.Return(returnLabel, target);
target = Expression.Condition(restrictions, target, Expression.Goto(CallSiteBinder.UpdateLabel));
return target;
}
[RequiresUnreferencedCode("Runtime binding may be incompatible with IL trimming")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2046", Justification = "No other way to express compatibility with timming")]
public override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel)
{
return Bind(args[0], parameters[0], returnLabel);
}
}
}