Skip to content

Complete via TypeAtPos #808

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 5 commits into from
Aug 17, 2023
Merged
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
@@ -17,6 +17,7 @@
- Add support for syntax highlighting in `%raw` and `%ffi` extension points. https://github.com/rescript-lang/rescript-vscode/pull/774
- Add completion to top level decorators. https://github.com/rescript-lang/rescript-vscode/pull/799
- Add code action for wrapping patterns where option is expected with `Some`. https://github.com/rescript-lang/rescript-vscode/pull/806
- Better completion from identifiers with inferred types. https://github.com/rescript-lang/rescript-vscode/pull/808

#### :nail_care: Polish

8 changes: 8 additions & 0 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
@@ -1113,6 +1113,14 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
[Completion.create "dummy" ~env ~kind:(kindFromInnerType typ)]
| None -> [])
| None -> [])
| CTypeAtPos loc -> (
match
References.getLocItem ~full ~pos:(Pos.ofLexing loc.loc_start) ~debug
with
| None -> []
| Some {locType = Typed (_, typExpr, _)} ->
[Completion.create "dummy" ~env ~kind:(Value typExpr)]
| _ -> [])

let getOpens ~debug ~rawOpens ~package ~env =
if debug && rawOpens <> [] then
21 changes: 21 additions & 0 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
@@ -591,6 +591,27 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
(Completable.Cexpression
{contextPath = ctxPath; prefix; nested = List.rev nested})
| _ -> ())
| {pvb_pat = {ppat_desc = Ppat_var {loc}}; pvb_expr}
when locHasCursor pvb_expr.pexp_loc -> (
(* Expression without a type annotation. We can complete this if this
has compiled previously and there's a type available for the identifier itself.
This is nice because the type is assigned even if the assignment isn't complete.

E.g: let x = {name: "name", <com>}, when `x` has compiled. *)
match
pvb_expr
|> CompletionExpressions.traverseExpr ~exprPath:[] ~pos:posBeforeCursor
~firstCharBeforeCursorNoWhite
with
| Some (prefix, nested) ->
(* This completion should be low prio, so let any deeper completion
hit first, and only set this TypeAtPos completion if nothing else
here hit. *)
Ast_iterator.default_iterator.value_binding iterator value_binding;
setResult
(Completable.Cexpression
{contextPath = CTypeAtPos loc; prefix; nested = List.rev nested})
| _ -> ())
| {
pvb_pat = {ppat_desc = Ppat_constraint (_pat, coreType); ppat_loc};
pvb_expr;
3 changes: 3 additions & 0 deletions analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
@@ -592,6 +592,8 @@ module Completable = struct
}
| CJsxPropValue of {pathToComponent: string list; propName: string}
| CPatternPath of {rootCtxPath: contextPath; nested: nestedPath list}
| CTypeAtPos of Location.t
(** A position holding something that might have a *compiled* type. *)

type patternMode = Default | Destructuring

@@ -671,6 +673,7 @@ module Completable = struct
^ (nested
|> List.map (fun nestedPath -> nestedPathToString nestedPath)
|> String.concat "->")
| CTypeAtPos _loc -> "CTypeAtPos()"

let toString = function
| Cpath cp -> "Cpath " ^ contextPathToString cp
25 changes: 25 additions & 0 deletions analysis/tests/src/TypeAtPosCompletion.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type optRecord = {
name: string,
age?: int,
online?: bool,
}

let optRecord = {
name: "Hello",
// ^com
}

type someVariant = One(int, optRecord)

let x = One(
1,
{
name: "What",
// ^com
},
)

let arr = [
optRecord,
// ^com
]
6 changes: 6 additions & 0 deletions analysis/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
@@ -1764,6 +1764,12 @@ Path T
"tags": [],
"detail": "file module",
"documentation": null
}, {
"label": "TypeAtPosCompletion",
"kind": 9,
"tags": [],
"detail": "file module",
"documentation": null
}, {
"label": "TypeDefinition",
"kind": 9,
6 changes: 6 additions & 0 deletions analysis/tests/src/expected/CompletionJsxProps.res.txt
Original file line number Diff line number Diff line change
@@ -68,6 +68,12 @@ Path CompletionSupport.TestComponent.make
"tags": [],
"detail": "file module",
"documentation": null
}, {
"label": "TypeAtPosCompletion",
"kind": 9,
"tags": [],
"detail": "file module",
"documentation": null
}, {
"label": "TypeDefinition",
"kind": 9,
4 changes: 4 additions & 0 deletions analysis/tests/src/expected/Fragment.res.txt
Original file line number Diff line number Diff line change
@@ -12,5 +12,9 @@ posCursor:[9:56] posNoWhite:[9:55] Found expr:[9:13->9:66]
JSX <SectionHeader:[9:13->9:26] > _children:9:26
posCursor:[9:56] posNoWhite:[9:55] Found expr:__ghost__[9:10->9:67]
Pexp_construct []:__ghost__[9:10->9:67] None
Completable: Cexpression CTypeAtPos()=[]->variantPayload::::($1)
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath CTypeAtPos()
null

60 changes: 60 additions & 0 deletions analysis/tests/src/expected/TypeAtPosCompletion.res.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Complete src/TypeAtPosCompletion.res 7:17
posCursor:[7:17] posNoWhite:[7:15] Found expr:[6:16->9:1]
Completable: Cexpression CTypeAtPos()->recordBody
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath CTypeAtPos()
[{
"label": "age",
"kind": 5,
"tags": [],
"detail": "age?: int\n\noptRecord",
"documentation": null
}, {
"label": "online",
"kind": 5,
"tags": [],
"detail": "online?: bool\n\noptRecord",
"documentation": null
}]

Complete src/TypeAtPosCompletion.res 16:18
posCursor:[16:18] posNoWhite:[16:16] Found expr:[13:8->19:1]
Pexp_construct One:[13:8->13:11] [13:11->19:1]
posCursor:[16:18] posNoWhite:[16:16] Found expr:[13:11->19:1]
posCursor:[16:18] posNoWhite:[16:16] Found expr:[15:2->18:3]
Completable: Cexpression CTypeAtPos()->variantPayload::One($1), recordBody
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath CTypeAtPos()
[{
"label": "age",
"kind": 5,
"tags": [],
"detail": "age?: int\n\noptRecord",
"documentation": null
}, {
"label": "online",
"kind": 5,
"tags": [],
"detail": "online?: bool\n\noptRecord",
"documentation": null
}]

Complete src/TypeAtPosCompletion.res 22:12
posCursor:[22:12] posNoWhite:[22:11] Found expr:[21:10->24:1]
Completable: Cexpression CTypeAtPos()->array
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath CTypeAtPos()
[{
"label": "{}",
"kind": 12,
"tags": [],
"detail": "optRecord",
"documentation": null,
"sortText": "A",
"insertText": "{$0}",
"insertTextFormat": 2
}]