@@ -514,7 +514,7 @@ let getComplementaryCompletionsForTypedValue ~opens ~allFiles ~scope ~env prefix
514514 in
515515 localCompletionsWithOpens @ fileModules
516516
517- let getCompletionsForPath ~debug ~package ~ opens ~full ~pos ~exact ~scope
517+ let getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~scope
518518 ~completionContext ~env path =
519519 if debug then Printf. printf " Path %s\n " (path |> String. concat " ." );
520520 let allFiles = allFilesInPackage full.package in
@@ -541,7 +541,9 @@ let getCompletionsForPath ~debug ~package ~opens ~full ~pos ~exact ~scope
541541 localCompletionsWithOpens @ fileModules
542542 | moduleName :: path -> (
543543 Log. log (" Path " ^ pathToString path);
544- match getEnvWithOpens ~scope ~env ~package ~opens ~module Name path with
544+ match
545+ getEnvWithOpens ~scope ~env ~package: full.package ~opens ~module Name path
546+ with
545547 | Some (env , prefix ) ->
546548 Log. log " Got the env" ;
547549 let namesUsed = Hashtbl. create 10 in
@@ -552,8 +554,8 @@ let rec digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
552554 ~scope path =
553555 match
554556 path
555- |> getCompletionsForPath ~debug ~completion Context:Type ~exact: true ~package
556- ~opens ~ full ~pos ~env ~scope
557+ |> getCompletionsForPath ~debug ~completion Context:Type ~exact: true ~opens
558+ ~full ~pos ~env ~scope
557559 with
558560 | {kind = Type {kind = Abstract (Some (p , _ ))} } :: _ ->
559561 (* This case happens when what we're looking for is a type alias.
@@ -769,8 +771,8 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
769771 | _ -> [] )
770772 | CPId (path , completionContext ) ->
771773 path
772- |> getCompletionsForPath ~debug ~package ~ opens ~full ~pos ~exact
773- ~completion Context ~ env ~scope
774+ |> getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~completion Context
775+ ~env ~scope
774776 | CPApply (cp , labels ) -> (
775777 match
776778 cp
@@ -815,7 +817,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
815817 | CPField (CPId (path , Module), fieldName ) ->
816818 (* M.field *)
817819 path @ [fieldName]
818- |> getCompletionsForPath ~debug ~package ~ opens ~full ~pos ~exact
820+ |> getCompletionsForPath ~debug ~opens ~full ~pos ~exact
819821 ~completion Context:Field ~env ~scope
820822 | CPField (cp , fieldName ) -> (
821823 let completionsForCtxPath =
@@ -933,52 +935,18 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
933935 | Tconstr (path, _typeArgs, _)
934936 | Tlink {desc = Tconstr (path, _typeArgs, _)}
935937 | Tsubst {desc = Tconstr (path, _typeArgs, _)}
936- | Tpoly ({desc = Tconstr (path , _typeArgs , _ )} , [] ) -> (
938+ | Tpoly ({desc = Tconstr (path , _typeArgs , _ )} , [] ) ->
937939 if debug then Printf. printf " CPPipe type path:%s\n " (Path. name path);
938- match Utils. expandPath path with
939- | _ :: pathRev ->
940- (* type path is relative to the completion environment
941- express it from the root of the file *)
942- let found, pathFromEnv =
943- QueryEnv. pathFromEnv envFromCompletionItem (List. rev pathRev)
944- in
945- if debug then
946- Printf. printf " CPPipe pathFromEnv:%s found:%b\n "
947- (pathFromEnv |> String. concat " ." )
948- found;
949- if pathFromEnv = [] then None
950- else if
951- env.file.moduleName <> envFromCompletionItem.file.moduleName
952- && found
953- (* If the module names are different, then one needs to qualify the path.
954- But only if the path belongs to the env from completion *)
955- then Some (envFromCompletionItem.file.moduleName :: pathFromEnv)
956- else Some pathFromEnv
957- | _ -> None )
940+ TypeUtils. getPathRelativeToEnv ~debug ~env
941+ ~env FromItem:envFromCompletionItem (Utils. expandPath path)
958942 | _ -> None )
959943 in
960944 match completionPath with
961945 | Some completionPath -> (
962- let rec removeRawOpen rawOpen modulePath =
963- match (rawOpen, modulePath) with
964- | [_], _ -> Some modulePath
965- | s :: inner , first :: restPath when s = first ->
966- removeRawOpen inner restPath
967- | _ -> None
968- in
969- let rec removeRawOpens rawOpens modulePath =
970- match rawOpens with
971- | rawOpen :: restOpens -> (
972- let newModulePath = removeRawOpens restOpens modulePath in
973- match removeRawOpen rawOpen newModulePath with
974- | None -> newModulePath
975- | Some mp -> mp)
976- | [] -> modulePath
977- in
978946 let completionPathMinusOpens =
979- completionPath |> Utils. flattenAnyNamespaceInPath
980- |> removeRawOpens package.opens
981- |> removeRawOpens rawOpens |> String. concat " ."
947+ TypeUtils. removeOpensFromCompletionPath ~raw Opens ~package
948+ completionPath
949+ |> String. concat " ."
982950 in
983951 let completionName name =
984952 if completionPathMinusOpens = " " then name
@@ -987,7 +955,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
987955 let completions =
988956 completionPath @ [funNamePrefix]
989957 |> getCompletionsForPath ~debug ~completion Context:Value ~exact: false
990- ~package ~ opens ~full ~pos ~env ~scope
958+ ~opens ~full ~pos ~env ~scope
991959 in
992960 let completions =
993961 completions
@@ -1051,7 +1019,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
10511019 let findTypeOfValue path =
10521020 path
10531021 |> getCompletionsForPath ~debug ~completion Context:Value ~exact: true
1054- ~package ~ opens ~full ~pos ~env ~scope
1022+ ~opens ~full ~pos ~env ~scope
10551023 |> completionsGetTypeEnv2 ~debug ~full ~opens ~raw Opens ~pos
10561024 in
10571025 let lowercaseComponent =
@@ -1061,16 +1029,25 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
10611029 in
10621030 let targetLabel =
10631031 if lowercaseComponent then
1064- match
1065- [" ReactDOM" ; " domProps" ]
1066- |> digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos
1067- ~env ~scope
1068- with
1069- | None -> None
1070- | Some fields -> (
1071- match fields |> List. find_opt (fun f -> f.fname.txt = propName) with
1072- | None -> None
1073- | Some f -> Some (f.fname.txt, f.typ, env))
1032+ let rec digToTypeForCompletion path =
1033+ match
1034+ path
1035+ |> getCompletionsForPath ~debug ~completion Context:Type ~exact: true
1036+ ~opens ~full ~pos ~env ~scope
1037+ with
1038+ | {kind = Type {kind = Abstract (Some (p , _ ))} } :: _ ->
1039+ (* This case happens when what we're looking for is a type alias.
1040+ This is the case in newer rescript-react versions where
1041+ ReactDOM.domProps is an alias for JsxEvent.t. *)
1042+ let pathRev = p |> Utils. expandPath in
1043+ pathRev |> List. rev |> digToTypeForCompletion
1044+ | {kind = Type {kind = Record fields } } :: _ -> (
1045+ match fields |> List. find_opt (fun f -> f.fname.txt = propName) with
1046+ | None -> None
1047+ | Some f -> Some (f.fname.txt, f.typ, env))
1048+ | _ -> None
1049+ in
1050+ [" ReactDOM" ; " domProps" ] |> digToTypeForCompletion
10741051 else
10751052 CompletionJsx. getJsxLabels ~component Path:pathToComponent
10761053 ~find TypeOfValue ~package
@@ -1202,14 +1179,67 @@ let printConstructorArgs argsLen ~asSnippet =
12021179
12031180type completionMode = Pattern of Completable .patternMode | Expression
12041181
1205- let rec completeTypedValue ~full ~prefix ~completionContext ~mode
1182+ let rec completeTypedValue ~rawOpens ~ full ~prefix ~completionContext ~mode
12061183 (t : SharedTypes.completionType ) =
12071184 let emptyCase num =
12081185 match mode with
12091186 | Expression -> " $" ^ string_of_int (num - 1 )
12101187 | Pattern _ -> " ${" ^ string_of_int num ^ " :_}"
12111188 in
12121189 match t with
1190+ | TtypeT {env; path} ->
1191+ (* Find all functions in the module that returns type t *)
1192+ let rec fnReturnsTypeT t =
1193+ match t.Types. desc with
1194+ | Tlink t1
1195+ | Tsubst t1
1196+ | Tpoly (t1, [] )
1197+ | Tconstr (Pident {name = "function$" } , [t1 ; _ ], _ ) ->
1198+ fnReturnsTypeT t1
1199+ | Tarrow _ -> (
1200+ match TypeUtils. extractFunctionType ~env ~package: full.package t with
1201+ | ( (Nolabel , {desc = Tconstr (Path. Pident {name = " t" }, _, _)}) :: _,
1202+ {desc = Tconstr (Path. Pident {name = " t" }, _, _)} ) ->
1203+ (* Filter out functions that take type t first. These are often
1204+ @send style functions that we don't want to have here because
1205+ they usually aren't meant to create a type t from scratch. *)
1206+ false
1207+ | _args , {desc = Tconstr (Path. Pident {name = "t" } , _ , _ )} -> true
1208+ | _ -> false )
1209+ | _ -> false
1210+ in
1211+ let functionsReturningTypeT =
1212+ Hashtbl. create (Hashtbl. length env.exported.values_)
1213+ in
1214+ env.exported.values_
1215+ |> Hashtbl. iter (fun name stamp ->
1216+ match Stamps. findValue env.file.stamps stamp with
1217+ | None -> ()
1218+ | Some {item} -> (
1219+ if fnReturnsTypeT item then
1220+ let fnNname =
1221+ TypeUtils. getPathRelativeToEnv ~debug: false
1222+ ~env: (QueryEnv. fromFile full.file)
1223+ ~env FromItem:env (Utils. expandPath path)
1224+ in
1225+
1226+ match fnNname with
1227+ | None -> ()
1228+ | Some base ->
1229+ let base =
1230+ TypeUtils. removeOpensFromCompletionPath ~raw Opens
1231+ ~package: full.package base
1232+ in
1233+ Hashtbl. add functionsReturningTypeT
1234+ ((base |> String. concat " ." ) ^ " ." ^ name)
1235+ item));
1236+ Hashtbl. fold
1237+ (fun fnName typeExpr all ->
1238+ Completion. createWithSnippet
1239+ ~name: (Printf. sprintf " %s()" fnName)
1240+ ~insert Text:(fnName ^ " ($0)" ) ~kind: (Value typeExpr) ~env ()
1241+ :: all)
1242+ functionsReturningTypeT []
12131243 | Tbool env ->
12141244 [
12151245 Completion. create " true" ~kind: (Label " bool" ) ~env ;
@@ -1268,7 +1298,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
12681298 | None -> []
12691299 | Some innerType ->
12701300 innerType
1271- |> completeTypedValue ~full ~prefix ~completion Context ~mode
1301+ |> completeTypedValue ~raw Opens ~ full ~prefix ~completion Context ~mode
12721302 |> List. map (fun (c : Completion.t ) ->
12731303 {
12741304 c with
@@ -1314,7 +1344,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
13141344 | None -> []
13151345 | Some innerType ->
13161346 innerType
1317- |> completeTypedValue ~full ~prefix ~completion Context ~mode
1347+ |> completeTypedValue ~raw Opens ~ full ~prefix ~completion Context ~mode
13181348 |> List. map (fun (c : Completion.t ) ->
13191349 {
13201350 c with
@@ -1331,7 +1361,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode
13311361 | None -> []
13321362 | Some innerType ->
13331363 innerType
1334- |> completeTypedValue ~full ~prefix ~completion Context ~mode
1364+ |> completeTypedValue ~raw Opens ~ full ~prefix ~completion Context ~mode
13351365 |> List. map (fun (c : Completion.t ) ->
13361366 {
13371367 c with
@@ -1549,8 +1579,8 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
15491579 let allFiles = allFilesInPackage package in
15501580 let findTypeOfValue path =
15511581 path
1552- |> getCompletionsForPath ~debug ~completion Context:Value ~exact: true
1553- ~package ~opens ~ full ~pos ~env ~scope
1582+ |> getCompletionsForPath ~debug ~completion Context:Value ~exact: true ~opens
1583+ ~full ~pos ~env ~scope
15541584 |> completionsGetTypeEnv2 ~debug ~full ~opens ~raw Opens ~pos
15551585 in
15561586 match completable with
@@ -1781,8 +1811,8 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
17811811 | Some (typ , _env , completionContext ) ->
17821812 let items =
17831813 typ
1784- |> completeTypedValue ~mode: (Pattern patternMode) ~full ~prefix
1785- ~completion Context
1814+ |> completeTypedValue ~raw Opens ~ mode: (Pattern patternMode) ~full
1815+ ~prefix ~ completion Context
17861816 in
17871817 fallbackOrEmpty ~items () )
17881818 | None -> fallbackOrEmpty () )
@@ -1819,7 +1849,7 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
18191849 in
18201850 let items =
18211851 typ
1822- |> completeTypedValue ~mode: Expression ~full ~prefix
1852+ |> completeTypedValue ~raw Opens ~ mode:Expression ~full ~prefix
18231853 ~completion Context
18241854 |> List. map (fun (c : Completion.t ) ->
18251855 if wrapInsertTextInBraces then
0 commit comments