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

special handling of optional fields when destructuring #715

Merged
merged 3 commits into from
Jan 26, 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
@@ -36,6 +36,7 @@
- Improve precision in signature help. You now do not need to type anything into the argument for it to highlight. https://github.com/rescript-lang/rescript-vscode/pull/675
- Remove redundant function name in signature help, to clean up what's shown to the user some. https://github.com/rescript-lang/rescript-vscode/pull/678
- Show docstrings in hover for record fields and variant constructors. https://github.com/rescript-lang/rescript-vscode/pull/694
- The necessary leading `?` is now automatically inserted for optional fields when destructuring records. https://github.com/rescript-lang/rescript-vscode/pull/715

#### :bug: Bug Fix

36 changes: 25 additions & 11 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
@@ -1047,10 +1047,10 @@ let printConstructorArgs argsLen ~asSnippet =
if List.length !args > 0 then "(" ^ (!args |> String.concat ", ") ^ ")"
else ""

type completionMode = Pattern | Expression
type completionMode = Pattern of Completable.patternMode | Expression

let rec completeTypedValue (t : SharedTypes.completionType) ~full ~prefix
~completionContext ~mode =
let rec completeTypedValue ~full ~prefix ~completionContext ~mode
(t : SharedTypes.completionType) =
match t with
| Tbool env ->
[
@@ -1142,10 +1142,23 @@ let rec completeTypedValue (t : SharedTypes.completionType) ~full ~prefix
|> List.filter (fun (field : field) ->
List.mem field.fname.txt seenFields = false)
|> List.map (fun (field : field) ->
Completion.create field.fname.txt
~kind:
(Field (field, TypeUtils.extractedTypeToString extractedType))
~env)
match (field.optional, mode) with
| true, Pattern Destructuring ->
Completion.create ("?" ^ field.fname.txt)
~docstring:
[
field.fname.txt
^ " is an optional field, and needs to be destructured \
using '?'.";
]
~kind:
(Field (field, TypeUtils.extractedTypeToString extractedType))
~env
| _ ->
Completion.create field.fname.txt
~kind:
(Field (field, TypeUtils.extractedTypeToString extractedType))
~env)
|> filterItems ~prefix
| None ->
if prefix = "" then
@@ -1157,7 +1170,7 @@ let rec completeTypedValue (t : SharedTypes.completionType) ~full ~prefix
(ExtractedType
( extractedType,
match mode with
| Pattern -> `Type
| Pattern _ -> `Type
| Expression -> `Value ))
~env ();
]
@@ -1190,7 +1203,7 @@ let rec completeTypedValue (t : SharedTypes.completionType) ~full ~prefix
(ExtractedType
( typ,
match mode with
| Pattern -> `Type
| Pattern _ -> `Type
| Expression -> `Value ))
~env ();
]
@@ -1360,7 +1373,7 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover
Utils.startsWith name prefix
&& (forHover || not (List.mem name identsSeen)))
|> List.map mkLabel
| Cpattern {contextPath; prefix; nested; fallback} -> (
| Cpattern {contextPath; prefix; nested; fallback; patternMode} -> (
let fallbackOrEmpty ?items () =
match (fallback, items) with
| Some fallback, (None | Some []) ->
@@ -1385,7 +1398,8 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover
| Some (typ, _env, completionContext) ->
let items =
typ
|> completeTypedValue ~mode:Pattern ~full ~prefix ~completionContext
|> completeTypedValue ~mode:(Pattern patternMode) ~full ~prefix
~completionContext
in
fallbackOrEmpty ~items ())
| None -> fallbackOrEmpty ())
4 changes: 4 additions & 0 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
@@ -317,6 +317,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
prefix;
nested = List.rev nestedPattern;
fallback = None;
patternMode = Default;
})
| _ -> ()
in
@@ -391,6 +392,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
nested = [];
prefix = "";
fallback = None;
patternMode = Default;
}))
| Pexp_match (exp, cases) -> (
(* If there's more than one case, or the case isn't a pattern hole, figure out if we're completing another
@@ -423,6 +425,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
nested = [];
prefix = "";
fallback = None;
patternMode = Default;
})
| false, false -> ()))
| _ -> unsetLookingForPat ()
@@ -524,6 +527,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
prefix;
nested = List.rev nested;
fallback = None;
patternMode = Destructuring;
})
| _ -> ())
| _ -> ());
3 changes: 3 additions & 0 deletions analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
@@ -631,6 +631,8 @@ module Completable = struct
^ ")"
| NArray -> "array"

type patternMode = Default | Destructuring

type t =
| Cdecorator of string (** e.g. @module *)
| CnamedArg of contextPath * string * string list
@@ -648,6 +650,7 @@ module Completable = struct
contextPath: contextPath;
nested: nestedPath list;
prefix: string;
patternMode: patternMode;
fallback: t option;
}
| CexhaustiveSwitch of {contextPath: contextPath; exprLoc: Location.t}
12 changes: 12 additions & 0 deletions analysis/tests/src/Destructuring.res
Original file line number Diff line number Diff line change
@@ -19,3 +19,15 @@ let f2 = (x: x) => {
// ^com
ignore(x)
}

type recordWithOptField = {
someField: int,
someOptField?: bool
}

let x: recordWithOptField = {
someField: 123
}

// let {} = x
// ^com
17 changes: 17 additions & 0 deletions analysis/tests/src/expected/Destructuring.res.txt
Original file line number Diff line number Diff line change
@@ -58,3 +58,20 @@ Completable: Cpattern Value[x]->recordBody
"documentation": null
}]

Complete src/Destructuring.res 31:8
posCursor:[31:8] posNoWhite:[31:7] Found pattern:[31:7->31:9]
Completable: Cpattern Value[x]->recordBody
[{
"label": "someField",
"kind": 5,
"tags": [],
"detail": "someField: int\n\nrecordWithOptField",
"documentation": null
}, {
"label": "?someOptField",
"kind": 5,
"tags": [],
"detail": "?someOptField: option<bool>\n\nrecordWithOptField",
"documentation": {"kind": "markdown", "value": "someOptField is an optional field, and needs to be destructured using '?'."}
}]