Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly calling method which refers to instance in ProvidedConstructor

How do I properly supply the code to a ProvidedConstructor's InvokeCode in a generative type provider which would do the equivalent of the following?

Given:

module Utils =
    let someFun (s : string) (inst : obj) =
          // Does something here...
          ()

I need to have the generated type effectively do:

type NewGeneratedType () as self =
     inherit BaseType ()

     do
         Utils.someFun "Foo" (box self)

I have the call to the base constructor working, but don't know how to properly slice in the instance and get the function called:

let ctor = ProvidedConstructor([])
let ci = baseType.GetConstructor(BindingFlags.Public ||| BindingFlags.Instance, null, [|  |], null)
ctor.BaseConstructorCall <- fun args -> ci, args 

// I do not know how to properly call this to match the constructor above
ctor.InvokeCode <- fun args -> <@@ () @@>
like image 902
Reed Copsey Avatar asked May 05 '16 04:05

Reed Copsey


2 Answers

it looks like a "this" argument is passed in as the last argument to the ctor

From there your InvokeCode function will get run and the returned quotation translated. So, i think all you need is something like:

ctor.InvokeCode <- fun args -> <@@ let me = Seq.last args @@>
like image 173
CAIndy Avatar answered Oct 26 '22 22:10

CAIndy


I got this working via:

ctor.InvokeCode <- 
    fun args -> 
        let this = Seq.head args
        let boxed = Expr.Coerce(this, typeof<obj>)
        <@@  Utils.someFun "Foo" %%(boxed) @@>

Note that trying to move the first two lines into the splice caused all sorts of errors, but when I pull it out, it works perfectly.

like image 4
Reed Copsey Avatar answered Oct 26 '22 21:10

Reed Copsey