Skip to content

Commit

Permalink
[flow][autocomplete] on-demand process_request_searcher
Browse files Browse the repository at this point in the history
Summary:
This diff implements the on-demand version of `Autocomplete_js` `process_request_searcher`, by filling in the latter's virtual methods. This is very similar to the changes in D55053049.

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision: D55053047

fbshipit-source-id: d43ba5693fa0b7fa0afd14370324f1fab2e495d0
  • Loading branch information
panagosg7 authored and facebook-github-bot committed Mar 20, 2024
1 parent 791a289 commit 7d84f76
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 14 deletions.
7 changes: 4 additions & 3 deletions src/services/autocomplete/autocompleteService_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2115,15 +2115,16 @@ let string_of_autocomplete_type ac_type =
let autocomplete_get_results typing ac_options trigger_character cursor =
let { options; reader; cx; file_sig; ast; typed_ast; _ } = typing in
let open Autocomplete_js in
match process_location ~trigger_character ~cursor ~typed_ast with
| None ->
match process_location cx ~trigger_character ~cursor ~ast ~typed_ast_opt:(Some typed_ast) with
| Error err -> (None, None, "None", AcFatalError err)
| Ok None ->
let result = { AcCompletion.items = []; is_incomplete = false } in
( None,
None,
"None",
AcResult { result; errors_to_log = ["Autocomplete token not found in AST"] }
)
| Some { tparams_rev; ac_loc; token; autocomplete_type } ->
| Ok (Some { tparams_rev; ac_loc; token; autocomplete_type }) ->
(* say you're completing `foo|Baz`. the token is "fooBaz" and ac_loc points at
"fooAUTO332Baz". if the suggestion is "fooBar", the user can choose to insert
into the token, yielding "fooBarBaz", or they can choose to replace the token,
Expand Down
75 changes: 66 additions & 9 deletions src/services/autocomplete/autocomplete_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,47 @@ class typed_ast_process_request_searcher ~(from_trigger_character : bool) ~(curs
Type.(AnyT.at Untyped loc)
end

module Statement = Fix_statement.Statement_

exception Internal_exn of string

class on_demand_process_request_searcher cx ~(from_trigger_character : bool) ~(cursor : Loc.t) =
object (this)
inherit [ALoc.t] process_request_searcher ~from_trigger_character ~cursor

method private loc_of_annot loc = loc

method on_type_annot x = x

method private type_from_enclosing_node loc =
let node = this#enclosing_node in
let typed_node = Typed_ast_finder.infer_node cx node in
match Typed_ast_finder.find_type_annot_in_node loc typed_node with
| None -> raise (Internal_exn "enclosing loc missing")
| Some t -> t

method private type_of_component_name_of_jsx_element loc expr =
let open Ast.JSX in
match this#infer_expression (loc, Ast.Expression.JSXElement expr) with
| (_, Ast.Expression.JSXElement { opening_element = (_, Opening.{ name; _ }); _ }) ->
type_of_jsx_name name
| _ -> raise (Internal_exn "typed AST structure mismatch")

method private type_of_expression expr =
let ((_, t), _) = this#infer_expression expr in
t

method private infer_expression expr = Statement.expression cx expr

method private infer_statement stmt = Statement.statement cx stmt

method private type_of_class_id loc cls =
let open Ast.Statement in
match this#infer_statement (loc, ClassDeclaration cls) with
| (_, ClassDeclaration { Flow_ast.Class.id = Some ((_, t), _); _ }) -> t
| _ -> raise (Internal_exn "typed AST structure mismatch")
end

let autocomplete_id ~cursor _cx _ac_name ac_loc = covers_target cursor ac_loc

let autocomplete_literal ~cursor _cx ac_loc = covers_target cursor ac_loc
Expand All @@ -955,15 +996,31 @@ let autocomplete_object_key ~cursor _cx _ac_name ac_loc = covers_target cursor a

let autocomplete_jsx ~cursor _cx _ac_name ac_loc = covers_target cursor ac_loc

let process_location ~trigger_character ~cursor ~typed_ast =
let searcher =
new typed_ast_process_request_searcher
~from_trigger_character:(trigger_character <> None)
~cursor
in
match searcher#program typed_ast with
| exception Found f -> Some f
| _ -> None
let process_location cx ~trigger_character ~cursor ~ast ~typed_ast_opt =
match typed_ast_opt with
| None ->
let searcher =
new on_demand_process_request_searcher
cx
~from_trigger_character:(trigger_character <> None)
~cursor
in
(* 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
(match searcher#program aloc_ast with
| exception Found f -> Ok (Some f)
| exception Internal_exn err -> Error err
| _ -> Ok None)
| Some typed_ast ->
let searcher =
new typed_ast_process_request_searcher
~from_trigger_character:(trigger_character <> None)
~cursor
in
(match searcher#program typed_ast with
| exception Found f -> Ok (Some f)
| _ -> Ok None)

let autocomplete_set_hooks ~cursor =
Type_inference_hooks_js.set_id_hook (autocomplete_id ~cursor);
Expand Down
6 changes: 4 additions & 2 deletions src/services/autocomplete/autocomplete_js.mli
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ type process_location_result = {
}

val process_location :
Context.t ->
trigger_character:string option ->
cursor:Loc.t ->
typed_ast:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t ->
process_location_result option
ast:(Loc.t, Loc.t) Flow_ast.Program.t ->
typed_ast_opt:(ALoc.t, ALoc.t * Type.t) Flow_ast.Program.t option ->
(process_location_result option, string) result

val autocomplete_set_hooks : cursor:Loc.t -> unit

Expand Down

0 comments on commit 7d84f76

Please sign in to comment.