Skip to content

Commit c8ece7c

Browse files
committed
handle polyvariants
1 parent 00a1c75 commit c8ece7c

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,18 @@ let rec resolveNestedPattern typ ~env ~package ~nested =
17841784
match List.nth_opt constructor.args payloadNum with
17851785
| None -> None
17861786
| Some (typ, _) -> typ |> resolveNestedPattern ~env ~package ~nested))
1787+
| ( PPolyvariantPayload {constructorName; payloadNum},
1788+
Some (Tpolyvariant {env; constructors}) ) -> (
1789+
match
1790+
constructors
1791+
|> List.find_opt (fun (c : polyVariantConstructor) ->
1792+
c.name = constructorName)
1793+
with
1794+
| None -> None
1795+
| Some constructor -> (
1796+
match List.nth_opt constructor.args payloadNum with
1797+
| None -> None
1798+
| Some typ -> typ |> resolveNestedPattern ~env ~package ~nested))
17871799
| _ -> None)
17881800

17891801
let processCompletable ~debug ~full ~scope ~env ~pos ~forHover

analysis/src/CompletionFrontEnd.ml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
509509
| Ppat_var {txt} -> commitFoundPat ~prefix:txt ()
510510
| Ppat_construct ({txt = Lident prefix}, None) ->
511511
commitFoundPat ~prefix ()
512+
| Ppat_variant (prefix, None) -> commitFoundPat ~prefix:("#" ^ prefix) ()
512513
| Ppat_tuple patterns -> (
513514
match patterns |> findPatTupleItemWithCursor ~pos:posBeforeCursor with
514515
| Some itemNum -> appendNestedPat (Completable.PTupleItem {itemNum})
@@ -604,6 +605,45 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
604605
appendNestedPat
605606
(Completable.PVariantPayload
606607
{constructorName = getUnqualifiedName txt; payloadNum}))
608+
| Ppat_variant
609+
( txt,
610+
Some {ppat_loc; ppat_desc = Ppat_construct ({txt = Lident "()"}, _)}
611+
)
612+
when ppat_loc
613+
|> CursorPosition.classifyLoc ~pos:posBeforeCursor
614+
= HasCursor ->
615+
(* Empty payload *)
616+
appendNestedPat
617+
(Completable.PPolyvariantPayload
618+
{constructorName = txt; payloadNum = 0});
619+
commitFoundPat ~prefix:"" ()
620+
| Ppat_variant
621+
( txt,
622+
Some
623+
{
624+
ppat_loc;
625+
ppat_desc =
626+
Ppat_var _ | Ppat_record _ | Ppat_construct _ | Ppat_variant _;
627+
} )
628+
when ppat_loc
629+
|> CursorPosition.classifyLoc ~pos:posBeforeCursor
630+
= HasCursor ->
631+
(* Single payload *)
632+
appendNestedPat
633+
(Completable.PPolyvariantPayload
634+
{constructorName = txt; payloadNum = 0})
635+
| Ppat_variant (txt, Some {ppat_loc; ppat_desc = Ppat_tuple tupleItems})
636+
when ppat_loc
637+
|> CursorPosition.classifyLoc ~pos:posBeforeCursor
638+
= HasCursor -> (
639+
(* Multiple payloads with cursor in item *)
640+
(* TODO: New item with comma *)
641+
match tupleItems |> findPatTupleItemWithCursor ~pos:posBeforeCursor with
642+
| None -> ()
643+
| Some payloadNum ->
644+
appendNestedPat
645+
(Completable.PPolyvariantPayload {constructorName = txt; payloadNum})
646+
)
607647
| _ -> ()
608648
in
609649
let case (iterator : Ast_iterator.iterator) (case : Parsetree.case) =

analysis/src/SharedTypes.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ module Completable = struct
558558
| PFollowRecordField of {fieldName: string}
559559
| PRecordBody of {seenFields: string list}
560560
| PVariantPayload of {constructorName: string; payloadNum: int}
561+
| PPolyvariantPayload of {constructorName: string; payloadNum: int}
561562

