From 011465059ed901449d22beee3e6487e527425009 Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Mon, 10 Jun 2024 10:50:34 -0300
Subject: [PATCH 1/8] add `moduletype` field for modules with explicitly
 annotated module type

---
 tools/src/tools.ml                            | 29 ++++++++++++++-----
 .../src/expected/DocExtractionRes.res.json    |  1 +
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/tools/src/tools.ml b/tools/src/tools.ml
index 9a314f92d..79837c717 100644
--- a/tools/src/tools.ml
+++ b/tools/src/tools.ml
@@ -44,7 +44,14 @@ type docItem =
           (** Additional documentation for constructors and record fields, if available. *)
     }
   | Module of docsForModule
-  | ModuleType of docsForModule
+  | ModuleType of {
+      id: string;
+      docstring: string list;
+      deprecated: string option;
+      name: string;
+      source: source;
+      items: docItem list;
+    }
   | ModuleAlias of {
       id: string;
       docstring: string list;
@@ -57,6 +64,7 @@ and docsForModule = {
   docstring: string list;
   deprecated: string option;
   name: string;
+  moduletype: string option;
   source: source;
   items: docItem list;
 }
@@ -195,6 +203,10 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
           match m.deprecated with
           | Some d -> Some (wrapInQuotes d)
           | None -> None );
+        ( "moduletype",
+          match m.moduletype with
+          | Some path -> Some (wrapInQuotes path)
+          | None -> None );
         ("docstrings", Some (stringifyDocstrings m.docstring));
         ( "source",
           Some (stringifySource ~indentation:(indentation + 1) m.source) );
@@ -356,6 +368,7 @@ let extractDocs ~entryPointFile ~debug =
             id = modulePath |> List.rev |> ident;
             docstring = structure.docstring |> List.map String.trim;
             name = structure.name;
+            moduletype = None;
             deprecated = structure.deprecated;
             source =
               {
@@ -439,6 +452,7 @@ let extractDocs ~entryPointFile ~debug =
                             {
                               id = modulePath |> List.rev |> ident;
                               name = m.name;
+                              moduletype = None;
                               docstring = item.docstring @ m.docstring;
                               deprecated = item.deprecated;
                               source;
@@ -469,12 +483,13 @@ let extractDocs ~entryPointFile ~debug =
                             (extractDocsForModule
                                ~modulePath:(interface.name :: modulePath)
                                interface))
-                     | Module {type_ = Constraint (Structure m, Ident _)} ->
-                       (* module M: T = {  }. Print M *)
-                       Some
-                         (Module
-                            (extractDocsForModule
-                               ~modulePath:(m.name :: modulePath) m))
+                     | Module {type_ = Constraint (Structure m, Ident p)} ->
+                       (* module M: T = { <impl> }. Print M *)
+                       let docs =
+                         extractDocsForModule ~modulePath:(m.name :: modulePath)
+                           m
+                       in
+                       Some (Module {docs with moduletype = Some (Path.name p)})
                      | _ -> None);
           }
         in
diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json
index 5f46f92db..01ea8a2ba 100644
--- a/tools/tests/src/expected/DocExtractionRes.res.json
+++ b/tools/tests/src/expected/DocExtractionRes.res.json
@@ -311,6 +311,7 @@
     "id": "DocExtractionRes.M",
     "name": "M",
     "kind": "module",
+    "moduletype": "Example",
     "docstrings": ["implementation of Example module type"],
     "source": {
       "filepath": "src/DocExtractionRes.res",

From a67efa57452f825da45bb7d8fd39a27895b17290 Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Mon, 10 Jun 2024 23:22:31 -0300
Subject: [PATCH 2/8] add full id

---
 tools/npm/Tools_Docgen.res                    |  1 +
 tools/npm/Tools_Docgen.resi                   |  1 +
 tools/src/tools.ml                            | 19 +++++++++++++------
 .../src/expected/DocExtractionRes.res.json    |  2 +-
 4 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/tools/npm/Tools_Docgen.res b/tools/npm/Tools_Docgen.res
index f060ab07e..c6b7d450c 100644
--- a/tools/npm/Tools_Docgen.res
+++ b/tools/npm/Tools_Docgen.res
@@ -56,6 +56,7 @@ type rec item =
       docstrings: array<string>,
       deprecated?: string,
       name: string,
+      moduletypeid?: string,
       source: source,
       items: array<item>,
     })
