Skip to content

Commit f759d83

Browse files
committed
include local values and modules in type based completions when there is a prefix to filter on
1 parent 74b65dd commit f759d83

File tree

3 files changed

+125
-91
lines changed

3 files changed

+125
-91
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,68 +1509,80 @@ let rec extractType ~env ~package (t : Types.type_expr) =
15091509
| Ttuple expressions -> Some (Tuple (env, expressions))
15101510
| _ -> None
15111511

1512-
let rec completeTypedValue t ~env ~full ~prefix ~expandOption =
1513-
match t |> extractType ~env ~package:full.package with
1514-
| Some (Toption (env, typ)) when expandOption ->
1515-
typ |> completeTypedValue ~env ~full ~prefix ~expandOption:false
1516-
| Some (Tbool env) ->
1512+
let completeTypedValue ~env ~full ~prefix ~expandOption =
1513+
let namesUsed = Hashtbl.create 10 in
1514+
let rec completeTypedValueInner t ~env ~full ~prefix ~expandOption =
15171515
let items =
1518-
[
1519-
Completion.create ~name:"true"
1520-
~kind:(Label (t |> Shared.typeToString))
1521-
~env;
1522-
Completion.create ~name:"false"
1523-
~kind:(Label (t |> Shared.typeToString))
1524-
~env;
1525-
]
1526-
in
1527-
if prefix = "" then items
1528-
else
1529-
items
1530-
|> List.filter (fun (item : Completion.t) ->
1531-
Utils.startsWith item.name prefix)
1532-
| Some (Tvariant {env; constructors}) ->
1533-
let items =
1534-
constructors
1535-
|> List.filter_map (fun (constructor : Constructor.t) ->
1536-
if
1537-
prefix <> ""
1538-
&& not (Utils.startsWith constructor.cname.txt prefix)
1539-
then None
1540-
else
1541-
Some
1542-
(Completion.create
1543-
~name:
1544-
(constructor.cname.txt
1545-
^
1546-
if constructor.args |> List.length > 0 then
1547-
"("
1548-
^ (constructor.args
1549-
|> List.map (fun _ -> "_")
1550-
|> String.concat ", ")
1551-
^ ")"
1552-
else "")
1553-
~kind:(Constructor (constructor, "" (* TODO *)))
1554-
~env))
1555-
in
1556-
items
1557-
| Some (Toption (env, t)) ->
1558-
let items =
1559-
[
1560-
Completion.create ~name:"None"
1561-
~kind:(Label (t |> Shared.typeToString))
1562-
~env;
1563-
Completion.create ~name:"Some(_)"
1564-
~kind:(Label (t |> Shared.typeToString))
1565-
~env;
1566-
]
1516+
match t |> extractType ~env ~package:full.package with
1517+
| Some (Toption (env, typ)) when expandOption ->
1518+
typ |> completeTypedValueInner ~env ~full ~prefix ~expandOption:false
1519+
| Some (Tbool env) ->
1520+
let items =
1521+
[
1522+
Completion.create ~name:"true"
1523+
~kind:(Label (t |> Shared.typeToString))
1524+
~env;
1525+
Completion.create ~name:"false"
1526+
~kind:(Label (t |> Shared.typeToString))
1527+
~env;
1528+
]
1529+
in
1530+
if prefix = "" then items
1531+
else
1532+
items
1533+
|> List.filter (fun (item : Completion.t) ->
1534+
Utils.startsWith item.name prefix)
1535+
| Some (Tvariant {env; constructors}) ->
1536+
let items =
1537+
constructors
1538+
|> List.filter_map (fun (constructor : Constructor.t) ->
1539+
if
1540+
prefix <> ""
1541+
&& not (Utils.startsWith constructor.cname.txt prefix)
1542+
then None
1543+
else
1544+
Some
1545+
(Completion.create
1546+
~name:
1547+
(constructor.cname.txt
1548+
^
1549+
if constructor.args |> List.length > 0 then
1550+
"("
1551+
^ (constructor.args
1552+
|> List.map (fun _ -> "_")
1553+
|> String.concat ", ")
1554+
^ ")"
1555+
else "")
1556+
~kind:(Constructor (constructor, "" (* TODO *)))
1557+
~env))
1558+
in
1559+
items
1560+
| Some (Toption (env, t)) ->
1561+
let items =
1562+
[
1563+
Completion.create ~name:"None"
1564+
~kind:(Label (t |> Shared.typeToString))
1565+
~env;
1566+
Completion.create ~name:"Some(_)"
1567+
~kind:(Label (t |> Shared.typeToString))
1568+
~env;
1569+
]
1570+
in
1571+
if prefix = "" then items
1572+
else
1573+
items
1574+
|> List.filter (fun (item : Completion.t) ->
1575+
Utils.startsWith item.name prefix)
1576+
| _ -> []
15671577
in
1578+
(* Include all values and modules in completion if there's a prefix, not otherwise *)
15681579
if prefix = "" then items
15691580
else
15701581
items
1571-
|> List.filter (fun (item : Completion.t) ->
1572-
Utils.startsWith item.name prefix)
1573-
| _ -> []
1582+
@ completionForExportedValues ~env ~prefix ~exact:false ~namesUsed
1583+
@ completionForExportedModules ~env ~prefix ~exact:false ~namesUsed
1584+
in
1585+
completeTypedValueInner ~env ~full ~prefix ~expandOption
15741586

15751587
let processCompletable ~debug ~full ~scope ~env ~pos ~forHover
15761588
(completable : Completable.t) =

analysis/tests/src/CompletionFunctionArguments.res

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ let someFn = (~isOn, ~isOff=false, ()) => {
66
}
77
}
88

