Skip to content

Commit

Permalink
[flow][match] Implement ast differ for match expressions and statements
Browse files Browse the repository at this point in the history
Summary:
Implement ast differ for match expressions and statements.

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision: D70825700

fbshipit-source-id: 64b2ef9043dc8748d3ac3a074ecd48e0552cd402
  • Loading branch information
gkz authored and facebook-github-bot committed Mar 8, 2025
1 parent 8be18ab commit d084055
Show file tree
Hide file tree
Showing 7 changed files with 475 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
{
"range": {
"start": {
"line": 4,
"character": 12
"line": 5,
"character": 3
},
"end": {
"line": 7,
"character": 1
"line": 5,
"character": 6
}
},
"newText": "match (x) {\n {const foo}: 0,\n _: 0,\n}"
"newText": "const foo"
}
]
}
Expand All @@ -44,15 +44,15 @@
{
"range": {
"start": {
"line": 4,
"character": 12
"line": 5,
"character": 3
},
"end": {
"line": 7,
"character": 1
"line": 5,
"character": 6
}
},
"newText": "match (x) {\n {foo: foo}: 0,\n _: 0,\n}"
"newText": "foo: foo"
}
]
}
Expand Down
184 changes: 184 additions & 0 deletions src/parser_utils/__tests__/flow_ast_differ_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,28 @@ class useless_mapper =
}
)
| _ -> member

method! match_pattern pattern =
let open Ast.MatchPattern in
match pattern with
| (loc, NullPattern _) ->
(loc, IdentifierPattern (Flow_ast_utils.ident_of_source (loc, "UpdatedPattern")))
| _ -> super#match_pattern pattern

method! match_object_pattern_property prop =
let open Ast.MatchPattern.ObjectPattern.Property in
match prop with
| (loc, InvalidShorthand (_, { Ast.Identifier.name = "changeProp"; _ })) ->
( loc,
Valid
{
key = Identifier (Flow_ast_utils.ident_of_source (loc, "UpdatedProp"));
pattern = (loc, Ast.MatchPattern.NullPattern None);
shorthand = false;
comments = None;
}
)
| _ -> super#match_object_pattern_property prop
end

