Skip to content

Explore type based autocomplete #493

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
wants to merge 81 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
7db9012
add base test case for completing jsx prop and labelled argument
zth Jul 14, 2022
4362bdf
commit the rest of the updated test result files
zth Jul 14, 2022
87508b3
fix accidentally broken completion example
zth Jul 14, 2022
5ed8bb4
identify typed context for labelled argument assignments
zth Jul 15, 2022
d121e73
remove special handling of equality char
zth Jul 16, 2022
57e7cce
use trick from JSX prop completion to identify empty assignment of la…
zth Jul 16, 2022
b125207
crude implementation of completing variant constructors
zth Jul 17, 2022
431ab48
rename and specialize test file so that it will only contain tests fo…
zth Jul 17, 2022
bdd2e11
generalize completion so it theoretically can handle more than variants
zth Jul 17, 2022
bea78fe
add assigned identifier to test file
zth Jul 17, 2022
5ebe602
add more args to test function in test file
zth Jul 17, 2022
b85c4ae
filter completed variant constructors on what the user has already wr…
zth Jul 17, 2022
dd8333e
add example completing variant from other file
zth Jul 17, 2022
ffa06f4
complete polyvariants in addition to regular variants
zth Jul 17, 2022
37e4f9b
clarifications and touch ups after pr comments
zth Jul 18, 2022
c2e2adf
add dedicated example file for JSX completions
zth Jul 18, 2022
d1d86e8
inline contextPath into NamedArg to pave way for JsxProp, that will n…
zth Jul 18, 2022
90ccf19
add jsx example completing across files
zth Jul 19, 2022
d54b562
basic JSX prop completion via type
zth Jul 18, 2022
2b29291
add completions from context in addition to the explicit type based c…
zth Jul 19, 2022
27532b0
bring contextual completions to labelled arguments as well
zth Jul 19, 2022
e87ad5a
remove redundant comment#
zth Jul 19, 2022
f79a38d
Merge branch 'master' into type-based-autocomplete
zth Jul 25, 2022
b260d38
take a step back and remove typed completions for now. focus on ident…
zth Jul 27, 2022
54e596c
add some completion cases for records
zth Jul 30, 2022
8c49fa5
refactor to continuously setting the typed context we're currently lo…
zth Jul 30, 2022
c8f112a
fix + debug util
zth Jul 30, 2022
49e45d8
identify and complete for record fields when destructuring
zth Jul 30, 2022
7c8a1ad
allow any expr, which makes fn returns also work
zth Jul 30, 2022
b34c35d
basic, slightly buggy completion for nested record fields
zth Jul 31, 2022
7b1b8cd
do not complete if we cant find the cursor inside of nested pattern
zth Aug 1, 2022
f79f21b
add more broken test cases
zth Aug 1, 2022
0df2b0c
ensure completing from empty root records work as expected
zth Aug 1, 2022
33cd645
look for ',' as first char before cursor to trigger completion in cas…
zth Aug 1, 2022
f21a06e
refactor
zth Aug 1, 2022
44698e4
refactor completion to use new way of recursively digging to the targ…
zth Aug 2, 2022
48b7bec
start refactoring the typed context
zth Aug 2, 2022
295be6b
add another label to the record so we can test prefix etc in a better…
zth Aug 2, 2022
5a2097e
bring back prefix and seen record fields filtering for destructuring …
zth Aug 2, 2022
da23ca8
change test message some
zth Aug 2, 2022
39a35ec
more completion exploration
zth Aug 4, 2022
f9515d1
cleanup and comments on where I'm at right now
zth Aug 4, 2022
a268d24
narrow the places where type based completion is invoked
zth Aug 9, 2022
9f511cd
complete record field destructuring in switch patterns
zth Aug 9, 2022
ef427d2
comment
zth Aug 9, 2022
555110f
wip
zth Aug 10, 2022
cf8b472
more work on nested completion in patterns
zth Aug 10, 2022
3a6a6e5
pick up already seen idents for constructors/record fields
zth Aug 11, 2022
339417c
basic completion of options
zth Aug 11, 2022
928e84e
complete empty | patterns
zth Aug 11, 2022
d134b8b
fix only descending to record field if valid
zth Aug 11, 2022
0d06fc6
more filtering of idents
zth Aug 11, 2022
d2ef230
fix record completion of empty ,
zth Aug 11, 2022
013680e
temp disable local completions + constructor completions in general s…
zth Aug 11, 2022
303eb57
commit test output from last commit
zth Aug 11, 2022
858be8f
handle completing empty patterns in records
zth Aug 11, 2022
d5ced33
complete booleans
zth Aug 11, 2022
1679769
more work, plugging holes etc
zth Aug 13, 2022
f262a50
complete patterns in arguments of fns passed to named arguments
zth Aug 13, 2022
28dddca
rename
zth Aug 14, 2022
8a98793
add debug tool and start setting up spec for typed context completion
zth Aug 15, 2022
5647a1e
start moving to rewrite of finding pattern completable
zth Aug 15, 2022
2c1b721
hook up completion backend with new pattern completion stuff
zth Aug 16, 2022
5d69adb
complete clean up of the old way of doing pattern completion
zth Aug 16, 2022
f061119
simplify
zth Aug 16, 2022
82796f9
complete empty tuples
zth Aug 16, 2022
6a0a884
introduce snippets
zth Aug 16, 2022
f98db04
properly apply command
zth Aug 16, 2022
5558995
implement support for tuple context paths in completion
zth Aug 16, 2022
5320d9e
dump pexp_field
zth Aug 16, 2022
36832cc
add typed expression completion type
zth Aug 17, 2022
eb3eb80
some cleanup and other fixes
zth Aug 17, 2022
859c3fd
track seen record fields when constructing a record
zth Aug 17, 2022
e67f63c
add a few test fixtures where the parser doesnt do quite what I need …
zth Aug 18, 2022
64f4f77
another broken case
zth Aug 20, 2022
40e3ec1
support completing expressions when assigning variables, even if the …
zth Aug 20, 2022
e330b68
pull put var from constraint pattern for now
zth Aug 20, 2022
fc48ca8
more cases
zth Aug 20, 2022
cd2161a
make sure the newest env is always propagated
zth Sep 2, 2022
0522d01
fix issue where Some variants wouldnt be handled properly
zth Sep 7, 2022
16a6f0f
complete inline records
zth Sep 7, 2022
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
72 changes: 71 additions & 1 deletion analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,18 @@ let rec extractRecordType ~env ~package (t : Types.type_expr) =
| _ -> None)
| _ -> None

