@@ -173,24 +173,71 @@ let findModuleInScope ~env ~moduleName ~scope =
173
173
scope |> Scope. iterModulesAfterFirstOpen processModule;
174
174
! result
175
175
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
+
176
216
let resolvePathFromStamps ~(env : QueryEnv.t ) ~package ~scope ~moduleName ~path
177
217
=
178
218
(* Log.log("Finding from stamps " ++ name); *)
179
219
match findModuleInScope ~env ~module Name ~scope with
180
220
| None -> None
181
221
| Some declared -> (
182
222
(* 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 ))))
194
241
195
242
let resolveModuleWithOpens ~opens ~package ~moduleName =
196
243
let rec loop opens =
@@ -219,12 +266,17 @@ let getEnvWithOpens ~scope ~(env : QueryEnv.t) ~package
219
266
match resolvePathFromStamps ~env ~scope ~module Name ~path ~package with
220
267
| Some x -> Some x
221
268
| 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 ))
228
280
229
281
let rec expandTypeExpr ~env ~package typeExpr =
230
282
match typeExpr |> Shared. digConstructor with
@@ -662,14 +714,47 @@ let getCompletionsForPath ~debug ~opens ~full ~pos ~exact ~scope
662
714
localCompletionsWithOpens @ fileModules
663
715
| moduleName :: path -> (
664
716
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 -> [] ))
673
758
674
759
(* * Completions intended for piping, from a completion path. *)
675
760
let completionsForPipeFromCompletionPath ~envCompletionIsMadeFrom ~opens ~pos
0 commit comments