mirror of
https://github.com/Smaug123/WoofWare.Whippet
synced 2025-10-05 07:48:40 +00:00
Some checks failed
.NET / build (Debug) (push) Has been cancelled
.NET / build (Release) (push) Has been cancelled
.NET / analyzers (push) Has been cancelled
.NET / build-nix (push) Has been cancelled
.NET / check-dotnet-format (push) Has been cancelled
.NET / check-nix-format (push) Has been cancelled
.NET / Check links (push) Has been cancelled
.NET / Check flake (push) Has been cancelled
.NET / nuget-pack (push) Has been cancelled
.NET / expected-pack (push) Has been cancelled
.NET / all-required-checks-complete (push) Has been cancelled
81 lines
2.8 KiB
Forth
81 lines
2.8 KiB
Forth
namespace WoofWare.Whippet.Fantomas
|
|
|
|
open Fantomas.FCS.Text.Range
|
|
open Fantomas.FCS.Syntax
|
|
open Fantomas.FCS.SyntaxTrivia
|
|
open Fantomas.FCS.Xml
|
|
|
|
/// The data needed to reconstitute a single piece of data within a union field, or a single record field.
|
|
/// This is generic on whether the field is identified. For example, in `type Foo = Blah of int`, the `int`
|
|
/// field is not identified; whereas in `type Foo = Blah of baz : int`, it is identified.
|
|
type SynFieldData<'Ident> =
|
|
{
|
|
/// Attributes on this field. I think you can only get these if this is a *record* field.
|
|
Attrs : SynAttribute list
|
|
/// The identifier of this field (see docstring for SynFieldData).
|
|
Ident : 'Ident
|
|
/// The type of the data contained in this field. For example, `type Foo = { Blah : int }`
|
|
/// has this being `int`.
|
|
Type : SynType
|
|
}
|
|
|
|
/// Methods for manipulating `SynField`, which represents a field of a record or union.
|
|
[<RequireQualifiedAccess>]
|
|
module SynField =
|
|
/// Get the useful information out of a SynField.
|
|
let extract (SynField (attrs, _, id, fieldType, _, _, _, _, _)) : SynFieldData<Ident option> =
|
|
{
|
|
Attrs = attrs |> List.collect (fun l -> l.Attributes)
|
|
Ident = id
|
|
Type = fieldType
|
|
}
|
|
|
|
/// Functorial `map`.
|
|
let mapIdent<'a, 'b> (f : 'a -> 'b) (x : SynFieldData<'a>) : SynFieldData<'b> =
|
|
let ident = f x.Ident
|
|
|
|
{
|
|
Attrs = x.Attrs
|
|
Ident = ident
|
|
Type = x.Type
|
|
}
|
|
|
|
/// Convert a `SynField` into our structured `SynFieldData` type. Throws if the field has no identifier.
|
|
let extractWithIdent (f : SynField) : SynFieldData<Ident> =
|
|
f
|
|
|> extract
|
|
|> mapIdent (fun ident ->
|
|
match ident with
|
|
| None -> failwith "expected field identifier to have a value, but it did not"
|
|
| Some i -> i
|
|
)
|
|
|
|
/// Convert our structured `SynFieldData` type into an AST `SynField`.
|
|
let make (data : SynFieldData<Ident option>) : SynField =
|
|
let attrs : SynAttributeList list =
|
|
data.Attrs
|
|
|> List.map (fun l ->
|
|
{
|
|
Attributes = [ l ]
|
|
Range = range0
|
|
}
|
|
)
|
|
|
|
SynField.SynField (
|
|
attrs,
|
|
false,
|
|
data.Ident,
|
|
data.Type,
|
|
false,
|
|
PreXmlDoc.Empty,
|
|
None,
|
|
range0,
|
|
SynFieldTrivia.Zero
|
|
)
|
|
|
|
/// Set the docstring of this `SynField`.
|
|
let withDocString (doc : PreXmlDoc) (f : SynField) : SynField =
|
|
match f with
|
|
| SynField (attributes, isStatic, idOpt, fieldType, isMutable, _, accessibility, range, trivia) ->
|
|
SynField (attributes, isStatic, idOpt, fieldType, isMutable, doc, accessibility, range, trivia)
|