-
-
Save bleis-tift/1075409 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let convert (inp:obj) : 'res = | |
inp |> unbox | |
let (?) (o : obj) (s:string) : 'a = | |
let ty = o.GetType() | |
let aty = typeof<'a> | |
if not (FSharpType.IsFunction aty) | |
then | |
let cs = CallSite<System.Func<CallSite, obj, obj>>.Create(Binder.GetMember(CSharpBinderFlags.None, s, null, [| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |])) | |
convert (cs.Target.Invoke(cs, o)) | |
else | |
if not (FSharpType.IsFunction aty) then failwithf "%A is not a function type" aty | |
let dty,rty = FSharpType.GetFunctionElements aty | |
let dtys = | |
if FSharpType.IsTuple dty then FSharpType.GetTupleElements dty | |
elif dty = typeof<unit> then [| |] | |
else [|dty|] | |
let objToObjFunction = | |
(fun argObj -> | |
let realArgs = | |
match dtys with | |
| [| |] -> [| |] | |
| [| argTy |] -> [| argObj |] | |
| argTys -> | |
assert Microsoft.FSharp.Reflection.FSharpType.IsTuple(argObj.GetType()) | |
Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields(argObj) | |
let fty = System.Linq.Expressions.Expression.GetFuncType [| yield typeof<CallSite>; yield typeof<obj>; yield! dtys; yield typeof<obj> |] | |
let cty = typedefof<CallSite<_>>.MakeGenericType [| fty |] | |
let cs = cty.InvokeMember("Create", BindingFlags.Public ||| BindingFlags.Static ||| BindingFlags.InvokeMethod, null, null, [|(box(Binder.InvokeMember(CSharpBinderFlags.None, s, null, null, Array.create (realArgs.Length + 1) (CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, s)))))|]) | |
|> unbox<CallSite> | |
let target = cs.GetType().GetField("Target").GetValue(cs) | |
let res = target.GetType().InvokeMember("Invoke", BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.InvokeMethod, null, target, [| yield box cs; yield box o; yield! realArgs |]) | |
res | |
) | |
let atyFunction = FSharpValue.MakeFunction(aty,objToObjFunction) | |
unbox<'a> atyFunction | |
let (?<-) (o : obj) (s : string) (v : 'a) : unit = | |
let cs = CallSite<System.Func<CallSite, obj, obj, obj>>.Create(Binder.SetMember(CSharpBinderFlags.None, s, null, [| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)|])) | |
cs.Target.Invoke(cs, o, v) |> ignore |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment