Skip to content

Commit

Permalink
[flow] only populate search index if autoimports is true
Browse files Browse the repository at this point in the history
Summary:
`Export_search` results are only used to service auto-imports. When auto-imports are disabled (e.g. through setting `autoimports=false` in the flowconfig) we don't need to worry about indexing files.

This diff makes `ServerEnv.exports` optional and only populates when the option is true.

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision:
D69668537

------------------------------------------------------------------------
(from 090ecacb3fea983e4ca4187aedab2bfcf92cff77)

fbshipit-source-id: 5bcb35be85f055ebc4bb5941c4658836731b022a
  • Loading branch information
panagosg7 authored and facebook-github-bot committed Feb 18, 2025
1 parent fc43315 commit 95569af
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"method": "textDocument/completion",
"result": {
"isIncomplete": false,
"items": [
{
"label": "Test",
"kind": 6,
"detail": "type Test = any",
"sortText": "00000000000000000000",
"insertTextFormat": 1,
"textEdit": {
"range": {
"start": {
"line": 2,
"character": 12
},
"end": {
"line": 2,
"character": 13
}
},
"newText": "Test"
},
"command": {
"title": "",
"command": "log:org.flow:<PLACEHOLDER_PROJECT_URL>",
"arguments": [
"textDocument/completion",
"unqualified type: local type identifier",
{
"token": "TAUTO332",
"index": 0,
"session_requests": 1,
"typed_length": 1,
"completion": "Test",
"ac_type": "Actype"
}
]
}
},
{
"label": "true",
"kind": 6,
"detail": "true",
"sortText": "00000000000000000001",
"insertTextFormat": 1,
"textEdit": {
"range": {
"start": {
"line": 2,
"character": 12
},
"end": {
"line": 2,
"character": 13
}
},
"newText": "true"
},
"command": {
"title": "",
"command": "log:org.flow:<PLACEHOLDER_PROJECT_URL>",
"arguments": [
"textDocument/completion",
"builtin type",
{
"token": "TAUTO332",
"index": 1,
"session_requests": 1,
"typed_length": 1,
"completion": "true",
"ac_type": "Actype"
}
]
}
},
{
"label": "$NonMaybeType",
"kind": 3,
"detail": "$NonMaybeType",
"sortText": "00000000000000000002",
"insertTextFormat": 1,
"textEdit": {
"range": {
"start": {
"line": 2,
"character": 12
},
"end": {
"line": 2,
"character": 13
}
},
"newText": "$NonMaybeType"
},
"command": {
"title": "",
"command": "log:org.flow:<PLACEHOLDER_PROJECT_URL>",
"arguments": [
"textDocument/completion",
"builtin type",
{
"token": "TAUTO332",
"index": 2,
"session_requests": 1,
"typed_length": 1,
"completion": "$NonMaybeType",
"ac_type": "Actype"
}
]
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[libs]
lib/

[options]
exact_by_default=false
autoimports=false

; disabling the builtins prevents this test from failing every time they change
no_flowlib=true
22 changes: 22 additions & 0 deletions newtests/lsp/completion/autoimports/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,5 +344,27 @@ module.exports = (suite(
],
),
]),

test('textDocument/completion with autoimports=false', [
addFiles('foo.js', 'types.js', 'lib/builtins.js'),
addCode(`type Test = T`),
lspStartAndConnect(),
lspRequestAndWaitUntilResponse('textDocument/completion', {
textDocument: {uri: '<PLACEHOLDER_PROJECT_URL>/test.js'},
position: {line: 2, character: 13},
context: {triggerKind: 1},
}).verifyLSPMessageSnapshot(
path.join(
__dirname,
'__snapshots__',
'completion_with_no_autoimports.json',
),
[
'textDocument/publishDiagnostics',
'window/showStatus',
'$/cancelRequest',
],
),
]).flowConfig('_flowconfig_autoimports_false'),
],
): SuiteType);
11 changes: 9 additions & 2 deletions src/server/command_handler/commandHandler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -499,14 +499,21 @@ let autocomplete_on_parsed
let open AutocompleteService_js in
let (token_opt, ac_loc, ac_type_string, results_res) =
Profiling_js.with_timer profiling ~timer:"GetResults" ~f:(fun () ->
let (search_exported_values, search_exported_types) =
match env.ServerEnv.exports with
| Some exports -> (search_exported_values ~exports, search_exported_types ~exports)
| None ->
let empty ~ac_options:_ _ = Export_search_types.empty_search_results in
(empty, empty)
in
let typing =
AutocompleteService_js.mk_typing_artifacts
~layout_options:(Code_action_utils.layout_options options)
~module_system_info:(mk_module_system_info ~options ~reader)
~loc_of_aloc:(Parsing_heaps.Reader.loc_of_aloc ~reader)
~get_ast_from_shared_mem:(Parsing_heaps.Reader.get_ast ~reader)
~search_exported_values:(search_exported_values ~exports:env.ServerEnv.exports)
~search_exported_types:(search_exported_types ~exports:env.ServerEnv.exports)
~search_exported_values
~search_exported_types
~cx
~file_sig
~ast
Expand Down
2 changes: 1 addition & 1 deletion src/server/env/serverEnv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ type env = {
coverage: Coverage.file_coverage Utils_js.FilenameMap.t;
collated_errors: Collated_errors.t;
connections: Persistent_connection.t;
exports: Export_search.t;
exports: Export_search.t option; (** None means auto-imports are not enabled *)
master_cx: Context.master_context;
}
23 changes: 14 additions & 9 deletions src/services/code_action/code_action_service.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1146,12 +1146,13 @@ let code_actions_of_errors
Flow_error.msg_of_error error |> Error_message.map_loc_of_error_message loc_of_aloc
in
let (suggest_imports_actions, has_missing_import) =
match error_message with
| Error_message.EBuiltinNameLookupFailed { loc = error_loc; name }
match (error_message, env) with
| ( Error_message.EBuiltinNameLookupFailed { loc = error_loc; name },
{ ServerEnv.exports = Some exports; _ }
)
when Options.autoimports options ->
let actions =
if include_quick_fixes && Loc.intersects error_loc loc then
let { ServerEnv.exports; _ } = env in
suggest_imports
~layout_options:(Code_action_utils.layout_options options)
~module_system_info
Expand Down Expand Up @@ -1512,15 +1513,16 @@ end)
(** insert imports for all undefined-variable errors that have only one suggestion *)
let autofix_imports ~options ~env ~loc_of_aloc ~module_system_info ~cx ~ast ~src_dir =
let errors = Context.errors cx in
let { ServerEnv.exports; _ } = env in
(* collect imports for all of the undefined variables in the file *)
let (imports, _) =
Flow_error.ErrorSet.fold
(fun error (imports, unbound_names) ->
match
Flow_error.msg_of_error error |> Error_message.map_loc_of_error_message loc_of_aloc
(Flow_error.msg_of_error error |> Error_message.map_loc_of_error_message loc_of_aloc, env)
with
| Error_message.EBuiltinNameLookupFailed { loc = error_loc; name }
| ( Error_message.EBuiltinNameLookupFailed { loc = error_loc; name },
{ ServerEnv.exports = Some exports; _ }
)
when Options.autoimports options ->
(match preferred_import ~ast ~exports name error_loc with
| Some (source, export_kind) when not (SSet.mem name unbound_names) ->
Expand Down Expand Up @@ -1616,14 +1618,17 @@ let suggest_imports_cli
let uri = File_key.to_string file_key |> Lsp_helpers.path_to_lsp_uri ~default_path:"" in
let get_edits ~cx ~ast =
let errors = Context.errors cx in
let { ServerEnv.exports; _ } = env in
let (imports, _) =
Flow_error.ErrorSet.fold
(fun error (imports, unbound_names) ->
match
Flow_error.msg_of_error error |> Error_message.map_loc_of_error_message loc_of_aloc
( Flow_error.msg_of_error error |> Error_message.map_loc_of_error_message loc_of_aloc,
env
)
with
| Error_message.EBuiltinNameLookupFailed { loc = error_loc; name }
| ( Error_message.EBuiltinNameLookupFailed { loc = error_loc; name },
{ ServerEnv.exports = Some exports; _ }
)
when Options.autoimports options ->
let ranked_imports =
suggest_imports
Expand Down
2 changes: 2 additions & 0 deletions src/services/export/search/types/export_search_types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ type search_results = {
is_incomplete: bool;
}
[@@deriving show]

let empty_search_results = { results = []; is_incomplete = false }
52 changes: 33 additions & 19 deletions src/services/inference/types_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1408,17 +1408,19 @@ end = struct
~sig_dependency_graph
in

Hh_logger.info "Updating index";
let%lwt exports =
with_memory_timer_lwt ~options "Indexing" profiling (fun () ->
Export_service.update
~workers
~reader
~dirty_files:sig_new_or_changed
env.ServerEnv.exports
)
match env.ServerEnv.exports with
| None -> Lwt.return None
| Some exports ->
Hh_logger.info "Updating index";
let%lwt exports =
with_memory_timer_lwt ~options "Indexing" profiling (fun () ->
Export_service.update ~workers ~reader ~dirty_files:sig_new_or_changed exports
)
in
Hh_logger.info "Done updating index";
Lwt.return (Some exports)
in
Hh_logger.info "Done updating index";

let%lwt ( errors,
coverage,
Expand Down Expand Up @@ -1822,13 +1824,19 @@ let init_with_initial_state

let%lwt dependency_info = restore_dependency_info () in

Hh_logger.info "Indexing files";
let%lwt exports =
with_memory_timer_lwt ~options "Indexing" profiling (fun () ->
Export_service.init ~workers ~reader ~libs:lib_exports parsed
)
if Options.autoimports options then (
Hh_logger.info "Indexing files";
let%lwt exports =
with_memory_timer_lwt ~options "Indexing" profiling (fun () ->
Export_service.init ~workers ~reader ~libs:lib_exports parsed
)
in
Hh_logger.info "Finished indexing files";
Lwt.return (Some exports)
) else
Lwt.return None
in
Hh_logger.info "Finished indexing files";

let connections =
Base.Option.value_map
Expand Down Expand Up @@ -2221,13 +2229,19 @@ let init_from_scratch ~profiling ~workers options =
)
in

Hh_logger.info "Indexing files";
let%lwt exports =
with_memory_timer_lwt ~options "Indexing" profiling (fun () ->
Export_service.init ~workers ~reader ~libs:lib_exports parsed_set
)
if Options.autoimports options then (
Hh_logger.info "Indexing files";
let%lwt exports =
with_memory_timer_lwt ~options "Indexing" profiling (fun () ->
Export_service.init ~workers ~reader ~libs:lib_exports parsed_set
)
in
Hh_logger.info "Finished indexing files";
Lwt.return (Some exports)
) else
Lwt.return None
in
Hh_logger.info "Finished indexing files";

let (collated_errors, _) =
ErrorCollator.update_local_collated_errors
Expand Down

0 comments on commit 95569af

Please sign in to comment.