Skip to content

Commit 2de0c17

Browse files
committed
tools: add source field
1 parent a9e1e18 commit 2de0c17

File tree

8 files changed

+281
-22
lines changed

8 files changed

+281
-22
lines changed

analysis/src/ProcessCmt.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t)
6060
name = declared.name.txt;
6161
docstring = declared.docstring;
6262
deprecated = declared.deprecated;
63+
loc = declared.extentLoc;
6364
};
6465
]
6566
| Sig_type
@@ -134,6 +135,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t)
134135
name = declared.name.txt;
135136
docstring = declared.docstring;
136137
deprecated = declared.deprecated;
138+
loc = declared.extentLoc;
137139
};
138140
]
139141
| Sig_module (ident, {md_type; md_attributes; md_loc}, _) ->
@@ -152,6 +154,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t)
152154
name = declared.name.txt;
153155
docstring = declared.docstring;
154156
deprecated = declared.deprecated;
157+
loc = declared.extentLoc;
155158
};
156159
]
157160
| _ -> []
@@ -316,6 +319,7 @@ let forTypeDeclaration ~env ~(exported : Exported.t)
316319
name = declared.name.txt;
317320
docstring = declared.docstring;
318321
deprecated = declared.deprecated;
322+
loc = declared.extentLoc;
319323
}
320324

321325
let rec forSignatureItem ~env ~(exported : Exported.t)
@@ -335,6 +339,7 @@ let rec forSignatureItem ~env ~(exported : Exported.t)
335339
name = declared.name.txt;
336340
docstring = declared.docstring;
337341
deprecated = declared.deprecated;
342+
loc = declared.extentLoc;
338343
};
339344
]
340345
| Tsig_type (recFlag, decls) ->
@@ -366,6 +371,7 @@ let rec forSignatureItem ~env ~(exported : Exported.t)
366371
name = declared.name.txt;
367372
docstring = declared.docstring;
368373
deprecated = declared.deprecated;
374+
loc = declared.extentLoc;
369375
};
370376
]
371377
| Tsig_recmodule modDecls ->
@@ -443,6 +449,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item =
443449
name = declared.name.txt;
444450
docstring = declared.docstring;
445451
deprecated = declared.deprecated;
452+
loc = declared.extentLoc;
446453
}
447454
:: !items
448455
| Tpat_tuple pats | Tpat_array pats | Tpat_construct (_, _, pats) ->
@@ -478,6 +485,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item =
478485
name = declared.name.txt;
479486
docstring = declared.docstring;
480487
deprecated = declared.deprecated;
488+
loc = declared.extentLoc;
481489
};
482490
]
483491
| Tstr_recmodule modDecls ->
@@ -509,6 +517,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item =
509517
name = declared.name.txt;
510518
docstring = declared.docstring;
511519
deprecated = declared.deprecated;
520+
loc = declared.extentLoc;
512521
};
513522
]
514523
| Tstr_include {incl_mod; incl_type} ->
@@ -538,6 +547,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item =
538547
name = declared.name.txt;
539548
docstring = declared.docstring;
540549
deprecated = declared.deprecated;
550+
loc = declared.extentLoc;
541551
};
542552
]
543553
| Tstr_type (recFlag, decls) ->

analysis/src/SharedTypes.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ module Module = struct
125125
and item = {
126126
kind: kind;
127127
name: string;
128+
loc: Location.t;
128129
docstring: string list;
129130
deprecated: string option;
130131
}

tools/src/tools.ml

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,20 @@ type constructorDoc = {
1818
items: constructorPayload option;
1919
}
2020

21+
type source = {filepath: string; line: int; col: int}
22+
2123
type docItemDetail =
2224
| Record of {fieldDocs: fieldDoc list}
2325
| Variant of {constructorDocs: constructorDoc list}
26+
2427
type docItem =
2528
| Value of {
2629
id: string;
2730
docstring: string list;
2831
signature: string;
2932
name: string;
3033
deprecated: string option;
34+
source: source;
3135
}
3236
| Type of {
3337
id: string;
@@ -36,20 +40,23 @@ type docItem =
3640
name: string;
3741
deprecated: string option;
3842
detail: docItemDetail option;
43+
source: source;
3944
(** Additional documentation for constructors and record fields, if available. *)
4045
}
4146
| Module of docsForModule
4247
| ModuleAlias of {
4348
id: string;
4449
docstring: string list;
4550
name: string;
51+
source: source;
4652
items: docItem list;
4753
}
4854
and docsForModule = {
4955
id: string;
5056
docstring: string list;
5157
deprecated: string option;
5258
name: string;
59+
source: source;
5360
items: docItem list;
5461
}
5562