(* TODO: add test for RegExp case? *)
Expand Down Expand Up @@ -3546,4 +3568,166 @@ import type { there as here } from \"new_import2\";const x: (() => number) = (bl
~expected:"enum Status {On = 1// a comment\n, Off = 2}"
~mapper:(new useless_mapper)
);
( "match_expression_arg" >:: fun ctxt ->
let source = "const e = match (null) {};" in
assert_edits_equal
ctxt
~edits:[((17, 21), "\"wasNull\"")]
~source
~expected:"const e = match (\"wasNull\") {};"
~mapper:(new literal_mapper)
);
( "match_statement_arg" >:: fun ctxt ->
let source = "match (null) {}" in
assert_edits_equal
ctxt
~edits:[((7, 11), "\"wasNull\"")]
~source
~expected:"match (\"wasNull\") {}"
~mapper:(new literal_mapper)
);
( "match_expression_case_body" >:: fun ctxt ->
let source = "const e = match (x) {1: null};" in
assert_edits_equal
ctxt
~edits:[((24, 28), "\"wasNull\"")]
~source
~expected:"const e = match (x) {1: \"wasNull\"};"
~mapper:(new literal_mapper)
);
( "match_expression_case_guard" >:: fun ctxt ->
let source = "const e = match (x) {1 if null: 0};" in
assert_edits_equal
ctxt
~edits:[((26, 30), "\"wasNull\"")]
~source
~expected:"const e = match (x) {1 if \"wasNull\": 0};"
~mapper:(new literal_mapper)
);
( "match_statement_case_guard" >:: fun ctxt ->
let source = "match (x) {1 if null: {}}" in
assert_edits_equal
ctxt
~edits:[((16, 20), "\"wasNull\"")]
~source
~expected:"match (x) {1 if \"wasNull\": {}}"
~mapper:(new literal_mapper)
);
( "match_null_pattern" >:: fun ctxt ->
let source = "match (x) {null: {}}" in
assert_edits_equal
ctxt
~edits:[((11, 15), "UpdatedPattern")]
~source
~expected:"match (x) {UpdatedPattern: {}}"
~mapper:(new useless_mapper)
);
( "match_identifier_pattern" >:: fun ctxt ->
let source = "match (x) {rename: {}}" in
assert_edits_equal
ctxt
~edits:[((11, 17), "gotRenamed")]
~source
~expected:"match (x) {gotRenamed: {}}"
~mapper:(new useless_mapper)
);
( "match_number_pattern" >:: fun ctxt ->
let source = "match (x) {4: {}}" in
assert_edits_equal
ctxt
~edits:[((11, 12), "5")]
~source
~expected:"match (x) {5: {}}"
~mapper:(new useless_mapper)
);
( "match_string_pattern" >:: fun ctxt ->
let source = "match (x) {\"RenameSL\": {}}" in
assert_edits_equal
ctxt
~edits:[((11, 21), "\"GotRenamedSL\"")]
~source
~expected:"match (x) {\"GotRenamedSL\": {}}"
~mapper:(new useless_mapper)
);
( "match_member_pattern" >:: fun ctxt ->
let source = "match (x) {O.rename: {}}" in
assert_edits_equal
ctxt
~edits:[((13, 19), "gotRenamed")]
~source
~expected:"match (x) {O.gotRenamed: {}}"
~mapper:(new useless_mapper)
);
( "match_unary_pattern" >:: fun ctxt ->
let source = "match (x) {-4: {}}" in
assert_edits_equal
ctxt
~edits:[((12, 13), "5")]
~source
~expected:"match (x) {-5: {}}"
~mapper:(new useless_mapper)
);
( "match_binding_pattern" >:: fun ctxt ->
let source = "match (x) {const rename: {}}" in
assert_edits_equal
ctxt
~edits:[((17, 23), "gotRenamed")]
~source
~expected:"match (x) {const gotRenamed: {}}"
~mapper:(new useless_mapper)
);
( "match_array_pattern" >:: fun ctxt ->
let source = "match (x) {[1, null, 3]: {}}" in
assert_edits_equal
ctxt
~edits:[((15, 19), "UpdatedPattern")]
~source
~expected:"match (x) {[1, UpdatedPattern, 3]: {}}"
~mapper:(new useless_mapper)
);
( "match_object_pattern_property_key" >:: fun ctxt ->
let source = "match (x) {{a: 1, rename: 2, c: 3}: {}}" in
assert_edits_equal
ctxt
~edits:[((18, 24), "gotRenamed")]
~source
~expected:"match (x) {{a: 1, gotRenamed: 2, c: 3}: {}}"
~mapper:(new useless_mapper)
);
( "match_object_pattern_property_value" >:: fun ctxt ->
let source = "match (x) {{a: 1, b: null, c: 3}: {}}" in
assert_edits_equal
ctxt
~edits:[((21, 25), "UpdatedPattern")]
~source
~expected:"match (x) {{a: 1, b: UpdatedPattern, c: 3}: {}}"
~mapper:(new useless_mapper)
);
( "match_object_pattern_property_entire" >:: fun ctxt ->
let source = "match (x) {{a: 1, changeProp, c: 3}: {}}" in
assert_edits_equal
ctxt
~edits:[((18, 28), "UpdatedProp: null")]
~source
~expected:"match (x) {{a: 1, UpdatedProp: null, c: 3}: {}}"
~mapper:(new useless_mapper)
);
( "match_as_pattern" >:: fun ctxt ->
let source = "match (x) {null as rename: {}}" in
assert_edits_equal
ctxt
~edits:[((11, 15), "UpdatedPattern"); ((19, 25), "gotRenamed")]
~source
~expected:"match (x) {UpdatedPattern as gotRenamed: {}}"
~mapper:(new useless_mapper)
);
( "match_or_pattern" >:: fun ctxt ->
let source = "match (x) {1 | null | 3: {}}" in
assert_edits_equal
ctxt
~edits:[((15, 19), "UpdatedPattern")]
~source
~expected:"match (x) {1 | UpdatedPattern | 3: {}}"
~mapper:(new useless_mapper)
);
]
Loading

0 comments on commit d084055

Please sign in to comment.