fsprojects / FSharp.TypeProviders.SDK

The SDK for creating F# type providers
https://fsprojects.github.io/FSharp.TypeProviders.SDK/
MIT License
298 stars 94 forks source link

Attempting to implement a Provided record #319

Closed chkeita closed 5 years ago

chkeita commented 5 years ago

Attempting to implement a Provided record

I am trying to implement a providedRecord for a type provider i a working on. My approach was to decompile a normal record and try to implement the methods and attributes present in the decompiled class. I used the decompiled code of this record as a template

    type MyRecordType = {
        Dummy1: string
        Dummy2: int
    }

here is the definition of the ProvidedRecord and an example of instantiation in a test Type Provider. and here is an example of usage of that provider (reproduced here)

type TestType = TestProvider.TestMainType<blah="demo">

let testRecordType () =
    FSharp.Reflection.FSharpType.IsRecord(typeof<TestType>)
    |> printfn "%A" 
    //=> true

    let test1 = TestType("", 1)
    printfn "%A" test1 
    //=> {prop1 = "";
    //=> prop2 = 1;}

    // This line does not compile 
    // error : The field, constructor or member 'prop1' is not defined
    // {TestType.prop1 = ""; TestType.prop2 = 1}

What else do i need to do to have my type behave like a real record ? Is it possible to implement a ProvidedRecord with this approach?

dsyme commented 5 years ago

Is it possible to implement a ProvidedRecord with this approach?

Not with this alone

What else do i need to do to have my type behave like a real record ?

You would need to modify the F# compiler (particularly infos.fs) to understand the compiled version of records as actual records.

chkeita commented 5 years ago

I think i have a working version of the changes needed for intellisense to work properly. However i am getting an exception when accessing the field at runtime.

Attempt by method 'Program.testRecordType()' to access field 'Program+TestType.prop1@' failed.

it looks like the compiler is accessing the backing field prop1@ instead of the public property prop1

My guess is that i am missing a couple of attribute on the internal field that i generate in the type provider. Unfortunately, i can't reflect on the backing field of real record type to find out what are the expected attributes.

Any pointers for how to solve this issue ?

chkeita commented 5 years ago

The backing fields were supposed internal instead of private