diff --git a/tools/npm/Tools_Docgen.resi b/tools/npm/Tools_Docgen.resi
index c410170aa..271f65f99 100644
--- a/tools/npm/Tools_Docgen.resi
+++ b/tools/npm/Tools_Docgen.resi
@@ -55,6 +55,7 @@ type rec item =
       docstrings: array<string>,
       deprecated?: string,
       name: string,
+      moduletypeid?: string,
       source: source,
       items: array<item>,
     })
diff --git a/tools/src/tools.ml b/tools/src/tools.ml
index 79837c717..bab297015 100644
--- a/tools/src/tools.ml
+++ b/tools/src/tools.ml
@@ -64,7 +64,7 @@ and docsForModule = {
   docstring: string list;
   deprecated: string option;
   name: string;
-  moduletype: string option;
+  moduletypeid: string option;
   source: source;
   items: docItem list;
 }
@@ -203,8 +203,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) =
           match m.deprecated with
           | Some d -> Some (wrapInQuotes d)
           | None -> None );
-        ( "moduletype",
-          match m.moduletype with
+        ( "moduletypeid",
+          match m.moduletypeid with
           | Some path -> Some (wrapInQuotes path)
           | None -> None );
         ("docstrings", Some (stringifyDocstrings m.docstring));
@@ -368,7 +368,7 @@ let extractDocs ~entryPointFile ~debug =
             id = modulePath |> List.rev |> ident;
             docstring = structure.docstring |> List.map String.trim;
             name = structure.name;
-            moduletype = None;
+            moduletypeid = None;
             deprecated = structure.deprecated;
             source =
               {
@@ -452,7 +452,7 @@ let extractDocs ~entryPointFile ~debug =
                             {
                               id = modulePath |> List.rev |> ident;
                               name = m.name;
-                              moduletype = None;
+                              moduletypeid = None;
                               docstring = item.docstring @ m.docstring;
                               deprecated = item.deprecated;
                               source;
@@ -489,7 +489,14 @@ let extractDocs ~entryPointFile ~debug =
                          extractDocsForModule ~modulePath:(m.name :: modulePath)
                            m
                        in
-                       Some (Module {docs with moduletype = Some (Path.name p)})
+                       Some
+                         (Module
+                            {
+                              docs with
+                              moduletypeid =
+                                Some
+                                  (makeId ~identifier:(Path.name p) modulePath);
+                            })
                      | _ -> None);
           }
         in
diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json
index 01ea8a2ba..a6505b0b7 100644
--- a/tools/tests/src/expected/DocExtractionRes.res.json
+++ b/tools/tests/src/expected/DocExtractionRes.res.json
@@ -311,7 +311,7 @@
     "id": "DocExtractionRes.M",
     "name": "M",
     "kind": "module",
-    "moduletype": "Example",
+    "moduletypeid": "DocExtractionRes.Example",
     "docstrings": ["implementation of Example module type"],
     "source": {
       "filepath": "src/DocExtractionRes.res",

From 162899d7d164f0460d4851f97845506fb59f8ada Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Wed, 12 Jun 2024 20:21:47 -0300
Subject: [PATCH 3/8] remove modulePath

---
 tools/src/tools.ml                                 | 3 +--
 tools/tests/src/expected/DocExtractionRes.res.json | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/src/tools.ml b/tools/src/tools.ml
index bab297015..8ea7a29ae 100644
--- a/tools/src/tools.ml
+++ b/tools/src/tools.ml
@@ -494,8 +494,7 @@ let extractDocs ~entryPointFile ~debug =
                             {
                               docs with
                               moduletypeid =
-                                Some
-                                  (makeId ~identifier:(Path.name p) modulePath);
+                                Some (makeId ~identifier:(Path.name p) []);
                             })
                      | _ -> None);
           }
diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json
index a6505b0b7..9c74d11cd 100644
--- a/tools/tests/src/expected/DocExtractionRes.res.json
+++ b/tools/tests/src/expected/DocExtractionRes.res.json
@@ -311,7 +311,7 @@
     "id": "DocExtractionRes.M",
     "name": "M",
     "kind": "module",
-    "moduletypeid": "DocExtractionRes.Example",
+    "moduletypeid": "Example",
     "docstrings": ["implementation of Example module type"],
     "source": {
       "filepath": "src/DocExtractionRes.res",

From 14aba6a42756ab5476a5045a06e8bbd1032ba8c2 Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Wed, 12 Jun 2024 20:23:44 -0300
Subject: [PATCH 4/8] update CHANGELOG.md

---
 tools/CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/CHANGELOG.md b/tools/CHANGELOG.md
index 184e006d8..391b24e16 100644
--- a/tools/CHANGELOG.md
+++ b/tools/CHANGELOG.md
@@ -12,6 +12,10 @@
 
 ## master
 
+#### :rocket: New Feature
+
+- Add `moduletypeid` field for explicitly annotated module type. https://github.com/rescript-lang/rescript-vscode/pull/1019
+
 ### :bug: Bug Fix
 
 - Print module structure with signature to module path. https://github.com/rescript-lang/rescript-vscode/pull/1018

From 4ef0bdee33706406eeab5e420e3c418951b0be8e Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Sat, 15 Jun 2024 18:56:14 -0300
Subject: [PATCH 5/8] fix moduletypeid

---
 tools/src/tools.ml                               | 16 +++++++++++++++-
 .../tests/src/expected/DocExtractionRes.res.json |  2 +-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/src/tools.ml b/tools/src/tools.ml
index 8ea7a29ae..45bf0dd1f 100644
--- a/tools/src/tools.ml
+++ b/tools/src/tools.ml
@@ -489,12 +489,26 @@ let extractDocs ~entryPointFile ~debug =
                          extractDocsForModule ~modulePath:(m.name :: modulePath)
                            m
                        in
+                       let identModulePath = p |> Path.head |> Ident.name in
+
+                       let moduleTypeIdPath =
+                         match
+                           ProcessCmt.fileForModule ~package:full.package
+                             identModulePath
+                           |> Option.is_none
+                         with
+                         | true -> modulePath
+                         | false -> []
+                       in
+
                        Some
                          (Module
                             {
                               docs with
                               moduletypeid =
-                                Some (makeId ~identifier:(Path.name p) []);
+                                Some
+                                  (makeId ~identifier:(Path.name p)
+                                     moduleTypeIdPath);
                             })
                      | _ -> None);
           }
diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json
index 9c74d11cd..a6505b0b7 100644
--- a/tools/tests/src/expected/DocExtractionRes.res.json
+++ b/tools/tests/src/expected/DocExtractionRes.res.json
@@ -311,7 +311,7 @@
     "id": "DocExtractionRes.M",
     "name": "M",
     "kind": "module",
-    "moduletypeid": "Example",
+    "moduletypeid": "DocExtractionRes.Example",
     "docstrings": ["implementation of Example module type"],
     "source": {
       "filepath": "src/DocExtractionRes.res",

From de2067645bdc5056a6b5926d960e4ef9463f3ccb Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Sun, 16 Jun 2024 17:52:21 -0300
Subject: [PATCH 6/8] ignore parent module name

---
 tools/src/tools.ml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/src/tools.ml b/tools/src/tools.ml
index 45bf0dd1f..08837943b 100644
--- a/tools/src/tools.ml
+++ b/tools/src/tools.ml
@@ -497,8 +497,8 @@ let extractDocs ~entryPointFile ~debug =
                              identModulePath
                            |> Option.is_none
                          with
-                         | true -> modulePath
                          | false -> []
+                         | true -> [modulePath |> List.rev |> List.hd]
                        in
 
                        Some

From a40df41b5abf0bca962834facfe7444b6d277590 Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Sun, 16 Jun 2024 17:57:10 -0300
Subject: [PATCH 7/8] add tests

---
 tools/tests/src/DocExtractionRes.res          | 14 +++
 .../src/expected/DocExtractionRes.res.json    | 86 +++++++++++++++++++
 2 files changed, 100 insertions(+)

diff --git a/tools/tests/src/DocExtractionRes.res b/tools/tests/src/DocExtractionRes.res
index 68c3256e6..37968afbc 100644
--- a/tools/tests/src/DocExtractionRes.res
+++ b/tools/tests/src/DocExtractionRes.res
@@ -128,4 +128,18 @@ module M: Example = {
   let f = (x: int) => x
 }
 
+module type MT = {
+  let x: int
+}
+
+module A: MT = {
+  let x = 42
+}
+
+module C = {
+  module D: MT = {// generates "moduletypeid": "Example.C.MT" - but should be Example.MT
+    let x = 42
+  }
+}
+
 // ^dex
diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json
index a6505b0b7..93a727b3b 100644
--- a/tools/tests/src/expected/DocExtractionRes.res.json
+++ b/tools/tests/src/expected/DocExtractionRes.res.json
@@ -343,5 +343,91 @@
         "col": 7
       }
     }]