@@ -132,10 +139,19 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) =
132139
|> array) );
133140
]
134141

142+
let stringifySource ~indentation source =
143+
let open Protocol in
144+
stringifyObject ~startOnNewline: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+
135151
let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
136152
let open Protocol in
137153
match item with
138-
| Value {id; docstring; signature; name; deprecated} ->
154+
| Value {id; docstring; signature; name; deprecated; source} ->
139155
stringifyObject ~startOnNewline:true ~indentation
140156
[
141157
("id", Some (wrapInQuotes id));
@@ -147,8 +163,9 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
147163
| None -> None );
148164
("signature", Some (signature |> String.trim |> wrapInQuotes));
149165
("docstrings", Some (stringifyDocstrings docstring));
166+
("source", Some (stringifySource ~indentation:(indentation + 1) source));
150167
]
151-
| Type {id; docstring; signature; name; deprecated; detail} ->
168+
| Type {id; docstring; signature; name; deprecated; detail; source} ->
152169
stringifyObject ~startOnNewline:true ~indentation
153170
[
154171
("id", Some (wrapInQuotes id));
@@ -160,6 +177,7 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
160177
| None -> None );
161178
("signature", Some (signature |> wrapInQuotes));
162179
("docstrings", Some (stringifyDocstrings docstring));
180+
("source", Some (stringifySource ~indentation:(indentation + 1) source));
163181
( "detail",
164182
match detail with
165183
| None -> None
@@ -177,6 +195,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
177195
| Some d -> Some (wrapInQuotes d)
178196
| None -> None );
179197
("docstrings", Some (stringifyDocstrings m.docstring));
198+
( "source",
199+
Some (stringifySource ~indentation:(indentation + 1) m.source) );
180200
( "items",
181201
Some
182202
(m.items
@@ -191,6 +211,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
191211
("kind", Some (wrapInQuotes "moduleAlias"));
192212
("name", Some (wrapInQuotes m.name));
193213
("docstrings", Some (stringifyDocstrings m.docstring));
214+
( "source",
215+
Some (stringifySource ~indentation:(indentation + 1) m.source) );
194216
( "items",
195217
Some
196218
(m.items
@@ -209,6 +231,7 @@ and stringifyDocsForModule ?(indentation = 0) ~originalEnv (d : docsForModule) =
209231
| Some d -> Some (wrapInQuotes d)
210232
| None -> None );
211233
("docstrings", Some (stringifyDocstrings d.docstring));
234+
("source", Some (stringifySource ~indentation:(indentation + 1) d.source));
212235
( "items",
213236
Some
214237
(d.items
@@ -257,6 +280,33 @@ let typeDetail typ ~env ~full =
257280
let makeId modulePath ~identifier =
258281
identifier :: modulePath |> List.rev |> SharedTypes.ident
259282

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 ~rootPath ~path:loc_start.pos_fname in
307+
308+
{filepath; line = line + 1; col = col + 1}
309+
260310
let extractDocs ~path ~debug =
261311
if debug then Printf.printf "extracting docs for %s\n" path;
262312
let result =
@@ -289,6 +339,7 @@ let extractDocs ~path ~debug =
289339
| Some full ->
290340
let file = full.file in
291341
let structure = file.structure in
342+
let rootPath = full.package.rootPath in
292343
let open SharedTypes in
293344
let env = QueryEnv.fromFile file in
294345
let rec extractDocsForModule ?(modulePath = [env.file.moduleName])
@@ -298,11 +349,22 @@ let extractDocs ~path ~debug =
298349
docstring = structure.docstring |> List.map String.trim;
299350
name = structure.name;
300351
deprecated = structure.deprecated;
352+
source =
353+
{
354+
filepath =
355+
(match rootPath = "." with
356+
| true -> file.uri |> Uri.toPath
357+
| false ->
358+
findRelativePath ~rootPath ~path:(file.uri |> Uri.toPath));
359+
line = 0;
360+
col = 0;
361+
};
301362
items =
302363
structure.items
303364
|> List.filter_map (fun (item : Module.item) ->
304365
match item.kind with
305366
| Value typ ->
367+
let source = getSource ~rootPath item.loc in
306368
Some
307369
(Value
308370
{
@@ -313,6 +375,9 @@ let extractDocs ~path ~debug =
313375
^ Shared.typeToString typ;
314376
name = item.name;
315377
deprecated = item.deprecated;
378+
source;
379+
(* source = *)
380+
(* getSource ~stamp:typ.id ~full ~name:item.name; *)
316381
})
317382
| Type (typ, _) ->
318383
Some
@@ -325,6 +390,7 @@ let extractDocs ~path ~debug =
325390
name = item.name;
326391
deprecated = item.deprecated;
327392
detail = typeDetail typ ~full ~env;
393+
source = getSource ~rootPath item.loc;
328394
})
329395
| Module (Ident p) ->
330396
(* module Whatever = OtherModule *)
@@ -350,6 +416,7 @@ let extractDocs ~path ~debug =
350416
{
351417
id;
352418
name = item.name;
419+
source = getSource ~rootPath item.loc;
353420
items;
354421
docstring =
355422
item.docstring @ internalDocstrings
@@ -366,6 +433,7 @@ let extractDocs ~path ~debug =
366433
name = m.name;
367434
docstring = item.docstring @ m.docstring;
368435
deprecated = item.deprecated;
436+
source = getSource ~rootPath item.loc;
369437
items = docs.items;
370438
})
371439
| Module

tools/tests/src/expected/DocExtraction2.res.json

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,70 @@
22
{
33
"name": "DocExtraction2",
44
"docstrings": ["Module level doc here."],
5+
"source": {
6+
"filepath": "src/DocExtraction2.resi",
7+
"line": 0,
8+
"col": 0
9+
},
510
"items": [
611
{
712
"id": "DocExtraction2.t",
813
"kind": "type",
914
"name": "t",
1015
"signature": "type t",
11-
"docstrings": ["Type t is pretty cool."]
16+
"docstrings": ["Type t is pretty cool."],
17+
"source": {
18+
"filepath": "src/DocExtraction2.resi",
19+
"line": 4,
20+
"col": 1
21+
}
1222
},
1323
{
1424
"id": "DocExtraction2.make",
1525
"kind": "value",
1626
"name": "make",
1727
"signature": "let make: (. unit) => t",
18-
"docstrings": ["Makerz of stuffz."]
28+
"docstrings": ["Makerz of stuffz."],
29+
"source": {
30+
"filepath": "src/DocExtraction2.resi",
31+
"line": 7,
32+
"col": 1
33+
}
1934
},
2035
{
2136
"id": "DocExtraction2.InnerModule",
2237
"name": "InnerModule",
2338
"kind": "module",
2439
"docstrings": [],
40+
"source": {
41+
"filepath": "src/DocExtraction2.resi",
42+
"line": 9,
43+
"col": 8
44+
},
2545
"items": [
2646
{
2747
"id": "DocExtraction2.InnerModule.t",
2848
"kind": "type",
2949
"name": "t",
3050
"signature": "type t",
31-
"docstrings": ["This type is also t."]
51+
"docstrings": ["This type is also t."],
52+
"source": {
53+
"filepath": "src/DocExtraction2.resi",
54+
"line": 13,
55+
"col": 3
56+
}
3257
},
3358
{
3459
"id": "DocExtraction2.InnerModule.make",
3560
"kind": "value",
3661
"name": "make",
3762
"signature": "let make: (. unit) => t",
38-
"docstrings": ["Maker of tea."]
63+
"docstrings": ["Maker of tea."],
64+
"source": {
65+
"filepath": "src/DocExtraction2.resi",
66+
"line": 15,
67+
"col": 3
68+
}
3969
}]
4070
}]
4171
}

0 commit comments

Comments
 (0)