Skip to content

Commit bbb52dd

Browse files
zthcristianoc
authored andcommitted
support leveraging type annotations when inferring
1 parent f035fbf commit bbb52dd

File tree

4 files changed

+83
-23
lines changed

4 files changed

+83
-23
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,12 @@ let completionsGetTypeEnv = function
604604
| {Completion.kind = Field ({typ}, _); env} :: _ -> Some (typ, env)
605605
| _ -> None
606606

607+
type getCompletionsForContextPathMode = Regular | Pipe
608+
609+
type completionsTypeEnvTyp =
610+
| TypeExpr of Types.type_expr
611+
| ExtractedType of completionType
612+
607613
let completionsGetCompletionType ~full = function
608614
| {Completion.kind = Value typ; env} :: _
609615
| {Completion.kind = ObjLabel typ; env} :: _
@@ -618,9 +624,27 @@ let completionsGetCompletionType ~full = function
618624
| {Completion.kind = ExtractedType (typ, _); env} :: _ -> Some (typ, env)
619625
| _ -> None
620626

621-
type getCompletionsForContextPathMode = Regular | Pipe
627+
let rec completionsGetCompletionType2 ~full ~opens ~rawOpens ~allFiles ~pos
628+
~scope = function
629+
| {Completion.kind = Value typ; env} :: _
630+
| {Completion.kind = ObjLabel typ; env} :: _
631+
| {Completion.kind = Field ({typ}, _); env} :: _ ->
632+
Some (TypeExpr typ, env)
633+
| {Completion.kind = FollowContextPath ctxPath; env} :: _ ->
634+
ctxPath
635+
|> getCompletionsForContextPath ~full ~env ~exact:true ~opens ~rawOpens
636+
~allFiles ~pos ~scope
637+
|> completionsGetCompletionType2 ~full ~opens ~rawOpens ~allFiles ~pos
638+
~scope
639+
| {Completion.kind = Type typ; env} :: _ -> (
640+
match TypeUtils.extractTypeFromResolvedType typ ~env ~full with
641+
| None -> None
642+
| Some extractedType -> Some (ExtractedType extractedType, env))
643+
| {Completion.kind = ExtractedType (typ, _); env} :: _ ->
644+
Some (ExtractedType typ, env)
645+
| _ -> None
622646

623-
let rec completionsGetTypeEnv2 (completions : Completion.t list) ~full ~opens
647+
and completionsGetTypeEnv2 (completions : Completion.t list) ~full ~opens
624648
~rawOpens ~allFiles ~pos ~scope =
625649
match completions with
626650
| {Completion.kind = Value typ; env} :: _ -> Some (typ, env)
@@ -760,29 +784,43 @@ and getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env
760784
|> getCompletionsForPath ~package ~opens ~allFiles ~pos ~exact
761785
~completionContext:Field ~env ~scope
762786
| CPField (cp, fieldName) -> (
763-
match
787+
let completionsForCtxPath =
764788
cp
765789
|> getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env
766790
~exact:true ~scope
767-
|> completionsGetTypeEnv2 ~full ~opens ~rawOpens ~allFiles ~pos ~scope
768-
with
769-
| Some (typ, env) -> (
770-
match typ |> TypeUtils.extractRecordType ~env ~package with
771-
| Some (env, fields, typDecl) ->
772-
fields
773-
|> Utils.filterMap (fun field ->
774-
if Utils.checkName field.fname.txt ~prefix:fieldName ~exact then
775-
Some
776-
(Completion.create field.fname.txt ~env
777-
~docstring:field.docstring ?deprecated:field.deprecated
778-
~kind:
779-
(Completion.Field
780-
( field,
781-
typDecl.item.decl
782-
|> Shared.declToString typDecl.name.txt )))
783-
else None)
784-
| None -> [])
785-
| None -> [])
791+
in
792+
let extracted =
793+
match
794+
completionsForCtxPath
795+
|> completionsGetCompletionType2 ~full ~opens ~rawOpens ~allFiles ~pos
796+
~scope
797+
with
798+
| Some (TypeExpr typ, env) -> (
799+
match typ |> TypeUtils.extractRecordType ~env ~package with
800+
| Some (env, fields, typDecl) ->
801+
Some
802+
( env,
803+
fields,
804+
typDecl.item.decl |> Shared.declToString typDecl.name.txt )
805+
| None -> None)
806+
| Some (ExtractedType typ, env) -> (
807+
match typ with
808+
| Trecord {fields} ->
809+
Some (env, fields, typ |> TypeUtils.extractedTypeToString)
810+
| _ -> None)
811+
| None -> None
812+
in
813+
match extracted with
814+
| None -> []
815+
| Some (env, fields, recordAsString) ->
816+
fields
817+
|> Utils.filterMap (fun field ->
818+
if Utils.checkName field.fname.txt ~prefix:fieldName ~exact then
819+
Some
820+
(Completion.create field.fname.txt ~env
821+
~docstring:field.docstring
822+
~kind:(Completion.Field (field, recordAsString)))
823+
else None))
786824
| CPObj (cp, label) -> (
787825
match
788826
cp

analysis/src/CompletionFrontEnd.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor ~text =
316316
fields |> List.iter (fun (_, p) -> scopePattern ?contextPath p)
317317
| Ppat_array pl -> pl |> List.iter (scopePattern ?contextPath)
318318
| Ppat_or (p1, _) -> scopePattern ?contextPath p1
319-
| Ppat_constraint (p, _) -> scopePattern ?contextPath p
319+
| Ppat_constraint (p, coreType) ->
320+
scopePattern ?contextPath:(TypeUtils.contextPathFromCoreType coreType) p
320321
| Ppat_type _ -> ()
321322
| Ppat_lazy p -> scopePattern ?contextPath p
322323
| Ppat_unpack {txt; loc} ->

analysis/tests/src/CompletionInferValues.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,6 @@ module Div = {
5454

5555
// let _ = <div onMouseEnter={event => { let btn = event->JsxEvent.Mouse.button->Belt.Int.toString->Js.String2.split("/"); btn->ma }} />
5656
// ^com
57+
58+
// let x: someRecord = {name: "Hello", age: 123}; x.
59+
// ^com

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,21 @@ Completable: Cpath Value[btn]->ma <<jsx>>
202202
"documentation": {"kind": "markdown", "value": "\nApplies the function (the second argument) to each item in the array, returning\na new array. The result array does not have to have elements of the same type\nas the input array. See\n[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)\non MDN.\n\n```res example\nJs.Array2.map([12, 4, 8], x => x * x) == [144, 16, 64]\nJs.Array2.map([\"animal\", \"vegetable\", \"mineral\"], Js.String.length) == [6, 9, 7]\n```\n"}
203203
}]
204204

205+
Complete src/CompletionInferValues.res 57:52
206+
posCursor:[57:52] posNoWhite:[57:51] Found expr:[57:50->57:52]
207+
Pexp_field [57:50->57:51] _:[60:0->57:52]
208+
Completable: Cpath Value[x].""
209+
[{
210+
"label": "name",
211+
"kind": 5,
212+
"tags": [],
213+
"detail": "name: string\n\ntype someRecord = {name: string, age: int}",
214+
"documentation": null
215+
}, {
216+
"label": "age",
217+
"kind": 5,
218+
"tags": [],
219+
"detail": "age: int\n\ntype someRecord = {name: string, age: int}",
220+
"documentation": null
221+
}]
222+

0 commit comments

Comments
 (0)