@@ -664,6 +664,97 @@ let completionsForPipeFromCompletionPath ~envCompletionIsMadeFrom ~opens ~pos
664664 in
665665 completions
666666
667+ let getPipeCompletions ~env ~full ~identifierLoc ~debug ~envCompletionIsMadeFrom
668+ ~opens ~pos ~scope ~prefix ~rawOpens ~inJsx
669+ ?(mainCompletionsAreSynthetic = false ) ?(formatCompletionsWithPipes = false )
670+ typ =
671+ let env, typ =
672+ typ
673+ |> TypeUtils. resolveTypeForPipeCompletion2 ~env ~package: full.package ~full
674+ ~lhs Loc:identifierLoc
675+ in
676+ let mainTypeId = TypeUtils. findRootTypeId ~full ~env typ in
677+ let typePath = TypeUtils. pathFromTypeExpr typ in
678+ match mainTypeId with
679+ | None ->
680+ if Debug. verbose () then
681+ Printf. printf
682+ " [pipe_completion] Could not find mainTypeId. Aborting pipe completions.\n " ;
683+ []
684+ | Some mainTypeId ->
685+ if Debug. verbose () then
686+ Printf. printf " [pipe_completion] mainTypeId: %s\n " mainTypeId;
687+ let pipeCompletions =
688+ (* We now need a completion path from where to look up the module for our dot completion type.
689+ This is from where we pull all of the functions we want to complete for the pipe.
690+
691+ A completion path here could be one of two things:
692+ 1. A module path to the main module for the type we've found
693+ 2. A module path to a builtin module, like `Int` for `int`, or `Array` for `array`
694+
695+ The below code will deliberately _not_ dig into type aliases for the main type when we're looking
696+ for what _module_ to complete from. This is because you should be able to control where completions
697+ come from even if your type is an alias.
698+ *)
699+ let completeAsBuiltin =
700+ match typePath with
701+ | Some t ->
702+ TypeUtils. completionPathFromMaybeBuiltin t ~package: full.package
703+ | None -> None
704+ in
705+ (* TODO(in-compiler) No need to have this configurable anymore, just use the new integrated modules from Core..*)
706+ let completionPath =
707+ match (completeAsBuiltin, typePath) with
708+ | Some completionPathForBuiltin , _ -> Some completionPathForBuiltin
709+ | _ , Some p -> (
710+ (* If this isn't a builtin, but we have a path, we try to resolve the
711+ module path relative to the env we're completing from. This ensures that
712+ what we get here is a module path we can find completions for regardless of
713+ of the current scope for the position we're at.*)
714+ match
715+ TypeUtils. getModulePathRelativeToEnv ~debug
716+ ~env: envCompletionIsMadeFrom ~env FromItem:env (Utils. expandPath p)
717+ with
718+ | None -> Some [env.file.moduleName]
719+ | Some p -> Some p)
720+ | _ -> None
721+ in
722+ match completionPath with
723+ | None -> []
724+ | Some completionPath ->
725+ completionsForPipeFromCompletionPath ~env CompletionIsMadeFrom ~opens
726+ ~pos ~scope ~debug ~prefix ~env ~raw Opens ~full completionPath
727+ |> TypeUtils. filterPipeableFunctions ~env ~full
728+ ~synthetic: mainCompletionsAreSynthetic ~target TypeId:mainTypeId
729+ in
730+ (* Extra completions can be drawn from the @editor.completeFrom attribute. Here we
731+ find and add those completions as well. *)
732+ let extraCompletions =
733+ TypeUtils. getExtraModuleTosCompleteFromForType ~env ~full typ
734+ |> List. map (fun completionPath ->
735+ completionsForPipeFromCompletionPath ~env CompletionIsMadeFrom
736+ ~opens ~pos ~scope ~debug ~prefix ~env ~raw Opens ~full
737+ completionPath)
738+ |> List. flatten
739+ |> TypeUtils. filterPipeableFunctions ~synthetic: true ~env ~full
740+ ~target TypeId:mainTypeId
741+ in
742+ (* Add JSX completion items if we're in a JSX context. *)
743+ let jsxCompletions =
744+ if inJsx then
745+ PipeCompletionUtils. addJsxCompletionItems ~env ~main TypeId ~prefix ~full
746+ ~raw Opens typ
747+ else []
748+ in
749+ let allCompletions = jsxCompletions @ pipeCompletions @ extraCompletions in
750+ if formatCompletionsWithPipes then
751+ allCompletions
752+ |> List. filter_map (fun (c : Completion.t ) ->
753+ c
754+ |> TypeUtils. transformCompletionToPipeCompletion ~env
755+ ~replace Range:identifierLoc ~synthetic: c.synthetic)
756+ else allCompletions
757+
667758let rec digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
668759 ~scope path =
669760 match
@@ -1035,99 +1126,16 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
10351126 " [dot_completion] Could not extract main type completion env.\n " ;
10361127 []
10371128 | Some (typ , env ) ->
1038- if Debug. verbose () then
1039- Printf. printf " [dot_completion] env module path: %s, type: %s\n "
1040- (TypeUtils. modulePathFromEnv env |> String. concat " ." )
1041- (Shared. typeToString typ);
1042- (* Let's first find the actual field completions. *)
10431129 let fieldCompletions =
10441130 DotCompletionUtils. fieldCompletionsForDotCompletion typ ~env ~package
10451131 ~prefix: fieldName ~field NameLoc ~exact
10461132 in
1047- (* Now, let's get the type id for the type of parent of the dot completion.
1048- The type id is a string that uniquely identifies a type, and that we can use
1049- to filter completions for pipe completion etc.*)
1050- let mainTypeId = TypeUtils. findRootTypeId ~full ~env typ in
1051- let allExtraCompletions =
1052- match mainTypeId with
1053- | None ->
1054- if Debug. verbose () then
1055- Printf. printf
1056- " [dot_completion] Could not find mainTypeId. Aborting extra pipe \
1057- completions.\n " ;
1058- []
1059- | Some mainTypeId ->
1060- if Debug. verbose () then
1061- Printf. printf " [dot_completion] mainTypeId: %s\n " mainTypeId;
1062-
1063- let pipeCompletions =
1064- (* We now need a completion path from where to look up the module for our dot completion type.
1065- This is from where we pull all of the functions we want to complete for the pipe. *)
1066-
1067- (* TODO(in-compiler) No need to have this configurable anymore, just use the new integrated modules from Core..*)
1068- let completionPath =
1069- (* First try completing it as a builtin *)
1070- match mainTypeId with
1071- | "array" -> Some package.builtInCompletionModules.arrayModulePath
1072- | "option" ->
1073- Some package.builtInCompletionModules.optionModulePath
1074- | "string" ->
1075- Some package.builtInCompletionModules.stringModulePath
1076- | "int" -> Some package.builtInCompletionModules.intModulePath
1077- | "float" -> Some package.builtInCompletionModules.floatModulePath
1078- | "promise" ->
1079- Some package.builtInCompletionModules.promiseModulePath
1080- | "list" -> Some package.builtInCompletionModules.listModulePath
1081- | "result" ->
1082- Some package.builtInCompletionModules.resultModulePath
1083- | "Js_re.t" ->
1084- Some package.builtInCompletionModules.regexpModulePath
1085- | "char" -> Some [" Char" ]
1086- | _ ->
1087- (* Currently, when completing regular types, we stop at the first module we find that owns the type.
1088- This means that completions will be made not from the root type necessarily, but from the module with
1089- a type alias if it's a type alias. *)
1090- let completionPathForType =
1091- match TypeUtils. pathFromTypeExpr typ with
1092- | None -> None
1093- | Some tPath -> (
1094- match
1095- TypeUtils. getModulePathRelativeToEnv ~debug
1096- ~env: envCompletionIsMadeFrom ~env FromItem:env
1097- (Utils. expandPath tPath)
1098- with
1099- | None -> Some [env.file.moduleName]
1100- | Some p -> Some p)
1101- in
1102- if Debug. verbose () then
1103- Printf. printf
1104- " [dot_completion] Looked up completion path: %s\n "
1105- (match completionPathForType with
1106- | None -> " -"
1107- | Some p -> p |> String. concat " ." );
1108- completionPathForType
1109- in
1110- match completionPath with
1111- | None -> []
1112- | Some completionPath ->
1113- completionsForPipeFromCompletionPath ~env CompletionIsMadeFrom
1114- ~opens ~pos ~scope ~debug ~prefix: fieldName ~env ~raw Opens ~full
1115- completionPath
1116- in
1117- (* TODO: Explain *)
1118- let extraCompletions =
1119- TypeUtils. getExtraModuleTosCompleteFromForType ~env ~full typ
1120- |> List. map (fun completionPath ->
1121- completionsForPipeFromCompletionPath ~env CompletionIsMadeFrom
1122- ~opens ~pos ~scope ~debug ~prefix: fieldName ~env ~raw Opens
1123- ~full completionPath)
1124- |> List. flatten
1125- in
1126- pipeCompletions @ extraCompletions
1127- |> TypeUtils. filterPipeableFunctions ~synthetic: true ~env ~full
1128- ~replace Range:fieldNameLoc ~target TypeId:mainTypeId
1133+ let pipeCompletions =
1134+ getPipeCompletions ~env ~full ~identifier Loc:fieldNameLoc
1135+ ~env CompletionIsMadeFrom ~debug ~opens ~raw Opens ~scope ~pos
1136+ ~in Jsx:false ~prefix: fieldName ~format CompletionsWithPipes:true typ
11291137 in
1130- fieldCompletions @ allExtraCompletions )
1138+ fieldCompletions @ pipeCompletions )
11311139 | CPObj (cp , label ) -> (
11321140 (* TODO: Also needs to support ExtractedType *)
11331141 if Debug. verbose () then print_endline " [ctx_path]--> CPObj" ;
@@ -1148,7 +1156,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
11481156 else None )
11491157 | None -> [] )
11501158 | None -> [] )
1151- | CPPipe {contextPath = cp ; id = funNamePrefix ; lhsLoc; inJsx} -> (
1159+ | CPPipe {contextPath = cp ; id = prefix ; lhsLoc; inJsx} -> (
11521160 if Debug. verbose () then print_endline " [ctx_path]--> CPPipe" ;
11531161 match
11541162 cp
@@ -1160,87 +1168,10 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
11601168 if Debug. verbose () then
11611169 print_endline " [CPPipe]--> Could not resolve type env" ;
11621170 []
1163- | Some (typ , env ) -> (
1164- let env, typ =
1165- typ
1166- |> TypeUtils. resolveTypeForPipeCompletion2 ~env ~package ~full ~lhs Loc
1167- in
1168- let mainTypeId = TypeUtils. findRootTypeId ~full ~env typ in
1169- let typePath = TypeUtils. pathFromTypeExpr typ in
1170- match mainTypeId with
1171- | None ->
1172- if Debug. verbose () then
1173- Printf. printf
1174- " [pipe_completion] Could not find mainTypeId. Aborting pipe \
1175- completions.\n " ;
1176- []
1177- | Some mainTypeId ->
1178- if Debug. verbose () then
1179- Printf. printf " [pipe_completion] mainTypeId: %s\n " mainTypeId;
1180- let pipeCompletions =
1181- (* We now need a completion path from where to look up the module for our dot completion type.
1182- This is from where we pull all of the functions we want to complete for the pipe.
1183-
1184- A completion path here could be one of two things:
1185- 1. A module path to the main module for the type we've found
1186- 2. A module path to a builtin module, like `Int` for `int`, or `Array` for `array`
1187-
1188- The below code will deliberately _not_ dig into type aliases for the main type when we're looking
1189- for what _module_ to complete from. This is because you should be able to control where completions
1190- come from even if your type is an alias.
1191- *)
1192- let completeAsBuiltin =
1193- match typePath with
1194- | Some t -> TypeUtils. completionPathFromMaybeBuiltin t ~package
1195- | None -> None
1196- in
1197- (* TODO(in-compiler) No need to have this configurable anymore, just use the new integrated modules from Core..*)
1198- let completionPath =
1199- match (completeAsBuiltin, typePath) with
1200- | Some completionPathForBuiltin , _ -> Some completionPathForBuiltin
1201- | _ , Some p -> (
1202- (* If this isn't a builtin, but we have a path, we try to resolve the
1203- module path relative to the env we're completing from. This ensures that
1204- what we get here is a module path we can find completions for regardless of
1205- of the current scope for the position we're at.*)
1206- match
1207- TypeUtils. getModulePathRelativeToEnv ~debug
1208- ~env: envCompletionIsMadeFrom ~env FromItem:env
1209- (Utils. expandPath p)
1210- with
1211- | None -> Some [env.file.moduleName]
1212- | Some p -> Some p)
1213- | _ -> None
1214- in
1215- match completionPath with
1216- | None -> []
1217- | Some completionPath ->
1218- completionsForPipeFromCompletionPath ~env CompletionIsMadeFrom ~opens
1219- ~pos ~scope ~debug ~prefix: funNamePrefix ~env ~raw Opens ~full
1220- completionPath
1221- |> TypeUtils. filterPipeableFunctions ~env ~full ~synthetic: false
1222- ~target TypeId:mainTypeId
1223- in
1224- (* Extra completions can be drawn from the @editor.completeFrom attribute. Here we
1225- find and add those completions as well. *)
1226- let extraCompletions =
1227- TypeUtils. getExtraModuleTosCompleteFromForType ~env ~full typ
1228- |> List. map (fun completionPath ->
1229- completionsForPipeFromCompletionPath ~env CompletionIsMadeFrom
1230- ~opens ~pos ~scope ~debug ~prefix: funNamePrefix ~env
1231- ~raw Opens ~full completionPath)
1232- |> List. flatten
1233- |> TypeUtils. filterPipeableFunctions ~synthetic: true ~env ~full
1234- ~target TypeId:mainTypeId
1235- in
1236- (* Add JSX completion items if we're in a JSX context. *)
1237- let jsxCompletions =
1238- if inJsx then
1239- PipeCompletionUtils. addJsxCompletionItems ~env ~main TypeId
1240- ~prefix: funNamePrefix ~full ~raw Opens typ
1241- else []
1242- in
1243- jsxCompletions @ pipeCompletions @ extraCompletions))
1171+ | Some (typ , env ) ->
1172+ getPipeCompletions ~env ~full ~identifier Loc:lhsLoc
1173+ ~env CompletionIsMadeFrom ~debug ~opens ~raw Opens ~scope ~pos ~in Jsx
1174+ ~prefix typ)
12441175 | CTuple ctxPaths ->
12451176 if Debug. verbose () then print_endline " [ctx_path]--> CTuple" ;
12461177 (* Turn a list of context paths into a list of type expressions. *)
0 commit comments