@@ -173,24 +173,71 @@ let findModuleInScope ~env ~moduleName ~scope =
173173 scope |> Scope. iterModulesAfterFirstOpen processModule;
174174 ! result
175175
176+ let rec moduleItemToStructureEnv ~(env : QueryEnv.t ) ~package (item : Module.t )
177+ =
178+ match item with
179+ | Module. Structure structure -> Some (env, structure)
180+ | Module. Constraint (_ , moduleType ) ->
181+ moduleItemToStructureEnv ~env ~package moduleType
182+ | Module. Ident p -> (
183+ match ResolvePath. resolveModuleFromCompilerPath ~env ~package p with
184+ | Some (env2 , Some declared2 ) ->
185+ moduleItemToStructureEnv ~env: env2 ~package declared2.item
186+ | _ -> None )
187+
188+ (* Given a declared module, return the env entered into its concrete structure
189+ and the structure itself. Follows constraints and aliases *)
190+ let enterStructureFromDeclared ~(env : QueryEnv.t ) ~package
191+ (declared : Module.t Declared.t ) =
192+ match moduleItemToStructureEnv ~env ~package declared.item with
193+ | Some (env , s ) -> Some (QueryEnv. enterStructure env s, s)
194+ | None -> None
195+
196+ let completionsFromStructureItems ~(env : QueryEnv.t )
197+ (structure : Module.structure ) =
198+ StructureUtils. unique_items structure
199+ |> List. filter_map (fun (it : Module.item ) ->
200+ match it.kind with
201+ | Module. Value typ ->
202+ Some
203+ (Completion. create ~env ~docstring: it.docstring
204+ ~kind: (Completion. Value typ) it.name)
205+ | Module. Module {type_ = m } ->
206+ Some
207+ (Completion. create ~env ~docstring: it.docstring
208+ ~kind:
209+ (Completion. Module {docstring = it.docstring; module_ = m})
210+ it.name)
211+ | Module. Type (t , _recStatus ) ->
212+ Some
213+ (Completion. create ~env ~docstring: it.docstring
214+ ~kind: (Completion. Type t) it.name))
215+
176216let resolvePathFromStamps ~(env : QueryEnv.t ) ~package ~scope ~moduleName ~path
177217 =
178218 (* Log.log("Finding from stamps " ++ name); *)
179219 match findModuleInScope ~env ~module Name ~scope with
180220 | None -> None
181221 | Some declared -> (
182222 (* Log.log("found it"); *)
183- match ResolvePath. findInModule ~env declared.item path with
184- | None -> None
185- | Some res -> (
186- match res with
187- | `Local (env , name ) -> Some (env, name)
188- | `Global (moduleName , fullPath ) -> (
189- match ProcessCmt. fileForModule ~package moduleName with
190- | None -> None
191- | Some file ->
192- ResolvePath. resolvePath ~env: (QueryEnv. fromFile file) ~path: fullPath
193- ~package )))
223+ (* [""] means completion after `ModuleName.` (trailing dot). *)
224+ match path with
225+ | [" " ] -> (
226+ match moduleItemToStructureEnv ~env ~package declared.item with
227+ | Some (env , structure ) -> Some (QueryEnv. enterStructure env structure, " " )
228+ | None -> None )
229+ | _ -> (
230+ match ResolvePath. findInModule ~env declared.item path with
231+ | None -> None
232+ | Some res -> (
233+ match res with
234+ | `Local (env , name ) -> Some (env, name)
235+ | `Global (moduleName , fullPath ) -> (
236+ match ProcessCmt. fileForModule ~package moduleName with
237+ | None -> None
238+ | Some file ->
239+ ResolvePath. resolvePath ~env: (QueryEnv. fromFile file) ~path: fullPath
240+ ~package ))))
194241
195242let resolveModuleWithOpens ~opens ~package ~moduleName =
196243 let rec loop opens =
@@ -219,12 +266,17 @@ let getEnvWithOpens ~scope ~(env : QueryEnv.t) ~package
219266 match resolvePathFromStamps ~env ~scope ~module Name ~path ~package with
220267 | Some x -> Some x
221268 | None -> (
222- match resolveModuleWithOpens ~opens ~package ~module Name with
223- | Some env -> ResolvePath. resolvePath ~env ~package ~path
224- | None -> (
225- match resolveFileModule ~module Name ~package with
226- | None -> None
227- | Some env -> ResolvePath. resolvePath ~env ~package ~path ))
269+ let env_opt =
270+ match resolveModuleWithOpens ~opens ~package ~module Name with
271+ | Some envOpens -> Some envOpens
272+ | None -> resolveFileModule ~module Name ~package
273+ in
274+ match env_opt with
275+ | None -> None
276+ | Some env -> (
277+ match path with
278+ | [" " ] -> Some (env, " " )
279+ | _ -> ResolvePath. resolvePath ~env ~package ~path ))
228280
229281let rec expandTypeExpr ~env ~package typeExpr =
230282 match typeExpr |> Shared. digConstructor with
@@ -662,14 +714,47 @@ let getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~scope
662714 localCompletionsWithOpens @ fileModules
663715 | moduleName :: path -> (
664716 Log. log (" Path " ^ pathToString path);
665- match
666- getEnvWithOpens ~scope ~env ~package: full.package ~opens ~module Name path
667- with
668- | Some (env , prefix ) ->
669- Log. log " Got the env" ;
670- let namesUsed = Hashtbl. create 10 in
671- findAllCompletions ~env ~prefix ~exact ~names Used ~completion Context
672- | None -> [] )
717+ (* [""] is trailing dot completion (`ModuleName.<com>`). *)
718+ match path with
719+ | [" " ] -> (
720+ let envFile = env in
721+ let declaredOpt =
722+ match findModuleInScope ~env: envFile ~module Name ~scope with
723+ | Some d -> Some d
724+ | None -> (
725+ match Exported. find envFile.exported Exported. Module moduleName with
726+ | Some stamp -> Stamps. findModule envFile.file.stamps stamp
727+ | None -> None )
728+ in
729+ match declaredOpt with
730+ | Some (declared : Module.t Declared.t ) when declared.isExported = false
731+ -> (
732+ match
733+ enterStructureFromDeclared ~env: envFile ~package: full.package declared
734+ with
735+ | None -> []
736+ | Some (envInModule , structure ) ->
737+ completionsFromStructureItems ~env: envInModule structure)
738+ | _ -> (
739+ match
740+ getEnvWithOpens ~scope ~env ~package: full.package ~opens ~module Name
741+ path
742+ with
743+ | Some (env , prefix ) ->
744+ Log. log " Got the env" ;
745+ let namesUsed = Hashtbl. create 10 in
746+ findAllCompletions ~env ~prefix ~exact ~names Used ~completion Context
747+ | None -> [] ))
748+ | _ -> (
749+ match
750+ getEnvWithOpens ~scope ~env ~package: full.package ~opens ~module Name
751+ path
752+ with
753+ | Some (env , prefix ) ->
754+ Log. log " Got the env" ;
755+ let namesUsed = Hashtbl. create 10 in
756+ findAllCompletions ~env ~prefix ~exact ~names Used ~completion Context
757+ | None -> [] ))
673758
674759(* * Completions intended for piping, from a completion path. *)
675760let completionsForPipeFromCompletionPath ~envCompletionIsMadeFrom ~opens ~pos
0 commit comments