Skip to content

Commit a8cc7ff

Browse files
committed
handle arrays
1 parent d6a67fb commit a8cc7ff

File tree

7 files changed

+157
-13
lines changed

7 files changed

+157
-13
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ let completionsGetCompletionType ~full = function
599599
| _ -> None
600600

601601
let rec getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env
602-
~exact ~scope (contextPath : Completable.contextPath) =
602+
~exact ~scope ?(mode = `Regular) (contextPath : Completable.contextPath) =
603603
let package = full.package in
604604
match contextPath with
605605
| CPString ->
@@ -623,13 +623,37 @@ let rec getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env
623623
(Completion.Value
624624
(Ctype.newconstr (Path.Pident (Ident.create "float")) []));
625625
]
626-
| CPArray ->
626+
| CPArray None ->
627627
[
628628
Completion.create "array" ~env
629629
~kind:
630630
(Completion.Value
631631
(Ctype.newconstr (Path.Pident (Ident.create "array")) []));
632632
]
633+
| CPArray (Some cp) -> (
634+
match mode with
635+
| `Regular -> (
636+
match
637+
cp
638+
|> getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos
639+
~env ~exact:true ~scope
640+
|> completionsGetCompletionType ~full
641+
with
642+
| None -> []
643+
| Some (typ, env) ->
644+
[
645+
Completion.create "dummy" ~env
646+
~kind:(Completion.ExtractedType (Tarray (env, typ), `Type));
647+
])
648+
| `Pipe ->
649+
(* Pipe completion with array just needs to know that it's an array, not
650+
what inner type it has. *)
651+
[
652+
Completion.create "array" ~env
653+
~kind:
654+
(Completion.Value
655+
(Ctype.newconstr (Path.Pident (Ident.create "array")) []));
656+
])
633657
| CPOption cp -> (
634658
match
635659
cp
@@ -748,7 +772,7 @@ let rec getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env
748772
match
749773
cp
750774
|> getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env
751-
~exact:true ~scope
775+
~exact:true ~scope ~mode:`Pipe
752776
|> completionsGetTypeEnv
753777
with
754778
| None -> []

analysis/src/CompletionFrontEnd.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ let rec exprToContextPath (e : Parsetree.expression) =
141141
| Pexp_constant (Pconst_string _) -> Some Completable.CPString
142142
| Pexp_constant (Pconst_integer _) -> Some CPInt
143143
| Pexp_constant (Pconst_float _) -> Some CPFloat
144-
| Pexp_array _ -> Some CPArray
144+
| Pexp_array exprs ->
145+
Some
146+
(CPArray
147+
(match exprs with
148+
| [] -> None
149+
| exp :: _ -> exprToContextPath exp))
145150
| Pexp_ident {txt} -> Some (CPId (Utils.flattenLongIdent txt, Value))
146151
| Pexp_field (e1, {txt = Lident name}) -> (
147152
match exprToContextPath e1 with

analysis/src/SharedTypes.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ module Completable = struct
586586

587587
type contextPath =
588588
| CPString
589-
| CPArray
589+
| CPArray of contextPath option
590590
| CPInt
591591
| CPFloat
592592
| CPOption of contextPath
@@ -673,7 +673,8 @@ module Completable = struct
673673
| Optional s -> "?" ^ s)
674674
|> String.concat ", ")
675675
^ ")"
676-
| CPArray -> "array"
676+
| CPArray (Some ctxPath) -> "array<" ^ contextPathToString ctxPath ^ ">"
677+
| CPArray None -> "array"
677678
| CPId (sl, completionContext) ->
678679
completionContextToString completionContext ^ list sl
679680
| CPField (cp, s) -> contextPathToString cp ^ "." ^ str s

analysis/src/TypeUtils.ml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ let rec contextPathFromCoreType (coreType : Parsetree.core_type) =
384384
| Ptyp_constr ({txt = Lident "option"}, [innerTyp]) ->
385385
innerTyp |> contextPathFromCoreType
386386
|> Option.map (fun innerTyp -> Completable.CPOption innerTyp)
387+
| Ptyp_constr ({txt = Lident "array"}, [innerTyp]) ->
388+
Some (Completable.CPArray (innerTyp |> contextPathFromCoreType))
387389
| Ptyp_constr (lid, _) ->
388390
Some (CPId (lid.txt |> Utils.flattenLongIdent, Type))
389391
| _ -> None
@@ -398,20 +400,26 @@ let printRecordFromFields ?name (fields : field list) =
398400
|> String.concat ", ")
399401
^ "}"
400402

401-
let rec extractedTypeToString = function
403+
let rec extractedTypeToString ?(inner = false) = function
402404
| Tuple (_, _, typ)
403405
| Tpolyvariant {typeExpr = typ}
404406
| Tfunction {typ}
405407
| Trecord {definition = `TypeExpr typ} ->
406-
Shared.typeToString typ
408+
if inner then
409+
match pathFromTypeExpr typ with
410+
| None -> "record" (* Won't happen *)
411+
| Some p -> p |> SharedTypes.pathIdentToString
412+
else Shared.typeToString typ
407413
| Tbool _ -> "bool"
408414
| Tstring _ -> "string"
409-
| Tarray (_, innerTyp) -> "array<" ^ extractedTypeToString innerTyp ^ ">"
410-
| Toption (_, innerTyp) -> "option<" ^ extractedTypeToString innerTyp ^ ">"
415+
| Tarray (_, innerTyp) ->
416+
"array<" ^ extractedTypeToString ~inner:true innerTyp ^ ">"
417+
| Toption (_, innerTyp) ->
418+
"option<" ^ extractedTypeToString ~inner:true innerTyp ^ ">"
411419
| Tvariant {variantDecl; variantName} ->
412-
Shared.declToString variantName variantDecl
420+
if inner then variantName else Shared.declToString variantName variantDecl
413421
| Trecord {definition = `NameOnly name; fields} ->
414-
printRecordFromFields ~name fields
422+
if inner then name else printRecordFromFields ~name fields
415423
| TinlineRecord {fields} -> printRecordFromFields fields
416424

417425
let unwrapCompletionTypeIfOption (t : SharedTypes.completionType) =

analysis/tests/src/CompletionTypeAnnotation.res

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,18 @@ type someTuple = (bool, option<bool>)
4040

4141
// let x: option<someVariant> =
4242
// ^com
43+
44+
// let x: option<someVariant> = Some()
45+
// ^com
46+
47+
// let x: array<someVariant> =
48+
// ^com
49+
50+
// let x: array<someVariant> = []
51+
// ^com
52+
53+
// let x: array<option<someVariant>> =
54+
// ^com
55+
56+
// let x: option<array<someVariant>> = Some([])
57+
// ^com

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ Found type for function (~age: int, ~name: string) => string
379379

380380
Complete src/Completion.res 26:13
381381
posCursor:[26:13] posNoWhite:[26:12] Found expr:[26:3->26:13]
382-
Completable: Cpath array->m
382+
Completable: Cpath array<int>->m
383383
[{
384384
"label": "Js.Array2.mapi",
385385
"kind": 12,

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,94 @@ Completable: Cexpression option<Type[someVariant]>
203203
"insertTextFormat": 2
204204
}]
205205

206+
Complete src/CompletionTypeAnnotation.res 43:37
207+
XXX Not found!
208+
Completable: Cexpression option<Type[someVariant]>->variantPayload::Some($0)
209+
[{
210+
"label": "One",
211+
"kind": 4,
212+
"tags": [],
213+
"detail": "One\n\ntype someVariant = One | Two(bool)",
214+
"documentation": null,
215+
"insertText": "One",
216+
"insertTextFormat": 2
217+
}, {
218+
"label": "Two(_)",
219+
"kind": 4,
220+
"tags": [],
221+
"detail": "Two(bool)\n\ntype someVariant = One | Two(bool)",
222+
"documentation": null,
223+
"insertText": "Two(${1:_})",
224+
"insertTextFormat": 2
225+
}]
226+
227+
Complete src/CompletionTypeAnnotation.res 46:30
228+
XXX Not found!
229+
Completable: Cexpression array<Type[someVariant]>
230+
[{
231+
"label": "[]",
232+
"kind": 12,
233+
"tags": [],
234+
"detail": "type someVariant = One | Two(bool)",
235+
"documentation": null,
236+
"sortText": "A",
237+
"insertText": "[$0]",
238+
"insertTextFormat": 2
239+
}]
240+
241+
Complete src/CompletionTypeAnnotation.res 49:32
242+
XXX Not found!
243+
Completable: Cexpression array<Type[someVariant]>->array
244+
[{
245+
"label": "One",
246+
"kind": 4,
247+
"tags": [],
248+
"detail": "One\n\ntype someVariant = One | Two(bool)",
249+
"documentation": null,
250+
"insertText": "One",
251+
"insertTextFormat": 2
252+
}, {
253+
"label": "Two(_)",
254+
"kind": 4,
255+
"tags": [],
256+
"detail": "Two(bool)\n\ntype someVariant = One | Two(bool)",
257+
"documentation": null,
258+
"insertText": "Two(${1:_})",
259+
"insertTextFormat": 2
260+
}]
261+
262+
Complete src/CompletionTypeAnnotation.res 52:38
263+
XXX Not found!
264+
Completable: Cexpression array<option<Type[someVariant]>>
265+
[{
266+
"label": "[]",
267+
"kind": 12,
268+
"tags": [],
269+
"detail": "option<someVariant>",
270+
"documentation": null,
271+
"sortText": "A",
272+
"insertText": "[$0]",
273+
"insertTextFormat": 2
274+
}]
275+
276+
Complete src/CompletionTypeAnnotation.res 55:45
277+
XXX Not found!
278+
Completable: Cexpression option<array<Type[someVariant]>>->variantPayload::Some($0), array
279+
[{
280+
"label": "One",
281+
"kind": 4,
282+
"tags": [],
283+
"detail": "One\n\ntype someVariant = One | Two(bool)",
284+
"documentation": null,
285+
"insertText": "One",
286+
"insertTextFormat": 2
287+
}, {
288+
"label": "Two(_)",
289+
"kind": 4,
290+
"tags": [],
291+
"detail": "Two(bool)\n\ntype someVariant = One | Two(bool)",
292+
"documentation": null,
293+
"insertText": "Two(${1:_})",
294+
"insertTextFormat": 2
295+
}]
296+

0 commit comments

Comments
 (0)