This repository was archived by the owner on Jun 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathres_js_ffi.ml
121 lines (115 loc) · 3.55 KB
/
res_js_ffi.ml
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
(* AST for js externals *)
type scope =
| Global
| Module of string (* bs.module("path") *)
| Scope of Longident.t (* bs.scope(/"window", "location"/) *)
type label_declaration = {
jld_attributes: Parsetree.attributes; [@live]
jld_name: string;
jld_alias: string;
jld_type: Parsetree.core_type;
jld_loc: Location.t;
}
type importSpec =
| Default of label_declaration
| Spec of label_declaration list
type import_description = {
jid_loc: Location.t;
jid_spec: importSpec;
jid_scope: scope;
jid_attributes: Parsetree.attributes;
}
let decl ~attrs ~loc ~name ~alias ~typ =
{
jld_loc = loc;
jld_attributes = attrs;
jld_name = name;
jld_alias = alias;
jld_type = typ;
}
let importDescr ~attrs ~scope ~importSpec ~loc =
{
jid_loc = loc;
jid_spec = importSpec;
jid_scope = scope;
jid_attributes = attrs;
}
let toParsetree importDescr =
let bsVal = (Location.mknoloc "val", Parsetree.PStr []) in
let attrs =
match importDescr.jid_scope with
| Global -> [bsVal]
(* @genType.import("./MyMath"),
* @genType.import(/"./MyMath", "default"/) *)
| Module s ->
let structure =
[
Parsetree.Pconst_string (s, None)
|> Ast_helper.Exp.constant |> Ast_helper.Str.eval;
]
in
let genType =
(Location.mknoloc "genType.import", Parsetree.PStr structure)
in
[genType]
| Scope longident ->
let structureItem =
let expr =
match
Longident.flatten longident
|> List.map (fun s ->
Ast_helper.Exp.constant (Parsetree.Pconst_string (s, None)))
with
| [expr] -> expr
| ([] as exprs) | (_ as exprs) -> exprs |> Ast_helper.Exp.tuple
in
Ast_helper.Str.eval expr
in
let bsScope =
(Location.mknoloc "scope", Parsetree.PStr [structureItem])
in
[bsVal; bsScope]
in
let valueDescrs =
match importDescr.jid_spec with
| Default decl ->
let prim = [decl.jld_name] in
let allAttrs =
List.concat [attrs; importDescr.jid_attributes]
|> List.map (fun attr ->
match attr with
| ( ({Location.txt = "genType.import"} as id),
Parsetree.PStr
[{pstr_desc = Parsetree.Pstr_eval (moduleName, _)}] ) ->
let default =
Parsetree.Pconst_string ("default", None)
|> Ast_helper.Exp.constant
in
let structureItem =
[moduleName; default] |> Ast_helper.Exp.tuple
|> Ast_helper.Str.eval
in
(id, Parsetree.PStr [structureItem])
| attr -> attr)
in
[
Ast_helper.Val.mk ~loc:importDescr.jid_loc ~prim ~attrs:allAttrs
(Location.mknoloc decl.jld_alias)
decl.jld_type
|> Ast_helper.Str.primitive;
]
| Spec decls ->
List.map
(fun decl ->
let prim = [decl.jld_name] in
let allAttrs = List.concat [attrs; decl.jld_attributes] in
Ast_helper.Val.mk ~loc:importDescr.jid_loc ~prim ~attrs:allAttrs
(Location.mknoloc decl.jld_alias)
decl.jld_type
|> Ast_helper.Str.primitive ~loc:decl.jld_loc)
decls
in
let jsFfiAttr = (Location.mknoloc "ns.jsFfi", Parsetree.PStr []) in
Ast_helper.Mod.structure ~loc:importDescr.jid_loc valueDescrs
|> Ast_helper.Incl.mk ~attrs:[jsFfiAttr] ~loc:importDescr.jid_loc
|> Ast_helper.Str.include_ ~loc:importDescr.jid_loc