Skip to content

Commit

Permalink
[flow] Scoped libdef support 2/n: Filter out unavailable results for …
Browse files Browse the repository at this point in the history
…IDE services

Summary:
In this diff, we will address the shortcoming from the previous diff, where we index every single globals, even if the scoped libdef config says that it won't be active for the current file.

This diff addresses it in a simple way: we will post-process the auto-import results to filter these away, based on `Context.active_global_builtins.`

Changelog: [internal]

Reviewed By: panagosg7

Differential Revision: D70532319

fbshipit-source-id: f213d61f70e97ec7e94bf8fce5177f5d54932655
  • Loading branch information
SamChou19815 authored and facebook-github-bot committed Mar 6, 2025
1 parent c721df6 commit 46881dd
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/services/autocomplete/autocompleteService_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,18 @@ type typing = {
canonical: Autocomplete_sigil.Canonical.token option;
}

let search_with_filtered_auto_import_results cx =
let is_available_autoimport_result = Lsp_import_edits.is_available_autoimport_result cx in
fun f ~ac_options name ->
let open Export_search_types in
let { results; is_incomplete } = f ~ac_options name in
let results =
Base.List.filter results ~f:(fun { search_result = { name; source; _ }; _ } ->
is_available_autoimport_result ~name ~source
)
in
{ results; is_incomplete }

let mk_typing_artifacts
~layout_options
~loc_of_aloc
Expand All @@ -378,8 +390,8 @@ let mk_typing_artifacts
loc_of_aloc;
get_ast_from_shared_mem;
module_system_info;
search_exported_values;
search_exported_types;
search_exported_values = search_with_filtered_auto_import_results cx search_exported_values;
search_exported_types = search_with_filtered_auto_import_results cx search_exported_types;
cx;
file_sig;
ast;
Expand Down
5 changes: 5 additions & 0 deletions src/services/code_action/code_action_service.ml
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ let maybe_sort_by_usage ~imports_ranked_usage imports =
imports

let suggest_imports
~cx
~layout_options
~module_system_info
~ast
Expand Down Expand Up @@ -504,8 +505,10 @@ let suggest_imports
source = Some "Flow" && code = lsp_code && Lsp_helpers.ranges_overlap range error_range
)
in
let is_available_autoimport_result = Lsp_import_edits.is_available_autoimport_result cx in
files
|> Export_index.ExportMap.bindings
|> Base.List.filter ~f:(fun ((source, _), _) -> is_available_autoimport_result ~name ~source)
|> maybe_sort_by_usage ~imports_ranked_usage
|> Base.List.fold ~init:[] ~f:(fun acc ((source, export_kind), _num) ->
match
Expand Down Expand Up @@ -1154,6 +1157,7 @@ let code_actions_of_errors
let actions =
if include_quick_fixes && Loc.intersects error_loc loc then
suggest_imports
~cx
~layout_options:(Code_action_utils.layout_options options)
~module_system_info
~ast
Expand Down Expand Up @@ -1632,6 +1636,7 @@ let suggest_imports_cli
when Options.autoimports options ->
let ranked_imports =
suggest_imports
~cx
~layout_options:(Code_action_utils.layout_options options)
~module_system_info
~ast
Expand Down
12 changes: 12 additions & 0 deletions src/services/code_action/lsp_import_edits.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@
open Code_action_text_edits
open Lsp_module_system_info

let is_available_autoimport_result cx =
let (available_globals, available_modules) =
let builtins = Context.active_global_builtins cx in
(Builtins.builtin_ordinary_name_set builtins, Builtins.builtin_modules_set builtins)
in
fun ~name ~source ->
let open Export_index in
match source with
| Global -> SSet.mem name available_globals
| Builtin mref -> SSet.mem mref available_modules
| File_key _ -> true

let main_of_package ~get_package_info package_dir =
let file_key = File_key.JsonFile (package_dir ^ Filename.dir_sep ^ "package.json") in
match get_package_info file_key with
Expand Down
2 changes: 2 additions & 0 deletions src/services/code_action/lsp_import_edits.mli
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*)

val is_available_autoimport_result : Context.t -> name:string -> source:Export_index.source -> bool

