-
-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathGeneratorHelpers.fs
More file actions
45 lines (39 loc) · 2.07 KB
/
Copy pathGeneratorHelpers.fs
File metadata and controls
45 lines (39 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
namespace Myriad.Plugins
open Fantomas.FCS.Syntax
open Myriad.Core
open Myriad.Core.Ast
module internal GeneratorHelpers =
/// Parses the input file specified in the generator context and returns the first parsed AST.
let parseInputAst (context: GeneratorContext) =
Ast.fromFilename context.InputFilename
|> Async.RunSynchronously
|> Array.head
/// Filters a list of (namespace, types) pairs, keeping only those namespaces that
/// contain at least one type decorated with the given attribute.
let filterByAttribute<'A> (namespacedTypes: (LongIdent * SynTypeDefn list) list) =
namespacedTypes
|> List.choose (fun (ns, types) ->
match types |> List.filter Ast.hasAttribute<'A> with
| [] -> None
| types -> Some (ns, types))
/// Resolves a DU case identifier, optionally qualifying it with the parent type name
/// when RequireQualifiedAccess is present.
let resolveCaseIdent (requiresQualifiedAccess: bool) (parent: LongIdent) (id: Ident) : SynLongIdent =
let parts =
if requiresQualifiedAccess then
(parent |> List.map (fun i -> i.idText)) @ [id.idText]
else
[id.idText]
SynLongIdent.Create parts
/// Runs the standard generator pipeline: parse input AST, extract types, filter by attribute,
/// and collect modules. Eliminates the boilerplate shared by DUCasesGenerator and FieldsGenerator.
let generateModules<'Attr> (context: GeneratorContext) (extract: ParsedInput -> (LongIdent * SynTypeDefn list) list) (create: LongIdent -> SynTypeDefn -> (string * obj) seq -> SynModuleOrNamespace) : Output =
let ast, _ = parseInputAst context
let namespacedTypes = extract ast |> filterByAttribute<'Attr>
let modules =
namespacedTypes
|> List.collect (fun (ns, types) ->
types |> List.map (fun t ->
let config = Generator.getConfigFromAttribute<'Attr> context.ConfigGetter t
create ns t config))
Output.Ast modules