From 2de0c17d7d57d0702658dd9c00c43bdc8854f05c Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Fri, 26 Jan 2024 22:18:18 -0300 Subject: [PATCH 1/7] tools: add source field --- analysis/src/ProcessCmt.ml | 10 ++ analysis/src/SharedTypes.ml | 1 + tools/src/tools.ml | 72 +++++++++++- .../src/expected/DocExtraction2.res.json | 38 +++++- .../src/expected/DocExtraction2.resi.json | 38 +++++- .../src/expected/DocExtractionRes.res.json | 110 ++++++++++++++++-- tools/tests/src/expected/ModC.res.json | 17 ++- tools/tests/src/expected/ModC.resi.json | 17 ++- 8 files changed, 281 insertions(+), 22 deletions(-) diff --git a/analysis/src/ProcessCmt.ml b/analysis/src/ProcessCmt.ml index 87fdba2b4..c54e625ca 100644 --- a/analysis/src/ProcessCmt.ml +++ b/analysis/src/ProcessCmt.ml @@ -60,6 +60,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Sig_type @@ -134,6 +135,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Sig_module (ident, {md_type; md_attributes; md_loc}, _) -> @@ -152,6 +154,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | _ -> [] @@ -316,6 +319,7 @@ let forTypeDeclaration ~env ~(exported : Exported.t) name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; } let rec forSignatureItem ~env ~(exported : Exported.t) @@ -335,6 +339,7 @@ let rec forSignatureItem ~env ~(exported : Exported.t) name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Tsig_type (recFlag, decls) -> @@ -366,6 +371,7 @@ let rec forSignatureItem ~env ~(exported : Exported.t) name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Tsig_recmodule modDecls -> @@ -443,6 +449,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; } :: !items | Tpat_tuple pats | Tpat_array pats | Tpat_construct (_, _, pats) -> @@ -478,6 +485,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Tstr_recmodule modDecls -> @@ -509,6 +517,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Tstr_include {incl_mod; incl_type} -> @@ -538,6 +547,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = name = declared.name.txt; docstring = declared.docstring; deprecated = declared.deprecated; + loc = declared.extentLoc; }; ] | Tstr_type (recFlag, decls) -> diff --git a/analysis/src/SharedTypes.ml b/analysis/src/SharedTypes.ml index cc25c5031..3262d41b1 100644 --- a/analysis/src/SharedTypes.ml +++ b/analysis/src/SharedTypes.ml @@ -125,6 +125,7 @@ module Module = struct and item = { kind: kind; name: string; + loc: Location.t; docstring: string list; deprecated: string option; } diff --git a/tools/src/tools.ml b/tools/src/tools.ml index 55e18ffa2..de025d6da 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -18,9 +18,12 @@ type constructorDoc = { items: constructorPayload option; } +type source = {filepath: string; line: int; col: int} + type docItemDetail = | Record of {fieldDocs: fieldDoc list} | Variant of {constructorDocs: constructorDoc list} + type docItem = | Value of { id: string; @@ -28,6 +31,7 @@ type docItem = signature: string; name: string; deprecated: string option; + source: source; } | Type of { id: string; @@ -36,6 +40,7 @@ type docItem = name: string; deprecated: string option; detail: docItemDetail option; + source: source; (** Additional documentation for constructors and record fields, if available. *) } | Module of docsForModule @@ -43,6 +48,7 @@ type docItem = id: string; docstring: string list; name: string; + source: source; items: docItem list; } and docsForModule = { @@ -50,6 +56,7 @@ and docsForModule = { docstring: string list; deprecated: string option; name: string; + source: source; items: docItem list; } @@ -132,10 +139,19 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) = |> array) ); ] +let stringifySource ~indentation source = + let open Protocol in + stringifyObject ~startOnNewline:false ~indentation + [ + ("filepath", Some (source.filepath |> wrapInQuotes)); + ("line", Some (source.line |> string_of_int)); + ("col", Some (source.col |> string_of_int)); + ] + let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) = let open Protocol in match item with - | Value {id; docstring; signature; name; deprecated} -> + | Value {id; docstring; signature; name; deprecated; source} -> stringifyObject ~startOnNewline:true ~indentation [ ("id", Some (wrapInQuotes id)); @@ -147,8 +163,9 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) = | None -> None ); ("signature", Some (signature |> String.trim |> wrapInQuotes)); ("docstrings", Some (stringifyDocstrings docstring)); + ("source", Some (stringifySource ~indentation:(indentation + 1) source)); ] - | Type {id; docstring; signature; name; deprecated; detail} -> + | Type {id; docstring; signature; name; deprecated; detail; source} -> stringifyObject ~startOnNewline:true ~indentation [ ("id", Some (wrapInQuotes id)); @@ -160,6 +177,7 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) = | None -> None ); ("signature", Some (signature |> wrapInQuotes)); ("docstrings", Some (stringifyDocstrings docstring)); + ("source", Some (stringifySource ~indentation:(indentation + 1) source)); ( "detail", match detail with | None -> None @@ -177,6 +195,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) = | Some d -> Some (wrapInQuotes d) | None -> None ); ("docstrings", Some (stringifyDocstrings m.docstring)); + ( "source", + Some (stringifySource ~indentation:(indentation + 1) m.source) ); ( "items", Some (m.items @@ -191,6 +211,8 @@ let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) = ("kind", Some (wrapInQuotes "moduleAlias")); ("name", Some (wrapInQuotes m.name)); ("docstrings", Some (stringifyDocstrings m.docstring)); + ( "source", + Some (stringifySource ~indentation:(indentation + 1) m.source) ); ( "items", Some (m.items @@ -209,6 +231,7 @@ and stringifyDocsForModule ?(indentation = 0) ~originalEnv (d : docsForModule) = | Some d -> Some (wrapInQuotes d) | None -> None ); ("docstrings", Some (stringifyDocstrings d.docstring)); + ("source", Some (stringifySource ~indentation:(indentation + 1) d.source)); ( "items", Some (d.items @@ -257,6 +280,33 @@ let typeDetail typ ~env ~full = let makeId modulePath ~identifier = identifier :: modulePath |> List.rev |> SharedTypes.ident +let findRelativePath ~rootPath ~path = + let open Filename in + let realPath = + match rootPath = "." with + | true -> Sys.getcwd () + | false -> + if is_relative rootPath then concat (Sys.getcwd ()) rootPath else rootPath + in + let rec loop dirPath acc = + match dirname dirPath = realPath with + | true -> basename dirPath :: acc |> String.concat dir_sep + | false -> ( + match dirPath with + | "/" -> failwith "Failed to find relative path of package" + | "." -> path + | _ -> loop (dirname dirPath) (basename dirPath :: acc)) + in + + loop path [] + +let getSource ~rootPath ({loc_start} : Location.t) = + let line, col = Pos.ofLexing loc_start in + + let filepath = findRelativePath ~rootPath ~path:loc_start.pos_fname in + + {filepath; line = line + 1; col = col + 1} + let extractDocs ~path ~debug = if debug then Printf.printf "extracting docs for %s\n" path; let result = @@ -289,6 +339,7 @@ let extractDocs ~path ~debug = | Some full -> let file = full.file in let structure = file.structure in + let rootPath = full.package.rootPath in let open SharedTypes in let env = QueryEnv.fromFile file in let rec extractDocsForModule ?(modulePath = [env.file.moduleName]) @@ -298,11 +349,22 @@ let extractDocs ~path ~debug = docstring = structure.docstring |> List.map String.trim; name = structure.name; deprecated = structure.deprecated; + source = + { + filepath = + (match rootPath = "." with + | true -> file.uri |> Uri.toPath + | false -> + findRelativePath ~rootPath ~path:(file.uri |> Uri.toPath)); + line = 0; + col = 0; + }; items = structure.items |> List.filter_map (fun (item : Module.item) -> match item.kind with | Value typ -> + let source = getSource ~rootPath item.loc in Some (Value { @@ -313,6 +375,9 @@ let extractDocs ~path ~debug = ^ Shared.typeToString typ; name = item.name; deprecated = item.deprecated; + source; + (* source = *) + (* getSource ~stamp:typ.id ~full ~name:item.name; *) }) | Type (typ, _) -> Some @@ -325,6 +390,7 @@ let extractDocs ~path ~debug = name = item.name; deprecated = item.deprecated; detail = typeDetail typ ~full ~env; + source = getSource ~rootPath item.loc; }) | Module (Ident p) -> (* module Whatever = OtherModule *) @@ -350,6 +416,7 @@ let extractDocs ~path ~debug = { id; name = item.name; + source = getSource ~rootPath item.loc; items; docstring = item.docstring @ internalDocstrings @@ -366,6 +433,7 @@ let extractDocs ~path ~debug = name = m.name; docstring = item.docstring @ m.docstring; deprecated = item.deprecated; + source = getSource ~rootPath item.loc; items = docs.items; }) | Module diff --git a/tools/tests/src/expected/DocExtraction2.res.json b/tools/tests/src/expected/DocExtraction2.res.json index 06467b54c..bdbe5214d 100644 --- a/tools/tests/src/expected/DocExtraction2.res.json +++ b/tools/tests/src/expected/DocExtraction2.res.json @@ -2,40 +2,70 @@ { "name": "DocExtraction2", "docstrings": ["Module level doc here."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 0, + "col": 0 + }, "items": [ { "id": "DocExtraction2.t", "kind": "type", "name": "t", "signature": "type t", - "docstrings": ["Type t is pretty cool."] + "docstrings": ["Type t is pretty cool."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 4, + "col": 1 + } }, { "id": "DocExtraction2.make", "kind": "value", "name": "make", "signature": "let make: (. unit) => t", - "docstrings": ["Makerz of stuffz."] + "docstrings": ["Makerz of stuffz."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 7, + "col": 1 + } }, { "id": "DocExtraction2.InnerModule", "name": "InnerModule", "kind": "module", "docstrings": [], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 9, + "col": 8 + }, "items": [ { "id": "DocExtraction2.InnerModule.t", "kind": "type", "name": "t", "signature": "type t", - "docstrings": ["This type is also t."] + "docstrings": ["This type is also t."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 13, + "col": 3 + } }, { "id": "DocExtraction2.InnerModule.make", "kind": "value", "name": "make", "signature": "let make: (. unit) => t", - "docstrings": ["Maker of tea."] + "docstrings": ["Maker of tea."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 15, + "col": 3 + } }] }] } diff --git a/tools/tests/src/expected/DocExtraction2.resi.json b/tools/tests/src/expected/DocExtraction2.resi.json index 06467b54c..bdbe5214d 100644 --- a/tools/tests/src/expected/DocExtraction2.resi.json +++ b/tools/tests/src/expected/DocExtraction2.resi.json @@ -2,40 +2,70 @@ { "name": "DocExtraction2", "docstrings": ["Module level doc here."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 0, + "col": 0 + }, "items": [ { "id": "DocExtraction2.t", "kind": "type", "name": "t", "signature": "type t", - "docstrings": ["Type t is pretty cool."] + "docstrings": ["Type t is pretty cool."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 4, + "col": 1 + } }, { "id": "DocExtraction2.make", "kind": "value", "name": "make", "signature": "let make: (. unit) => t", - "docstrings": ["Makerz of stuffz."] + "docstrings": ["Makerz of stuffz."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 7, + "col": 1 + } }, { "id": "DocExtraction2.InnerModule", "name": "InnerModule", "kind": "module", "docstrings": [], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 9, + "col": 8 + }, "items": [ { "id": "DocExtraction2.InnerModule.t", "kind": "type", "name": "t", "signature": "type t", - "docstrings": ["This type is also t."] + "docstrings": ["This type is also t."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 13, + "col": 3 + } }, { "id": "DocExtraction2.InnerModule.make", "kind": "value", "name": "make", "signature": "let make: (. unit) => t", - "docstrings": ["Maker of tea."] + "docstrings": ["Maker of tea."], + "source": { + "filepath": "src/DocExtraction2.resi", + "line": 15, + "col": 3 + } }] }] } diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json index c31159024..f0fa0e89d 100644 --- a/tools/tests/src/expected/DocExtractionRes.res.json +++ b/tools/tests/src/expected/DocExtractionRes.res.json @@ -2,6 +2,11 @@ { "name": "DocExtractionRes", "docstrings": ["Module level documentation goes here."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 0, + "col": 0 + }, "items": [ { "id": "DocExtractionRes.t", @@ -9,6 +14,11 @@ "name": "t", "signature": "type t = {name: string, online: bool}", "docstrings": ["This type represents stuff."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 4, + "col": 1 + }, "detail": { "kind": "record", @@ -30,27 +40,47 @@ "kind": "value", "name": "make", "signature": "let make: (. string) => t", - "docstrings": ["Create stuff.\n\n```rescript example\nlet stuff = make(\"My name\")\n```"] + "docstrings": ["Create stuff.\n\n```rescript example\nlet stuff = make(\"My name\")\n```"], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 17, + "col": 5 + } }, { "id": "DocExtractionRes.asOffline", "kind": "value", "name": "asOffline", "signature": "let asOffline: (. t) => t", - "docstrings": ["Stuff goes offline."] + "docstrings": ["Stuff goes offline."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 23, + "col": 5 + } }, { "id": "DocExtractionRes.SomeConstant\\", "kind": "value", "name": "SomeConstant\\", "signature": "let SomeConstant\\: int", - "docstrings": ["exotic identifier"] + "docstrings": ["exotic identifier"], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 26, + "col": 5 + } }, { "id": "DocExtractionRes.SomeInnerModule", "name": "SomeInnerModule", "kind": "module", "docstrings": ["Another module level docstring here."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 28, + "col": 8 + }, "items": [ { "id": "DocExtractionRes.SomeInnerModule.status", @@ -58,6 +88,11 @@ "name": "status", "signature": "type status = Started(t) | Stopped | Idle", "docstrings": [], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 30, + "col": 3 + }, "detail": { "kind": "variant", @@ -84,14 +119,24 @@ "kind": "type", "name": "validInputs", "signature": "type validInputs = [\n | #\"needs-escaping\"\n | #something\n | #status(status)\n | #withPayload(int)\n]", - "docstrings": ["These are all the valid inputs."] + "docstrings": ["These are all the valid inputs."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 34, + "col": 3 + } }, { "id": "DocExtractionRes.SomeInnerModule.callback", "kind": "type", "name": "callback", "signature": "type callback = (. t, ~status: status) => unit", - "docstrings": [] + "docstrings": [], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 36, + "col": 3 + } }] }, { @@ -99,12 +144,22 @@ "name": "AnotherModule", "kind": "module", "docstrings": ["Mighty fine module here too!"], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 39, + "col": 8 + }, "items": [ { "id": "DocExtractionRes.LinkedModule", "kind": "moduleAlias", "name": "LinkedModule", "docstrings": ["This links another module. Neat."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 43, + "col": 10 + }, "items": [] }, { @@ -112,14 +167,24 @@ "kind": "type", "name": "callback", "signature": "type callback = (. SomeInnerModule.status) => unit", - "docstrings": ["Testing what this looks like."] + "docstrings": ["Testing what this looks like."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 47, + "col": 3 + } }, { "id": "DocExtractionRes.AnotherModule.isGoodStatus", "kind": "value", "name": "isGoodStatus", "signature": "let isGoodStatus: (. SomeInnerModule.status) => bool", - "docstrings": [] + "docstrings": [], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 49, + "col": 7 + } }, { "id": "DocExtractionRes.AnotherModule.someVariantWithInlineRecords", @@ -127,6 +192,11 @@ "name": "someVariantWithInlineRecords", "signature": "type someVariantWithInlineRecords =\n | SomeStuff({offline: bool, online?: bool})", "docstrings": ["Trying how it looks with an inline record in a variant."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 52, + "col": 3 + }, "detail": { "kind": "variant", @@ -157,7 +227,12 @@ "kind": "type", "name": "domRoot", "signature": "type domRoot = (. unit) => ReactDOM.Client.Root.t", - "docstrings": ["Callback to get the DOM root..."] + "docstrings": ["Callback to get the DOM root..."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 62, + "col": 3 + } }] }, { @@ -165,20 +240,35 @@ "name": "ModuleWithThingsThatShouldNotBeExported", "kind": "module", "docstrings": [], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 0, + "col": 0 + }, "items": [ { "id": "DocExtractionRes.ModuleWithThingsThatShouldNotBeExported.t", "kind": "type", "name": "t", "signature": "type t", - "docstrings": ["The type t is stuff."] + "docstrings": ["The type t is stuff."], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 69, + "col": 3 + } }, { "id": "DocExtractionRes.ModuleWithThingsThatShouldNotBeExported.make", "kind": "value", "name": "make", "signature": "let make: (. unit) => t", - "docstrings": ["The maker of stuff!"] + "docstrings": ["The maker of stuff!"], + "source": { + "filepath": "src/DocExtractionRes.res", + "line": 71, + "col": 3 + } }] }] } diff --git a/tools/tests/src/expected/ModC.res.json b/tools/tests/src/expected/ModC.res.json index d6afb7a69..e35d2b48c 100644 --- a/tools/tests/src/expected/ModC.res.json +++ b/tools/tests/src/expected/ModC.res.json @@ -2,19 +2,34 @@ { "name": "ModC", "docstrings": [], + "source": { + "filepath": "src/ModC.resi", + "line": 0, + "col": 0 + }, "items": [ { "id": "ModC.User", "name": "User", "kind": "module", "docstrings": ["User Module from interface file"], + "source": { + "filepath": "src/ModC.resi", + "line": 4, + "col": 8 + }, "items": [ { "id": "ModC.User.name", "kind": "value", "name": "name", "signature": "let name: string", - "docstrings": [] + "docstrings": [], + "source": { + "filepath": "src/ModC.resi", + "line": 5, + "col": 3 + } }] }] } diff --git a/tools/tests/src/expected/ModC.resi.json b/tools/tests/src/expected/ModC.resi.json index d6afb7a69..e35d2b48c 100644 --- a/tools/tests/src/expected/ModC.resi.json +++ b/tools/tests/src/expected/ModC.resi.json @@ -2,19 +2,34 @@ { "name": "ModC", "docstrings": [], + "source": { + "filepath": "src/ModC.resi", + "line": 0, + "col": 0 + }, "items": [ { "id": "ModC.User", "name": "User", "kind": "module", "docstrings": ["User Module from interface file"], + "source": { + "filepath": "src/ModC.resi", + "line": 4, + "col": 8 + }, "items": [ { "id": "ModC.User.name", "kind": "value", "name": "name", "signature": "let name: string", - "docstrings": [] + "docstrings": [], + "source": { + "filepath": "src/ModC.resi", + "line": 5, + "col": 3 + } }] }] } From 79e7e1e9853e574c8a13ce2a6dffcf03d0d1245a Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Fri, 26 Jan 2024 22:51:58 -0300 Subject: [PATCH 2/7] tools: refactor --- tools/bin/main.ml | 2 +- tools/src/tools.ml | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/bin/main.ml b/tools/bin/main.ml index f1dc157b1..d9b4f2ae4 100644 --- a/tools/bin/main.ml +++ b/tools/bin/main.ml @@ -41,7 +41,7 @@ let main () = | Some "true" -> Analysis.Cfg.isDocGenFromCompiler := true | _ -> () in - logAndExit (Tools.extractDocs ~path ~debug:false) + logAndExit (Tools.extractDocs ~entryPointFile:path ~debug:false) | _ -> logAndExit (Error docHelp)) | "reanalyze" :: _ -> let len = Array.length Sys.argv in diff --git a/tools/src/tools.ml b/tools/src/tools.ml index de025d6da..34d15b0a1 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -302,12 +302,15 @@ let findRelativePath ~rootPath ~path = let getSource ~rootPath ({loc_start} : Location.t) = let line, col = Pos.ofLexing loc_start in - let filepath = findRelativePath ~rootPath ~path:loc_start.pos_fname in - {filepath; line = line + 1; col = col + 1} -let extractDocs ~path ~debug = +let extractDocs ~entryPointFile ~debug = + let path = + match Filename.is_relative entryPointFile with + | true -> Unix.realpath entryPointFile + | false -> entryPointFile + in if debug then Printf.printf "extracting docs for %s\n" path; let result = match @@ -362,9 +365,9 @@ let extractDocs ~path ~debug = items = structure.items |> List.filter_map (fun (item : Module.item) -> + let source = getSource ~rootPath item.loc in match item.kind with | Value typ -> - let source = getSource ~rootPath item.loc in Some (Value { @@ -376,8 +379,6 @@ let extractDocs ~path ~debug = name = item.name; deprecated = item.deprecated; source; - (* source = *) - (* getSource ~stamp:typ.id ~full ~name:item.name; *) }) | Type (typ, _) -> Some @@ -390,7 +391,7 @@ let extractDocs ~path ~debug = name = item.name; deprecated = item.deprecated; detail = typeDetail typ ~full ~env; - source = getSource ~rootPath item.loc; + source; }) | Module (Ident p) -> (* module Whatever = OtherModule *) @@ -416,7 +417,7 @@ let extractDocs ~path ~debug = { id; name = item.name; - source = getSource ~rootPath item.loc; + source; items; docstring = item.docstring @ internalDocstrings @@ -433,7 +434,7 @@ let extractDocs ~path ~debug = name = m.name; docstring = item.docstring @ m.docstring; deprecated = item.deprecated; - source = getSource ~rootPath item.loc; + source; items = docs.items; }) | Module From 10818a4b50d0d9bfcfd09b1b075945d5385da583 Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Sat, 27 Jan 2024 15:11:01 -0300 Subject: [PATCH 3/7] tools: fix dir_sep and update rescript files --- tools/npm/RescriptTools.bs.js | 8 ++++++++ tools/npm/Tools_Docgen.bs.js | 10 ++++++++++ tools/npm/Tools_Docgen.res | 11 +++++++++++ tools/npm/Tools_Docgen.resi | 18 +++++++++++++++++- tools/src/tools.ml | 9 ++++++--- .../tests/src/expected/DocExtraction2.res.json | 4 ++-- .../src/expected/DocExtraction2.resi.json | 4 ++-- .../src/expected/DocExtractionRes.res.json | 8 ++++---- tools/tests/src/expected/ModC.res.json | 4 ++-- tools/tests/src/expected/ModC.resi.json | 4 ++-- 10 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 tools/npm/RescriptTools.bs.js create mode 100644 tools/npm/Tools_Docgen.bs.js diff --git a/tools/npm/RescriptTools.bs.js b/tools/npm/RescriptTools.bs.js new file mode 100644 index 000000000..281db50e0 --- /dev/null +++ b/tools/npm/RescriptTools.bs.js @@ -0,0 +1,8 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +'use strict'; + + +var Docgen; + +exports.Docgen = Docgen; +/* No side effect */ diff --git a/tools/npm/Tools_Docgen.bs.js b/tools/npm/Tools_Docgen.bs.js new file mode 100644 index 000000000..40e71b116 --- /dev/null +++ b/tools/npm/Tools_Docgen.bs.js @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +'use strict'; + + +function decodeFromJson(prim) { + return prim; +} + +exports.decodeFromJson = decodeFromJson; +/* No side effect */ diff --git a/tools/npm/Tools_Docgen.res b/tools/npm/Tools_Docgen.res index d62458d00..631a54ce8 100644 --- a/tools/npm/Tools_Docgen.res +++ b/tools/npm/Tools_Docgen.res @@ -22,6 +22,12 @@ type detail = | @as("record") Record({items: array}) | @as("variant") Variant({items: array}) +type source = { + filepath: string, + line: int, + col: int, +} + @tag("kind") type rec item = | @as("value") @@ -31,6 +37,7 @@ type rec item = signature: string, name: string, deprecated?: string, + source: source, }) | @as("type") Type({ @@ -39,6 +46,7 @@ type rec item = signature: string, name: string, deprecated?: string, + source: source, /** Additional documentation for constructors and record fields, if available. */ detail?: detail, }) @@ -48,6 +56,7 @@ type rec item = docstrings: array, deprecated?: string, name: string, + source: source, items: array, }) | @as("moduleAlias") @@ -55,6 +64,7 @@ type rec item = id: string, docstrings: array, name: string, + source: source, items: array, }) @@ -62,6 +72,7 @@ type doc = { name: string, deprecated: option, docstrings: array, + source: source, items: array, } diff --git a/tools/npm/Tools_Docgen.resi b/tools/npm/Tools_Docgen.resi index f1c338a8a..c6d7595eb 100644 --- a/tools/npm/Tools_Docgen.resi +++ b/tools/npm/Tools_Docgen.resi @@ -21,6 +21,12 @@ type detail = | @as("record") Record({items: array}) | @as("variant") Variant({items: array}) +type source = { + filepath: string, + line: int, + col: int, +} + @tag("kind") type rec item = | @as("value") @@ -30,6 +36,7 @@ type rec item = signature: string, name: string, deprecated?: string, + source: source, }) | @as("type") Type({ @@ -38,6 +45,7 @@ type rec item = signature: string, name: string, deprecated?: string, + source: source, /** Additional documentation for constructors and record fields, if available. */ detail?: detail, }) @@ -47,6 +55,7 @@ type rec item = docstrings: array, deprecated?: string, name: string, + source: source, items: array, }) | @as("moduleAlias") @@ -54,9 +63,16 @@ type rec item = id: string, docstrings: array, name: string, + source: source, items: array, }) -type doc = {name: string, deprecated: option, docstrings: array, items: array} +type doc = { + name: string, + deprecated: option, + docstrings: array, + source: source, + items: array, +} let decodeFromJson: Js.Json.t => doc diff --git a/tools/src/tools.ml b/tools/src/tools.ml index 34d15b0a1..0ee17a67c 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -280,6 +280,9 @@ let typeDetail typ ~env ~full = let makeId modulePath ~identifier = identifier :: modulePath |> List.rev |> SharedTypes.ident +(** +Get relative path to res/resi file +*) let findRelativePath ~rootPath ~path = let open Filename in let realPath = @@ -290,7 +293,7 @@ let findRelativePath ~rootPath ~path = in let rec loop dirPath acc = match dirname dirPath = realPath with - | true -> basename dirPath :: acc |> String.concat dir_sep + | true -> basename dirPath :: acc |> String.concat "/" | false -> ( match dirPath with | "/" -> failwith "Failed to find relative path of package" @@ -359,8 +362,8 @@ let extractDocs ~entryPointFile ~debug = | true -> file.uri |> Uri.toPath | false -> findRelativePath ~rootPath ~path:(file.uri |> Uri.toPath)); - line = 0; - col = 0; + line = 1; + col = 1; }; items = structure.items diff --git a/tools/tests/src/expected/DocExtraction2.res.json b/tools/tests/src/expected/DocExtraction2.res.json index bdbe5214d..745efd0e5 100644 --- a/tools/tests/src/expected/DocExtraction2.res.json +++ b/tools/tests/src/expected/DocExtraction2.res.json @@ -4,8 +4,8 @@ "docstrings": ["Module level doc here."], "source": { "filepath": "src/DocExtraction2.resi", - "line": 0, - "col": 0 + "line": 1, + "col": 1 }, "items": [ { diff --git a/tools/tests/src/expected/DocExtraction2.resi.json b/tools/tests/src/expected/DocExtraction2.resi.json index bdbe5214d..745efd0e5 100644 --- a/tools/tests/src/expected/DocExtraction2.resi.json +++ b/tools/tests/src/expected/DocExtraction2.resi.json @@ -4,8 +4,8 @@ "docstrings": ["Module level doc here."], "source": { "filepath": "src/DocExtraction2.resi", - "line": 0, - "col": 0 + "line": 1, + "col": 1 }, "items": [ { diff --git a/tools/tests/src/expected/DocExtractionRes.res.json b/tools/tests/src/expected/DocExtractionRes.res.json index f0fa0e89d..a07ada95f 100644 --- a/tools/tests/src/expected/DocExtractionRes.res.json +++ b/tools/tests/src/expected/DocExtractionRes.res.json @@ -4,8 +4,8 @@ "docstrings": ["Module level documentation goes here."], "source": { "filepath": "src/DocExtractionRes.res", - "line": 0, - "col": 0 + "line": 1, + "col": 1 }, "items": [ { @@ -242,8 +242,8 @@ "docstrings": [], "source": { "filepath": "src/DocExtractionRes.res", - "line": 0, - "col": 0 + "line": 1, + "col": 1 }, "items": [ { diff --git a/tools/tests/src/expected/ModC.res.json b/tools/tests/src/expected/ModC.res.json index e35d2b48c..4f68f6191 100644 --- a/tools/tests/src/expected/ModC.res.json +++ b/tools/tests/src/expected/ModC.res.json @@ -4,8 +4,8 @@ "docstrings": [], "source": { "filepath": "src/ModC.resi", - "line": 0, - "col": 0 + "line": 1, + "col": 1 }, "items": [ { diff --git a/tools/tests/src/expected/ModC.resi.json b/tools/tests/src/expected/ModC.resi.json index e35d2b48c..4f68f6191 100644 --- a/tools/tests/src/expected/ModC.resi.json +++ b/tools/tests/src/expected/ModC.resi.json @@ -4,8 +4,8 @@ "docstrings": [], "source": { "filepath": "src/ModC.resi", - "line": 0, - "col": 0 + "line": 1, + "col": 1 }, "items": [ { From 3aca6695f5faff7f0177e4b9f7ad1ad60550556e Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Sat, 27 Jan 2024 15:13:18 -0300 Subject: [PATCH 4/7] update CHANGELOG.md --- tools/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/CHANGELOG.md b/tools/CHANGELOG.md index a7ab7a4c7..cec81c65e 100644 --- a/tools/CHANGELOG.md +++ b/tools/CHANGELOG.md @@ -12,6 +12,10 @@ ## master +#### :rocket: New Feature + +- Add `source` property to type, value, module and module alias. https://github.com/rescript-lang/rescript-vscode/pull/900. + #### :bug: Bug Fix - Print docstrings for nested submodules. https://github.com/rescript-lang/rescript-vscode/pull/897 From e5bb9f59d7db523be172e9cb1a28f7963a7eb4c8 Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Sat, 27 Jan 2024 15:15:47 -0300 Subject: [PATCH 5/7] disable in-source --- tools/npm/RescriptTools.bs.js | 8 -------- tools/npm/Tools_Docgen.bs.js | 10 ---------- tools/rescript.json | 2 +- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 tools/npm/RescriptTools.bs.js delete mode 100644 tools/npm/Tools_Docgen.bs.js diff --git a/tools/npm/RescriptTools.bs.js b/tools/npm/RescriptTools.bs.js deleted file mode 100644 index 281db50e0..000000000 --- a/tools/npm/RescriptTools.bs.js +++ /dev/null @@ -1,8 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - - -var Docgen; - -exports.Docgen = Docgen; -/* No side effect */ diff --git a/tools/npm/Tools_Docgen.bs.js b/tools/npm/Tools_Docgen.bs.js deleted file mode 100644 index 40e71b116..000000000 --- a/tools/npm/Tools_Docgen.bs.js +++ /dev/null @@ -1,10 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - - -function decodeFromJson(prim) { - return prim; -} - -exports.decodeFromJson = decodeFromJson; -/* No side effect */ diff --git a/tools/rescript.json b/tools/rescript.json index 8917b16ec..c780f5e87 100644 --- a/tools/rescript.json +++ b/tools/rescript.json @@ -9,6 +9,6 @@ "suffix": ".bs.js", "package-specs": { "module": "commonjs", - "in-source": true + "in-source": false } } From 5396f79b7cfb08e1970652883542d4b79b8df910 Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Sat, 27 Jan 2024 17:18:19 -0300 Subject: [PATCH 6/7] remove findRelativePath --- tools/src/tools.ml | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/tools/src/tools.ml b/tools/src/tools.ml index 0ee17a67c..d4ee10ce1 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -280,32 +280,9 @@ let typeDetail typ ~env ~full = let makeId modulePath ~identifier = identifier :: modulePath |> List.rev |> SharedTypes.ident -(** -Get relative path to res/resi file -*) -let findRelativePath ~rootPath ~path = - let open Filename in - let realPath = - match rootPath = "." with - | true -> Sys.getcwd () - | false -> - if is_relative rootPath then concat (Sys.getcwd ()) rootPath else rootPath - in - let rec loop dirPath acc = - match dirname dirPath = realPath with - | true -> basename dirPath :: acc |> String.concat "/" - | false -> ( - match dirPath with - | "/" -> failwith "Failed to find relative path of package" - | "." -> path - | _ -> loop (dirname dirPath) (basename dirPath :: acc)) - in - - loop path [] - let getSource ~rootPath ({loc_start} : Location.t) = let line, col = Pos.ofLexing loc_start in - let filepath = findRelativePath ~rootPath ~path:loc_start.pos_fname in + let filepath = Files.relpath rootPath loc_start.pos_fname in {filepath; line = line + 1; col = col + 1} let extractDocs ~entryPointFile ~debug = @@ -360,8 +337,7 @@ let extractDocs ~entryPointFile ~debug = filepath = (match rootPath = "." with | true -> file.uri |> Uri.toPath - | false -> - findRelativePath ~rootPath ~path:(file.uri |> Uri.toPath)); + | false -> Files.relpath rootPath (file.uri |> Uri.toPath)); line = 1; col = 1; }; From 433a8513a963c5ea3ee61d7a155d6f52edbc7c21 Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Sat, 27 Jan 2024 17:31:00 -0300 Subject: [PATCH 7/7] fix dir_sep on windows --- tools/src/tools.ml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/src/tools.ml b/tools/src/tools.ml index d4ee10ce1..0db7ee50b 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -282,7 +282,11 @@ let makeId modulePath ~identifier = let getSource ~rootPath ({loc_start} : Location.t) = let line, col = Pos.ofLexing loc_start in - let filepath = Files.relpath rootPath loc_start.pos_fname in + let filepath = + Files.relpath rootPath loc_start.pos_fname + |> Files.split Filename.dir_sep + |> String.concat "/" + in {filepath; line = line + 1; col = col + 1} let extractDocs ~entryPointFile ~debug = @@ -337,7 +341,10 @@ let extractDocs ~entryPointFile ~debug = filepath = (match rootPath = "." with | true -> file.uri |> Uri.toPath - | false -> Files.relpath rootPath (file.uri |> Uri.toPath)); + | false -> + Files.relpath rootPath (file.uri |> Uri.toPath) + |> Files.split Filename.dir_sep + |> String.concat "/"); line = 1; col = 1; };