Header menu logo Fabulous.AST

Migration Guide to v2.0.0

This guide covers the breaking changes introduced in Fabulous.AST 2.0.0 and shows how to migrate your code.

Overview of Breaking Changes

  1. Return type changes: MemberDefn, TypeDefn, and ModuleDecl builders now return unified types instead of specific node types
  2. EscapeHatch requirement: Raw SyntaxOak nodes must be wrapped with EscapeHatch() when yielding into collections
  3. Unified modifiers: Per-node modifiers have been replaced with unified modifier extensions
  4. NestedModule return type: Module builder now returns CollectionBuilder<ModuleDecl, ModuleDecl>

1. Return Type Changes

MemberDefn Builders

Member definition builders now return WidgetBuilder<MemberDefn> instead of specific types like WidgetBuilder<BindingNode>.

Before (v1.x):

#r "../src/Fabulous.AST/bin/Release/netstandard2.1/publish/Fantomas.Core.dll"
#r "../src/Fabulous.AST/bin/Release/netstandard2.1/publish/Fabulous.AST.dll"
#r "../src/Fabulous.AST/bin/Release/netstandard2.1/publish/Fantomas.FCS.dll"

open Fabulous.AST
open type Fabulous.AST.Ast

// In v1.x, Member returned WidgetBuilder<BindingNode>
// let method: WidgetBuilder<BindingNode> = Member("this.DoSomething()", ConstantExpr(Int 42))

After (v2.0):

The same code now returns WidgetBuilder<MemberDefn>, which is compatible with all member collection contexts:

