Skip to content

Commit 51e1e77

Browse files
committed
complete polyvariants
1 parent b4ffaa3 commit 51e1e77

File tree

6 files changed

+144
-3
lines changed

6 files changed

+144
-3
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,14 @@ let detail name (kind : Completion.kind) =
711711
| FileModule _ -> "file module"
712712
| Field ({typ}, s) -> name ^ ": " ^ (typ |> Shared.typeToString) ^ "\n\n" ^ s
713713
| Constructor (c, s) -> showConstructor c ^ "\n\n" ^ s
714+
| PolyvariantConstructor ({name; payload}, s) ->
715+
"#" ^ name
716+
^ (match payload with
717+
| None -> ""
718+
| Some ({desc = Types.Ttuple _} as typeExpr) ->
719+
typeExpr |> Shared.typeToString
720+
| Some typeExpr -> "(" ^ (typeExpr |> Shared.typeToString) ^ ")")
721+
^ "\n\n" ^ s
714722

715723
let findAllCompletions ~(env : QueryEnv.t) ~prefix ~exact ~namesUsed
716724
~(completionContext : Completable.completionContext) =
@@ -1519,6 +1527,27 @@ let rec extractType ~env ~package (t : Types.type_expr) =
15191527
{env; constructors; variantName = name.txt; variantDecl = decl})
15201528
| _ -> None)
15211529
| Ttuple expressions -> Some (Tuple (env, expressions, t))
1530+
| Tvariant {row_fields} ->
1531+
let constructors =
1532+
row_fields
1533+
|> List.map (fun (label, field) ->
1534+
{
1535+
name = label;
1536+
payload =
1537+
(match field with
1538+
| Types.Rpresent maybeTypeExpr -> maybeTypeExpr
1539+
| _ -> None);
1540+
args =
1541+
(* Multiple arguments are represented as a Ttuple, while a single argument is just the type expression itself. *)
1542+
(match field with
1543+
| Types.Rpresent (Some typeExpr) -> (
1544+
match typeExpr.desc with
1545+
| Ttuple args -> args
1546+
| _ -> [typeExpr])
1547+
| _ -> []);
1548+
})
1549+
in
1550+
Some (Tpolyvariant {env; constructors; typeExpr = t})
15221551
| _ -> None
15231552

15241553
let filterItems items ~prefix =
@@ -1575,6 +1604,26 @@ let completeTypedValue ~env ~envWhereCompletionStarted ~full ~prefix
15751604
variantDecl |> Shared.declToString variantName ))
15761605
~env ())
15771606
|> filterItems ~prefix
1607+
| Some (Tpolyvariant {env; constructors; typeExpr}) ->
1608+
constructors
1609+
|> List.map (fun (constructor : polyVariantConstructor) ->
1610+
Completion.createWithSnippet
1611+
~name:
1612+
("#" ^ constructor.name
1613+
^ printConstructorArgs
1614+
(List.length constructor.args)
1615+
~asSnippet:false)
1616+
~insertText:
1617+
((if Utils.startsWith prefix "#" then "" else "#")
1618+
^ constructor.name
1619+
^ printConstructorArgs
1620+
(List.length constructor.args)
1621+
~asSnippet:true)
1622+
~kind:
1623+
(PolyvariantConstructor
1624+
(constructor, typeExpr |> Shared.typeToString))
1625+
~env ())
1626+
|> filterItems ~prefix
15781627
| Some (Toption (env, t)) ->
15791628
[
15801629
Completion.create ~name:"None"

analysis/src/CompletionFrontEnd.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ let extractCompletableArgValueInfo exp =
1111
match exp.Parsetree.pexp_desc with
1212
| Pexp_ident {txt = Lident txt} -> Some txt
1313
| Pexp_construct ({txt = Lident "()"}, _) -> Some ""
14-
| Pexp_construct ({txt = Lident txt}, _) -> Some txt
14+
| Pexp_construct ({txt = Lident txt}, None) -> Some txt
15+
| Pexp_variant (label, None) -> Some ("#" ^ label)
1516
| _ -> None
1617

1718
let isExprHole exp =

analysis/src/SharedTypes.ml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,12 @@ end = struct
279279
{env with exported = structure.exported; pathRev; parent = Some env}
280280
end
281281

282+
type polyVariantConstructor = {
283+
name: string;
284+
payload: Types.type_expr option;
285+
args: Types.type_expr list;
286+
}
287+
282288
module Completion = struct
283289
type kind =
284290
| Module of Module.t
@@ -287,6 +293,7 @@ module Completion = struct
287293
| Label of string
288294
| Type of Type.t
289295
| Constructor of Constructor.t * string
296+
| PolyvariantConstructor of polyVariantConstructor * string
290297
| Field of field * string
291298
| FileModule of string
292299

@@ -331,7 +338,7 @@ module Completion = struct
331338
match kind with
332339
| Module _ -> 9
333340
| FileModule _ -> 9
334-
| Constructor (_, _) -> 4
341+
| Constructor (_, _) | PolyvariantConstructor (_, _) -> 4
335342
| ObjLabel _ -> 4
336343
| Label _ -> 4
337344
| Field (_, _) -> 5
@@ -578,6 +585,11 @@ module Completable = struct
578585
variantDecl: Types.type_declaration;
579586
variantName: string;
580587
}
588+
| Tpolyvariant of {
589+
env: QueryEnv.t;
590+
constructors: polyVariantConstructor list;
591+
typeExpr: Types.type_expr;
592+
}
581593

