Skip to content

Show Docstrings for completion items #837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 63 additions & 45 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ let resolveOpens ~env opens ~package =
(* loop(previous) *)
[] opens

let completionForExporteds iterExported getDeclared ~prefix ~exact ~env
let completionForExporteds iterExported getDeclared ~prefix ~exact ~(env : QueryEnv.t) ~package
~namesUsed transformContents =
let res = ref [] in
iterExported (fun name stamp ->
Expand All @@ -65,27 +65,32 @@ let completionForExporteds iterExported getDeclared ~prefix ~exact ~env
| Some (declared : _ Declared.t)
when not (Hashtbl.mem namesUsed declared.name.txt) ->
Hashtbl.add namesUsed declared.name.txt ();
let docstring =
match ProcessCmt.fileForModule (env.file.moduleName ^ "." ^ name) ~package with
| Some file -> file.structure.docstring
| None -> declared.docstring
in
res :=
{
(Completion.create declared.name.txt ~env
~kind:(transformContents declared.item))
with
deprecated = declared.deprecated;
docstring = declared.docstring;
docstring;
}
:: !res
| _ -> ());
!res

let completionForExportedModules ~env ~prefix ~exact ~namesUsed =
let completionForExportedModules ~env ~package ~prefix ~exact ~namesUsed =
completionForExporteds (Exported.iter env.QueryEnv.exported Exported.Module)
(Stamps.findModule env.file.stamps) ~prefix ~exact ~env ~namesUsed (fun m ->
Completion.Module m)
(Stamps.findModule env.file.stamps) ~prefix ~exact ~env ~package ~namesUsed
(fun m -> Completion.Module m)

let completionForExportedValues ~env ~prefix ~exact ~namesUsed =
let completionForExportedValues ~env ~package ~prefix ~exact ~namesUsed =
completionForExporteds (Exported.iter env.QueryEnv.exported Exported.Value)
(Stamps.findValue env.file.stamps) ~prefix ~exact ~env ~namesUsed (fun v ->
Completion.Value v)
(Stamps.findValue env.file.stamps) ~prefix ~exact ~env ~package ~namesUsed
(fun v -> Completion.Value v)

