@@ -18,16 +18,20 @@ type constructorDoc = {
18
18
items : constructorPayload option ;
19
19
}
20
20
21
+ type source = {filepath : string ; line : int ; col : int }
22
+
21
23
type docItemDetail =
22
24
| Record of {fieldDocs : fieldDoc list }
23
25
| Variant of {constructorDocs : constructorDoc list }
26
+
24
27
type docItem =
25
28
| Value of {
26
29
id : string ;
27
30
docstring : string list ;
28
31
signature : string ;
29
32
name : string ;
30
33
deprecated : string option ;
34
+ source : source ;
31
35
}
32
36
| Type of {
33
37
id : string ;
@@ -36,20 +40,23 @@ type docItem =
36
40
name : string ;
37
41
deprecated : string option ;
38
42
detail : docItemDetail option ;
43
+ source : source ;
39
44
(* * Additional documentation for constructors and record fields, if available. *)
40
45
}
41
46
| Module of docsForModule
42
47
| ModuleAlias of {
43
48
id : string ;
44
49
docstring : string list ;
45
50
name : string ;
51
+ source : source ;
46
52
items : docItem list ;
47
53
}
48
54
and docsForModule = {
49
55
id : string ;
50
56
docstring : string list ;
51
57
deprecated : string option ;
52
58
name : string ;
59
+ source : source ;
53
60
items : docItem list ;
54
61
}
55
62
@@ -132,10 +139,19 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
132
139
|> array ) );
133
140
]
134
141
142
+ let stringifySource ~indentation source =
143
+ let open Protocol in
144
+ stringifyObject ~start OnNewline:false ~indentation
145
+ [
146
+ (" filepath" , Some (source.filepath |> wrapInQuotes));
147
+ (" line" , Some (source.line |> string_of_int));
148
+ (" col" , Some (source.col |> string_of_int));
149
+ ]
150
+
135
151
let rec stringifyDocItem ?(indentation = 0 ) ~originalEnv (item : docItem ) =
136
152
let open Protocol in
137
153
match item with
138
- | Value {id; docstring; signature; name; deprecated} ->
154
+ | Value {id; docstring; signature; name; deprecated; source } ->
139
155
stringifyObject ~start OnNewline:true ~indentation
140
156
[
141
157
(" id" , Some (wrapInQuotes id));
@@ -147,8 +163,9 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
147
163
| None -> None );
148
164
(" signature" , Some (signature |> String. trim |> wrapInQuotes));
149
165
(" docstrings" , Some (stringifyDocstrings docstring));
166
+ (" source" , Some (stringifySource ~indentation: (indentation + 1 ) source));
150
167
]
151
- | Type {id; docstring; signature; name; deprecated; detail} ->
168
+ | Type {id; docstring; signature; name; deprecated; detail; source } ->
152
169
stringifyObject ~start OnNewline:true ~indentation
153
170
[
154
171
(" id" , Some (wrapInQuotes id));
@@ -160,6 +177,7 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
160
177
| None -> None );
161
178
(" signature" , Some (signature |> wrapInQuotes));
162
179
(" docstrings" , Some (stringifyDocstrings docstring));
180
+ (" source" , Some (stringifySource ~indentation: (indentation + 1 ) source));
163
181
( " detail" ,
164
182
match detail with
165
183
| None -> None
@@ -177,6 +195,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
177
195
| Some d -> Some (wrapInQuotes d)
178
196
| None -> None );
179
197
(" docstrings" , Some (stringifyDocstrings m.docstring));
198
+ ( " source" ,
199
+ Some (stringifySource ~indentation: (indentation + 1 ) m.source) );
180
200
( " items" ,
181
201
Some
182
202
(m.items
@@ -191,6 +211,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
191
211
(" kind" , Some (wrapInQuotes " moduleAlias" ));
192
212
(" name" , Some (wrapInQuotes m.name));
193
213
(" docstrings" , Some (stringifyDocstrings m.docstring));
214
+ ( " source" ,
215
+ Some (stringifySource ~indentation: (indentation + 1 ) m.source) );
194
216
( " items" ,
195
217
Some
196
218
(m.items
@@ -209,6 +231,7 @@ and stringifyDocsForModule ?(indentation = 0) ~originalEnv (d : docsForModule) =
209
231
| Some d -> Some (wrapInQuotes d)
210
232
| None -> None );
211
233
(" docstrings" , Some (stringifyDocstrings d.docstring));
234
+ (" source" , Some (stringifySource ~indentation: (indentation + 1 ) d.source));
212
235
( " items" ,
213
236
Some
214
237
(d.items
@@ -257,6 +280,33 @@ let typeDetail typ ~env ~full =
257
280
let makeId modulePath ~identifier =
258
281
identifier :: modulePath |> List. rev |> SharedTypes. ident
259
282
283
+ let findRelativePath ~rootPath ~path =
284
+ let open Filename in
285
+ let realPath =
286
+ match rootPath = " ." with
287
+ | true -> Sys. getcwd ()
288
+ | false ->
289
+ if is_relative rootPath then concat (Sys. getcwd () ) rootPath else rootPath
290
+ in
291
+ let rec loop dirPath acc =
292
+ match dirname dirPath = realPath with
293
+ | true -> basename dirPath :: acc |> String. concat dir_sep
294
+ | false -> (
295
+ match dirPath with
296
+ | "/" -> failwith " Failed to find relative path of package"
297
+ | "." -> path
298
+ | _ -> loop (dirname dirPath) (basename dirPath :: acc))
299
+ in
300
+
301
+ loop path []
302
+
303
+ let getSource ~rootPath ({loc_start} : Location.t ) =
304
+ let line, col = Pos. ofLexing loc_start in
305
+
306
+ let filepath = findRelativePath ~root Path ~path: loc_start.pos_fname in
307
+
308
+ {filepath; line = line + 1 ; col = col + 1 }
309
+
260
310
let extractDocs ~path ~debug =
261
311
if debug then Printf. printf " extracting docs for %s\n " path;
262
312
let result =
@@ -289,6 +339,7 @@ let extractDocs ~path ~debug =
289
339
| Some full ->
290
340
let file = full.file in
291
341
let structure = file.structure in
342
+ let rootPath = full.package.rootPath in
292
343
let open SharedTypes in
293
344
let env = QueryEnv. fromFile file in
294
345
let rec extractDocsForModule ?(modulePath = [env.file.moduleName])
@@ -298,11 +349,22 @@ let extractDocs ~path ~debug =
298
349
docstring = structure.docstring |> List. map String. trim;
299
350
name = structure.name;
300
351
deprecated = structure.deprecated;
352
+ source =
353
+ {
354
+ filepath =
355
+ (match rootPath = " ." with
356
+ | true -> file.uri |> Uri. toPath
357
+ | false ->
358
+ findRelativePath ~root Path ~path: (file.uri |> Uri. toPath));
359
+ line = 0 ;
360
+ col = 0 ;
361
+ };
301
362
items =
302
363
structure.items
303
364
|> List. filter_map (fun (item : Module.item ) ->
304
365
match item.kind with
305
366
| Value typ ->
367
+ let source = getSource ~root Path item.loc in
306
368
Some
307
369
(Value
308
370
{
@@ -313,6 +375,9 @@ let extractDocs ~path ~debug =
313
375
^ Shared. typeToString typ;
314
376
name = item.name;
315
377
deprecated = item.deprecated;
378
+ source;
379
+ (* source = *)
380
+ (* getSource ~stamp:typ.id ~full ~name:item.name; *)
316
381
})
317
382
| Type (typ , _ ) ->
318
383
Some
@@ -325,6 +390,7 @@ let extractDocs ~path ~debug =
325
390
name = item.name;
326
391
deprecated = item.deprecated;
327
392
detail = typeDetail typ ~full ~env ;
393
+ source = getSource ~root Path item.loc;
328
394
})
329
395
| Module (Ident p ) ->
330
396
(* module Whatever = OtherModule *)
@@ -350,6 +416,7 @@ let extractDocs ~path ~debug =
350
416
{
351
417
id;
352
418
name = item.name;
419
+ source = getSource ~root Path item.loc;
353
420
items;
354
421
docstring =
355
422
item.docstring @ internalDocstrings
@@ -366,6 +433,7 @@ let extractDocs ~path ~debug =
366
433
name = m.name;
367
434
docstring = item.docstring @ m.docstring;
368
435
deprecated = item.deprecated;
436
+ source = getSource ~root Path item.loc;
369
437
items = docs.items;
370
438
})
371
439
| Module
0 commit comments