9+
let tLocalVar = false
10+
911
// let _ = someFn(~isOn=)
1012
// ^com
1113

@@ -30,6 +32,8 @@ let someOtherFn = (includeName, age) => {
3032
// let _ = someOtherFn(f)
3133
// ^com
3234

35+
module OIncludeMeInCompletions = {}
36+
3337
type someVariant = One | Two | Three(int, string)
3438

3539
let someFnTakingVariant = (

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

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
Complete src/CompletionFunctionArguments.res 8:24
2-
posCursor:[8:24] posNoWhite:[8:23] Found expr:[8:11->8:25]
3-
Pexp_apply ...[8:11->8:17] (~isOn8:19->8:23=...__ghost__[0:-1->0:-1])
1+
Complete src/CompletionFunctionArguments.res 10:24
2+
posCursor:[10:24] posNoWhite:[10:23] Found expr:[10:11->10:25]
3+
Pexp_apply ...[10:11->10:17] (~isOn10:19->10:23=...__ghost__[0:-1->0:-1])
44
Completable: Value[someFn](~isOn)
55
[{
66
"label": "true",
@@ -16,21 +16,27 @@ Completable: Value[someFn](~isOn)
1616
"documentation": null
1717
}]
1818

19-
Complete src/CompletionFunctionArguments.res 11:25
20-
posCursor:[11:25] posNoWhite:[11:24] Found expr:[11:11->11:26]
21-
Pexp_apply ...[11:11->11:17] (~isOn11:19->11:23=...[11:24->11:25])
19+
Complete src/CompletionFunctionArguments.res 13:25
20+
posCursor:[13:25] posNoWhite:[13:24] Found expr:[13:11->13:26]
21+
Pexp_apply ...[13:11->13:17] (~isOn13:19->13:23=...[13:24->13:25])
2222
Completable: Value[someFn](~isOn=t)
2323
[{
2424
"label": "true",
2525
"kind": 4,
2626
"tags": [],
2727
"detail": "bool",
2828
"documentation": null
29+
}, {
30+
"label": "tLocalVar",
31+
"kind": 12,
32+
"tags": [],
33+
"detail": "bool",
34+
"documentation": null
2935
}]
3036

31-
Complete src/CompletionFunctionArguments.res 14:25
32-
posCursor:[14:25] posNoWhite:[14:24] Found expr:[14:11->14:26]
33-
Pexp_apply ...[14:11->14:17] (~isOff14:19->14:24=...__ghost__[0:-1->0:-1])
37+
Complete src/CompletionFunctionArguments.res 16:25
38+
posCursor:[16:25] posNoWhite:[16:24] Found expr:[16:11->16:26]
39+
Pexp_apply ...[16:11->16:17] (~isOff16:19->16:24=...__ghost__[0:-1->0:-1])
3440
Completable: Value[someFn](~isOff)
3541
[{
3642
"label": "true",
@@ -46,13 +52,13 @@ Completable: Value[someFn](~isOff)
4652
"documentation": null
4753
}]
4854

49-
Complete src/CompletionFunctionArguments.res 19:27
50-
posCursor:[19:27] posNoWhite:[19:26] Found expr:[17:8->23:1]
51-
Pexp_apply ...[17:8->17:14] (~isOn18:3->18:7=...[19:7->21:8])
52-
posCursor:[19:27] posNoWhite:[19:26] Found expr:[19:7->21:8]
53-
posCursor:[19:27] posNoWhite:[19:26] Found expr:[19:7->19:28]
54-
posCursor:[19:27] posNoWhite:[19:26] Found expr:[19:14->19:28]
55-
Pexp_apply ...[19:14->19:20] (~isOn19:22->19:26=...__ghost__[0:-1->0:-1])
55+
Complete src/CompletionFunctionArguments.res 21:27
56+
posCursor:[21:27] posNoWhite:[21:26] Found expr:[19:8->25:1]
57+
Pexp_apply ...[19:8->19:14] (~isOn20:3->20:7=...[21:7->23:8])
58+
posCursor:[21:27] posNoWhite:[21:26] Found expr:[21:7->23:8]
59+
posCursor:[21:27] posNoWhite:[21:26] Found expr:[21:7->21:28]
60+
posCursor:[21:27] posNoWhite:[21:26] Found expr:[21:14->21:28]
61+
Pexp_apply ...[21:14->21:20] (~isOn21:22->21:26=...__ghost__[0:-1->0:-1])
5662
Completable: Value[someFn](~isOn)
5763
[{
5864
"label": "true",
@@ -68,9 +74,9 @@ Completable: Value[someFn](~isOn)
6874
"documentation": null
6975
}]
7076

71-
Complete src/CompletionFunctionArguments.res 29:24
72-
posCursor:[29:24] posNoWhite:[29:23] Found expr:[29:11->29:25]
73-
Pexp_apply ...[29:11->29:22] (...[29:23->29:24])
77+
Complete src/CompletionFunctionArguments.res 31:24
78+
posCursor:[31:24] posNoWhite:[31:23] Found expr:[31:11->31:25]
79+
Pexp_apply ...[31:11->31:22] (...[31:23->31:24])
7480
Completable: Value[someOtherFn]($0=f)
7581
[{
7682
"label": "false",
@@ -80,9 +86,9 @@ Completable: Value[someOtherFn]($0=f)
8086
"documentation": null
8187
}]
8288

83-
Complete src/CompletionFunctionArguments.res 44:39
84-
posCursor:[44:39] posNoWhite:[44:38] Found expr:[44:11->44:40]
85-
Pexp_apply ...[44:11->44:30] (~config44:32->44:38=...__ghost__[0:-1->0:-1])
89+
Complete src/CompletionFunctionArguments.res 48:39
90+
posCursor:[48:39] posNoWhite:[48:38] Found expr:[48:11->48:40]
91+
Pexp_apply ...[48:11->48:30] (~config48:32->48:38=...__ghost__[0:-1->0:-1])
8692
Completable: Value[someFnTakingVariant](~config)
8793
[{
8894
"label": "One",
@@ -104,21 +110,27 @@ Completable: Value[someFnTakingVariant](~config)
104110
"documentation": null
105111
}]
106112

107-
Complete src/CompletionFunctionArguments.res 47:40
108-
posCursor:[47:40] posNoWhite:[47:39] Found expr:[47:11->47:41]
109-
Pexp_apply ...[47:11->47:30] (~config47:32->47:38=...[47:39->47:40])
113+
Complete src/CompletionFunctionArguments.res 51:40
114+
posCursor:[51:40] posNoWhite:[51:39] Found expr:[51:11->51:41]
115+
Pexp_apply ...[51:11->51:30] (~config51:32->51:38=...[51:39->51:40])
110116
Completable: Value[someFnTakingVariant](~config=O)
111117
[{
112118
"label": "One",
113119
"kind": 4,
114120
"tags": [],
115121
"detail": "One\n\n",
116122
"documentation": null
123+
}, {
124+
"label": "OIncludeMeInCompletions",
125+
"kind": 9,
126+
"tags": [],
127+
"detail": "module",
128+
"documentation": null
117129
}]
118130

119-
Complete src/CompletionFunctionArguments.res 50:32
120-
posCursor:[50:32] posNoWhite:[50:31] Found expr:[50:11->50:33]
121-
Pexp_apply ...[50:11->50:30] (...[50:31->50:32])
131+
Complete src/CompletionFunctionArguments.res 54:32
132+
posCursor:[54:32] posNoWhite:[54:31] Found expr:[54:11->54:33]
133+
Pexp_apply ...[54:11->54:30] (...[54:31->54:32])
122134
Completable: Value[someFnTakingVariant]($0=S)
123135
[{
124136
"label": "Some(_)",
@@ -128,21 +140,27 @@ Completable: Value[someFnTakingVariant]($0=S)
128140
"documentation": null
129141
}]
130142

131-
Complete src/CompletionFunctionArguments.res 53:44
132-
posCursor:[53:44] posNoWhite:[53:43] Found expr:[53:11->53:45]
133-
Pexp_apply ...[53:11->53:30] (~configOpt253:32->53:42=...[53:43->53:44])
143+
Complete src/CompletionFunctionArguments.res 57:44
144+
posCursor:[57:44] posNoWhite:[57:43] Found expr:[57:11->57:45]
145+
Pexp_apply ...[57:11->57:30] (~configOpt257:32->57:42=...[57:43->57:44])
134146
Completable: Value[someFnTakingVariant](~configOpt2=O)
135147
[{
136148
"label": "One",
137149
"kind": 4,
138150
"tags": [],
139151
"detail": "One\n\n",
140152
"documentation": null
153+
}, {
154+
"label": "OIncludeMeInCompletions",
155+
"kind": 9,
156+
"tags": [],
157+
"detail": "module",
158+
"documentation": null
141159
}]
142160

143-
Complete src/CompletionFunctionArguments.res 57:25
144-
posCursor:[57:25] posNoWhite:[57:24] Found expr:[57:11->57:30]
145-
Pexp_apply ...[57:11->57:17] (~isOff57:19->57:24=...[57:27->57:29])
161+
Complete src/CompletionFunctionArguments.res 61:25
162+
posCursor:[61:25] posNoWhite:[61:24] Found expr:[61:11->61:30]
163+
Pexp_apply ...[61:11->61:17] (~isOff61:19->61:24=...[61:27->61:29])
146164
Completable: CnamedArg(Value[someFn], "", [isOff])
147165
Found type for function (~isOn: bool, ~isOff: bool=?, unit) => string
148166
[{

0 commit comments

Comments
 (0)