Skip to content

Commit e380c48

Browse files
committed
add utils for extracting relevant completion information from type expr
1 parent b17f61d commit e380c48

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

analysis/src/CompletionBackEnd.ml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,54 @@ let getArgs ~env (t : Types.type_expr) ~full =
14831483
in
14841484
t |> getArgsLoop ~env ~full ~currentArgumentPosition:0
14851485

1486+
type extractedType =
1487+
| Declared of QueryEnv.t * Type.t Declared.t
1488+
| Polyvariant of QueryEnv.t * SharedTypes.polyVariantConstructor list
1489+
| Tuple of QueryEnv.t * Types.type_expr list
1490+
| Toption of QueryEnv.t * Types.type_expr
1491+
| Tbool of QueryEnv.t
1492+
1493+
(* This is a more general extraction function for pulling out the type of a type_expr. We already have other similar functions, but they are all specialized on something (variants, records, etc). *)
1494+
let rec extractType ~env ~package (t : Types.type_expr) =
1495+
match t.desc with
1496+
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> extractType ~env ~package t1
1497+
| Tconstr (Path.Pident {name = "option"}, [payloadTypeExpr], _) ->
1498+
(* Handle option. TODO: Look up how the compiler does this and copy that behavior. *)
1499+
Some (Toption (env, payloadTypeExpr))
1500+
| Tconstr (Path.Pident {name = "bool"}, [], _) ->
1501+
(* Handle bool. TODO: Look up how the compiler does this and copy that behavior. *)
1502+
Some (Tbool env)
1503+
| Tconstr (path, _, _) -> (
1504+
match References.digConstructor ~env ~package path with
1505+
| Some (env, {item = {decl = {type_manifest = Some t1}}}) ->
1506+
extractType ~env ~package t1
1507+
| Some (env, typ) -> Some (Declared (env, typ))
1508+
| None -> None)
1509+
| Tvariant {row_fields} ->
1510+
(* Since polyvariants are strutural, they're "inlined". So, we extract just
1511+
what we need for completion from that definition here. *)
1512+
let constructors =
1513+
row_fields
1514+
|> List.map (fun (label, field) ->
1515+
{
1516+
name = label;
1517+
payload =
1518+
(match field with
1519+
| Types.Rpresent maybeTypeExpr -> maybeTypeExpr
1520+
| _ -> None);
1521+
args =
1522+
(* Multiple arguments are represented as a Ttuple, while a single argument is just the type expression itself. *)
1523+
(match field with
1524+
| Types.Rpresent (Some typeExpr) -> (
1525+
match typeExpr.desc with
1526+
| Ttuple args -> args
1527+
| _ -> [typeExpr])
1528+
| _ -> []);
1529+
})
1530+
in
1531+
Some (Polyvariant (env, constructors))
1532+
| Ttuple expressions -> Some (Tuple (env, expressions))
1533+
| _ -> None
14861534
let processCompletable ~debug ~full ~scope ~env ~pos ~forHover
14871535
(completable : Completable.t) =
14881536
let package = full.package in

analysis/src/SharedTypes.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,12 @@ let locItemToString {loc = {Location.loc_start; loc_end}; locType} =
498498
(* needed for debugging *)
499499
let _ = locItemToString
500500

501+
type polyVariantConstructor = {
502+
name: string;
503+
payload: Types.type_expr option;
504+
args: Types.type_expr list;
505+
}
506+
501507
module Completable = struct
502508
(* Completion context *)
503509
type completionContext = Type | Value | Module | Field

0 commit comments

Comments
 (0)