+  }, 
+  {
+    "id": "DocExtractionRes.MT",
+    "name": "MT",
+    "kind": "moduleType",
+    "docstrings": [],
+    "source": {
+      "filepath": "src/DocExtractionRes.res",
+      "line": 131,
+      "col": 13
+    },
+    "items": [
+    {
+      "id": "DocExtractionRes.MT.x",
+      "kind": "value",
+      "name": "x",
+      "signature": "let x: int",
+      "docstrings": [],
+      "source": {
+        "filepath": "src/DocExtractionRes.res",
+        "line": 132,
+        "col": 3
+      }
+    }]
+  }, 
+  {
+    "id": "DocExtractionRes.A",
+    "name": "A",
+    "kind": "module",
+    "moduletypeid": "DocExtractionRes.MT",
+    "docstrings": [],
+    "source": {
+      "filepath": "src/DocExtractionRes.res",
+      "line": 1,
+      "col": 1
+    },
+    "items": [
+    {
+      "id": "DocExtractionRes.A.x",
+      "kind": "value",
+      "name": "x",
+      "signature": "let x: int",
+      "docstrings": [],
+      "source": {
+        "filepath": "src/DocExtractionRes.res",
+        "line": 136,
+        "col": 7
+      }
+    }]
+  }, 
+  {
+    "id": "DocExtractionRes.C",
+    "name": "C",
+    "kind": "module",
+    "docstrings": [],
+    "source": {
+      "filepath": "src/DocExtractionRes.res",
+      "line": 139,
+      "col": 8
+    },
+    "items": [
+    {
+      "id": "DocExtractionRes.C.D",
+      "name": "D",
+      "kind": "module",
+      "moduletypeid": "DocExtractionRes.MT",
+      "docstrings": [],
+      "source": {
+        "filepath": "src/DocExtractionRes.res",
+        "line": 1,
+        "col": 1
+      },
+      "items": [
+      {
+        "id": "DocExtractionRes.C.D.x",
+        "kind": "value",
+        "name": "x",
+        "signature": "let x: int",
+        "docstrings": [],
+        "source": {
+          "filepath": "src/DocExtractionRes.res",
+          "line": 141,
+          "col": 9
+        }
+      }]
+    }]
   }]
 }

From 862eff90d9ae5e06e70798bf1677c779e2334876 Mon Sep 17 00:00:00 2001
From: Pedro Castro <aspeddro@gmail.com>
Date: Sun, 16 Jun 2024 20:18:26 -0300
Subject: [PATCH 8/8] remove comment

---
 tools/tests/src/DocExtractionRes.res | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/tests/src/DocExtractionRes.res b/tools/tests/src/DocExtractionRes.res
index 37968afbc..b9c7f25cf 100644
--- a/tools/tests/src/DocExtractionRes.res
+++ b/tools/tests/src/DocExtractionRes.res
@@ -137,7 +137,7 @@ module A: MT = {
 }
 
 module C = {
-  module D: MT = {// generates "moduletypeid": "Example.C.MT" - but should be Example.MT
+  module D: MT = {
     let x = 42
   }
 }