diff --git a/analysis/src/DocExtraction.ml b/analysis/src/DocExtraction.ml index 202541ec5..8ead07453 100644 --- a/analysis/src/DocExtraction.ml +++ b/analysis/src/DocExtraction.ml @@ -1,9 +1,16 @@ -type fieldDoc = {fieldName: string; docstrings: string list; signature: string} +type fieldDoc = { + fieldName: string; + docstrings: string list; + signature: string; + optional: bool; + deprecated: string option; +} type constructorDoc = { constructorName: string; docstrings: string list; signature: string; + deprecated: string option; } type docsForModuleAlias = { @@ -22,12 +29,14 @@ type docItem = docstring: string list; signature: string; name: string; + deprecated: string option; } | Type of { id: string; docstring: string list; signature: string; name: string; + deprecated: string option; detail: docItemDetail option; (** Additional documentation for constructors and record fields, if available. *) } @@ -36,6 +45,7 @@ type docItem = and docsForModule = { id: string; docstring: string list; + deprecated: string option; name: string; items: docItem list; } @@ -69,6 +79,11 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) = stringifyObject ~indentation:(indentation + 1) [ ("fieldName", Some (wrapInQuotes fieldDoc.fieldName)); + ( "deprecated", + match fieldDoc.deprecated with + | Some d -> Some (wrapInQuotes d) + | None -> None ); + ("optional", Some (string_of_bool fieldDoc.optional)); ( "docstrings", Some (stringifyDocstrings fieldDoc.docstrings) ); ("signature", Some (wrapInQuotes fieldDoc.signature)); @@ -88,6 +103,10 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) = [ ( "constructorName", Some (wrapInQuotes constructorDoc.constructorName) ); + ( "deprecated", + match constructorDoc.deprecated with + | Some d -> Some (wrapInQuotes d) + | None -> None ); ( "docstrings", Some (stringifyDocstrings constructorDoc.docstrings) ); ( "signature", @@ -99,22 +118,30 @@ let stringifyDetail ?(indentation = 0) (detail : docItemDetail) = let rec stringifyDocItem ?(indentation = 0) ~originalEnv (item : docItem) = let open Protocol in match item with - | Value {id; docstring; signature; name} -> + | Value {id; docstring; signature; name; deprecated} -> stringifyObject ~startOnNewline:true ~indentation [ ("id", Some (wrapInQuotes id)); ("kind", Some (wrapInQuotes "value")); ("name", Some (name |> Json.escape |> wrapInQuotes)); + ( "deprecated", + match deprecated with + | Some d -> Some (wrapInQuotes d) + | None -> None ); ( "signature", Some (signature |> String.trim |> Json.escape |> wrapInQuotes) ); ("docstrings", Some (stringifyDocstrings docstring)); ] - | Type {id; docstring; signature; name; detail} -> + | Type {id; docstring; signature; name; deprecated; detail} -> stringifyObject ~startOnNewline:true ~indentation [ ("id", Some (wrapInQuotes id)); ("kind", Some (wrapInQuotes "type")); ("name", Some (name |> Json.escape |> wrapInQuotes)); + ( "deprecated", + match deprecated with + | Some d -> Some (wrapInQuotes d) + | None -> None ); ("signature", Some (signature |> Json.escape |> wrapInQuotes)); ("docstrings", Some (stringifyDocstrings docstring)); ( "detail", @@ -147,6 +174,10 @@ and stringifyDocsForModule ?(indentation = 0) ~originalEnv (d : docsForModule) = stringifyObject ~startOnNewline:true ~indentation [ ("name", Some (wrapInQuotes d.name)); + ( "deprecated", + match d.deprecated with + | Some d -> Some (wrapInQuotes d) + | None -> None ); ("docstrings", Some (stringifyDocstrings d.docstring)); ( "items", Some @@ -169,7 +200,9 @@ let typeDetail typ ~env ~full = { fieldName = field.fname.txt; docstrings = field.docstring; + optional = field.optional; signature = Shared.typeToString field.typ; + deprecated = field.deprecated; }); }) | Some (Tvariant {constructors}) -> @@ -183,6 +216,7 @@ let typeDetail typ ~env ~full = constructorName = c.cname.txt; docstrings = c.docstring; signature = CompletionBackEnd.showConstructor c; + deprecated = c.deprecated; }); }) | _ -> None @@ -225,6 +259,7 @@ let extractDocs ~path ~debug = id = modulePath |> ident; docstring = structure.docstring |> List.map String.trim; name = structure.name; + deprecated = structure.deprecated; items = structure.items |> List.filter_map (fun (item : Module.item) -> @@ -239,6 +274,7 @@ let extractDocs ~path ~debug = "let " ^ item.name ^ ": " ^ Shared.typeToString typ |> formatCode; name = item.name; + deprecated = item.deprecated; }) | Type (typ, _) -> Some @@ -251,6 +287,7 @@ let extractDocs ~path ~debug = |> Shared.declToString item.name |> formatCode; name = item.name; + deprecated = item.deprecated; detail = typeDetail typ ~full ~env; }) | Module (Ident p) -> diff --git a/analysis/src/ProcessCmt.ml b/analysis/src/ProcessCmt.ml index c2249e7c8..6468fc83f 100644 --- a/analysis/src/ProcessCmt.ml +++ b/analysis/src/ProcessCmt.ml @@ -59,6 +59,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) Module.kind = Module.Value declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Sig_type @@ -132,6 +133,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) Module.kind = Type (declared.item, recStatus); name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Sig_module (ident, {md_type; md_attributes; md_loc}, _) -> @@ -149,6 +151,7 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) Module.kind = Module declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | _ -> [] @@ -160,7 +163,7 @@ and forTypeSignature ~name ~env signature = (fun item items -> forTypeSignatureItem ~env ~exported item @ items) signature [] in - {Module.name; docstring = []; exported; items} + {Module.name; docstring = []; exported; items; deprecated = None} and forTypeModule ~name ~env moduleType = match moduleType with @@ -312,6 +315,7 @@ let forTypeDeclaration ~env ~(exported : Exported.t) Module.kind = Module.Type (declared.item, recStatus); name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; } let rec forSignatureItem ~env ~(exported : Exported.t) @@ -330,6 +334,7 @@ let rec forSignatureItem ~env ~(exported : Exported.t) Module.kind = Module.Value declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Tsig_type (recFlag, decls) -> @@ -360,6 +365,7 @@ let rec forSignatureItem ~env ~(exported : Exported.t) Module.kind = Module declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Tsig_recmodule modDecls -> @@ -395,7 +401,8 @@ let forSignature ~name ~env sigItems = | _ -> [] in let docstring = attrsToDocstring attributes in - {Module.name; docstring; exported; items} + let deprecated = ProcessAttributes.findDeprecatedAttribute attributes in + {Module.name; docstring; exported; items; deprecated} let forTreeModuleType ~name ~env {Typedtree.mty_desc} = match mty_desc with @@ -435,6 +442,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = Module.kind = Module.Value declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; } :: !items | Tpat_tuple pats | Tpat_array pats | Tpat_construct (_, _, pats) -> @@ -469,6 +477,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = Module.kind = Module declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Tstr_recmodule modDecls -> @@ -499,6 +508,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = Module.kind = Module modTypeItem; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Tstr_include {incl_mod; incl_type} -> @@ -527,6 +537,7 @@ let rec forStructureItem ~env ~(exported : Exported.t) item = Module.kind = Value declared.item; name = declared.name.txt; docstring = declared.docstring; + deprecated = declared.deprecated; }; ] | Tstr_type (recFlag, decls) -> @@ -587,7 +598,8 @@ and forStructure ~name ~env strItems = | _ -> [] in let docstring = attrsToDocstring attributes in - {Module.name; docstring; exported; items} + let deprecated = ProcessAttributes.findDeprecatedAttribute attributes in + {Module.name; docstring; exported; items; deprecated} let fileForCmtInfos ~moduleName ~uri ({cmt_modname; cmt_annots} : Cmt_format.cmt_infos) = diff --git a/analysis/src/SharedTypes.ml b/analysis/src/SharedTypes.ml index 75eb39c6e..52daa283f 100644 --- a/analysis/src/SharedTypes.ml +++ b/analysis/src/SharedTypes.ml @@ -122,13 +122,19 @@ module Module = struct | Type of Type.t * Types.rec_status | Module of t - and item = {kind: kind; name: string; docstring: string list} + and item = { + kind: kind; + name: string; + docstring: string list; + deprecated: string option; + } and structure = { name: string; docstring: string list; exported: Exported.t; items: item list; + deprecated: string option } and t = Ident of Path.t | Structure of structure | Constraint of t * t @@ -253,6 +259,7 @@ module File = struct docstring = []; exported = Exported.init (); items = []; + deprecated = None }; } end diff --git a/analysis/tests/src/expected/DocExtractionRes.res.txt b/analysis/tests/src/expected/DocExtractionRes.res.txt index 48e6d3617..62010867d 100644 --- a/analysis/tests/src/expected/DocExtractionRes.res.txt +++ b/analysis/tests/src/expected/DocExtractionRes.res.txt @@ -16,10 +16,12 @@ extracting docs for src/DocExtractionRes.res "kind": "record", "fieldDocs": [{ "fieldName": "name", + "optional": false, "docstrings": ["The name of the stuff."], "signature": "string" }, { "fieldName": "online", + "optional": false, "docstrings": ["Whether stuff is online."], "signature": "bool" }]