Skip to content

Commit

Permalink
[flow][match] Autocomplete for member patterns in match expressions
Browse files Browse the repository at this point in the history
Summary:
Autocomplete for match member patterns.

Changelog: [internal]

Reviewed By: panagosg7

Differential Revision: D67830067

fbshipit-source-id: c95916176240364f16e66182710a03fbe3c901c4
  • Loading branch information
gkz authored and facebook-github-bot committed Jan 7, 2025
1 parent b62f486 commit a8ea098
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/services/autocomplete/autocomplete_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ module Inference = struct
match Statement.statement cx (loc, ClassDeclaration cls) with
| (_, ClassDeclaration { Flow_ast.Class.id = Some ((_, t), _); _ }) -> t
| _ -> raise (Internal_exn "typed AST structure mismatch")

let type_of_identifier cx loc id = Statement.identifier cx id loc

let type_of_match_member_pattern cx loc mem =
Match_pattern.type_of_member_pattern
cx
~on_identifier:Statement.identifier
~on_expression:Statement.expression
(loc, mem)
end

class process_request_searcher cx ~from_trigger_character ~cursor =
Expand Down Expand Up @@ -939,6 +948,56 @@ class process_request_searcher cx ~from_trigger_character ~cursor =
this#find loc token Ac_ignored
else
key

method! match_member_pattern member_pattern =
let open Ast.MatchPattern.MemberPattern in
let (loc, { base; property; _ }) = member_pattern in
let base_loc =
match base with
| BaseIdentifier (loc, _)
| BaseMember (loc, _) ->
loc
in
let member_loc = Some (compute_member_loc ~expr_loc:loc ~obj_loc:base_loc) in
let obj_type () =
match base with
| BaseIdentifier (loc, id) -> Inference.type_of_identifier cx loc id
| BaseMember (loc, mem) -> Inference.type_of_match_member_pattern cx loc mem
in
(match property with
| PropertyIdentifier (prop_loc, { Ast.Identifier.name; _ }) when this#covers_target prop_loc
->
this#find
prop_loc
name
(Ac_member
{
obj_type = obj_type ();
in_optional_chain = false;
bracket_syntax = None;
member_loc;
is_type_annotation = false;
is_super = false;
}
)
| PropertyString (prop_loc, { Ast.StringLiteral.raw = token; _ })
when this#covers_target prop_loc ->
let obj_type = obj_type () in
this#find
prop_loc
token
(Ac_member
{
obj_type;
in_optional_chain = false;
bracket_syntax = Some (this#default_bracket_syntax obj_type);
member_loc;
is_type_annotation = false;
is_super = false;
}
)
| _ -> ());
super#match_member_pattern member_pattern
end

let autocomplete_id ~cursor _cx _ac_name ac_loc = covers_target cursor ac_loc
Expand Down
4 changes: 4 additions & 0 deletions src/typing/match_pattern.ml
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,7 @@ and object_properties cx ~on_identifier ~on_expression ~on_binding ~in_or_patter

let pattern cx ~on_identifier ~on_expression ~on_binding acc (loc, p) =
pattern_ cx ~on_identifier ~on_expression ~on_binding ~in_or_pattern:false acc (loc, p)

let type_of_member_pattern cx ~on_identifier ~on_expression mem =
let (_, ((_, t), _)) = member cx ~on_identifier ~on_expression mem in
t
8 changes: 8 additions & 0 deletions src/typing/match_pattern.mli
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ val pattern :
(ALoc.t, ALoc.t) Ast.Expression.t ->
(ALoc.t, ALoc.t) Ast.MatchPattern.t ->
(ALoc.t, ALoc.t * Type.t) Ast.MatchPattern.t

val type_of_member_pattern :
Context.t ->
on_identifier:(Context.t -> ALoc.t Ast.Identifier.t' -> ALoc.t -> Type.t) ->
on_expression:
(Context.t -> (ALoc.t, ALoc.t) Ast.Expression.t -> (ALoc.t, ALoc.t * Type.t) Ast.Expression.t) ->
(ALoc.t, ALoc.t) Ast.MatchPattern.MemberPattern.t ->
Type.t
28 changes: 28 additions & 0 deletions tests/autocomplete_match/autocomplete_match.exp
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,31 @@ pattern-object.js:6:5
Flags: --pretty
{"result":[]}

pattern-member.js:6:6
Flags: --pretty
{
"result":[
{"name":"[\"zip-zap\"]","type":"3"},
{"name":"bar","type":"{baz: 2}"},
{"name":"foo","type":"1"}
]
}

pattern-member.js:8:7
Flags: --pretty
{"result":[{"name":"foo","type":"1"}]}

pattern-member.js:10:11
Flags: --pretty
{"result":[{"name":"baz","type":"2"}]}

pattern-member.js:12:6
Flags: --pretty
{
"result":[
{"name":"\"bar\"","type":"{baz: 2}"},
{"name":"\"foo\"","type":"1"},
{"name":"\"zip-zap\"","type":"3"}
]
}

14 changes: 14 additions & 0 deletions tests/autocomplete_match/pattern-member.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
declare const x: number;

declare const O: {foo: 1, bar: {baz: 2}, 'zip-zap': 3};

const e = match (x) {
O. : 0,
// ^
O.f : 0,
// ^
O.bar.b : 0,
// ^
O[ ]: 0,
// ^
};
1 change: 1 addition & 0 deletions tests/autocomplete_match/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ queries_in_file autocomplete "keyword-expression.js" --pretty
queries_in_file autocomplete "pattern-identifier.js" --pretty
queries_in_file autocomplete "pattern-binding.js" --pretty
queries_in_file autocomplete "pattern-object.js" --pretty
queries_in_file autocomplete "pattern-member.js" --pretty

0 comments on commit a8ea098

Please sign in to comment.