diff --git a/src/commands/glean/gleanRunner.ml b/src/commands/glean/gleanRunner.ml index 90f988f1f8c..712f6a1ef81 100644 --- a/src/commands/glean/gleanRunner.ml +++ b/src/commands/glean/gleanRunner.ml @@ -252,7 +252,7 @@ let type_declaration_references ~root ~write_root ~reader ~cx ~typed_ast = let extract_member_def ~cx ~typed_ast ~file_sig scheme name : ALoc.t list = let open Ty_members in - match extract ~cx ~typed_ast ~file_sig scheme with + match extract ~cx ~typed_ast_opt:(Some typed_ast) ~file_sig scheme with | Error _ -> [] | Ok { members; _ } -> Base.Option.value diff --git a/src/server/command_handler/commandHandler.ml b/src/server/command_handler/commandHandler.ml index 5790865ae4d..fd09c5a7087 100644 --- a/src/server/command_handler/commandHandler.ml +++ b/src/server/command_handler/commandHandler.ml @@ -349,7 +349,7 @@ let autocomplete ~cx ~file_sig ~ast - ~typed_ast + ~typed_ast_opt:(Some typed_ast) ~exports:env.ServerEnv.exports in let (token_opt, ac_loc, ac_type_string, results_res) = @@ -456,7 +456,7 @@ let get_def_of_check_result ~options ~reader ~profiling ~check_result (file, lin ~cx ~file_sig ~ast - ~typed_ast + ~typed_ast_opt:(Some typed_ast) ~purpose:Get_def_types.Purpose.GoToDefinition loc |> fun result -> diff --git a/src/services/autocomplete/autocompleteService_js.ml b/src/services/autocomplete/autocompleteService_js.ml index 03a0fb6a8fb..370489586d9 100644 --- a/src/services/autocomplete/autocompleteService_js.ml +++ b/src/services/autocomplete/autocompleteService_js.ml @@ -359,20 +359,16 @@ type typing = { cx: Context.t; file_sig: File_sig.t; ast: (Loc.t, Loc.t) Flow_ast.Program.t; - typed_ast: (ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t; + typed_ast_opt: (ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t option; exports: Export_search.t; norm_genv: Ty_normalizer_env.genv; } -let mk_typing_artifacts ~options ~reader ~cx ~file_sig ~ast ~typed_ast ~exports = +let mk_typing_artifacts ~options ~reader ~cx ~file_sig ~ast ~typed_ast_opt ~exports = let norm_genv = - Ty_normalizer_flow.mk_genv - ~options:ty_normalizer_options - ~cx - ~typed_ast_opt:(Some typed_ast) - ~file_sig + Ty_normalizer_flow.mk_genv ~options:ty_normalizer_options ~cx ~typed_ast_opt ~file_sig in - { options; reader; cx; file_sig; ast; typed_ast; exports; norm_genv } + { options; reader; cx; file_sig; ast; typed_ast_opt; exports; norm_genv } type ac_result = { result: AcCompletion.t; @@ -392,7 +388,7 @@ let jsdoc_of_member typing info = | [def_loc] -> jsdoc_of_def_loc typing def_loc | _ -> None -let jsdoc_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast loc = +let jsdoc_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast_opt loc = let open GetDef_js.Get_def_result in match GetDef_js.get_def @@ -401,7 +397,7 @@ let jsdoc_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast loc = ~cx ~file_sig ~ast - ~typed_ast + ~typed_ast_opt ~purpose:Get_def_types.Purpose.GoToDefinition loc with @@ -425,9 +421,9 @@ let documentation_and_tags_of_member typing info = |> Base.Option.value_map ~default:(None, None) ~f:documentation_and_tags_of_jsdoc ) -let documentation_and_tags_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast loc = +let documentation_and_tags_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast_opt loc = lazy - (jsdoc_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast loc + (jsdoc_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast_opt loc |> Base.Option.value_map ~default:(None, None) ~f:documentation_and_tags_of_jsdoc ) @@ -444,8 +440,8 @@ let members_of_type ?(include_interface_members = false) ?(exclude_keys = SSet.empty) t = - let { cx; typed_ast; file_sig; _ } = typing in - let ty_members = Ty_members.extract ~force_instance ~cx ~typed_ast ~file_sig t in + let { cx; typed_ast_opt; file_sig; _ } = typing in + let ty_members = Ty_members.extract ~force_instance ~cx ~typed_ast_opt ~file_sig t in let include_valid_member (s, (Ty_members.{ inherited; source; _ } as info)) = if (exclude_proto_members && inherited) @@ -483,7 +479,7 @@ let members_of_type ) let local_value_identifiers ~typing ~genv ~ac_loc = - let { options; reader; cx; ast; typed_ast; file_sig; _ } = typing in + let { options; reader; cx; ast; typed_ast_opt; file_sig; _ } = typing in let scope_info = Scope_builder.program ~enable_enums:(Context.enable_enums cx) ~with_types:false ast in @@ -528,7 +524,7 @@ let local_value_identifiers ~typing ~genv ~ac_loc = Type_env.checked_find_loc_env_write_opt cx Env_api.OrdinaryNameLoc (ALoc.of_loc loc) in let documentation_and_tags = - documentation_and_tags_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast loc + documentation_and_tags_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast_opt loc in ((name, documentation_and_tags), type_) ) @@ -1268,7 +1264,8 @@ let make_type_param ~edit_locs name = insert_text_format = Lsp.Completion.PlainText; } -let local_type_identifiers ~ast ~typed_ast_opt ~cx ~genv = +let local_type_identifiers artifacts = + let { ast; typed_ast_opt; cx; norm_genv; _ } = artifacts in let rev_ids = match typed_ast_opt with | Some typed_ast -> @@ -1282,7 +1279,7 @@ let local_type_identifiers ~ast ~typed_ast_opt ~cx ~genv = in rev_ids |> Base.List.rev_map ~f:(fun ((loc, t), Flow_ast.Identifier.{ name; _ }) -> ((name, loc), t)) - |> Ty_normalizer_flow.from_types genv + |> Ty_normalizer_flow.from_types norm_genv let autocomplete_unqualified_type ~typing @@ -1292,7 +1289,7 @@ let autocomplete_unqualified_type ~ac_loc ~edit_locs ~token = - let { options; reader; cx; file_sig; ast; typed_ast; exports; norm_genv = genv } = typing in + let { options; reader; cx; file_sig; ast; typed_ast_opt; exports; norm_genv = genv } = typing in let ac_loc = loc_of_aloc ~reader ac_loc |> Autocomplete_sigil.remove_from_loc in let exact_by_default = Context.exact_by_default cx in let items_rev = @@ -1301,14 +1298,14 @@ let autocomplete_unqualified_type |> Base.List.rev_map_append utility_types ~f:(make_utility_type ~edit_locs) |> Base.List.rev_map_append tparams_rev ~f:(make_type_param ~edit_locs) in - let type_identifiers = local_type_identifiers ~ast ~typed_ast_opt:(Some typed_ast) ~cx ~genv in + let type_identifiers = local_type_identifiers typing in let (items_rev, errors_to_log) = type_identifiers |> List.fold_left (fun (items_rev, errors_to_log) ((name, aloc), ty_result) -> let documentation_and_tags = loc_of_aloc ~reader aloc - |> documentation_and_tags_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast + |> documentation_and_tags_of_loc ~options ~reader ~cx ~file_sig ~ast ~typed_ast_opt in match ty_result with | Ok elt -> @@ -2100,9 +2097,9 @@ let string_of_autocomplete_type ac_type = | Ac_jsx_attribute _ -> "Acjsx" let autocomplete_get_results typing ac_options trigger_character cursor = - let { options; reader; cx; ast; typed_ast; norm_genv = genv; _ } = typing in + let { options; reader; cx; ast; typed_ast_opt; norm_genv = genv; _ } = typing in let open Autocomplete_js in - match process_location cx ~trigger_character ~cursor ~ast ~typed_ast_opt:(Some typed_ast) with + match process_location cx ~trigger_character ~cursor ~ast ~typed_ast_opt with | Error err -> (None, None, "None", AcFatalError err) | Ok None -> let result = { AcCompletion.items = []; is_incomplete = false } in diff --git a/src/services/autocomplete/autocompleteService_js.mli b/src/services/autocomplete/autocompleteService_js.mli index 72113eb59e0..9ceec14b59d 100644 --- a/src/services/autocomplete/autocompleteService_js.mli +++ b/src/services/autocomplete/autocompleteService_js.mli @@ -50,7 +50,7 @@ val mk_typing_artifacts : cx:Context.t -> file_sig:File_sig.t -> ast:(Loc.t, Loc.t) Flow_ast.Program.t -> - typed_ast:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t -> + typed_ast_opt:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t option -> exports:Export_search.t -> typing diff --git a/src/services/code_action/autofix_class_member_access.ml b/src/services/code_action/autofix_class_member_access.ml index d21859f2692..c267a3cfe10 100644 --- a/src/services/code_action/autofix_class_member_access.ml +++ b/src/services/code_action/autofix_class_member_access.ml @@ -73,7 +73,9 @@ let prefix_with_this ast target = mapper#program ast let is_member cx typed_ast file_sig type_ name = - match Ty_members.extract ~force_instance:true ~cx ~typed_ast ~file_sig type_ with + match + Ty_members.extract ~force_instance:true ~cx ~typed_ast_opt:(Some typed_ast) ~file_sig type_ + with | Error _ -> false | Ok Ty_members.{ members; _ } -> NameUtils.Map.keys members diff --git a/src/services/get_def/getDefUtils.ml b/src/services/get_def/getDefUtils.ml index 39437cb0c2a..ceaa816862e 100644 --- a/src/services/get_def/getDefUtils.ml +++ b/src/services/get_def/getDefUtils.ml @@ -551,7 +551,17 @@ let get_def_info ~options ~reader ~purpose (ast, file_sig, _) type_info loc : | Error error -> Error error | Ok (Some props_info) -> Ok (PropertyDefinition props_info) | Ok None -> - (match GetDef_js.get_def ~options ~loc_of_aloc ~cx ~file_sig ~ast ~typed_ast ~purpose loc with + (match + GetDef_js.get_def + ~options + ~loc_of_aloc + ~cx + ~file_sig + ~ast + ~typed_ast_opt:(Some typed_ast) + ~purpose + loc + with | GetDef_js.Get_def_result.Def (locs, name) | GetDef_js.Get_def_result.Partial (locs, name, _) -> Ok (VariableDefinition (Loc_collections.LocSet.elements locs, name)) diff --git a/src/services/get_def/getDef_js.ml b/src/services/get_def/getDef_js.ml index 6c3c7db469a..0f62b0bf452 100644 --- a/src/services/get_def/getDef_js.ml +++ b/src/services/get_def/getDef_js.ml @@ -18,9 +18,11 @@ end open Get_def_result -let extract_member_def ~loc_of_aloc ~cx ~file_sig ~typed_ast ~force_instance t name = +let extract_member_def ~loc_of_aloc ~cx ~file_sig ~typed_ast_opt ~force_instance t name = let ( let* ) = Result.bind in - let* Ty_members.{ members; _ } = Ty_members.extract ~force_instance ~cx ~typed_ast ~file_sig t in + let* Ty_members.{ members; _ } = + Ty_members.extract ~force_instance ~cx ~typed_ast_opt ~file_sig t + in let def_locs = Base.Option.bind (NameUtils.Map.find_opt (Reason.OrdinaryName name) members) @@ -31,7 +33,7 @@ let extract_member_def ~loc_of_aloc ~cx ~file_sig ~typed_ast ~force_instance t n | Some def_locs -> Ok (Nel.map loc_of_aloc def_locs, Some name) | None -> Error (Printf.sprintf "failed to find member %s in members map" name) -let rec process_request ~options ~loc_of_aloc ~cx ~is_legit_require ~ast ~typed_ast ~file_sig : +let rec process_request ~options ~loc_of_aloc ~cx ~is_legit_require ~ast ~typed_ast_opt ~file_sig : (ALoc.t, ALoc.t * Type.t) Get_def_request.t -> (Loc.t Nel.t * string option, string) result = function | Get_def_request.Identifier { name; loc = (aloc, type_) } -> @@ -47,18 +49,11 @@ let rec process_request ~options ~loc_of_aloc ~cx ~is_legit_require ~ast ~typed_ let def_loc = def.Scope_api.With_Loc.Def.locs in Ok (def_loc, Some name) | [] -> - process_request - ~options - ~loc_of_aloc - ~cx - ~is_legit_require - ~ast - ~typed_ast - ~file_sig - (Get_def_request.Type { annot = (aloc, type_); name = Some name }) + let req = Get_def_request.Type { annot = (aloc, type_); name = Some name } in + process_request ~options ~loc_of_aloc ~cx ~is_legit_require ~ast ~typed_ast_opt ~file_sig req | _ :: _ :: _ -> Error "Scope builder found multiple matching identifiers") | Get_def_request.(Member { prop_name = name; object_type = (_loc, t); force_instance }) -> - extract_member_def ~loc_of_aloc ~cx ~file_sig ~typed_ast ~force_instance t name + extract_member_def ~loc_of_aloc ~cx ~file_sig ~typed_ast_opt ~force_instance t name | Get_def_request.Type { annot = (_, v); name } -> Get_def_process_location.process_type_request cx v |> Base.Result.map ~f:(fun aloc -> (Nel.one (loc_of_aloc aloc), name)) @@ -70,17 +65,12 @@ let rec process_request ~options ~loc_of_aloc ~cx ~is_legit_require ~ast ~typed_ Flow_js.flow cx (component_t, Type.ReactKitT (use_op, reason, Type.React.GetConfig tvar)) ) in - process_request - ~options - ~loc_of_aloc - ~cx - ~is_legit_require - ~ast - ~typed_ast - ~file_sig + let req = Get_def_request.( Member { prop_name = name; object_type = (loc, props_object); force_instance = false } ) + in + process_request ~options ~loc_of_aloc ~cx ~is_legit_require ~ast ~typed_ast_opt ~file_sig req module Depth = struct let limit = 100 @@ -129,7 +119,7 @@ module Depth = struct depth.results <- Loc_collections.LocMap.add loc result results end -let get_def ~options ~loc_of_aloc ~cx ~file_sig ~ast ~typed_ast ~purpose requested_loc = +let get_def ~options ~loc_of_aloc ~cx ~file_sig ~ast ~typed_ast_opt ~purpose requested_loc = let require_loc_map = File_sig.require_loc_map file_sig in let is_legit_require source_aloc = let source_loc = loc_of_aloc source_aloc in @@ -158,7 +148,7 @@ let get_def ~options ~loc_of_aloc ~cx ~file_sig ~ast ~typed_ast ~purpose request | Ok Depth.NoResult -> let open Get_def_process_location in let result = - match process_location_in_typed_ast ~is_legit_require ~typed_ast ~purpose req_loc with + match process_location cx ~ast ~is_legit_require ~typed_ast_opt ~purpose req_loc with | OwnDef (aloc, name) -> Def (LocSet.singleton (loc_of_aloc aloc), Some name) | Request request -> begin match @@ -168,7 +158,7 @@ let get_def ~options ~loc_of_aloc ~cx ~file_sig ~ast ~typed_ast ~purpose request ~cx ~is_legit_require ~ast - ~typed_ast + ~typed_ast_opt ~file_sig request with diff --git a/src/services/get_def/getDef_js.mli b/src/services/get_def/getDef_js.mli index 9e64931c1a8..a08e25ecd70 100644 --- a/src/services/get_def/getDef_js.mli +++ b/src/services/get_def/getDef_js.mli @@ -21,7 +21,7 @@ val get_def : cx:Context.t -> file_sig:File_sig.t -> ast:(Loc.t, Loc.t) Flow_ast.Program.t -> - typed_ast:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t -> + typed_ast_opt:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t option -> purpose:Get_def_types.Purpose.t -> Loc.t -> Get_def_result.t diff --git a/src/services/get_def/get_def_process_location.ml b/src/services/get_def/get_def_process_location.ml index 01eecc7d423..1f37020a82f 100644 --- a/src/services/get_def/get_def_process_location.ml +++ b/src/services/get_def/get_def_process_location.ml @@ -670,18 +670,22 @@ class on_demand_searcher cx ~is_legit_require ~covers_target ~purpose = | Some t -> t end -let process_location_in_typed_ast ~typed_ast ~is_legit_require ~purpose loc = - let covers_target test_loc = Reason.in_range loc (ALoc.to_loc_exn test_loc) in - let searcher = new typed_ast_searcher () ~typed_ast ~is_legit_require ~covers_target ~purpose in - (try ignore (searcher#program typed_ast) with - | Found -> ()); - searcher#found_loc - -let process_location_in_ast cx ast ~is_legit_require ~purpose loc = - let aloc_ast = Ast_loc_utils.loc_to_aloc_mapper#program ast in - let covers_target test_loc = Reason.in_range loc (ALoc.to_loc_exn test_loc) in - let searcher = new on_demand_searcher cx ~is_legit_require ~covers_target ~purpose in - match searcher#program aloc_ast with +let search ~searcher ast = + match searcher#program ast with | exception Found -> searcher#found_loc | exception Internal_error_exn err -> InternalError err | _ -> searcher#found_loc + +let process_location cx ~ast ~typed_ast_opt ~is_legit_require ~purpose loc = + match typed_ast_opt with + | Some typed_ast -> + let covers_target test_loc = Reason.in_range loc (ALoc.to_loc_exn test_loc) in + let searcher = new typed_ast_searcher () ~typed_ast ~is_legit_require ~covers_target ~purpose in + search ~searcher typed_ast + | None -> + (* Computing the aloc_ast here is temporary. When on-demand autocomplete is ready, + * we can use the same aloc_ast used when computing the typed environment. *) + let aloc_ast = Ast_loc_utils.loc_to_aloc_mapper#program ast in + let covers_target test_loc = Reason.in_range loc (ALoc.to_loc_exn test_loc) in + let searcher = new on_demand_searcher cx ~is_legit_require ~covers_target ~purpose in + search ~searcher aloc_ast diff --git a/src/services/get_def/get_def_process_location.mli b/src/services/get_def/get_def_process_location.mli index 345f6b07add..68093702977 100644 --- a/src/services/get_def/get_def_process_location.mli +++ b/src/services/get_def/get_def_process_location.mli @@ -59,16 +59,10 @@ class virtual ['T] searcher : val process_type_request : Context.t -> Type.t -> (ALoc.t, string) Stdlib.result -val process_location_in_typed_ast : - typed_ast:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t -> - is_legit_require:(ALoc.t -> bool) -> - purpose:Get_def_types.Purpose.t -> - Loc.t -> - ALoc.t result - -val process_location_in_ast : +val process_location : Context.t -> - (Loc.t, Loc.t) Flow_ast.Program.t -> + ast:(Loc.t, Loc.t) Flow_ast.Program.t -> + typed_ast_opt:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t option -> is_legit_require:(ALoc.t -> bool) -> purpose:Get_def_types.Purpose.t -> Loc.t -> diff --git a/src/services/references/localImportRefSearcher.ml b/src/services/references/localImportRefSearcher.ml index db3104b6c3e..31f6af77410 100644 --- a/src/services/references/localImportRefSearcher.ml +++ b/src/services/references/localImportRefSearcher.ml @@ -59,7 +59,7 @@ let search ~options ~loc_of_aloc ~cx ~file_sig ~ast ~typed_ast def_locs = ~cx ~file_sig ~ast - ~typed_ast + ~typed_ast_opt:(Some typed_ast) ~purpose:Get_def_types.Purpose.FindReferences remote_loc with diff --git a/src/services/type_info/signature_help.ml b/src/services/type_info/signature_help.ml index d0ef3f5e4b8..7fe2f875e95 100644 --- a/src/services/type_info/signature_help.ml +++ b/src/services/type_info/signature_help.ml @@ -307,7 +307,7 @@ let find_signatures ~options ~reader ~cx ~file_sig ~ast ~typed_ast loc = ~cx ~file_sig ~ast - ~typed_ast + ~typed_ast_opt:(Some typed_ast) ~purpose:Get_def_types.Purpose.GoToDefinition callee_loc with diff --git a/src/typing/ty_members.ml b/src/typing/ty_members.ml index 4047b11deea..f2f33b92d1a 100644 --- a/src/typing/ty_members.ml +++ b/src/typing/ty_members.ml @@ -311,8 +311,8 @@ let extract = toplevel_is_type_identifier_reference = false; } in - fun ?(force_instance = false) ~cx ~typed_ast ~file_sig scheme -> - let genv = Ty_normalizer_flow.mk_genv ~options ~cx ~typed_ast_opt:(Some typed_ast) ~file_sig in + fun ?(force_instance = false) ~cx ~typed_ast_opt ~file_sig scheme -> + let genv = Ty_normalizer_flow.mk_genv ~options ~cx ~typed_ast_opt ~file_sig in match Ty_normalizer_flow.expand_members ~force_instance genv scheme with | Error error -> Error (Ty_normalizer.error_to_string error) | Ok (Ty.Any _) -> Error "not enough type information to extract members" diff --git a/src/typing/ty_members.mli b/src/typing/ty_members.mli index 6a07d19be99..5a40842ffc8 100644 --- a/src/typing/ty_members.mli +++ b/src/typing/ty_members.mli @@ -24,7 +24,7 @@ type ty_members = { val extract : ?force_instance:bool -> cx:Context.t -> - typed_ast:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t -> + typed_ast_opt:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t option -> file_sig:File_sig.t -> Type.t -> (ty_members, string) result