(** Generates the 'from' part of 'import ... from ...' required to import [source] from
a file in [src_dir] *)
val from_of_source :
Expand Down
3 changes: 3 additions & 0 deletions src/typing/builtins.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ let builtin_ordinary_name_set { original_global_values; original_global_types; _
let add = SMap.fold (fun k _ acc -> SSet.add k acc) in
SSet.empty |> add original_global_values |> add original_global_types

let builtin_modules_set { original_global_modules; _ } =
SMap.fold (fun k _ acc -> SSet.add k acc) original_global_modules SSet.empty

let get_builtin_value_opt { original_global_values; type_mapper; mapped_global_names; _ } name =
match Hashtbl.find_opt mapped_global_names name with
| Some v -> Some v
Expand Down
2 changes: 2 additions & 0 deletions src/typing/builtins.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ type t

val builtin_ordinary_name_set : t -> SSet.t

val builtin_modules_set : t -> SSet.t

val get_builtin_value_opt : t -> string -> (ALoc.t * Type.t) option

val get_builtin_type_opt : t -> string -> (ALoc.t * Type.t) option
Expand Down
7 changes: 7 additions & 0 deletions tests/libdef_scoped_autocomplete/.flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[libs]
common_lib.js
'<PROJECT_ROOT>/foo' -> 'foo_lib.js'
'<PROJECT_ROOT>/bar' -> 'bar_lib.js'

[options]
all=true
1 change: 1 addition & 0 deletions tests/libdef_scoped_autocomplete/.testconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shell: test.sh
6 changes: 6 additions & 0 deletions tests/libdef_scoped_autocomplete/bar/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
common
// ^
fooS
// ^
barS
// ^
2 changes: 2 additions & 0 deletions tests/libdef_scoped_autocomplete/bar_lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare const commonValueWithOverride: boolean;
declare const barSpecific: string;
2 changes: 2 additions & 0 deletions tests/libdef_scoped_autocomplete/common_lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare const commonValueNoOverride: string;
declare const commonValueWithOverride: string;
6 changes: 6 additions & 0 deletions tests/libdef_scoped_autocomplete/common_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
common
// ^
fooS
// ^
barS
// ^
6 changes: 6 additions & 0 deletions tests/libdef_scoped_autocomplete/foo/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
common
// ^
fooS
// ^
barS
// ^
2 changes: 2 additions & 0 deletions tests/libdef_scoped_autocomplete/foo_lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare const commonValueWithOverride: number;
declare const fooSpecific: string;
51 changes: 51 additions & 0 deletions tests/libdef_scoped_autocomplete/libdef_scoped_autocomplete.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
common_test.js:1:7
Flags: --pretty --imports
{
"result":[
{"name":"commonValueNoOverride","type":"(global)"},
{"name":"commonValueWithOverride","type":"(global)"}
]
}

common_test.js:3:5
Flags: --pretty --imports
{"result":[]}

common_test.js:5:5
Flags: --pretty --imports
{"result":[]}

foo/test.js:1:7
Flags: --pretty --imports
{
"result":[
{"name":"commonValueNoOverride","type":"(global)"},
{"name":"commonValueWithOverride","type":"(global)"}
]
}

foo/test.js:3:5
Flags: --pretty --imports
{"result":[{"name":"fooSpecific","type":"(global)"}]}

foo/test.js:5:5
Flags: --pretty --imports
{"result":[]}

bar/test.js:1:7
Flags: --pretty --imports
{
"result":[
{"name":"commonValueNoOverride","type":"(global)"},
{"name":"commonValueWithOverride","type":"(global)"}
]
}

bar/test.js:3:5
Flags: --pretty --imports
{"result":[]}

bar/test.js:5:5
Flags: --pretty --imports
{"result":[{"name":"barSpecific","type":"(global)"}]}

11 changes: 11 additions & 0 deletions tests/libdef_scoped_autocomplete/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# shellcheck disable=SC2094

queries_in_file autocomplete "common_test.js" --pretty --imports
queries_in_file autocomplete "foo/test.js" --pretty --imports
queries_in_file autocomplete "bar/test.js" --pretty --imports

0 comments on commit 46881dd

Please sign in to comment.