582594
let toString =
583595
let completionContextToString = function

analysis/tests/src/CompletionJsxProps.res

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@
77
// let _ = <CompletionSupport.TestComponent test=T
88
// ^com
99

10+
// let _ = <CompletionSupport.TestComponent polyArg=
11+
// ^com
12+
13+
// let _ = <CompletionSupport.TestComponent polyArg=#t
14+
// ^com
15+

analysis/tests/src/CompletionSupport.res

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ type testVariant = One | Two | Three(int)
99

1010
module TestComponent = {
1111
@react.component
12-
let make = (~on: bool, ~test: testVariant) => {
12+
let make = (
13+
~on: bool,
14+
~test: testVariant,
15+
~polyArg: option<[#one | #two | #two2 | #three(int, bool)]>=?,
16+
) => {
1317
ignore(on)
1418
ignore(test)
19+
ignore(polyArg)
1520
React.null
1621
}
1722
}

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,71 @@ Completable: CjsxPropValue [CompletionSupport, TestComponent] test=T
5050
"insertTextFormat": 2
5151
}]
5252

53+
Complete src/CompletionJsxProps.res 9:52
54+
posCursor:[9:52] posNoWhite:[9:51] Found expr:[9:12->9:52]
55+
JSX <CompletionSupport.TestComponent:[9:12->9:43] polyArg[9:44->9:51]=...__ghost__[0:-1->0:-1]> _children:None
56+
Completable: CjsxPropValue [CompletionSupport, TestComponent] polyArg=
57+
[{
58+
"label": "#one",
59+
"kind": 4,
60+
"tags": [],
61+
"detail": "#one\n\n[#one | #three(int, bool) | #two | #two2]",
62+
"documentation": null,
63+
"insertText": "#one",
64+
"insertTextFormat": 2
65+
}, {
66+
"label": "#three(_, _)",
67+
"kind": 4,
68+
"tags": [],
69+
"detail": "#three(int, bool)\n\n[#one | #three(int, bool) | #two | #two2]",
70+
"documentation": null,
71+
"insertText": "#three(${1:_}, ${2:_})",
72+
"insertTextFormat": 2
73+
}, {
74+
"label": "#two",
75+
"kind": 4,
76+
"tags": [],
77+
"detail": "#two\n\n[#one | #three(int, bool) | #two | #two2]",
78+
"documentation": null,
79+
"insertText": "#two",
80+
"insertTextFormat": 2
81+
}, {
82+
"label": "#two2",
83+
"kind": 4,
84+
"tags": [],
85+
"detail": "#two2\n\n[#one | #three(int, bool) | #two | #two2]",
86+
"documentation": null,
87+
"insertText": "#two2",
88+
"insertTextFormat": 2
89+
}]
90+
91+
Complete src/CompletionJsxProps.res 12:54
92+
posCursor:[12:54] posNoWhite:[12:53] Found expr:[12:12->12:54]
93+
JSX <CompletionSupport.TestComponent:[12:12->12:43] polyArg[12:44->12:51]=...[12:52->12:54]> _children:None
94+
Completable: CjsxPropValue [CompletionSupport, TestComponent] polyArg=#t
95+
[{
96+
"label": "#three(_, _)",
97+
"kind": 4,
98+
"tags": [],
99+
"detail": "#three(int, bool)\n\n[#one | #three(int, bool) | #two | #two2]",
100+
"documentation": null,
101+
"insertText": "three(${1:_}, ${2:_})",
102+
"insertTextFormat": 2
103+
}, {
104+
"label": "#two",
105+
"kind": 4,
106+
"tags": [],
107+
"detail": "#two\n\n[#one | #three(int, bool) | #two | #two2]",
108+
"documentation": null,
109+
"insertText": "two",
110+
"insertTextFormat": 2
111+
}, {
112+
"label": "#two2",
113+
"kind": 4,
114+
"tags": [],
115+
"detail": "#two2\n\n[#one | #three(int, bool) | #two | #two2]",
116+
"documentation": null,
117+
"insertText": "two2",
118+
"insertTextFormat": 2
119+
}]
120+

0 commit comments

Comments
 (0)