562563
let patternPathToString p =
563564
match p with
@@ -567,6 +568,9 @@ module Completable = struct
567568
| PVariantPayload {constructorName; payloadNum} ->
568569
"variantPayload::" ^ constructorName ^ "($" ^ string_of_int payloadNum
569570
^ ")"
571+
| PPolyvariantPayload {constructorName; payloadNum} ->
572+
"polyvariantPayload::" ^ constructorName ^ "($" ^ string_of_int payloadNum
573+
^ ")"
570574

571575
type t =
572576
| Cdecorator of string (** e.g. @module *)

analysis/tests/src/CompletionPattern.res

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,16 @@ ignore(z)
9292

9393
// switch z { | Three({})}
9494
// ^com
95+
96+
type somePolyVariant = [#one | #two(bool) | #three(someRecord, bool)]
97+
let b: somePolyVariant = #two(true)
98+
ignore(b)
99+
100+
// switch b { | #two()}
101+
// ^com
102+
103+
// switch b { | #two(t)}
104+
// ^com
105+
106+
// switch b { | #three({})}
107+
// ^com

analysis/tests/src/expected/CompletionPattern.res.txt

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,69 @@ Completable: Cpattern Value[z]->variantPayload::Three($0), recordBody
324324
"documentation": null
325325
}]
326326

327+
Complete src/CompletionPattern.res 99:21
328+
looking for: Cpath Value[b]
329+
posCursor:[99:21] posNoWhite:[99:20] Found expr:[99:3->99:23]
330+
posCursor:[99:21] posNoWhite:[99:20] Found pattern:[99:16->99:22]
331+
posCursor:[99:21] posNoWhite:[99:20] Found pattern:[99:20->99:21]
332+
Completable: Cpattern Value[b]->polyvariantPayload::two($0)
333+
[{
334+
"label": "true",
335+
"kind": 4,
336+
"tags": [],
337+
"detail": "bool",
338+
"documentation": null
339+
}, {
340+
"label": "false",
341+
"kind": 4,
342+
"tags": [],
343+
"detail": "bool",
344+
"documentation": null
345+
}]
346+
347+
Complete src/CompletionPattern.res 102:22
348+
looking for: Cpath Value[b]
349+
posCursor:[102:22] posNoWhite:[102:21] Found expr:[102:3->102:24]
350+
posCursor:[102:22] posNoWhite:[102:21] Found pattern:[102:16->102:23]
351+
posCursor:[102:22] posNoWhite:[102:21] Found pattern:[102:21->102:22]
352+
Completable: Cpattern Value[b]=t->polyvariantPayload::two($0)
353+
[{
354+
"label": "true",
355+
"kind": 4,
356+
"tags": [],
357+
"detail": "bool",
358+
"documentation": null
359+
}]
360+
361+
Complete src/CompletionPattern.res 105:24
362+
looking for: Cpath Value[b]
363+
posCursor:[105:24] posNoWhite:[105:23] Found expr:[105:3->105:27]
364+
posCursor:[105:24] posNoWhite:[105:23] Found pattern:[105:16->105:26]
365+
posCursor:[105:24] posNoWhite:[105:23] Found pattern:[105:23->105:25]
366+
Completable: Cpattern Value[b]->polyvariantPayload::three($0), recordBody
367+
[{
368+
"label": "first",
369+
"kind": 5,
370+
"tags": [],
371+
"detail": "first: int\n\nsomeRecord",
372+
"documentation": null
373+
}, {
374+
"label": "second",
375+
"kind": 5,
376+
"tags": [],
377+
"detail": "second: (bool, option<someRecord>)\n\nsomeRecord",
378+
"documentation": null
379+
}, {
380+
"label": "optThird",
381+
"kind": 5,
382+
"tags": [],
383+
"detail": "optThird: option<[#second(someRecord) | #first]>\n\nsomeRecord",
384+
"documentation": null
385+
}, {
386+
"label": "nest",
387+
"kind": 5,
388+
"tags": [],
389+
"detail": "nest: nestedRecord\n\nsomeRecord",
390+
"documentation": null
391+
}]
392+

0 commit comments

Comments
 (0)