let rec extractVariantType ~env ~package (t : Types.type_expr) =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably something like that already. Or maybe not.
Anyhow no need to worry about this for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored this into a general one for extracting a type, so the code is slightly more ready for completing more things than just variants.

match t.desc with
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractVariantType ~env ~package t1
| Tconstr (path, _, _) -> (
match References.digConstructor ~env ~package path with
| Some (env, ({item = {kind = Variant constructors}} as typ)) ->
Some (env, constructors, typ)
| Some (env, {item = {decl = {type_manifest = Some t1}}}) ->
extractVariantType ~env ~package t1
| _ -> None)
| _ -> None

let rec extractObjectType ~env ~package (t : Types.type_expr) =
match t.desc with
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractObjectType ~env ~package t1
Expand Down Expand Up @@ -1337,7 +1349,6 @@ let processCompletable ~debug ~package ~scope ~env ~pos ~forHover
in
match completable with
| Cnone -> []
| CtypedContext _contextPath -> []
| Cpath contextPath ->
contextPath
|> getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles ~pos
Expand Down Expand Up @@ -1687,3 +1698,62 @@ Note: The `@react.component` decorator requires the react-jsx config to be set i
Utils.startsWith name prefix
&& (forHover || not (List.mem name identsSeen)))
|> List.map mkLabel
| CtypedContext (cp, typedContext) -> (
match typedContext with
| NamedArg argName -> (
(* TODO: Should probably share this with the branch handling CnamedArg... *)
let labels =
match
cp
|> getCompletionsForContextPath ~package ~opens ~rawOpens ~allFiles
~pos ~env ~exact:true ~scope
|> completionsGetTypeEnv
with
| Some (typ, _env) ->
let rec getLabels ~env (t : Types.type_expr) =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must exist already. Doesn't matter for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it exists in another branch. I think it can be done in a better way, so can refactor that later.

match t.desc with
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> getLabels ~env t1
| Tarrow ((Labelled l | Optional l), tArg, tRet, _) ->
(l, tArg) :: getLabels ~env tRet
| Tarrow (Nolabel, _, tRet, _) -> getLabels ~env tRet
| Tconstr (path, _, _) -> (
match References.digConstructor ~env ~package path with
| Some (env, {item = {decl = {type_manifest = Some t1}}}) ->
getLabels ~env t1
| _ -> [])
| _ -> []
in
typ |> getLabels ~env
| None -> []
in
let targetLabel =
labels |> List.find_opt (fun (name, _t) -> name = argName)
in
match targetLabel with
| None -> []
| Some (_, typeExpr) -> (
match extractVariantType ~env ~package typeExpr with
| None ->
if debug then Printf.printf "Could not extract variant type\n";
[]
| Some (_env, constructors, _typ) ->
if debug then
Printf.printf "Found variant type for NamedArg typed context %s\n"
(typeExpr |> Shared.typeToString);

(* TODO: Account for existing prefix (e.g what the user has already started typing, if anything)?
According to the LS protocol the client can perform that filtering by itself in the simplest cases.
Investigate if doing it ourselves here would be more robust. *)
(* TODO: Investigate completing seen identifiers _with the correct type_ here too. If completing
variant someVariant, and there's a someVariable of type someVariant, add that to the completion list. *)
constructors
|> List.map (fun constructor ->
(* TODO: Can we leverage snippets here for automatically moving the cursor when there are multiple payloads?
Eg. Some($1) as completion item. *)
Completion.create
~name:
(constructor.Constructor.cname.txt
^ if constructor.args |> List.length > 0 then "(_)" else ""
)
~kind:(Constructor (constructor, ""))
~env))))
4 changes: 2 additions & 2 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,12 @@ let findNamedArgCompletable ~(args : arg list) ~endPos ~posBeforeCursor
then Some (Completable.CnamedArg (contextPath, labelled.name, allNames))
else if exp.pexp_loc |> Loc.hasPos ~pos:posBeforeCursor then (
if debug then Printf.printf "found typed context \n";
Some (Completable.CtypedContext contextPath))
Some (Completable.CtypedContext (contextPath, NamedArg labelled.name)))
else if exp.pexp_loc |> Loc.end_ = (Location.none |> Loc.end_) then (
(* Expr assigned presumably is "rescript.exprhole" after parser recovery.
Assume this is an empty expression. *)
if debug then Printf.printf "found typed context \n";
Some (Completable.CtypedContext contextPath))
Some (Completable.CtypedContext (contextPath, NamedArg labelled.name)))
else loop rest
| {label = None; exp} :: rest ->
if exp.pexp_loc |> Loc.hasPos ~pos:posBeforeCursor then None
Expand Down
16 changes: 14 additions & 2 deletions analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,12 @@ module Completable = struct
| CPObj of contextPath * string
| CPPipe of contextPath * string