let completionForExportedTypes ~env ~prefix ~exact ~namesUsed =
completionForExporteds (Exported.iter env.QueryEnv.exported Exported.Type)
Expand Down Expand Up @@ -219,8 +224,8 @@ let kindToDetail name (kind : Completion.kind) =
| Value typ -> typ |> Shared.typeToString
| ObjLabel typ -> typ |> Shared.typeToString
| Label typString -> typString
| Module _ -> "module"
| FileModule _ -> "file module"
| Module _ -> ""
| FileModule docstring -> docstring
| Field ({typ; optional}, s) ->
(* Handle optional fields. Checking for "?" is because sometimes optional
fields are prefixed with "?" when completing, and at that point we don't
Expand All @@ -247,21 +252,22 @@ let kindToDetail name (kind : Completion.kind) =
| ExtractedType (extractedType, _) ->
TypeUtils.extractedTypeToString extractedType

let findAllCompletions ~(env : QueryEnv.t) ~prefix ~exact ~namesUsed
let findAllCompletions ~(env : QueryEnv.t) ~package ~prefix ~exact ~namesUsed
~(completionContext : Completable.completionContext) =
Log.log ("findAllCompletions uri:" ^ Uri.toString env.file.uri);
match completionContext with
| Value ->
completionForExportedValues ~env ~prefix ~exact ~namesUsed
completionForExportedValues ~env ~package ~prefix ~exact ~namesUsed
@ completionsForExportedConstructors ~env ~prefix ~exact ~namesUsed
@ completionForExportedModules ~env ~prefix ~exact ~namesUsed
@ completionForExportedModules ~env ~package ~prefix ~exact ~namesUsed
| Type ->
completionForExportedTypes ~env ~prefix ~exact ~namesUsed
@ completionForExportedModules ~env ~prefix ~exact ~namesUsed
| Module -> completionForExportedModules ~env ~prefix ~exact ~namesUsed
completionForExportedTypes ~env ~package ~prefix ~exact ~namesUsed
@ completionForExportedModules ~env ~package ~prefix ~exact ~namesUsed
| Module ->
completionForExportedModules ~env ~package ~prefix ~exact ~namesUsed
| Field ->
completionForExportedFields ~env ~prefix ~exact ~namesUsed
@ completionForExportedModules ~env ~prefix ~exact ~namesUsed
@ completionForExportedModules ~env ~package ~prefix ~exact ~namesUsed

let processLocalValue name loc contextPath ~prefix ~exact ~env
~(localTables : LocalTables.t) =
Expand Down Expand Up @@ -362,19 +368,20 @@ let processLocalModule name loc ~prefix ~exact ~env
(Printf.sprintf "Completion Module Not Found %s loc:%s\n" name
(Loc.toString loc))

let getItemsFromOpens ~opens ~localTables ~prefix ~exact ~completionContext =
let getItemsFromOpens ~opens ~package ~localTables ~prefix ~exact
~completionContext =
opens
|> List.fold_left
(fun results env ->
let completionsFromThisOpen =
findAllCompletions ~env ~prefix ~exact
findAllCompletions ~env ~package ~prefix ~exact
~namesUsed:localTables.LocalTables.namesUsed ~completionContext
in
completionsFromThisOpen @ results)
[]

let findLocalCompletionsForValuesAndConstructors ~(localTables : LocalTables.t)
~env ~prefix ~exact ~opens ~scope =
~env ~package ~prefix ~exact ~opens ~scope =
localTables |> LocalTables.populateValues ~env;
localTables |> LocalTables.populateConstructors ~env;
localTables |> LocalTables.populateModules ~env;
Expand All @@ -389,7 +396,7 @@ let findLocalCompletionsForValuesAndConstructors ~(localTables : LocalTables.t)
(processLocalModule ~prefix ~exact ~env ~localTables);

let valuesFromOpens =
getItemsFromOpens ~opens ~localTables ~prefix ~exact
getItemsFromOpens ~opens ~package ~localTables ~prefix ~exact
~completionContext:Value
in

Expand All @@ -404,8 +411,8 @@ let findLocalCompletionsForValuesAndConstructors ~(localTables : LocalTables.t)
(processLocalModule ~prefix ~exact ~env ~localTables);
List.rev_append localTables.resultRev valuesFromOpens

let findLocalCompletionsForValues ~(localTables : LocalTables.t) ~env ~prefix
~exact ~opens ~scope =
let findLocalCompletionsForValues ~(localTables : LocalTables.t) ~env ~package
~prefix ~exact ~opens ~scope =
localTables |> LocalTables.populateValues ~env;
localTables |> LocalTables.populateModules ~env;
scope
Expand All @@ -416,7 +423,7 @@ let findLocalCompletionsForValues ~(localTables : LocalTables.t) ~env ~prefix
(processLocalModule ~prefix ~exact ~env ~localTables);

let valuesFromOpens =
getItemsFromOpens ~opens ~localTables ~prefix ~exact
getItemsFromOpens ~opens ~package ~localTables ~prefix ~exact
~completionContext:Value
in

Expand All @@ -428,8 +435,8 @@ let findLocalCompletionsForValues ~(localTables : LocalTables.t) ~env ~prefix
(processLocalModule ~prefix ~exact ~env ~localTables);
List.rev_append localTables.resultRev valuesFromOpens

let findLocalCompletionsForTypes ~(localTables : LocalTables.t) ~env ~prefix
~exact ~opens ~scope =
let findLocalCompletionsForTypes ~(localTables : LocalTables.t) ~env ~package
~prefix ~exact ~opens ~scope =
localTables |> LocalTables.populateTypes ~env;
localTables |> LocalTables.populateModules ~env;
scope
Expand All @@ -440,7 +447,8 @@ let findLocalCompletionsForTypes ~(localTables : LocalTables.t) ~env ~prefix
(processLocalModule ~prefix ~exact ~env ~localTables);

let valuesFromOpens =
getItemsFromOpens ~opens ~localTables ~prefix ~exact ~completionContext:Type
getItemsFromOpens ~opens ~package ~localTables ~prefix ~exact
~completionContext:Type
in

scope
Expand All @@ -451,15 +459,15 @@ let findLocalCompletionsForTypes ~(localTables : LocalTables.t) ~env ~prefix
(processLocalModule ~prefix ~exact ~env ~localTables);
List.rev_append localTables.resultRev valuesFromOpens

let findLocalCompletionsForModules ~(localTables : LocalTables.t) ~env ~prefix
~exact ~opens ~scope =
let findLocalCompletionsForModules ~(localTables : LocalTables.t) ~env ~package
~prefix ~exact ~opens ~scope =
localTables |> LocalTables.populateModules ~env;
scope
|> Scope.iterModulesBeforeFirstOpen
(processLocalModule ~prefix ~exact ~env ~localTables);

let valuesFromOpens =
getItemsFromOpens ~opens ~localTables ~prefix ~exact
getItemsFromOpens ~opens ~package ~localTables ~prefix ~exact
~completionContext:Module
in

Expand All @@ -468,32 +476,34 @@ let findLocalCompletionsForModules ~(localTables : LocalTables.t) ~env ~prefix
(processLocalModule ~prefix ~exact ~env ~localTables);
List.rev_append localTables.resultRev valuesFromOpens

let findLocalCompletionsWithOpens ~pos ~(env : QueryEnv.t) ~prefix ~exact ~opens
~scope ~(completionContext : Completable.completionContext) =
let findLocalCompletionsWithOpens ~pos ~package ~(env : QueryEnv.t) ~prefix
~exact ~opens ~scope ~(completionContext : Completable.completionContext) =
(* TODO: handle arbitrary interleaving of opens and local bindings correctly *)
Log.log
("findLocalCompletionsWithOpens uri:" ^ Uri.toString env.file.uri ^ " pos:"
^ Pos.toString pos);
let localTables = LocalTables.create () in
match completionContext with
| Value ->
findLocalCompletionsForValuesAndConstructors ~localTables ~env ~prefix
~exact ~opens ~scope
findLocalCompletionsForValuesAndConstructors ~localTables ~env ~package
~prefix ~exact ~opens ~scope
| Type ->
findLocalCompletionsForTypes ~localTables ~env ~prefix ~exact ~opens ~scope
findLocalCompletionsForTypes ~localTables ~env ~package ~prefix ~exact
~opens ~scope
| Module ->
findLocalCompletionsForModules ~localTables ~env ~prefix ~exact ~opens
~scope
findLocalCompletionsForModules ~localTables ~env ~package ~prefix ~exact
~opens ~scope
| Field ->
(* There's no local completion for fields *)
[]

let getComplementaryCompletionsForTypedValue ~opens ~allFiles ~scope ~env prefix
=
let getComplementaryCompletionsForTypedValue ~opens ~allFiles ~scope ~env
~package prefix =
let exact = false in
let localCompletionsWithOpens =
let localTables = LocalTables.create () in
findLocalCompletionsForValues ~localTables ~env ~prefix ~exact ~opens ~scope
findLocalCompletionsForValues ~localTables ~env ~package ~prefix ~exact
~opens ~scope
in
let fileModules =
allFiles |> FileSet.elements
Expand All @@ -518,8 +528,8 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
| [] -> []
| [prefix] ->
let localCompletionsWithOpens =
findLocalCompletionsWithOpens ~pos ~env ~prefix ~exact ~opens ~scope
~completionContext
findLocalCompletionsWithOpens ~pos ~package ~env ~prefix ~exact ~opens
~scope ~completionContext
in
let fileModules =
allFiles |> FileSet.elements
Expand All @@ -530,8 +540,14 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
(* TODO complete the namespaced name too *)
(String.contains name '-')
then
let docstring =
match ProcessCmt.fileForModule ~package name with
| None -> []
| Some file -> file.structure.docstring
in
Some
(Completion.create name ~env ~kind:(Completion.FileModule name))
(Completion.create name ~env ~docstring
~kind:(Completion.FileModule name))
else None)
in
localCompletionsWithOpens @ fileModules
Expand All @@ -541,7 +557,8 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
| Some (env, prefix) ->
Log.log "Got the env";
let namesUsed = Hashtbl.create 10 in
findAllCompletions ~env ~prefix ~exact ~namesUsed ~completionContext
findAllCompletions ~env ~package ~prefix ~exact ~namesUsed
~completionContext
| None -> [])

