Skip to content

Commit f066b35

Browse files
authored
distinguish regular modules from module types (#925)
1 parent 7c9f1bd commit f066b35

File tree

7 files changed

+145
-12
lines changed

7 files changed

+145
-12
lines changed

analysis/src/ProcessCmt.ml

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
open SharedTypes
22

3+
let isModuleType (declared : Module.t Declared.t) =
4+
match declared.modulePath with
5+
| ExportedModule {isType} -> isType
6+
| _ -> false
7+
38
let addDeclared ~(name : string Location.loc) ~extent ~stamp ~(env : Env.t)
49
~item attributes addExported addStamp =
510
let isExported = addExported name.txt stamp in
@@ -150,7 +155,8 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t)
150155
in
151156
[
152157
{
153-
Module.kind = Module declared.item;
158+
Module.kind =
159+
Module {type_ = declared.item; isModuleType = isModuleType declared};
154160
name = declared.name.txt;
155161
docstring = declared.docstring;
156162
deprecated = declared.deprecated;
@@ -367,7 +373,8 @@ let rec forSignatureItem ~env ~(exported : Exported.t)
367373
in
368374
[
369375
{
370-
Module.kind = Module declared.item;
376+
Module.kind =
377+
Module {type_ = declared.item; isModuleType = isModuleType declared};
371378
name = declared.name.txt;
372379
docstring = declared.docstring;
373380
deprecated = declared.deprecated;
@@ -481,7 +488,8 @@ let rec forStructureItem ~env ~(exported : Exported.t) item =
481488
in
482489
[
483490
{
484-
Module.kind = Module declared.item;
491+
Module.kind =
492+
Module {type_ = declared.item; isModuleType = isModuleType declared};
485493
name = declared.name.txt;
486494
docstring = declared.docstring;
487495
deprecated = declared.deprecated;
@@ -513,7 +521,8 @@ let rec forStructureItem ~env ~(exported : Exported.t) item =
513521
in
514522
[
515523
{
516-
Module.kind = Module modTypeItem;
524+
Module.kind =
525+
Module {type_ = declared.item; isModuleType = isModuleType declared};
517526
name = declared.name.txt;
518527
docstring = declared.docstring;
519528
deprecated = declared.deprecated;

analysis/src/SharedTypes.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ module Module = struct
120120
type kind =
121121
| Value of Types.type_expr
122122
| Type of Type.t * Types.rec_status
123-
| Module of t
123+
| Module of {type_: t; isModuleType: bool}
124124

125125
and item = {
126126
kind: kind;

tools/npm/Tools_Docgen.res

+9
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ type rec item =
5959
source: source,
6060
items: array<item>,
6161
})
62+
| @as("moduleType")
63+
ModuleType({
64+
id: string,
65+
docstrings: array<string>,
66+
deprecated?: string,
67+
name: string,
68+
source: source,
69+
items: array<item>,
70+
})
6271
| @as("moduleAlias")
6372
ModuleAlias({
6473
id: string,

tools/npm/Tools_Docgen.resi

+9
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ type rec item =
5858
source: source,
5959
items: array<item>,
6060
})
61+
| @as("moduleType")
62+
ModuleType({
63+
id: string,
64+
docstrings: array<string>,
65+
deprecated?: string,
66+
name: string,
67+
source: source,
68+
items: array<item>,
69+
})
6170
| @as("moduleAlias")
6271
ModuleAlias({
6372
id: string,

tools/src/tools.ml

+41-3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type docItem =
4444
(** Additional documentation for constructors and record fields, if available. *)
4545
}
4646
| Module of docsForModule
47+
| ModuleType of docsForModule
4748
| ModuleAlias of {
4849
id: string;
4950
docstring: string list;
@@ -204,6 +205,26 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
204205
(stringifyDocItem ~originalEnv ~indentation:(indentation + 1))
205206
|> array) );
206207
]
208+
| ModuleType m ->
209+
stringifyObject ~startOnNewline:true ~indentation
210+
[
211+
("id", Some (wrapInQuotes m.id));
212+
("name", Some (wrapInQuotes m.name));
213+
("kind", Some (wrapInQuotes "moduleType"));
214+
( "deprecated",
215+
match m.deprecated with
216+
| Some d -> Some (wrapInQuotes d)
217+
| None -> None );
218+
("docstrings", Some (stringifyDocstrings m.docstring));
219+
( "source",
220+
Some (stringifySource ~indentation:(indentation + 1) m.source) );
221+
( "items",
222+
Some
223+
(m.items
224+
|> List.map
225+
(stringifyDocItem ~originalEnv ~indentation:(indentation + 1))
226+
|> array) );
227+
]
207228
| ModuleAlias m ->
208229
stringifyObject ~startOnNewline:true ~indentation
209230
[
@@ -379,7 +400,7 @@ let extractDocs ~entryPointFile ~debug =
379400
detail = typeDetail typ ~full ~env;
380401
source;
381402
})
382-
| Module (Ident p) ->
403+
| Module {type_ = Ident p; isModuleType = false} ->
383404
(* module Whatever = OtherModule *)
384405
let aliasToModule = p |> pathIdentToString in
385406
let id =
@@ -409,7 +430,7 @@ let extractDocs ~entryPointFile ~debug =
409430
item.docstring @ internalDocstrings
410431
|> List.map String.trim;
411432
})
412-
| Module (Structure m) ->
433+
| Module {type_ = Structure m; isModuleType = false} ->
413434
(* module Whatever = {} in res or module Whatever: {} in resi. *)
414435
let modulePath = m.name :: modulePath in
415436
let docs = extractDocsForModule ~modulePath m in
@@ -423,8 +444,25 @@ let extractDocs ~entryPointFile ~debug =
423444
source;
424445
items = docs.items;
425446
})
447+
| Module {type_ = Structure m; isModuleType = true} ->
448+
(* module type Whatever = {} *)
449+
let modulePath = m.name :: modulePath in
450+
let docs = extractDocsForModule ~modulePath m in
451+
Some
452+
(ModuleType
453+
{
454+
id = modulePath |> List.rev |> ident;
455+
name = m.name;
456+
docstring = item.docstring @ m.docstring;
457+
deprecated = item.deprecated;
458+
source;
459+
items = docs.items;
460+
})
426461
| Module
427-
(Constraint (Structure _impl, Structure interface)) ->
462+
{
463+
type_ =
464+
Constraint (Structure _impl, Structure interface);
465+
} ->
428466
(* module Whatever: { <interface> } = { <impl> }. Prefer the interface. *)
429467
Some
430468
(Module

tools/tests/src/DocExtractionRes.res

+33-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ let make = name => {
2323
let asOffline = (t: t) => {...t, online: false}
2424

2525
/** exotic identifier */
26-
let \"SomeConstant\" = 12
26+
let \"SomeConstant" = 12
2727

2828
module SomeInnerModule = {
2929
/*** Another module level docstring here.*/
@@ -96,4 +96,36 @@ module ModuleWithThingsThatShouldNotBeExported: {
9696
}
9797
}
9898

99+
module type Example = {
100+
/***
101+
this is an example module type
102+
*/
103+
104+
/**
105+
main type of this module
106+
*/
107+
type t
108+
109+
/**
110+
function from t to t
111+
*/
112+
let f: t => t
113+
}
114+
115+
module M: Example = {
116+
/***
117+
implementation of Example module type
118+
*/
119+
120+
/**
121+
main type
122+
*/
123+
type t = int
124+
125+
/**
126+
identity function
127+
*/
128+
let f = (x: int) => x
129+
}
130+
99131
// ^dex

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

+39-3
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@
6060
}
6161
},
6262
{
63-
"id": "DocExtractionRes.SomeConstant\\",
63+
"id": "DocExtractionRes.SomeConstant",
6464
"kind": "value",
65-
"name": "SomeConstant\\",
66-
"signature": "let SomeConstant\\: int",
65+
"name": "SomeConstant",
66+
"signature": "let SomeConstant: int",
6767
"docstrings": ["exotic identifier"],
6868
"source": {
6969
"filepath": "src/DocExtractionRes.res",
@@ -270,5 +270,41 @@
270270
"col": 3
271271
}
272272
}]
273+
},
274+
{
275+
"id": "DocExtractionRes.Example",
276+
"name": "Example",
277+
"kind": "moduleType",
278+
"docstrings": [],
279+
"source": {
280+
"filepath": "src/DocExtractionRes.res",
281+
"line": 99,
282+
"col": 13
283+
},
284+
"items": [
285+
{
286+
"id": "DocExtractionRes.Example.t",
287+
"kind": "type",
288+
"name": "t",
289+
"signature": "type t",
290+
"docstrings": ["main type of this module"],
291+
"source": {
292+
"filepath": "src/DocExtractionRes.res",
293+
"line": 107,
294+
"col": 3
295+
}
296+
},
297+
{
298+
"id": "DocExtractionRes.Example.f",
299+
"kind": "value",
300+
"name": "f",
301+
"signature": "let f: t => t",
302+
"docstrings": ["function from t to t"],
303+
"source": {
304+
"filepath": "src/DocExtractionRes.res",
305+
"line": 109,
306+
"col": 3
307+
}
308+
}]
273309
}]
274310
}

0 commit comments

Comments
 (0)