type typedContext = NamedArg of string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a comment: the argument name of a function type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it a record instead and added comments.


let typedContextToString typedContext =
match typedContext with
| NamedArg argName -> "NamedArg(" ^ argName ^ ")"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a very quick solution just to complete the actual items. I understand this is probably not the right way to do it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just debug printing. Unless the comment refers to the type definition, which is perfectly fine for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was referring to the type def.


type t =
| Cdecorator of string (** e.g. @module *)
| CnamedArg of contextPath * string * string list
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

~prefix with [this, that] seen.
So it would complete a label whose name starts with prefix and excludes labels this and that which have been used already and should not be suggested.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done that now, but I haven't done anything about this/that seen, because I don't think it makes sense in the context of completing a labelled argument? There's nothing else to have been seen already, right?

Expand All @@ -433,7 +439,8 @@ module Completable = struct
| Cpath of contextPath
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you start adding comments to Cpath and contextPath?
There's the question of whether there should be an entirely different case of type t, or whether typed context info should be integrated into the existing ones.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind helping me out with adding comments to those that exist already? I have a hard time parsing what they are/mean.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cpath is for complex expressions

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CPString is for string constants, used in pipe expressions 34 -> ...
CPArray is for arrays used in pipe expressions [] -> ....
CPApply of contextPath * Asttypes.arg_label list is application with a list of labels