Oak() {
    AnonymousModule() {
        TypeDefn("MyClass", UnitPat()) {
            // Member now returns WidgetBuilder<MemberDefn>
            Member("this.DoSomething()", ConstantExpr(Int 42))
            // Property also returns WidgetBuilder<MemberDefn>
            Member("this.Value", ConstantExpr(String "hello"))
        }
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
type MyClass() =
    member this.DoSomething() = 42
    member this.Value = "hello"

TypeDefn Builders

Type definition builders now return WidgetBuilder<TypeDefn> instead of specific types like TypeDefnRecordNode.

Before (v1.x):

// In v1.x, Record returned CollectionBuilder with TypeDefnRecordNode
// let record: CollectionBuilder<TypeDefnRecordNode, FieldNode> = Record("Person") { ... }

After (v2.0):

The same code now returns CollectionBuilder<TypeDefn, FieldNode>:

Oak() {
    AnonymousModule() {
        // Record now returns CollectionBuilder<TypeDefn, FieldNode>
        Record("Person") {
            Field("Name", String())
            Field("Age", Int())
        }

        // Enum returns WidgetBuilder<TypeDefn>
        Enum("Color") {
            EnumCase("Red", Int(0))
            EnumCase("Green", Int(1))
        }

        // Abbrev returns WidgetBuilder<TypeDefn>
        Abbrev("MyInt", Int())
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
type Person = { Name: string; Age: int }

type Color =
    | Red = 0
    | Green = 1

type MyInt = int

ModuleDecl Builders

Module declaration builders now return WidgetBuilder<ModuleDecl> instead of specific types.

Before (v1.x):

// In v1.x, Open returned a specific type
// let openDecl: WidgetBuilder<OpenListNode> = Open("System")

After (v2.0):

Oak() {
    AnonymousModule() {
        // Open now returns WidgetBuilder<ModuleDecl>
        Open("System")
        Open("System.Collections.Generic")

        Value("x", Int(42))
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
open System
open System.Collections.Generic
let x = 42

2. EscapeHatch for Raw SyntaxOak Nodes

When you need to inject raw SyntaxOak nodes into collections, you must now wrap them with EscapeHatch().

Before (v1.x):

open Fantomas.Core.SyntaxOak
open Fantomas.FCS.Text

// In v1.x, you could yield raw nodes directly in some contexts
// AnonymousModule() {
//     TypeDefn.Abbrev(myAbbrevNode)  // This worked in v1.x
// }

After (v2.0):

// Create a raw TypeDefnAbbrevNode
let abbrevNode =
    TypeDefnAbbrevNode(
        TypeNameNode(
            None,
            None,
            SingleTextNode("type", Range.Zero),
            Some(SingleTextNode("MyFloat", Range.Zero)),
            IdentListNode([ IdentifierOrDot.Ident(SingleTextNode("=", Range.Zero)) ], Range.Zero),
            None,
            [],
            None,
            None,
            None,
            Range.Zero
        ),
        Type.LongIdent(IdentListNode([ IdentifierOrDot.Ident(SingleTextNode.Create("float")) ], Range.Zero)),
        [],
        Range.Zero
    )

Ast.Oak() {
    AnonymousModule() {
        // Use the DSL widget normally
        Abbrev("MyInt", Int())

        // Wrap raw SyntaxOak nodes with EscapeHatch
        EscapeHatch(TypeDefn.Abbrev(abbrevNode))
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
type MyInt = int
type MyFloat = float

EscapeHatch with ModuleDecl

let bindingNode =
    BindingNode(
        None,
        None,
        MultipleTextsNode([ SingleTextNode("let", Range.Zero) ], Range.Zero),
        false,
        None,
        None,
        Choice1Of2(IdentListNode([ IdentifierOrDot.Ident(SingleTextNode("y", Range.Zero)) ], Range.Zero)),
        None,
        List.Empty,
        None,
        SingleTextNode("=", Range.Zero),
        Expr.Constant(Constant.FromText(SingleTextNode("99", Range.Zero))),
        Range.Zero
    )

Ast.Oak() {
    AnonymousModule() {
        Value("x", Int(42))

        // Wrap raw ModuleDecl nodes with EscapeHatch
        EscapeHatch(ModuleDecl.TopLevelBinding(bindingNode))
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
let x = 42
let y = 99

EscapeHatch with Enum Cases

let enumCaseNode =
    EnumCaseNode(
        None,
        None,
        None,
        SingleTextNode("Black", Range.Zero),
        SingleTextNode("=", Range.Zero),
        Expr.Constant(Constant.FromText(SingleTextNode("3", Range.Zero))),
        Range.Zero
    )

Ast.Oak() {
    AnonymousModule() {
        Enum("Colors") {
            EnumCase("Red", Int(0))
            EnumCase("Green", Int(1))
            EnumCase("Blue", Int(2))

            // Wrap raw EnumCaseNode with EscapeHatch
            EscapeHatch(enumCaseNode)
        }
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
type Colors =
    | Red = 0
    | Green = 1
    | Blue = 2
    | Black = 3

EscapeHatch with Expr nodes

let exprNode = Expr.Constant(Constant.FromText(SingleTextNode("name", Range.Zero)))

Ast.Oak() {
    AnonymousModule() {
        TypeDefn("Person", UnitPat()) {
            // Wrap raw Expr nodes with EscapeHatch when needed
            Member(ConstantPat(Constant("this.Name")), EscapeHatch(exprNode))
        }
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
type Person() =
    member this.Name = name

3. Unified Modifiers

Modifiers are now unified across widget types. Instead of per-node specific modifiers, use the common modifier extensions.

MemberDefn Modifiers

Available modifiers for WidgetBuilder<MemberDefn>: - xmlDocs - Add XML documentation - attributes / attribute - Add attributes - toPrivate / toPublic / toInternal - Set accessibility - toMutable - Make mutable - toInlined - Make inline - toStatic - Make static - typeParams - Add type parameters

Ast.Oak() {
    AnonymousModule() {
        TypeDefn("MyClass", UnitPat()) {
            Member("this.PublicMethod()", ConstantExpr(Int 1))

            Member("this.PrivateMethod()", ConstantExpr(Int 2)) |> _.toPrivate()

            Member("this.InlineMethod()", ConstantExpr(Int 3)) |> _.toInlined()

            Member("this.DocumentedMethod()", ConstantExpr(Int 4))
            |> _.xmlDocs([ "This is a documented method" ])
        }
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
type MyClass() =
    member this.PublicMethod() = 1
    member private this.PrivateMethod() = 2
    member inline this.InlineMethod() = 3
    /// This is a documented method
    member this.DocumentedMethod() = 4

TypeDefn Modifiers

Available modifiers for WidgetBuilder<TypeDefn>: - members - Add members to the type - xmlDocs - Add XML documentation - attributes / attribute - Add attributes - typeParams - Add type parameters - toPrivate / toPublic / toInternal - Set accessibility - toRecursive - Make recursive

Ast.Oak() {
    AnonymousModule() {
        Record("Person") {
            Field("Name", String())
            Field("Age", Int())
        }
        |> _.xmlDocs([ "Represents a person" ])
        |> _.attribute(Attribute("Serializable"))

        TypeDefn("GenericClass", UnitPat()) { Member("this.Value", ConstantExpr(String "")) }
        |> _.typeParams(PostfixList([ "'a"; "'b" ]))
        |> _.toPrivate()
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
/// Represents a person
[<Serializable>]
type Person = { Name: string; Age: int }

type private GenericClass<'a, 'b>() =
    member this.Value = ""

ModuleDecl Modifiers

Available modifiers for Module/NestedModule: - xmlDocs - Add XML documentation - attributes / attribute - Add attributes - toPrivate / toPublic / toInternal - Set accessibility - toRecursive - Make recursive

Ast.Oak() {
    AnonymousModule() {
        Module("MyModule") { Value("x", Int(42)) }
        |> _.xmlDocs([ "My module documentation" ])
        |> _.attribute(Attribute("AutoOpen"))

        Module("PrivateModule") { Value("secret", Int(999)) } |> _.toPrivate()

        Module("RecursiveModule") { Value("data", Int(1)) } |> _.toRecursive()
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
/// My module documentation
[<AutoOpen>]
module MyModule =
    let x = 42

module private PrivateModule =
    let secret = 999

module rec RecursiveModule =
    let data = 1

4. NestedModule Return Type Change

The Module builder now returns CollectionBuilder<ModuleDecl, ModuleDecl> instead of a specific nested module type. This allows for more flexible composition but may require adjustments if you were storing the result in a typed variable.

Before (v1.x):

// In v1.x:
// let myModule: WidgetBuilder<NestedModuleNode> = Module("MyModule") { ... }

After (v2.0):

// The Module builder works the same way in usage, just with a different return type
Ast.Oak() {
    AnonymousModule() {
        Module("OuterModule") {
            Value("x", Int(1))

            Module("InnerModule") { Value("y", Int(2)) }
        }
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
module OuterModule =
    let x = 1

    module InnerModule =
        let y = 2

5. Complete Migration Example

Here's a complete example showing a type that uses multiple v2.0 features:

Ast.Oak() {
    Namespace("MyApp.Domain") {
        Module("Types") {
            // Type with unified modifiers
            Record("Customer") {
                Field("Id", Int())
                Field("Name", String())
                Field("Email", String())
            }
            |> _.xmlDocs([ "Represents a customer in the system" ])
            |> _.attribute(Attribute("Serializable"))

            // Enum with unified modifiers
            Enum("OrderStatus") {
                EnumCase("Pending", Int(0))
                EnumCase("Processing", Int(1))
                EnumCase("Completed", Int(2))
                EnumCase("Cancelled", Int(3))
            }
            |> _.attribute(Attribute("FlagsAttribute"))

            // Class with members using unified modifiers
            TypeDefn("OrderService", Constructor(ParameterPat("customerId", Int()))) {
                Member("this.CustomerId", ConstantExpr("customerId"))

                Member("this.Process()", ConstantExpr(String "Processing"))
                |> _.xmlDocs([ "Processes the order" ])
            }
        }
        |> _.attribute(Attribute("AutoOpen"))
    }
}
|> Gen.mkOak
|> Gen.run
|> printfn "%s"

// produces the following code:
namespace MyApp.Domain

[<AutoOpen>]
module Types =
    /// Represents a customer in the system
    [<Serializable>]
    type Customer =
        { Id: int; Name: string; Email: string }

    [<FlagsAttribute>]
    type OrderStatus =
        | Pending = 0
        | Processing = 1
        | Completed = 2
        | Cancelled = 3

    type OrderService(customerId: int) =
        member this.CustomerId = customerId
        /// Processes the order
        member this.Process() = "Processing"

Summary

When migrating to v2.0.0:

  1. No code changes needed for most DSL usage - the return type changes are transparent
  2. Wrap raw SyntaxOak nodes with EscapeHatch() when yielding into collections
  3. Use unified modifiers like toPrivate(), xmlDocs(), attribute() which work consistently across all widget types
  4. Update type annotations if you explicitly typed variables with specific node types like WidgetBuilder<BindingNode> - change them to WidgetBuilder<MemberDefn>

The v2.0 changes provide a cleaner, more consistent API while maintaining full compatibility with the Fantomas Oak AST.

namespace Fabulous
namespace Fabulous.AST
type Ast = class end
Multiple items
static member Ast.Oak: unit -> CollectionBuilder<Fantomas.Core.SyntaxOak.Oak,'marker>

--------------------
module Oak from Fabulous.AST
static member Ast.AnonymousModule: unit -> CollectionBuilder<Fantomas.Core.SyntaxOak.ModuleOrNamespaceNode,Fantomas.Core.SyntaxOak.ModuleDecl>
Multiple items
static member Ast.TypeDefn: name: string -> CollectionBuilder<Fantomas.Core.SyntaxOak.TypeDefn,Fantomas.Core.SyntaxOak.MemberDefn>
static member Ast.TypeDefn: name: string * constructor: WidgetBuilder<Fantomas.Core.SyntaxOak.ImplicitConstructorNode> -> CollectionBuilder<Fantomas.Core.SyntaxOak.TypeDefn,Fantomas.Core.SyntaxOak.MemberDefn>
static member Ast.TypeDefn: name: string * constructor: WidgetBuilder<Fantomas.Core.SyntaxOak.Pattern> -> CollectionBuilder<Fantomas.Core.SyntaxOak.TypeDefn,Fantomas.Core.SyntaxOak.MemberDefn>

--------------------
module TypeDefn from Fabulous.AST
<summary> Common attributes shared by all TypeDefn widgets </summary>
static member Ast.UnitPat: unit -> WidgetBuilder<Fantomas.Core.SyntaxOak.Pattern>
static member Ast.Member: name: string * body: string * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: string * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * body: string * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * body: string * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * body: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.MemberDefn>
   (+0 other overloads)
static member Ast.ConstantExpr: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Expr>
static member Ast.ConstantExpr: value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Expr>
static member Ast.Int: value: int -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>
static member Ast.Int: unit -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>
Multiple items
static member Ast.String: value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>
static member Ast.String: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.Constant>
static member Ast.String: unit -> WidgetBuilder<Fantomas.Core.SyntaxOak.Type>

--------------------
module String from Fabulous.AST

--------------------
module String from Microsoft.FSharp.Core
module Gen from Fabulous.AST
<summary> It takes the root of the widget tree and create the corresponding Fantomas node, and recursively creating all children nodes </summary>
val mkOak: root: WidgetBuilder<'node> -> 'node
val run: oak: Fantomas.Core.SyntaxOak.Oak -> string
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
Multiple items
static member Ast.Record: name: string -> CollectionBuilder<Fantomas.Core.SyntaxOak.TypeDefn,Fantomas.Core.SyntaxOak.FieldNode>

--------------------
module Record from Fabulous.AST
Multiple items
static member Ast.Field: name: string * fieldType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.FieldNode>
static member Ast.Field: name: string * fieldType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.FieldNode>
static member Ast.Field: fieldType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.FieldNode>
static member Ast.Field: fieldType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.FieldNode>

--------------------
module Field from Fabulous.AST
Multiple items
static member Ast.Enum: name: string -> CollectionBuilder<Fantomas.Core.SyntaxOak.TypeDefn,Fantomas.Core.SyntaxOak.EnumCaseNode>

--------------------
module Enum from Fabulous.AST
Multiple items
static member Ast.EnumCase: name: string * field: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.EnumCaseNode>
static member Ast.EnumCase: name: string * field: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.EnumCaseNode>
static member Ast.EnumCase: name: string * field: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> -> WidgetBuilder<Fantomas.Core.SyntaxOak.EnumCaseNode>

--------------------
module EnumCase from Fabulous.AST
static member Ast.Abbrev: name: string * alias: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.TypeDefn>
static member Ast.Abbrev: name: string * alias: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.TypeDefn>
Multiple items
static member Ast.Open: value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.ModuleDecl>
static member Ast.Open: values: string seq -> WidgetBuilder<Fantomas.Core.SyntaxOak.ModuleDecl>

--------------------
module Open from Fabulous.AST
static member Ast.Value: name: string * value: string * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: string * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> * returnType: WidgetBuilder<Fantomas.Core.SyntaxOak.Type> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Expr> -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
static member Ast.Value: name: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * value: WidgetBuilder<Fantomas.Core.SyntaxOak.Constant> * returnType: string -> WidgetBuilder<Fantomas.Core.SyntaxOak.BindingNode>
   (+0 other overloads)
namespace Fantomas
namespace Fantomas.Core
module SyntaxOak from Fantomas.Core
namespace Fantomas.FCS
namespace Fantomas.FCS.Text
val abbrevNode: TypeDefnAbbrevNode
Multiple items
module TypeDefnAbbrevNode from Fabulous.AST

--------------------
type TypeDefnAbbrevNode = inherit NodeBase interface ITypeDefn new: typeNameNode: TypeNameNode * t: Type * members: MemberDefn list * range: range -> TypeDefnAbbrevNode override Children: Node array member Type: Type

--------------------
new: typeNameNode: TypeNameNode * t: Type * members: MemberDefn list * range: range -> TypeDefnAbbrevNode
Multiple items
module TypeNameNode from Fabulous.AST

--------------------
type TypeNameNode = inherit NodeBase new: xmlDoc: XmlDocNode option * attributes: MultipleAttributeListNode option * leadingKeyword: SingleTextNode * ao: SingleTextNode option * identifier: IdentListNode * typeParams: TyparDecls option * constraints: TypeConstraint list * implicitConstructor: ImplicitConstructorNode option * equalsToken: SingleTextNode option * withKeyword: SingleTextNode option * range: range -> TypeNameNode member Accessibility: SingleTextNode option member Attributes: MultipleAttributeListNode option override Children: Node array member Constraints: TypeConstraint list member EqualsToken: SingleTextNode option member Identifier: IdentListNode member ImplicitConstructor: ImplicitConstructorNode option member IsFirstType: bool ...

--------------------
new: xmlDoc: XmlDocNode option * attributes: MultipleAttributeListNode option * leadingKeyword: SingleTextNode * ao: SingleTextNode option * identifier: IdentListNode * typeParams: TyparDecls option * constraints: TypeConstraint list * implicitConstructor: ImplicitConstructorNode option * equalsToken: SingleTextNode option * withKeyword: SingleTextNode option * range: range -> TypeNameNode
union case Option.None: Option<'T>
Multiple items
module SingleTextNode from Fabulous.AST

--------------------
type SingleTextNode = inherit NodeBase new: idText: string * range: range -> SingleTextNode override Children: Node array member Text: string

--------------------
new: idText: string * range: range -> SingleTextNode
Multiple items
module Range from Fantomas.FCS.Text

--------------------
[<Struct>] type Range = member End: pos member EndColumn: int member EndLine: int member EndRange: range member FileName: string member IsSynthetic: bool member Start: pos member StartColumn: int member StartLine: int member StartRange: range ...
property Range.Zero: range with get
union case Option.Some: Value: 'T -> Option<'T>
Multiple items
type IdentListNode = inherit NodeBase new: content: IdentifierOrDot list * range: range -> IdentListNode override Children: Node array member Content: IdentifierOrDot list member IsEmpty: bool static member Empty: IdentListNode

--------------------
new: content: IdentifierOrDot list * range: range -> IdentListNode
type IdentifierOrDot = | Ident of SingleTextNode | KnownDot of SingleTextNode | UnknownDot member Equals: IdentifierOrDot * IEqualityComparer -> bool member Range: range option
union case IdentifierOrDot.Ident: SingleTextNode -> IdentifierOrDot
type Type = | Funs of TypeFunsNode | Tuple of TypeTupleNode | HashConstraint of TypeHashConstraintNode | MeasurePower of TypeMeasurePowerNode | StaticConstant of Constant | StaticConstantExpr of TypeStaticConstantExprNode | StaticConstantNamed of TypeStaticConstantNamedNode | Array of TypeArrayNode | Anon of SingleTextNode | Var of SingleTextNode ... static member Node: x: Type -> Node
union case Type.LongIdent: IdentListNode -> Type
static member SingleTextNode.Create: idText: string -> SingleTextNode
static member Ast.Oak: unit -> CollectionBuilder<Oak,'marker>
static member Ast.AnonymousModule: unit -> CollectionBuilder<ModuleOrNamespaceNode,ModuleDecl>
static member Ast.Abbrev: name: string * alias: string -> WidgetBuilder<TypeDefn>
static member Ast.Abbrev: name: string * alias: WidgetBuilder<Type> -> WidgetBuilder<TypeDefn>
static member Ast.Int: value: int -> WidgetBuilder<Constant>
static member Ast.Int: unit -> WidgetBuilder<Type>
Multiple items
static member Ast.EscapeHatch: node: 'T -> WidgetBuilder<'T>

--------------------
module EscapeHatch from Fabulous.AST
Multiple items
static member Ast.TypeDefn: name: string -> CollectionBuilder<TypeDefn,MemberDefn>
static member Ast.TypeDefn: name: string * constructor: WidgetBuilder<ImplicitConstructorNode> -> CollectionBuilder<TypeDefn,MemberDefn>
static member Ast.TypeDefn: name: string * constructor: WidgetBuilder<Pattern> -> CollectionBuilder<TypeDefn,MemberDefn>

--------------------
module TypeDefn from Fabulous.AST
<summary> Common attributes shared by all TypeDefn widgets </summary>

--------------------
type TypeDefn = | Enum of TypeDefnEnumNode | Union of TypeDefnUnionNode | Record of TypeDefnRecordNode | None of TypeNameNode | Abbrev of TypeDefnAbbrevNode | Explicit of TypeDefnExplicitNode | Augmentation of TypeDefnAugmentationNode | Delegate of TypeDefnDelegateNode | Regular of TypeDefnRegularNode static member Node: x: TypeDefn -> Node static member TypeDefnNode: x: TypeDefn -> ITypeDefn
union case TypeDefn.Abbrev: TypeDefnAbbrevNode -> TypeDefn
val run: oak: Oak -> string
val bindingNode: BindingNode
Multiple items
module BindingNode from Fabulous.AST

--------------------
type BindingNode = inherit NodeBase new: xmlDoc: XmlDocNode option * attributes: MultipleAttributeListNode option * leadingKeyword: MultipleTextsNode * isMutable: bool * inlineNode: SingleTextNode option * accessibility: SingleTextNode option * functionName: Choice<IdentListNode,Pattern> * genericTypeParameters: TyparDecls option * parameters: Pattern list * returnType: BindingReturnInfoNode option * equals: SingleTextNode * expr: Expr * range: range -> BindingNode member Accessibility: SingleTextNode option member Attributes: MultipleAttributeListNode option override Children: Node array member Equals: SingleTextNode member Expr: Expr member FunctionName: Choice<IdentListNode,Pattern> member GenericTypeParameters: TyparDecls option member Inline: SingleTextNode option ...

--------------------
new: xmlDoc: XmlDocNode option * attributes: MultipleAttributeListNode option * leadingKeyword: MultipleTextsNode * isMutable: bool * inlineNode: SingleTextNode option * accessibility: SingleTextNode option * functionName: Choice<IdentListNode,Pattern> * genericTypeParameters: TyparDecls option * parameters: Pattern list * returnType: BindingReturnInfoNode option * equals: SingleTextNode * expr: Expr * range: range -> BindingNode
Multiple items
type MultipleTextsNode = inherit NodeBase new: content: SingleTextNode list * range: range -> MultipleTextsNode override Children: Node array member Content: SingleTextNode list

--------------------
new: content: SingleTextNode list * range: range -> MultipleTextsNode
union case Choice.Choice1Of2: 'T1 -> Choice<'T1,'T2>
Multiple items
static member Ast.List: unit -> WidgetBuilder<Type>

--------------------
module List from Fabulous.AST

--------------------
module List from Microsoft.FSharp.Collections

--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
property List.Empty: 'T list with get
Multiple items
union case TextSegment.Expr: WidgetBuilder<FillExprNode> * int -> TextSegment

--------------------
module Expr from Fabulous.AST

--------------------
type Expr = | Lazy of ExprLazyNode | Single of ExprSingleNode | Constant of Constant | Null of SingleTextNode | Quote of ExprQuoteNode | Typed of ExprTypedNode | New of ExprNewNode | Tuple of ExprTupleNode | StructTuple of ExprStructTupleNode | ArrayOrList of ExprArrayOrListNode ... static member Node: x: Expr -> Node member HasParentheses: bool
union case Expr.Constant: Constant -> Expr
Multiple items
static member Ast.Constant: value: string -> WidgetBuilder<Constant>

--------------------
module Constant from Fabulous.AST

--------------------
type Constant = | FromText of SingleTextNode | Unit of UnitNode | Measure of ConstantMeasureNode static member Node: c: Constant -> NodeBase
union case Constant.FromText: SingleTextNode -> Constant
static member Ast.Value: name: string * value: string * returnType: string -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: string * returnType: WidgetBuilder<Type> -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: string -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Constant> * returnType: string -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Constant> * returnType: WidgetBuilder<Type> -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Constant> -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Expr> * returnType: string -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Expr> * returnType: WidgetBuilder<Type> -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: string * value: WidgetBuilder<Expr> -> WidgetBuilder<BindingNode>
   (+0 other overloads)
static member Ast.Value: name: WidgetBuilder<Constant> * value: WidgetBuilder<Constant> * returnType: string -> WidgetBuilder<BindingNode>
   (+0 other overloads)
Multiple items
module ModuleDecl from Fabulous.AST
<summary> Shared attribute definitions used across module declaration widget types </summary>

--------------------
type ModuleDecl = | OpenList of OpenListNode | HashDirectiveList of HashDirectiveListNode | Attributes of ModuleDeclAttributesNode | DeclExpr of Expr | Exception of ExceptionDefnNode | ExternBinding of ExternBindingNode | TopLevelBinding of BindingNode | ModuleAbbrev of ModuleAbbrevNode | NestedModule of NestedModuleNode | TypeDefn of TypeDefn ... static member Node: x: ModuleDecl -> Node
union case ModuleDecl.TopLevelBinding: BindingNode -> ModuleDecl
val enumCaseNode: EnumCaseNode
Multiple items
type EnumCaseNode = inherit NodeBase new: xmlDoc: XmlDocNode option * bar: SingleTextNode option * attributes: MultipleAttributeListNode option * identifier: SingleTextNode * equals: SingleTextNode * constant: Expr * range: range -> EnumCaseNode member Attributes: MultipleAttributeListNode option member Bar: SingleTextNode option override Children: Node array member Constant: Expr member Equals: SingleTextNode member Identifier: SingleTextNode member XmlDoc: XmlDocNode option

--------------------
new: xmlDoc: XmlDocNode option * bar: SingleTextNode option * attributes: MultipleAttributeListNode option * identifier: SingleTextNode * equals: SingleTextNode * constant: Expr * range: range -> EnumCaseNode
Multiple items
static member Ast.Enum: name: string -> CollectionBuilder<TypeDefn,EnumCaseNode>

--------------------
module Enum from Fabulous.AST
Multiple items
static member Ast.EnumCase: name: string * field: string -> WidgetBuilder<EnumCaseNode>
static member Ast.EnumCase: name: string * field: WidgetBuilder<Constant> -> WidgetBuilder<EnumCaseNode>
static member Ast.EnumCase: name: string * field: WidgetBuilder<Expr> -> WidgetBuilder<EnumCaseNode>

--------------------
module EnumCase from Fabulous.AST
val exprNode: Expr
static member Ast.UnitPat: unit -> WidgetBuilder<Pattern>
static member Ast.Member: name: string * body: string * returnType: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: string * returnType: WidgetBuilder<Type> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Constant> * returnType: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Constant> * returnType: WidgetBuilder<Type> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Constant> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: WidgetBuilder<Constant> * body: string * returnType: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: WidgetBuilder<Constant> * body: string * returnType: WidgetBuilder<Type> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: WidgetBuilder<Constant> * body: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Member: name: string * body: WidgetBuilder<Expr> * returnType: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.ConstantPat: value: string -> WidgetBuilder<Pattern>
static member Ast.ConstantPat: value: WidgetBuilder<Constant> -> WidgetBuilder<Pattern>
static member Ast.ConstantExpr: value: string -> WidgetBuilder<Expr>
static member Ast.ConstantExpr: value: WidgetBuilder<Constant> -> WidgetBuilder<Expr>
Multiple items
static member Ast.Record: name: string -> CollectionBuilder<TypeDefn,FieldNode>

--------------------
module Record from Fabulous.AST
Multiple items
static member Ast.Field: name: string * fieldType: string -> WidgetBuilder<FieldNode>
static member Ast.Field: name: string * fieldType: WidgetBuilder<Type> -> WidgetBuilder<FieldNode>
static member Ast.Field: fieldType: string -> WidgetBuilder<FieldNode>
static member Ast.Field: fieldType: WidgetBuilder<Type> -> WidgetBuilder<FieldNode>

--------------------
module Field from Fabulous.AST
Multiple items
static member Ast.String: value: WidgetBuilder<Constant> -> WidgetBuilder<Constant>
static member Ast.String: value: string -> WidgetBuilder<Constant>
static member Ast.String: unit -> WidgetBuilder<Type>

--------------------
module String from Fabulous.AST

--------------------
module String from Microsoft.FSharp.Core
static member Ast.Attribute: value: string * expr: string -> WidgetBuilder<AttributeNode>
static member Ast.Attribute: value: string * expr: WidgetBuilder<Constant> -> WidgetBuilder<AttributeNode>
static member Ast.Attribute: value: string * expr: WidgetBuilder<Expr> -> WidgetBuilder<AttributeNode>
static member Ast.Attribute: value: string -> WidgetBuilder<AttributeNode>
static member Ast.PostfixList: decls: string * constraints: WidgetBuilder<TypeConstraint> -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decls: WidgetBuilder<TyparDeclNode> * constraints: WidgetBuilder<TypeConstraint> -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: constraints: WidgetBuilder<TypeConstraint> -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: constraints: WidgetBuilder<TypeConstraint> seq -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decl: string -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decl: WidgetBuilder<TyparDeclNode> -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decls: string seq -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decls: WidgetBuilder<TyparDeclNode> seq -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decls: string seq * constraints: WidgetBuilder<TypeConstraint> seq -> WidgetBuilder<TyparDecls>
static member Ast.PostfixList: decls: WidgetBuilder<TyparDeclNode> seq * constraints: WidgetBuilder<TypeConstraint> seq -> WidgetBuilder<TyparDecls>
static member Ast.Module: name: string -> CollectionBuilder<ModuleDecl,ModuleDecl>
static member Ast.Namespace: name: string -> CollectionBuilder<ModuleOrNamespaceNode,ModuleDecl>
static member Ast.Constructor: unit -> WidgetBuilder<ImplicitConstructorNode>
   (+0 other overloads)
static member Ast.Constructor: pattern: string -> WidgetBuilder<ImplicitConstructorNode>
   (+0 other overloads)
static member Ast.Constructor: pattern: WidgetBuilder<Constant> -> WidgetBuilder<ImplicitConstructorNode>
   (+0 other overloads)
static member Ast.Constructor: pattern: WidgetBuilder<Pattern> -> WidgetBuilder<ImplicitConstructorNode>
   (+0 other overloads)
static member Ast.Constructor: pattern: string * expr: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Constructor: pattern: WidgetBuilder<Pattern> * expr: string -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Constructor: pattern: WidgetBuilder<Constant> * expr: WidgetBuilder<Constant> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Constructor: pattern: WidgetBuilder<Pattern> * expr: WidgetBuilder<Constant> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Constructor: pattern: string * expr: WidgetBuilder<Expr> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.Constructor: pattern: WidgetBuilder<Constant> * expr: WidgetBuilder<Expr> -> WidgetBuilder<MemberDefn>
   (+0 other overloads)
static member Ast.ParameterPat: name: string -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: WidgetBuilder<Constant> -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: WidgetBuilder<Pattern> -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: string * pType: string -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: string * pType: WidgetBuilder<Type> -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: WidgetBuilder<Constant> * pType: string -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: WidgetBuilder<Constant> * pType: WidgetBuilder<Type> -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: WidgetBuilder<Pattern> * pType: string -> WidgetBuilder<Pattern>
static member Ast.ParameterPat: name: WidgetBuilder<Pattern> * pType: WidgetBuilder<Type> -> WidgetBuilder<Pattern>

Type something to start searching.