let mkItem ~name ~kind ~detail ~deprecated ~docstring =
Expand Down Expand Up @@ -1601,7 +1618,8 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
if prefix = "" then []
else
prefix
|> getComplementaryCompletionsForTypedValue ~opens ~allFiles ~env ~scope
|> getComplementaryCompletionsForTypedValue ~opens ~allFiles ~env
~package ~scope
in
match
contextPath
Expand Down
32 changes: 16 additions & 16 deletions analysis/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ Path Array.
"label": "Floatarray",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand Down Expand Up @@ -816,7 +816,7 @@ Path O.
"label": "Comp",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand Down Expand Up @@ -874,14 +874,14 @@ Path Lis
"label": "List",
"kind": 9,
"tags": [],
"detail": "file module",
"documentation": null
"detail": "List",
"documentation": {"kind": "markdown", "value": " List operations.\n\n Some functions are flagged as not tail-recursive. A tail-recursive\n function uses constant stack space, while a non-tail-recursive function\n uses stack space proportional to the length of its list argument, which\n can be a problem with very long lists. When the function takes several\n list arguments, an approximate formula giving stack usage (in some\n unspecified constant unit) is shown in parentheses.\n\n The above considerations can usually be ignored if your lists are not\n longer than about 10000 elements.\n"}
}, {
"label": "ListLabels",
"kind": 9,
"tags": [],
"detail": "file module",
"documentation": null
"detail": "ListLabels",
"documentation": {"kind": "markdown", "value": " List operations.\n\n Some functions are flagged as not tail-recursive. A tail-recursive\n function uses constant stack space, while a non-tail-recursive function\n uses stack space proportional to the length of its list argument, which\n can be a problem with very long lists. When the function takes several\n list arguments, an approximate formula giving stack usage (in some\n unspecified constant unit) is shown in parentheses.\n\n The above considerations can usually be ignored if your lists are not\n longer than about 10000 elements.\n"}
}]

