Skip to content
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

Make completion engine understand await #813

Merged
merged 2 commits into from
Aug 20, 2023
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#### :nail_care: Polish

- Revamp "Insert missing cases" code action to make it apply in more cases and be much more robust. https://github.com/rescript-lang/rescript-vscode/pull/804
- Make the completion engine understand async/await. https://github.com/rescript-lang/rescript-vscode/pull/813

#### :bug: Bug Fix

Expand Down
11 changes: 11 additions & 0 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,16 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
~kind:
(Completion.ExtractedType (Toption (env, ExtractedType typ), `Type));
])
| CPAwait cp -> (
match
cp
|> getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env
~exact:true ~scope
|> completionsGetCompletionType ~full
with
| Some (Tpromise (env, typ), _env) ->
[Completion.create "dummy" ~env ~kind:(Completion.Value typ)]
| _ -> [])
| CPId (path, completionContext) ->
path
|> getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact
Expand Down Expand Up @@ -1433,6 +1443,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
]
~env;
]
| Tpromise _ -> []

let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
if debug then
Expand Down
11 changes: 10 additions & 1 deletion analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ let findArgCompletables ~(args : arg list) ~endPos ~posBeforeCursor
})
| _ -> loop args

let rec exprToContextPath (e : Parsetree.expression) =
let rec exprToContextPathInner (e : Parsetree.expression) =
match e.pexp_desc with
| Pexp_constant (Pconst_string _) -> Some Completable.CPString
| Pexp_constant (Pconst_integer _) -> Some CPInt
Expand Down Expand Up @@ -199,6 +199,15 @@ let rec exprToContextPath (e : Parsetree.expression) =
else None
| _ -> None

and exprToContextPath (e : Parsetree.expression) =
match
( Res_parsetree_viewer.hasAwaitAttribute e.pexp_attributes,
exprToContextPathInner e )
with
| true, Some ctxPath -> Some (CPAwait ctxPath)
| false, Some ctxPath -> Some ctxPath
| _, None -> None

let completePipeChain (exp : Parsetree.expression) =
(* Complete the end of pipe chains by reconstructing the pipe chain as a single pipe,
so it can be completed.
Expand Down
3 changes: 3 additions & 0 deletions analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ type innerType = TypeExpr of Types.type_expr | ExtractedType of completionType
and completionType =
| Tuple of QueryEnv.t * Types.type_expr list * Types.type_expr
| Texn of QueryEnv.t
| Tpromise of QueryEnv.t * Types.type_expr
| Toption of QueryEnv.t * innerType
| Tbool of QueryEnv.t
| Tarray of QueryEnv.t * innerType
Expand Down Expand Up @@ -578,6 +579,7 @@ module Completable = struct
| CPId of string list * completionContext
| CPField of contextPath * string
| CPObj of contextPath * string
| CPAwait of contextPath
| CPPipe of {
contextPath: contextPath;
id: string;
Expand Down Expand Up @@ -631,6 +633,7 @@ module Completable = struct
| CPInt -> "int"
| CPFloat -> "float"
| CPBool -> "bool"
| CPAwait ctxPath -> "await " ^ contextPathToString ctxPath
| CPOption ctxPath -> "option<" ^ contextPathToString ctxPath ^ ">"
| CPApply (cp, labels) ->
contextPathToString cp ^ "("
Expand Down
3 changes: 3 additions & 0 deletions analysis/src/TypeUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ let rec extractType ~env ~package (t : Types.type_expr) =
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractType ~env ~package t1
| Tconstr (Path.Pident {name = "option"}, [payloadTypeExpr], _) ->
Some (Toption (env, TypeExpr payloadTypeExpr))
| Tconstr (Path.Pident {name = "promise"}, [payloadTypeExpr], _) ->
Some (Tpromise (env, payloadTypeExpr))
| Tconstr (Path.Pident {name = "array"}, [payloadTypeExpr], _) ->
Some (Tarray (env, TypeExpr payloadTypeExpr))
| Tconstr (Path.Pident {name = "bool"}, [], _) -> Some (Tbool env)
Expand Down Expand Up @@ -595,6 +597,7 @@ let rec extractedTypeToString ?(inner = false) = function
"option<" ^ Shared.typeToString innerTyp ^ ">"
| Toption (_, ExtractedType innerTyp) ->
"option<" ^ extractedTypeToString ~inner:true innerTyp ^ ">"
| Tpromise (_, innerTyp) -> "promise<" ^ Shared.typeToString innerTyp ^ ">"
| Tvariant {variantDecl; variantName} ->
if inner then variantName else Shared.declToString variantName variantDecl
| Trecord {definition = `NameOnly name; fields} ->
Expand Down
5 changes: 5 additions & 0 deletions analysis/tests/src/CompletionPattern.res
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,8 @@ let xn: exn = Obj.magic()

// switch xn { | }
// ^com

let getThing = async () => One

// switch await getThing() { | }
// ^com
35 changes: 35 additions & 0 deletions analysis/tests/src/expected/CompletionPattern.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1070,3 +1070,38 @@ Path xn
"documentation": {"kind": "markdown", "value": "Matches on a JavaScript error. Read more in the [documentation on catching JS exceptions](https://rescript-lang.org/docs/manual/latest/exception#catching-js-exceptions)."}
}]

Complete src/CompletionPattern.res 211:30
XXX Not found!
Completable: Cpattern await Value[getThing](Nolabel)
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath await Value[getThing](Nolabel)
ContextPath Value[getThing](Nolabel)
ContextPath Value[getThing]
Path getThing
[{
"label": "One",
"kind": 4,
"tags": [],
"detail": "One\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)",
"documentation": null,
"insertText": "One",
"insertTextFormat": 2
}, {
"label": "Two(_)",
"kind": 4,
"tags": [],
"detail": "Two(bool)\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)",
"documentation": null,
"insertText": "Two(${1:_})",
"insertTextFormat": 2
}, {
"label": "Three(_, _)",
"kind": 4,
"tags": [],
"detail": "Three(someRecord, bool)\n\ntype someVariant = One | Two(bool) | Three(someRecord, bool)",
"documentation": null,
"insertText": "Three(${1:_}, ${2:_})",
"insertTextFormat": 2
}]