CPId of string list * completionContext is for a path A. or A.B.C. and the rhs is the rest to be completed

CPField of contextPath * string is the .z of record access expr.z
CPObj of contextPath * string is the ["hello"] of object access expr["hello"]
CPPipe of contextPath * string is expr->foo where foo is the function whose first argument is expr.

| Cjsx of string list * string * string list
(** E.g. (["M", "Comp"], "id", ["id1", "id2"]) for <M.Comp id1=... id2=... ... id *)
| CtypedContext of contextPath (** WIP, just a dummy arg for now *)
| CtypedContext of contextPath * typedContext
(** A typed context we want to complete, like completing a labelled argument assignment *)

let toString =
let str s = if s = "" then "\"\"" else s in
Expand Down Expand Up @@ -472,5 +479,10 @@ module Completable = struct
| Cnone -> "Cnone"
| Cjsx (sl1, s, sl2) ->
"Cjsx(" ^ (sl1 |> list) ^ ", " ^ str s ^ ", " ^ (sl2 |> list) ^ ")"
| CtypedContext cp -> "CtypedContext(" ^ (cp |> contextPathToString) ^ ")"
| CtypedContext (cp, typedContext) ->
"CtypedContext("
^ (cp |> contextPathToString)
^ ", "
^ (typedContext |> typedContextToString)
^ ")"
end
3 changes: 2 additions & 1 deletion analysis/tests/src/TypeContextCompletion.res
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
type someVariant = One | Two | Three | Four
type someVariant = One | Two | Three | Four | Five(int) | Six(option<string>)

let someVariantToString = (~someVariant) =>
switch someVariant {
| One => "One"
| Two => "Two"
| Three => "Three"
| Four => "Four"
| _ => "-"
}

