1
- let formatCode content =
2
- let {Res_driver. parsetree = signature; comments} =
3
- Res_driver. parseInterfaceFromSource ~for Printer:true
4
- ~display Filename:" <missing-file>" ~source: content
5
- in
6
- Res_printer. printInterface ~width: ! Res_cli.ResClflags. width ~comments
7
- signature
8
- |> String. trim
1
+ type linkableType = {
2
+ name : string ;
3
+ path : Path .t ;
4
+ env : SharedTypes.QueryEnv .t ;
5
+ loc : Location .t ;
6
+ }
9
7
10
8
type docItemDetail =
11
9
| Record of {fieldDocs : (string * string list ) list }
12
10
| Variant of {constructorDocs : (string * string list ) list }
13
11
type docItem =
14
- | Value of {docstring : string list ; signature : string ; name : string }
12
+ | Value of {
13
+ docstring : string list ;
14
+ signature : string ;
15
+ name : string ;
16
+ linkables : linkableType list ;
17
+ (* * Relevant types to link to, found in relation to this value. *)
18
+ }
15
19
| Type of {
16
20
docstring : string list ;
17
21
signature : string ;
18
22
name : string ;
19
23
detail : docItemDetail option ;
24
+ (* * Additional documentation for constructors and record fields, if available. *)
25
+ linkables : linkableType list ;
26
+ (* * Relevant types to link to, found in relation to this type. *)
20
27
}
21
28
| Module of docsForModule
22
29
and docsForModule = {docstring : string list ; name : string ; items : docItem list }
23
30
31
+ let formatCode content =
32
+ let {Res_driver. parsetree = signature; comments} =
33
+ Res_driver. parseInterfaceFromSource ~for Printer:true
34
+ ~display Filename:" <missing-file>" ~source: content
35
+ in
36
+ Res_printer. printInterface ~width: ! Res_cli.ResClflags. width ~comments
37
+ signature
38
+ |> String. trim
39
+
40
+ module Linkables = struct
41
+ (* TODO: Extend this by going into function arguments, tuples etc... *)
42
+ let labelDeclarationsTypes lds =
43
+ lds |> List. map (fun (ld : Types.label_declaration ) -> ld.ld_type)
44
+
45
+ let rec linkablesFromDecl (decl : Types.type_declaration ) ~env ~full =
46
+ match decl.type_kind with
47
+ | Type_record (lds , _ ) -> (env, lds |> labelDeclarationsTypes)
48
+ | Type_variant cds ->
49
+ ( env,
50
+ cds
51
+ |> List. map (fun (cd : Types.constructor_declaration ) ->
52
+ let fromArgs =
53
+ match cd.cd_args with
54
+ | Cstr_tuple ts -> ts
55
+ | Cstr_record lds -> lds |> labelDeclarationsTypes
56
+ in
57
+ match cd.cd_res with
58
+ | None -> fromArgs
59
+ | Some t -> t :: fromArgs)
60
+ |> List. flatten )
61
+ | _ -> (
62
+ match decl.type_manifest with
63
+ | None -> (env, [] )
64
+ | Some typ -> linkablesFromTyp typ ~env ~full )
65
+
66
+ and linkablesFromTyp ~env ~(full : SharedTypes.full ) typ =
67
+ match typ |> Shared. digConstructor with
68
+ | Some path -> (
69
+ match References. digConstructor ~env ~package: full.package path with
70
+ | None -> (env, [typ])
71
+ | Some (env1 , {item = {decl} } ) -> linkablesFromDecl decl ~env: env1 ~full )
72
+ | None -> (env, [typ])
73
+
74
+ type linkableSource =
75
+ | Typ of SharedTypes.Type .t
76
+ | TypeExpr of Types .type_expr
77
+
78
+ let findLinkables ~env ~(full : SharedTypes.full ) (typ : linkableSource ) =
79
+ (* Expand definitions of types mentioned in typ.
80
+ If typ itself is a record or variant, search its body *)
81
+ let envToSearch, typesToSearch =
82
+ match typ with
83
+ | Typ t -> linkablesFromDecl ~env t.decl ~full
84
+ | TypeExpr t -> linkablesFromTyp t ~env ~full
85
+ in
86
+ let fromConstructorPath ~env path =
87
+ match References. digConstructor ~env ~package: full.package path with
88
+ | None -> None
89
+ | Some (env , {name = {txt} ; extentLoc} ) ->
90
+ if Utils. isUncurriedInternal path then None
91
+ else Some {name = txt; env; loc = extentLoc; path}
92
+ in
93
+ let constructors = Shared. findTypeConstructors typesToSearch in
94
+ constructors |> List. filter_map (fromConstructorPath ~env: envToSearch)
95
+ end
96
+
24
97
let stringifyDocstrings docstrings =
25
98
let open Protocol in
26
99
docstrings
27
100
|> List. map (fun docstring ->
28
101
docstring |> String. trim |> Json. escape |> wrapInQuotes)
29
102
|> array
30
103
104
+ let stringifyLinkables ?(indentation = 0 )
105
+ ~(originalEnv : SharedTypes.QueryEnv.t ) (linkables : linkableType list ) =
106
+ let open Protocol in
107
+ linkables
108
+ |> List. map (fun l ->
109
+ stringifyObject ~indentation: (indentation + 1 )
110
+ [
111
+ ( " path" ,
112
+ Some
113
+ (l.path |> SharedTypes. pathIdentToString |> Json. escape
114
+ |> wrapInQuotes) );
115
+ (" moduleName" , Some (l.env.file.moduleName |> wrapInQuotes));
116
+ ( " external" ,
117
+ Some
118
+ (Printf. sprintf " %b" (originalEnv.file.uri <> l.env.file.uri))
119
+ );
120
+ ])
121
+ |> array
122
+
31
123
let stringifyDetail ?(indentation = 0 ) (detail : docItemDetail ) =
32
124
let open Protocol in
33
125
match detail with
@@ -63,25 +155,33 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
63
155
|> array ) );
64
156
]
65
157
66
- let rec stringifyDocItem ?(indentation = 0 ) (item : docItem ) =
158
+ let rec stringifyDocItem ?(indentation = 0 ) ~ originalEnv (item : docItem ) =
67
159
let open Protocol in
68
160
match item with
69
- | Value {docstring; signature; name} ->
161
+ | Value {docstring; signature; name; linkables } ->
70
162
stringifyObject ~start OnNewline:true ~indentation
71
163
[
72
164
(" kind" , Some (wrapInQuotes " value" ));
73
165
(" name" , Some (name |> Json. escape |> wrapInQuotes));
74
166
( " signature" ,
75
167
Some (signature |> String. trim |> Json. escape |> wrapInQuotes) );
76
168
(" docstrings" , Some (stringifyDocstrings docstring));
169
+ ( " linkables" ,
170
+ Some
171
+ (stringifyLinkables ~original Env ~indentation: (indentation + 1 )
172
+ linkables) );
77
173
]
78
- | Type {docstring; signature; name; detail} ->
174
+ | Type {docstring; signature; name; detail; linkables } ->
79
175
stringifyObject ~start OnNewline:true ~indentation
80
176
[
81
177
(" kind" , Some (wrapInQuotes " type" ));
82
178
(" name" , Some (name |> Json. escape |> wrapInQuotes));
83
179
(" signature" , Some (signature |> Json. escape |> wrapInQuotes));
84
180
(" docstrings" , Some (stringifyDocstrings docstring));
181
+ ( " linkables" ,
182
+ Some
183
+ (stringifyLinkables ~original Env ~indentation: (indentation + 1 )
184
+ linkables) );
85
185
( " detail" ,
86
186
match detail with
87
187
| None -> None
@@ -92,10 +192,13 @@ let rec stringifyDocItem ?(indentation = 0) (item : docItem) =
92
192
stringifyObject ~start OnNewline:true ~indentation
93
193
[
94
194
(" kind" , Some (wrapInQuotes " module" ));
95
- (" item" , Some (stringifyDocsForModule ~indentation: (indentation + 1 ) m));
195
+ ( " item" ,
196
+ Some
197
+ (stringifyDocsForModule ~original Env ~indentation: (indentation + 1 )
198
+ m) );
96
199
]
97
200
98
- and stringifyDocsForModule ?(indentation = 0 ) (d : docsForModule ) =
201
+ and stringifyDocsForModule ?(indentation = 0 ) ~ originalEnv (d : docsForModule ) =
99
202
let open Protocol in
100
203
stringifyObject ~start OnNewline:true ~indentation
101
204
[
@@ -104,7 +207,8 @@ and stringifyDocsForModule ?(indentation = 0) (d : docsForModule) =
104
207
( " items" ,
105
208
Some
106
209
(d.items
107
- |> List. map (stringifyDocItem ~indentation: (indentation + 1 ))
210
+ |> List. map
211
+ (stringifyDocItem ~original Env ~indentation: (indentation + 1 ))
108
212
|> array ) );
109
213
]
110
214
@@ -133,11 +237,15 @@ let extractDocs ~path ~debug =
133
237
" let " ^ item.name ^ " : " ^ Shared. typeToString typ
134
238
|> formatCode;
135
239
name = item.name;
240
+ linkables =
241
+ TypeExpr typ |> Linkables. findLinkables ~env ~full ;
136
242
})
137
243
| Type (typ , _ ) ->
138
244
Some
139
245
(Type
140
246
{
247
+ linkables =
248
+ Typ typ |> Linkables. findLinkables ~env ~full ;
141
249
docstring = item.docstring |> List. map String. trim;
142
250
signature =
143
251
typ.decl
@@ -176,4 +284,4 @@ let extractDocs ~path ~debug =
176
284
}
177
285
in
178
286
let docs = extractDocs structure in
179
- print_endline (stringifyDocsForModule docs)
287
+ print_endline (stringifyDocsForModule ~original Env:env docs)
0 commit comments