Skip to content

Better completion for applications #7291

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

Merged
merged 7 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
10 changes: 8 additions & 2 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,11 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
| [], [(Nolabel | Labelled _ | Optional _)] ->
(* should not happen, but just ignore extra arguments *) []
in

(* (match typ.desc with
| Tarrow _ -> print_endline "its an arrow"
| Tconstr _ -> print_endline "it's an alias"
| _ -> print_endline "something else"); *)
match TypeUtils.extractFunctionType ~env ~package typ with
| args, tRet when args <> [] ->
let args = processApply args labels in
Expand Down Expand Up @@ -1047,6 +1052,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
| None -> [])
| None -> [])
| CPPipe {contextPath = cp; id = prefix; lhsLoc; inJsx; synthetic} -> (
(* TODO: resolve somewhere in here a potential alias *)
if Debug.verbose () then print_endline "[ctx_path]--> CPPipe";
match
cp
Expand Down Expand Up @@ -1119,7 +1125,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
~pos ~scope ~debug ~prefix ~env ~rawOpens ~full completionPath
|> TypeUtils.filterPipeableFunctions ~env ~full ~synthetic
~targetTypeId:mainTypeId
|> List.filter (fun (c : Completion.t) ->
(* |> List.filter (fun (c : Completion.t) ->
(* If we're completing from the current module then we need to care about scope.
This is automatically taken care of in other cases. *)
if isFromCurrentModule then
Expand All @@ -1133,7 +1139,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
| _ -> false)
|> Option.is_some
| _ -> false
else true)
else true) *)
in
(* Extra completions can be drawn from the @editor.completeFrom attribute. Here we
find and add those completions as well. *)
Expand Down
10 changes: 0 additions & 10 deletions analysis/src/TypeUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -248,16 +248,6 @@ let extractFunctionType ~env ~package typ =
match t.desc with
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> loop ~env acc t1
| Tarrow (label, tArg, tRet, _, _) -> loop ~env ((label, tArg) :: acc) tRet
| Tconstr (path, typeArgs, _) -> (
match References.digConstructor ~env ~package path with
| Some
( env,
{
item = {decl = {type_manifest = Some t1; type_params = typeParams}};
} ) ->
let t1 = t1 |> instantiateType ~typeParams ~typeArgs in
loop ~env acc t1
| _ -> (List.rev acc, t))
| _ -> (List.rev acc, t)
in
loop ~env [] typ
Expand Down
11 changes: 7 additions & 4 deletions tests/analysis_tests/tests/src/CompletionTaggedTemplate.res
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module M = {
type t
type t = promise<string>

let a = (_t:t) => 4
let b = (_:t) => "c"
Expand All @@ -9,8 +9,11 @@ module M = {
@module("meh") @taggedTemplate
external meh: (array<string>, array<string>) => M.t = "default"

let w = meh``

// ^dv+
// let _ = w.
// ^com

// let x = meh`foo`.
// ^com

// let y = meh`bar`.x
// ^com
10 changes: 8 additions & 2 deletions tests/analysis_tests/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1885,13 +1885,19 @@ Resolved opens 2 Completion Completion
ContextPath Value[withCallback](~a)
ContextPath Value[withCallback]
Path withCallback
Found type for function (~b: int) => int
Found type for function (~b: int) => callback
[{
"label": "b",
"kind": 4,
"tags": [],
"detail": "int",
"documentation": null
}, {
"label": "a",
"kind": 4,
"tags": [],
"detail": "int",
"documentation": null
}]

Complete src/Completion.res 332:21
Expand All @@ -1904,7 +1910,7 @@ Resolved opens 2 Completion Completion
ContextPath Value[withCallback](~b)
ContextPath Value[withCallback]
Path withCallback
Found type for function (~a: int) => int
Found type for function callback
[{
"label": "a",
"kind": 4,
Expand Down
9 changes: 5 additions & 4 deletions tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,23 +162,24 @@ ContextPath Value[Js, String2, trim](Nolabel)->st <<jsx>>
ContextPath Value[Js, String2, trim](Nolabel)
ContextPath Value[Js, String2, trim]
Path Js.String2.trim
Path Js.String2.st
CPPipe pathFromEnv: found:true
Path Js_string2.st
[{
"label": "React.string",
"kind": 12,
"tags": [],
"detail": "string",
"detail": "t",
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
"label": "Js.String2.startsWith",
"label": "Js_string2.startsWith",
"kind": 12,
"tags": [],
"detail": "(t, t) => bool",
"documentation": {"kind": "markdown", "value": "\nES2015: `startsWith(str, substr)` returns `true` if the `str` starts with\n`substr`, `false` otherwise.\n\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith)\non MDN.\n\n## Examples\n\n```rescript\nJs.String2.startsWith(\"ReScript\", \"Re\") == true\nJs.String2.startsWith(\"ReScript\", \"\") == true\nJs.String2.startsWith(\"JavaScript\", \"Re\") == false\n```\n"}
}, {
"label": "Js.String2.startsWithFrom",
"label": "Js_string2.startsWithFrom",
"kind": 12,
"tags": [],
"detail": "(t, t, int) => bool",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
Complete src/CompletionTaggedTemplate.res 11:20
posCursor:[11:20] posNoWhite:[11:19] Found expr:[11:11->0:-1]
Completable: Cpath Value[meh](Nolabel, Nolabel).""

Complete src/CompletionTaggedTemplate.res 14:13
[decoratorCompletion] Found @module with non-string payload
posCursor:[14:13] posNoWhite:[14:12] Found expr:[14:11->14:13]
Pexp_field [14:11->14:12] _:[20:0->14:13]
[set_result] set new result to Cpath Value[w].""
Completable: Cpath Value[w].""
Package opens Pervasives.JsxModules.place holder
ContextPath Value[meh](Nolabel, Nolabel).""
ContextPath Value[meh](Nolabel, Nolabel)
ContextPath Value[meh]
Path meh
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)->
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)
ContextPath Value[meh]
Path meh
ContextPath Value[w].""
[dot_completion]--> Triggered
ContextPath Value[w]
[ctx_path]--> CPId
Path w
[extract_type]--> starting extraction of type: M.t, in env: CompletionTaggedTemplate. Has type arg ctx: false
[extract_type]--> digging for type M.t in CompletionTaggedTemplate
[extract_type]--> found type manifest
[extract_type]--> starting extraction of type: promise<string>, in env: CompletionTaggedTemplate.M. Has type arg ctx: false
ContextPath Value[w]->
[ctx_path]--> CPPipe
ContextPath Value[w]
[ctx_path]--> CPId
Path w
[pipe_completion] mainTypeId: promise
CPPipe pathFromEnv:M found:true
Path M.
[{
Expand All @@ -21,7 +32,7 @@ Path M.
"sortText": "xyz",
"insertText": "->M.xyz",
"additionalTextEdits": [{
"range": {"start": {"line": 11, "character": 19}, "end": {"line": 11, "character": 20}},
"range": {"start": {"line": 14, "character": 12}, "end": {"line": 14, "character": 13}},
"newText": ""
}]
}, {
Expand All @@ -33,7 +44,7 @@ Path M.
"sortText": "b",
"insertText": "->M.b",
"additionalTextEdits": [{
"range": {"start": {"line": 11, "character": 19}, "end": {"line": 11, "character": 20}},
"range": {"start": {"line": 14, "character": 12}, "end": {"line": 14, "character": 13}},
"newText": ""
}]
}, {
Expand All @@ -45,25 +56,34 @@ Path M.
"sortText": "a",
"insertText": "->M.a",
"additionalTextEdits": [{
"range": {"start": {"line": 11, "character": 19}, "end": {"line": 11, "character": 20}},
"range": {"start": {"line": 14, "character": 12}, "end": {"line": 14, "character": 13}},
"newText": ""
}]
}]

Complete src/CompletionTaggedTemplate.res 14:21
posCursor:[14:21] posNoWhite:[14:20] Found expr:[14:11->14:21]
Completable: Cpath Value[meh](Nolabel, Nolabel).x
Complete src/CompletionTaggedTemplate.res 17:20
[decoratorCompletion] Found @module with non-string payload
[set_result] set new result to Cpath Value[meh](Nolabel, Nolabel).""
posCursor:[17:20] posNoWhite:[17:19] Found expr:[17:11->0:-1]
Completable: Cpath Value[meh](Nolabel, Nolabel).""
Package opens Pervasives.JsxModules.place holder
ContextPath Value[meh](Nolabel, Nolabel).x
ContextPath Value[meh](Nolabel, Nolabel).""
[dot_completion]--> Triggered
ContextPath Value[meh](Nolabel, Nolabel)
[ctx_path]--> CPApply
ContextPath Value[meh]
[ctx_path]--> CPId
Path meh
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)->x
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)->
[ctx_path]--> CPPipe
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)
[ctx_path]--> CPApply
ContextPath Value[meh]
[ctx_path]--> CPId
Path meh
[pipe_completion] mainTypeId: promise
CPPipe pathFromEnv:M found:true
Path M.x
Path M.
[{
"label": "->M.xyz",
"kind": 12,
Expand All @@ -73,7 +93,31 @@ Path M.x
"sortText": "xyz",
"insertText": "->M.xyz",
"additionalTextEdits": [{
"range": {"start": {"line": 14, "character": 19}, "end": {"line": 14, "character": 20}},
"range": {"start": {"line": 17, "character": 19}, "end": {"line": 17, "character": 20}},
"newText": ""
}]
}, {
"label": "->M.b",
"kind": 12,
"tags": [],
"detail": "t => string",
"documentation": null,
"sortText": "b",
"insertText": "->M.b",
"additionalTextEdits": [{
"range": {"start": {"line": 17, "character": 19}, "end": {"line": 17, "character": 20}},
"newText": ""
}]
}, {
"label": "->M.a",
"kind": 12,
"tags": [],
"detail": "t => int",
"documentation": null,
"sortText": "a",
"insertText": "->M.a",
"additionalTextEdits": [{
"range": {"start": {"line": 17, "character": 19}, "end": {"line": 17, "character": 20}},
"newText": ""
}]
}]
Expand Down
Loading
Loading