Guest User

Untitled

a guest
Feb 18th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.94 KB | None | 0 0
  1. #if INTERACTIVE
  2. #r "Microsoft.CSharp.dll"
  3. #endif
  4.  
  5. open System
  6. open System.Dynamic
  7. open System.Linq.Expressions
  8. open System.Reflection
  9. open System.Runtime.CompilerServices
  10. open Microsoft.CSharp.RuntimeBinder
  11. open Microsoft.FSharp.Reflection
  12.  
  13. let (?) (targetObject : obj) (targetMember:string) : 'TargetResult =
  14. let targetResultType = typeof<'TargetResult>
  15. if not (FSharpType.IsFunction targetResultType)
  16. then
  17. let cs = CallSite<Func<CallSite, obj, obj>>.Create(Binder.GetMember(CSharpBinderFlags.None, targetMember, null, [| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |]))
  18. unbox (cs.Target.Invoke(cs, targetObject))
  19. else
  20. if not (FSharpType.IsFunction targetResultType) then failwithf "%A is not a function type" targetResultType
  21. let domainType,_ = FSharpType.GetFunctionElements targetResultType
  22. let domainTypes =
  23. if FSharpType.IsTuple domainType then FSharpType.GetTupleElements domainType
  24. elif domainType = typeof<unit> then [| |]
  25. else [|domainType|]
  26. let objToObjFunction =
  27. (fun argObj ->
  28. let realArgs =
  29. match domainTypes with
  30. | [| |] -> [| |]
  31. | [| argTy |] -> [| argObj |]
  32. | argTys -> FSharpValue.GetTupleFields(argObj)
  33.  
  34. let funcType = Expression.GetFuncType [| yield typeof<CallSite>; yield typeof<obj>; yield! domainTypes; yield typeof<obj> |]
  35. let cty = typedefof<CallSite<_>>.MakeGenericType [| funcType |]
  36. let cs = cty.InvokeMember("Create", BindingFlags.Public ||| BindingFlags.Static ||| BindingFlags.InvokeMethod, null, null, [|(box(Binder.InvokeMember(CSharpBinderFlags.None, targetMember, null, null, Array.create (realArgs.Length + 1) (CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, targetMember)))))|])
  37. |> unbox<CallSite>
  38. let target = cs.GetType().GetField("Target").GetValue(cs)
  39. target.GetType().InvokeMember("Invoke", BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.InvokeMethod, null, target, [| yield box cs; yield box targetObject; yield! realArgs |])
  40. )
  41. let atyFunction = FSharpValue.MakeFunction(targetResultType,objToObjFunction)
  42. unbox<'TargetResult> atyFunction
  43.  
  44. let (?<-) (targetObject : obj) (targetMember : string) (args : 'Args) : unit =
  45. let argumentInfos = [| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
  46. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant ||| CSharpArgumentInfoFlags.UseCompileTimeType, null) |]
  47. let binder = Binder.SetMember(CSharpBinderFlags.None,
  48. targetMember,
  49. targetObject.GetType(),
  50. argumentInfos)
  51. let setterSite = CallSite<Func<CallSite, obj, 'Args, obj>>.Create(binder)
  52. setterSite.Target.Invoke(setterSite, targetObject, args) |> ignore
Add Comment
Please, Sign In to add comment