From 084e294c038a49094941f93d47025ef64e7189f9 Mon Sep 17 00:00:00 2001 From: metoule Date: Sun, 18 Aug 2024 18:26:03 +0200 Subject: [PATCH] Extract LateBinders --- src/DynamicExpresso.Core/Parsing/Parser.cs | 70 ------------------ .../Resolution/LateBinders.cs | 71 +++++++++++++++++++ 2 files changed, 71 insertions(+), 70 deletions(-) create mode 100644 src/DynamicExpresso.Core/Resolution/LateBinders.cs diff --git a/src/DynamicExpresso.Core/Parsing/Parser.cs b/src/DynamicExpresso.Core/Parsing/Parser.cs index df5050a..282526e 100644 --- a/src/DynamicExpresso.Core/Parsing/Parser.cs +++ b/src/DynamicExpresso.Core/Parsing/Parser.cs @@ -1,14 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Dynamic; using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; -using System.Runtime.CompilerServices; -using System.Security; using System.Text; using DynamicExpresso.Exceptions; using DynamicExpresso.Reflection; @@ -2590,71 +2586,5 @@ private static Expression GenerateNullableTypeConversion(Expression expr) var conversionType = typeof(Nullable<>).MakeGenericType(exprType); return Expression.ConvertChecked(expr, conversionType); } - - /// - /// Binds to a member access of an instance as late as possible. This allows the use of anonymous types on dynamic values. - /// - private class LateGetMemberCallSiteBinder : CallSiteBinder - { - private readonly string _propertyOrFieldName; - - public LateGetMemberCallSiteBinder(string propertyOrFieldName) - { - _propertyOrFieldName = propertyOrFieldName; - } - - public override Expression Bind(object[] args, ReadOnlyCollection parameters, LabelTarget returnLabel) - { - var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember( - Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None, - _propertyOrFieldName, - TypeUtils.RemoveArrayType(args[0]?.GetType()), - new[] { Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null) } - ); - return binder.Bind(args, parameters, returnLabel); - } - } - - /// - /// Binds to a method invocation of an instance as late as possible. This allows the use of anonymous types on dynamic values. - /// - private class LateInvokeMethodCallSiteBinder : CallSiteBinder - { - private readonly string _methodName; - - public LateInvokeMethodCallSiteBinder(string methodName) - { - _methodName = methodName; - } - - public override Expression Bind(object[] args, ReadOnlyCollection parameters, LabelTarget returnLabel) - { - var binderM = Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember( - Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None, - _methodName, - null, - TypeUtils.RemoveArrayType(args[0]?.GetType()), - parameters.Select(x => Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null)) - ); - return binderM.Bind(args, parameters, returnLabel); - } - } - - /// - /// Binds to an items invocation of an instance as late as possible. This allows the use of anonymous types on dynamic values. - /// - private class LateInvokeIndexCallSiteBinder : CallSiteBinder - { - public override Expression Bind(object[] args, ReadOnlyCollection parameters, LabelTarget returnLabel) - { - var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetIndex( - Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None, - TypeUtils.RemoveArrayType(args[0]?.GetType()), - parameters.Select(x => Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null)) - ); - return binder.Bind(args, parameters, returnLabel); - } - } - } } diff --git a/src/DynamicExpresso.Core/Resolution/LateBinders.cs b/src/DynamicExpresso.Core/Resolution/LateBinders.cs new file mode 100644 index 0000000..6fc40b0 --- /dev/null +++ b/src/DynamicExpresso.Core/Resolution/LateBinders.cs @@ -0,0 +1,71 @@ +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using DynamicExpresso.Reflection; +using Microsoft.CSharp.RuntimeBinder; + +namespace DynamicExpresso.Resolution +{ + internal class LateGetMemberCallSiteBinder : CallSiteBinder + { + private readonly string _propertyOrFieldName; + + public LateGetMemberCallSiteBinder(string propertyOrFieldName) + { + _propertyOrFieldName = propertyOrFieldName; + } + + public override Expression Bind(object[] args, ReadOnlyCollection parameters, LabelTarget returnLabel) + { + var binder = Binder.GetMember( + CSharpBinderFlags.None, + _propertyOrFieldName, + TypeUtils.RemoveArrayType(args[0]?.GetType()), + new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) } + ); + return binder.Bind(args, parameters, returnLabel); + } + } + + /// + /// Binds to a method invocation of an instance as late as possible. This allows the use of anonymous types on dynamic values. + /// + internal class LateInvokeMethodCallSiteBinder : CallSiteBinder + { + private readonly string _methodName; + + public LateInvokeMethodCallSiteBinder(string methodName) + { + _methodName = methodName; + } + + public override Expression Bind(object[] args, ReadOnlyCollection parameters, LabelTarget returnLabel) + { + var binderM = Binder.InvokeMember( + CSharpBinderFlags.None, + _methodName, + null, + TypeUtils.RemoveArrayType(args[0]?.GetType()), + parameters.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)) + ); + return binderM.Bind(args, parameters, returnLabel); + } + } + + /// + /// Binds to an items invocation of an instance as late as possible. This allows the use of anonymous types on dynamic values. + /// + internal class LateInvokeIndexCallSiteBinder : CallSiteBinder + { + public override Expression Bind(object[] args, ReadOnlyCollection parameters, LabelTarget returnLabel) + { + var binder = Binder.GetIndex( + CSharpBinderFlags.None, + TypeUtils.RemoveArrayType(args[0]?.GetType()), + parameters.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)) + ); + return binder.Bind(args, parameters, returnLabel); + } + } +}