How can I create an F# AST for a record type definition programmatically?

87 Views Asked by At

For example this record:

type City =
  {
    ID : string
    Name : string
  }

How can I create an F# AST for a record type definition programmatically?

open FSharp.Compiler.Syntax
open FSharp.Compiler.Text

module M =

  let ty =
    SynModuleDecl.CreateSimpleType( // something...

I later intend to print the AST using Fantomas.

1

There are 1 best solutions below

0
Brian Berns On BEST ANSWER

I think this does what you want in F# 5:

open FSharp.Compiler.Range
open FSharp.Compiler.SyntaxTree
open FSharp.Compiler.XmlDoc

module Ident =

    let ofString str =
        Ident(str, range.Zero)

    let toLongIdent ident : LongIdent =
        [ ident ]

    let toLongIdentWithDots ident =
        LongIdentWithDots (toLongIdent ident, List.empty)

module Field =

    let create name typ =
        SynField.Field (
            [],
            false,
            name
                |> Ident.ofString
                |> Some,
            SynType.LongIdent (
                typ
                    |> Ident.ofString
                    |> Ident.toLongIdentWithDots),
            false,
            PreXmlDoc.Empty,
            None,
            range.Zero)

module Program =

    [<EntryPoint>]
    let main argv =
        let typeInfo =
            ComponentInfo (
                [], [], [],
                "City"
                    |> Ident.ofString
                    |> Ident.toLongIdent,
                PreXmlDoc.Empty,
                false,
                None,
                range.Zero)
        let typeRepr =
            SynTypeDefnRepr.Simple (
                SynTypeDefnSimpleRepr.Record (
                    None,
                    [
                        Field.create "ID" "string"
                        Field.create "Name" "string"
                    ],
                    range.Zero
                ),
                range.Zero
            )
        let typeDefn =
            TypeDefn (
                typeInfo,
                typeRepr,
                List.empty,
                range.Zero)
        printfn "%A" typeDefn
        0

The resulting syntax tree is:

TypeDefn
  (ComponentInfo
     ([], [], [], [City], PreXmlDocEmpty, false, None,
      unknown (0,0--0,0) IsSynthetic=false),
   Simple
     (Record
        (None,
         [Field
            ([], false, Some ID, LongIdent (LongIdentWithDots ([string], [])),
             false, PreXmlDocEmpty, None, unknown (0,0--0,0) IsSynthetic=false);
          Field
            ([], false, Some Name, LongIdent (LongIdentWithDots ([string], [])),
             false, PreXmlDocEmpty, None, unknown (0,0--0,0) IsSynthetic=false)],
         unknown (0,0--0,0) IsSynthetic=false),
      unknown (0,0--0,0) IsSynthetic=false), [],
   unknown (0,0--0,0) IsSynthetic=false)

Related Questions in F#