module SomeComponent = {
Expand Down
2 changes: 1 addition & 1 deletion analysis/tests/src/expected/Dce.res.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
DCE src/Dce.res
issues:241
issues:243

200 changes: 174 additions & 26 deletions analysis/tests/src/expected/TypeContextCompletion.res.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Complete src/TypeContextCompletion.res 17:41
posCursor:[17:41] posNoWhite:[17:40] Found expr:[17:11->17:41]
Pexp_apply ...[17:11->17:30] (~someVaria17:32->17:41=...[17:32->17:41])
Complete src/TypeContextCompletion.res 18:41
posCursor:[18:41] posNoWhite:[18:40] Found expr:[18:11->18:41]
Pexp_apply ...[18:11->18:30] (~someVaria18:32->18:41=...[18:32->18:41])
Completable: CnamedArg(Value[someVariantToString], someVaria, [someVaria])
Found type for function (~someVariant: someVariant) => string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check where this is coming from: presumably named arg completion finding the type of the function.

[{
Expand All @@ -11,36 +11,184 @@ Found type for function (~someVariant: someVariant) => string
"documentation": null
}]

Complete src/TypeContextCompletion.res 20:44
posCursor:[20:44] posNoWhite:[20:43] Found expr:[20:11->20:44]
Pexp_apply ...[20:11->20:30] (~someVariant20:32->20:43=...__ghost__[0:-1->0:-1])
Complete src/TypeContextCompletion.res 21:44
posCursor:[21:44] posNoWhite:[21:43] Found expr:[21:11->21:44]
Pexp_apply ...[21:11->21:30] (~someVariant21:32->21:43=...__ghost__[0:-1->0:-1])
found typed context
Completable: CtypedContext(Value[someVariantToString])
[]
Completable: CtypedContext(Value[someVariantToString], NamedArg(someVariant))
Found variant type for NamedArg typed context someVariant
[{
"label": "One",
"kind": 4,
"tags": [],
"detail": "One\n\n",
"documentation": null
}, {
"label": "Two",
"kind": 4,
"tags": [],
"detail": "Two\n\n",
"documentation": null
}, {
"label": "Three",
"kind": 4,
"tags": [],
"detail": "Three\n\n",
"documentation": null
}, {
"label": "Four",
"kind": 4,
"tags": [],
"detail": "Four\n\n",
"documentation": null
}, {
"label": "Five(_)",
"kind": 4,
"tags": [],
"detail": "Five(int)\n\n",
"documentation": null
}, {
"label": "Six(_)",
"kind": 4,
"tags": [],
"detail": "Six(option<string>)\n\n",
"documentation": null
}]
Comment on lines +20 to +56
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Barring details like the payloads, filtering according to what the user has already typed, whether we should use snippets etc, this at least produces the output we're after - all of the variant constructors.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filtering is the next step. Nothing else need to be done.
Snippets etc we don't have to worry about. Perhaps later.


Complete src/TypeContextCompletion.res 23:45
posCursor:[23:45] posNoWhite:[23:43] Found expr:[23:11->23:44]
Pexp_apply ...[23:11->23:30] (~someVariant23:32->23:43=...__ghost__[0:-1->0:-1])
Complete src/TypeContextCompletion.res 24:45
posCursor:[24:45] posNoWhite:[24:43] Found expr:[24:11->24:44]
Pexp_apply ...[24:11->24:30] (~someVariant24:32->24:43=...__ghost__[0:-1->0:-1])
found typed context
Completable: CtypedContext(Value[someVariantToString])
[]
Completable: CtypedContext(Value[someVariantToString], NamedArg(someVariant))
Found variant type for NamedArg typed context someVariant
[{
"label": "One",
"kind": 4,
"tags": [],
"detail": "One\n\n",
"documentation": null
}, {
"label": "Two",
"kind": 4,
"tags": [],
"detail": "Two\n\n",
"documentation": null
}, {
"label": "Three",
"kind": 4,
"tags": [],
"detail": "Three\n\n",
"documentation": null
}, {
"label": "Four",
"kind": 4,
"tags": [],
"detail": "Four\n\n",
"documentation": null
}, {
"label": "Five(_)",
"kind": 4,
"tags": [],
"detail": "Five(int)\n\n",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's the question of what one would like to show here.
O I get it. Now I understand what "snippets" means. They're the templates for a variant with payloads?
If so then sure why not tackle them next.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, essentially we could return this: Five($1, $2) and the editor would put the cursor on $1 first, and then a tab would put the cursor on $2. This can be quite convenient when autocompleting things like this. For example, later when we do sub expression type aware completion (that's not a proper sentence...), the experience could be quite nice. Something like:

  1. Complete someFn(~somethingOptional=, gives Some($1)
  2. Select that completion, trigger autocomplete again. Get a list of all variant constructors if it's a variant, or all identifiers in scope matching the inner type of somethingOptional, etc

We do need to support both with and without snippets, because I'm unsure if all editors support them. I'll have a look at that later.

Copy link
Collaborator

@cristianoc cristianoc Jul 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know if "sub expression type aware completion" is a proper sentence but is sure sounds cool.
What kind of format does vocode support for these kinds of templates? Does it expect things with dollar signs.
It would be great if there were a way to convey the type too, but don't know what format is possible and one would not like super-long names. But if the names were hoverable, then that would be pretty sweet.

Not sure if you want to go down the rabbit hole now, or move on with other aspects and come back to this later.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can come back later, there's other things snippet syntax would be nice to leverage for too. But yeah, too much of a side track now.

"documentation": null
}, {
"label": "Six(_)",
"kind": 4,
"tags": [],
"detail": "Six(option<string>)\n\n",
"documentation": null
}]

Complete src/TypeContextCompletion.res 26:45
posCursor:[26:45] posNoWhite:[26:44] Found expr:[26:11->26:45]
Pexp_apply ...[26:11->26:30] (~someVariant26:32->26:43=...[26:44->26:45])
Complete src/TypeContextCompletion.res 27:45
posCursor:[27:45] posNoWhite:[27:44] Found expr:[27:11->27:45]
Pexp_apply ...[27:11->27:30] (~someVariant27:32->27:43=...[27:44->27:45])
found typed context
Completable: CtypedContext(Value[someVariantToString])
[]
Completable: CtypedContext(Value[someVariantToString], NamedArg(someVariant))
Found variant type for NamedArg typed context someVariant
[{
"label": "One",
"kind": 4,
"tags": [],
"detail": "One\n\n",
"documentation": null
}, {
"label": "Two",
"kind": 4,
"tags": [],
"detail": "Two\n\n",
"documentation": null
}, {
"label": "Three",
"kind": 4,
"tags": [],
"detail": "Three\n\n",
"documentation": null
}, {
"label": "Four",
"kind": 4,
"tags": [],
"detail": "Four\n\n",
"documentation": null
}, {
"label": "Five(_)",
"kind": 4,
"tags": [],
"detail": "Five(int)\n\n",
"documentation": null
}, {
"label": "Six(_)",
"kind": 4,
"tags": [],
"detail": "Six(option<string>)\n\n",
"documentation": null
}]

Complete src/TypeContextCompletion.res 29:45
posCursor:[29:45] posNoWhite:[29:44] Found expr:[29:11->29:45]
Pexp_apply ...[29:11->29:30] (~someVariant29:32->29:43=...[29:44->29:45])
Complete src/TypeContextCompletion.res 30:45
posCursor:[30:45] posNoWhite:[30:44] Found expr:[30:11->30:45]
Pexp_apply ...[30:11->30:30] (~someVariant30:32->30:43=...[30:44->30:45])
found typed context
Completable: CtypedContext(Value[someVariantToString])
[]
Completable: CtypedContext(Value[someVariantToString], NamedArg(someVariant))
Found variant type for NamedArg typed context someVariant
[{
"label": "One",
"kind": 4,
"tags": [],
"detail": "One\n\n",
"documentation": null
}, {
"label": "Two",
"kind": 4,
"tags": [],
"detail": "Two\n\n",
"documentation": null
}, {
"label": "Three",
"kind": 4,
"tags": [],
"detail": "Three\n\n",
"documentation": null
}, {
"label": "Four",
"kind": 4,
"tags": [],
"detail": "Four\n\n",
"documentation": null
}, {
"label": "Five(_)",
"kind": 4,
"tags": [],
"detail": "Five(int)\n\n",
"documentation": null
}, {
"label": "Six(_)",
"kind": 4,
"tags": [],
"detail": "Six(option<string>)\n\n",
"documentation": null
}]

Complete src/TypeContextCompletion.res 32:37
posCursor:[32:37] posNoWhite:[32:36] Found expr:[32:14->32:37]
JSX <SomeComponent:[32:14->32:27] whatever[32:28->32:36]=...__ghost__[0:-1->0:-1]> _children:None
Complete src/TypeContextCompletion.res 33:37
posCursor:[33:37] posNoWhite:[33:36] Found expr:[33:14->33:37]
JSX <SomeComponent:[33:14->33:27] whatever[33:28->33:36]=...__ghost__[0:-1->0:-1]> _children:None
[]