@@ -510,7 +510,7 @@ let getComplementaryCompletionsForTypedValue ~opens ~allFiles ~scope ~env prefix
510
510
in
511
511
localCompletionsWithOpens @ fileModules
512
512
513
- let getCompletionsForPath ~debug ~package ~ opens ~full ~pos ~exact ~scope
513
+ let getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~scope
514
514
~completionContext ~env path =
515
515
if debug then Printf. printf " Path %s\n " (path |> String. concat " ." );
516
516
let allFiles = allFilesInPackage full.package in
@@ -537,13 +537,33 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
537
537
localCompletionsWithOpens @ fileModules
538
538
| moduleName :: path -> (
539
539
Log. log (" Path " ^ pathToString path);
540
- match getEnvWithOpens ~scope ~env ~package ~opens ~module Name path with
540
+ match
541
+ getEnvWithOpens ~scope ~env ~package: full.package ~opens ~module Name path
542
+ with
541
543
| Some (env , prefix ) ->
542
544
Log. log " Got the env" ;
543
545
let namesUsed = Hashtbl. create 10 in
544
546
findAllCompletions ~env ~prefix ~exact ~names Used ~completion Context
545
547
| None -> [] )
546
548
549
+ let rec digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
550
+ ~scope path =
551
+ match
552
+ path
553
+ |> getCompletionsForPath ~debug ~completion Context:Type ~exact: true ~opens
554
+ ~full ~pos ~env ~scope
555
+ with
556
+ | {kind = Type {kind = Abstract (Some (p , _ ))} } :: _ ->
557
+ (* This case happens when what we're looking for is a type alias.
558
+ This is the case in newer rescript-react versions where
559
+ ReactDOM.domProps is an alias for JsxEvent.t. *)
560
+ let pathRev = p |> Utils. expandPath in
561
+ pathRev |> List. rev
562
+ |> digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
563
+ ~scope
564
+ | {kind = Type {kind = Record fields } } :: _ -> Some fields
565
+ | _ -> None
566
+
547
567
let mkItem ~name ~kind ~detail ~deprecated ~docstring =
548
568
let docContent =
549
569
(match deprecated with
@@ -567,7 +587,7 @@ let mkItem ~name ~kind ~detail ~deprecated ~docstring =
567
587
detail;
568
588
documentation =
569
589
(if docContent = " " then None
570
- else Some {kind = " markdown" ; value = docContent});
590
+ else Some {kind = " markdown" ; value = docContent});
571
591
sortText = None ;
572
592
insertText = None ;
573
593
insertTextFormat = None ;
@@ -747,8 +767,8 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
747
767
| _ -> [] )
748
768
| CPId (path , completionContext ) ->
749
769
path
750
- |> getCompletionsForPath ~debug ~package ~ opens ~full ~pos ~exact
751
- ~completion Context ~ env ~scope
770
+ |> getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~completion Context
771
+ ~env ~scope
752
772
| CPApply (cp , labels ) -> (
753
773
match
754
774
cp
@@ -793,7 +813,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
793
813
| CPField (CPId (path , Module), fieldName ) ->
794
814
(* M.field *)
795
815
path @ [fieldName]
796
- |> getCompletionsForPath ~debug ~package ~ opens ~full ~pos ~exact
816
+ |> getCompletionsForPath ~debug ~opens ~full ~pos ~exact
797
817
~completion Context:Field ~env ~scope
798
818
| CPField (cp , fieldName ) -> (
799
819
let completionsForCtxPath =
@@ -911,52 +931,18 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
911
931
| Tconstr (path, _typeArgs, _)
912
932
| Tlink {desc = Tconstr (path, _typeArgs, _)}
913
933
| Tsubst {desc = Tconstr (path, _typeArgs, _)}
914
- | Tpoly ({desc = Tconstr (path , _typeArgs , _ )} , [] ) -> (
934
+ | Tpoly ({desc = Tconstr (path , _typeArgs , _ )} , [] ) ->
915
935
if debug then Printf. printf " CPPipe type path:%s\n " (Path. name path);
916
- match Utils. expandPath path with
917
- | _ :: pathRev ->
918
- (* type path is relative to the completion environment
919
- express it from the root of the file *)
920
- let found, pathFromEnv =
921
- QueryEnv. pathFromEnv envFromCompletionItem (List. rev pathRev)
922
- in
923
- if debug then
924
- Printf. printf " CPPipe pathFromEnv:%s found:%b\n "
925
- (pathFromEnv |> String. concat " ." )
926
- found;
927
- if pathFromEnv = [] then None
928
- else if
929
- env.file.moduleName <> envFromCompletionItem.file.moduleName
930
- && found
931
- (* If the module names are different, then one needs to qualify the path.
932
- But only if the path belongs to the env from completion *)
933
- then Some (envFromCompletionItem.file.moduleName :: pathFromEnv)
934
- else Some pathFromEnv
935
- | _ -> None )
936
+ TypeUtils. getPathRelativeToEnv ~debug ~env
937
+ ~env FromItem:envFromCompletionItem (Utils. expandPath path)
936
938
| _ -> None )
937
939
in
938
940
match completionPath with
939
941
| Some completionPath -> (
940
- let rec removeRawOpen rawOpen modulePath =
941
- match (rawOpen, modulePath) with
942
- | [_], _ -> Some modulePath
943
- | s :: inner , first :: restPath when s = first ->
944
- removeRawOpen inner restPath
945
- | _ -> None
946
- in
947
- let rec removeRawOpens rawOpens modulePath =
948
- match rawOpens with
949
- | rawOpen :: restOpens -> (
950
- let newModulePath = removeRawOpens restOpens modulePath in
951
- match removeRawOpen rawOpen newModulePath with
952
- | None -> newModulePath
953
- | Some mp -> mp)
954
- | [] -> modulePath
955
- in
956
942
let completionPathMinusOpens =
957
- completionPath |> Utils. flattenAnyNamespaceInPath
958
- |> removeRawOpens package.opens
959
- |> removeRawOpens rawOpens |> String. concat " ."
943
+ TypeUtils. removeOpensFromCompletionPath ~raw Opens ~package
944
+ completionPath
945
+ |> String. concat " ."
960
946
in
961
947
let completionName name =
962
948
if completionPathMinusOpens = " " then name
@@ -965,7 +951,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
965
951
let completions =
966
952
completionPath @ [funNamePrefix]
967
953
|> getCompletionsForPath ~debug ~completion Context:Value ~exact: false
968
- ~package ~ opens ~full ~pos ~env ~scope
954
+ ~opens ~full ~pos ~env ~scope
969
955
in
970
956
let completions =
971
957
completions
@@ -1029,7 +1015,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1029
1015
let findTypeOfValue path =
1030
1016
path
1031
1017
|> getCompletionsForPath ~debug ~completion Context:Value ~exact: true
1032
- ~package ~ opens ~full ~pos ~env ~scope
1018
+ ~opens ~full ~pos ~env ~scope
1033
1019
|> completionsGetTypeEnv2 ~debug ~full ~opens ~raw Opens ~pos
1034
1020
in
1035
1021
let lowercaseComponent =
@@ -1043,7 +1029,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
1043
1029
match
1044
1030
path
1045
1031
|> getCompletionsForPath ~debug ~completion Context:Type ~exact: true
1046
- ~package ~ opens ~full ~pos ~env ~scope
1032
+ ~opens ~full ~pos ~env ~scope
1047
1033
with
1048
1034
| {kind = Type {kind = Abstract (Some (p , _ ))} } :: _ ->
1049
1035
(* This case happens when what we're looking for is a type alias.
@@ -1189,9 +1175,62 @@ let printConstructorArgs argsLen ~asSnippet =
1189
1175
1190
1176
type completionMode = Pattern of Completable .patternMode | Expression
1191
1177
1192
- let rec completeTypedValue ~full ~prefix ~completionContext ~mode
1178
+ let rec completeTypedValue ~rawOpens ~ full ~prefix ~completionContext ~mode
1193
1179
(t : SharedTypes.completionType ) =
1194
1180
match t with
1181
+ | TtypeT {env; path} ->
1182
+ (* Find all functions in the module that returns type t *)
1183
+ let rec fnReturnsTypeT t =
1184
+ match t.Types. desc with
1185
+ | Tlink t1
1186
+ | Tsubst t1
1187
+ | Tpoly (t1, [] )
1188
+ | Tconstr (Pident {name = "function$" } , [t1 ; _ ], _ ) ->
1189
+ fnReturnsTypeT t1
1190
+ | Tarrow _ -> (
1191
+ match TypeUtils. extractFunctionType ~env ~package: full.package t with
1192
+ | ( (Nolabel , {desc = Tconstr (Path. Pident {name = " t" }, _, _)}) :: _,
1193
+ {desc = Tconstr (Path. Pident {name = " t" }, _, _)} ) ->
1194
+ (* Filter out functions that take type t first. These are often
1195
+ @send style functions that we don't want to have here because
1196
+ they usually aren't meant to create a type t from scratch. *)
1197
+ false
1198
+ | _args , {desc = Tconstr (Path. Pident {name = "t" } , _ , _ )} -> true
1199
+ | _ -> false )
1200
+ | _ -> false
1201
+ in
1202
+ let functionsReturningTypeT =
1203
+ Hashtbl. create (Hashtbl. length env.exported.values_)
1204
+ in
1205
+ env.exported.values_
1206
+ |> Hashtbl. iter (fun name stamp ->
1207
+ match Stamps. findValue env.file.stamps stamp with
1208
+ | None -> ()
1209
+ | Some {item} -> (
1210
+ if fnReturnsTypeT item then
1211
+ let fnNname =
1212
+ TypeUtils. getPathRelativeToEnv ~debug: false
1213
+ ~env: (QueryEnv. fromFile full.file)
1214
+ ~env FromItem:env (Utils. expandPath path)
1215
+ in
1216
+
1217
+ match fnNname with
1218
+ | None -> ()
1219
+ | Some base ->
1220
+ let base =
1221
+ TypeUtils. removeOpensFromCompletionPath ~raw Opens
1222
+ ~package: full.package base
1223
+ in
1224
+ Hashtbl. add functionsReturningTypeT
1225
+ ((base |> String. concat " ." ) ^ " ." ^ name)
1226
+ item));
1227
+ Hashtbl. fold
1228
+ (fun fnName typeExpr all ->
1229
+ Completion. createWithSnippet
1230
+ ~name: (Printf. sprintf " %s()" fnName)
1231
+ ~insert Text:(fnName ^ " ($0)" ) ~kind: (Value typeExpr) ~env ()
1232
+ :: all)
1233
+ functionsReturningTypeT []
1195
1234
| Tbool env ->
1196
1235
[
1197
1236
Completion. create " true" ~kind: (Label " bool" ) ~env ;
@@ -1250,7 +1289,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
1250
1289
| None -> []
1251
1290
| Some innerType ->
1252
1291
innerType
1253
- |> completeTypedValue ~full ~prefix ~completion Context ~mode
1292
+ |> completeTypedValue ~raw Opens ~ full ~prefix ~completion Context ~mode
1254
1293
|> List. map (fun (c : Completion.t ) ->
1255
1294
{
1256
1295
c with
@@ -1294,7 +1333,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
1294
1333
| None -> []
1295
1334
| Some innerType ->
1296
1335
innerType
1297
- |> completeTypedValue ~full ~prefix ~completion Context ~mode
1336
+ |> completeTypedValue ~raw Opens ~ full ~prefix ~completion Context ~mode
1298
1337
|> List. map (fun (c : Completion.t ) ->
1299
1338
{
1300
1339
c with
@@ -1311,7 +1350,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
1311
1350
| None -> []
1312
1351
| Some innerType ->
1313
1352
innerType
1314
- |> completeTypedValue ~full ~prefix ~completion Context ~mode
1353
+ |> completeTypedValue ~raw Opens ~ full ~prefix ~completion Context ~mode
1315
1354
|> List. map (fun (c : Completion.t ) ->
1316
1355
{
1317
1356
c with
@@ -1527,8 +1566,8 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
1527
1566
let allFiles = allFilesInPackage package in
1528
1567
let findTypeOfValue path =
1529
1568
path
1530
- |> getCompletionsForPath ~debug ~completion Context:Value ~exact: true
1531
- ~package ~opens ~ full ~pos ~env ~scope
1569
+ |> getCompletionsForPath ~debug ~completion Context:Value ~exact: true ~opens
1570
+ ~full ~pos ~env ~scope
1532
1571
|> completionsGetTypeEnv2 ~debug ~full ~opens ~raw Opens ~pos
1533
1572
in
1534
1573
match completable with
@@ -1730,8 +1769,8 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
1730
1769
| Some (typ , _env , completionContext ) ->
1731
1770
let items =
1732
1771
typ
1733
- |> completeTypedValue ~mode: (Pattern patternMode) ~full ~prefix
1734
- ~completion Context
1772
+ |> completeTypedValue ~raw Opens ~ mode: (Pattern patternMode) ~full
1773
+ ~prefix ~ completion Context
1735
1774
in
1736
1775
fallbackOrEmpty ~items () )
1737
1776
| None -> fallbackOrEmpty () )
@@ -1768,7 +1807,7 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
1768
1807
in
1769
1808
let items =
1770
1809
typ
1771
- |> completeTypedValue ~mode: Expression ~full ~prefix
1810
+ |> completeTypedValue ~raw Opens ~ mode:Expression ~full ~prefix
1772
1811
~completion Context
1773
1812
|> List. map (fun (c : Completion.t ) ->
1774
1813
if wrapInsertTextInBraces then
0 commit comments