Complete src/Completion.res 169:16
Expand All @@ -896,7 +896,7 @@ Path WithChildren
"label": "WithChildren",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand Down Expand Up @@ -971,7 +971,7 @@ Path For
"label": "ForAuto",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand Down Expand Up @@ -1205,7 +1205,7 @@ Path SomeLo
"label": "SomeLocalModule",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand Down Expand Up @@ -1261,7 +1261,7 @@ Path SomeLocal
"label": "SomeLocalModule",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand All @@ -1279,7 +1279,7 @@ Path SomeLocal
"label": "SomeLocalModule",
"kind": 9,
"tags": [],
"detail": "module",
"detail": "",
"documentation": null
}]

Expand Down Expand Up @@ -1648,13 +1648,13 @@ Path Res
"label": "RescriptReactErrorBoundary",
"kind": 9,
"tags": [],
"detail": "file module",
"detail": "RescriptReactErrorBoundary",
"documentation": null
}, {
"label": "RescriptReactRouter",
"kind": 9,
"tags": [],
"detail": "file module",
"detail": "RescriptReactRouter",
"documentation": null
}]

Expand Down Expand Up @@ -1762,19 +1762,19 @@ Path T
"label": "TableclothMap",
"kind": 9,
"tags": [],
"detail": "file module",
"detail": "TableclothMap",
"documentation": null
}, {
"label": "TypeAtPosCompletion",
"kind": 9,
"tags": [],
"detail": "file module",
"detail": "TypeAtPosCompletion",
"documentation": null
}, {
"label": "TypeDefinition",
"kind": 9,
"tags": [],
"detail": "file module",
"detail": "TypeDefinition",
"documentation": null
}]

Expand Down
Loading