Skip to content

Commit

Permalink
[flow] make typed_ast optional in get-def/autocomplete
Browse files Browse the repository at this point in the history
Summary:
Now that we've made autocompleteService_js.ml and get_def_process_location.ml be able to run with and without a typed AST, we make `typed_ast` an optional input to these modules.

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision: D55053048

fbshipit-source-id: e65b082c94c6884a538f5406d580ba7ca38f7645
  • Loading branch information
panagosg7 authored and facebook-github-bot committed Mar 20, 2024
1 parent 9c7d85c commit 8f45dae
Show file tree
Hide file tree
Showing 14 changed files with 77 additions and 80 deletions.
2 changes: 1 addition & 1 deletion src/commands/glean/gleanRunner.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/server/command_handler/commandHandler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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) =
Expand Down Expand Up @@ -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 ->
Expand Down
43 changes: 20 additions & 23 deletions src/services/autocomplete/autocompleteService_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
)

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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_)
)
Expand Down Expand Up @@ -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 ->
Expand All @@ -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
Expand All @@ -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 =
Expand All @@ -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 ->
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/services/autocomplete/autocompleteService_js.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion src/services/code_action/autofix_class_member_access.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 11 additions & 1 deletion src/services/get_def/getDefUtils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
38 changes: 14 additions & 24 deletions src/services/get_def/getDef_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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_) } ->
Expand All @@ -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))
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/services/get_def/getDef_js.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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
28 changes: 16 additions & 12 deletions src/services/get_def/get_def_process_location.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 3 additions & 9 deletions src/services/get_def/get_def_process_location.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand Down
2 changes: 1 addition & 1 deletion src/services/references/localImportRefSearcher.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/services/type_info/signature_help.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/typing/ty_members.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading

0 comments on commit 8f45dae

Please sign in to comment.