From 79ff78dccd6595967bf46c71234fe675bd30503c Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 19 May 2018 18:45:33 -0700 Subject: [PATCH 1/5] Missing `=>` infix operator escape This PR applies the same solution that we use for `/\*` and makes `=\>` work fixes #1941 --- formatTest/unit_tests/expected_output/infix.re | 6 ++++++ formatTest/unit_tests/input/infix.re | 7 +++++++ src/reason-parser/reason_lexer.mll | 8 +++++--- src/reason-parser/reason_syntax_util.ml | 4 +++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/formatTest/unit_tests/expected_output/infix.re b/formatTest/unit_tests/expected_output/infix.re index 839145b60..f3dc5293c 100644 --- a/formatTest/unit_tests/expected_output/infix.re +++ b/formatTest/unit_tests/expected_output/infix.re @@ -1202,6 +1202,7 @@ let (=-) = (a, b) => a + b; let foo = (a, b) => a =- b; +<<<<<<< HEAD let (=><) = (a, b) => a + b; let x = a =>< b; @@ -1311,3 +1312,8 @@ let not = x => !x; let other = x => not(x); let derefInsideArray = [|a^|]; + +/* #1941: infix `=>` */ +let (=\>) = (a, b) => a + b; + +let x = a =\> b; diff --git a/formatTest/unit_tests/input/infix.re b/formatTest/unit_tests/input/infix.re index 8ee32f76b..ecf550731 100644 --- a/formatTest/unit_tests/input/infix.re +++ b/formatTest/unit_tests/input/infix.re @@ -919,6 +919,7 @@ let (=-) = (a, b) => a + b; let foo = (a, b) => a =- b; +<<<<<<< HEAD let (=><) = (a, b) => a + b; let x = a =>< b; @@ -1004,3 +1005,9 @@ let not = (x) => !x; let other = (x) => not(x); let derefInsideArray = [|a^|]; + +/* #1941: infix `=>` */ +let (=\>) = (a, b) => a + b; + +let x = a =\> b; + diff --git a/src/reason-parser/reason_lexer.mll b/src/reason-parser/reason_lexer.mll index d7fb9ef6d..ed028acbd 100644 --- a/src/reason-parser/reason_lexer.mll +++ b/src/reason-parser/reason_lexer.mll @@ -612,9 +612,11 @@ rule token = parse | '\\'? ['~' '?' '!'] operator_chars+ { PREFIXOP(lexeme_operator lexbuf) } | '\\'? ['=' '<' '>' '|' '&' '$'] operator_chars* - { - INFIXOP0(lexeme_operator lexbuf) - } + { INFIXOP0(lexeme_operator lexbuf) } + (* `=\>` is treated especially due to conflicts with the function declaration + syntax *) + | '\\'? '=' '\\'? '>' operator_chars* + { INFIXOP0(lexeme_operator lexbuf) } | '\\'? '@' operator_chars* { INFIXOP1(lexeme_operator lexbuf) } | '\\'? '^' ('\\' '.')? operator_chars* diff --git a/src/reason-parser/reason_syntax_util.ml b/src/reason-parser/reason_syntax_util.ml index 2d4456d1e..4d859dad2 100644 --- a/src/reason-parser/reason_syntax_util.ml +++ b/src/reason-parser/reason_syntax_util.ml @@ -396,10 +396,12 @@ let remove_literal_attrs_mapper = (** escape_stars_slashes_mapper escapes all stars and slashes in an AST *) let escape_stars_slashes_mapper = let escape_stars_slashes str = - if String.contains str '/' then + if (String.contains str '/') || + ((String.contains str '=') && (String.contains str '>')) then replace_string "/*" "/\\*" @@ replace_string "*/" "*\\/" @@ replace_string "//" "/\\/" @@ + replace_string "=>" "=\>" @@ str else str From fa307a2823e405b9a6cb55c4b9b6aef4911ac09e Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 19 May 2018 19:24:25 -0700 Subject: [PATCH 2/5] fix warning --- src/reason-parser/reason_syntax_util.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reason-parser/reason_syntax_util.ml b/src/reason-parser/reason_syntax_util.ml index 4d859dad2..cea72e1f7 100644 --- a/src/reason-parser/reason_syntax_util.ml +++ b/src/reason-parser/reason_syntax_util.ml @@ -401,7 +401,7 @@ let escape_stars_slashes_mapper = replace_string "/*" "/\\*" @@ replace_string "*/" "*\\/" @@ replace_string "//" "/\\/" @@ - replace_string "=>" "=\>" @@ + replace_string "=>" "=\\>" @@ str else str From 1d5e115216eb93d2b545f0cd9dce6b5e164f1114 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 19 May 2018 21:22:40 -0700 Subject: [PATCH 3/5] only escape fat arrow --- src/reason-parser/reason_syntax_util.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/reason-parser/reason_syntax_util.ml b/src/reason-parser/reason_syntax_util.ml index cea72e1f7..b7e4ac5ae 100644 --- a/src/reason-parser/reason_syntax_util.ml +++ b/src/reason-parser/reason_syntax_util.ml @@ -396,8 +396,7 @@ let remove_literal_attrs_mapper = (** escape_stars_slashes_mapper escapes all stars and slashes in an AST *) let escape_stars_slashes_mapper = let escape_stars_slashes str = - if (String.contains str '/') || - ((String.contains str '=') && (String.contains str '>')) then + if (String.contains str '/') || (str = "=>") then replace_string "/*" "/\\*" @@ replace_string "*/" "*\\/" @@ replace_string "//" "/\\/" @@ From 9d25a580f6c71a39cc4f271d199447da78654bdd Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Tue, 22 May 2018 20:56:47 -0700 Subject: [PATCH 4/5] better / more tests --- formatTest/unit_tests/expected_output/infix.re | 3 ++- formatTest/unit_tests/input/infix.re | 2 +- src/reason-parser/reason_lexer.mll | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/formatTest/unit_tests/expected_output/infix.re b/formatTest/unit_tests/expected_output/infix.re index f3dc5293c..30b56c949 100644 --- a/formatTest/unit_tests/expected_output/infix.re +++ b/formatTest/unit_tests/expected_output/infix.re @@ -1202,7 +1202,6 @@ let (=-) = (a, b) => a + b; let foo = (a, b) => a =- b; -<<<<<<< HEAD let (=><) = (a, b) => a + b; let x = a =>< b; @@ -1317,3 +1316,5 @@ let derefInsideArray = [|a^|]; let (=\>) = (a, b) => a + b; let x = a =\> b; + +let (=>>) = (a, b) => a + b; diff --git a/formatTest/unit_tests/input/infix.re b/formatTest/unit_tests/input/infix.re index ecf550731..8c8831c88 100644 --- a/formatTest/unit_tests/input/infix.re +++ b/formatTest/unit_tests/input/infix.re @@ -919,7 +919,6 @@ let (=-) = (a, b) => a + b; let foo = (a, b) => a =- b; -<<<<<<< HEAD let (=><) = (a, b) => a + b; let x = a =>< b; @@ -1011,3 +1010,4 @@ let (=\>) = (a, b) => a + b; let x = a =\> b; +let (=>>) = (a, b) => a + b; diff --git a/src/reason-parser/reason_lexer.mll b/src/reason-parser/reason_lexer.mll index ed028acbd..ddd9e5bf9 100644 --- a/src/reason-parser/reason_lexer.mll +++ b/src/reason-parser/reason_lexer.mll @@ -615,7 +615,7 @@ rule token = parse { INFIXOP0(lexeme_operator lexbuf) } (* `=\>` is treated especially due to conflicts with the function declaration syntax *) - | '\\'? '=' '\\'? '>' operator_chars* + | '\\'? "=\\>" { INFIXOP0(lexeme_operator lexbuf) } | '\\'? '@' operator_chars* { INFIXOP1(lexeme_operator lexbuf) } From 69fb82a3961ba41e6c7f5636da4532cadfd0d928 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Thu, 11 Oct 2018 16:23:28 +0100 Subject: [PATCH 5/5] Implement Jordan's suggestion --- formatTest/unit_tests/expected_output/infix.re | 4 ++-- formatTest/unit_tests/input/infix.re | 4 ++-- src/reason-parser/reason_lexer.mll | 4 ---- src/reason-parser/reason_syntax_util.ml | 10 ++++++++-- src/reason-parser/reason_syntax_util.mli | 3 +++ src/reason-parser/reason_toolchain.ml | 4 +++- src/refmt/reason_implementation_printer.ml | 4 +++- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/formatTest/unit_tests/expected_output/infix.re b/formatTest/unit_tests/expected_output/infix.re index 30b56c949..17af535ea 100644 --- a/formatTest/unit_tests/expected_output/infix.re +++ b/formatTest/unit_tests/expected_output/infix.re @@ -1313,8 +1313,8 @@ let other = x => not(x); let derefInsideArray = [|a^|]; /* #1941: infix `=>` */ -let (=\>) = (a, b) => a + b; +let (\=>) = (a, b) => a + b; -let x = a =\> b; +let x = a \=> b; let (=>>) = (a, b) => a + b; diff --git a/formatTest/unit_tests/input/infix.re b/formatTest/unit_tests/input/infix.re index 8c8831c88..df126fd54 100644 --- a/formatTest/unit_tests/input/infix.re +++ b/formatTest/unit_tests/input/infix.re @@ -1006,8 +1006,8 @@ let other = (x) => not(x); let derefInsideArray = [|a^|]; /* #1941: infix `=>` */ -let (=\>) = (a, b) => a + b; +let (\=>) = (a, b) => a + b; -let x = a =\> b; +let x = a \=> b; let (=>>) = (a, b) => a + b; diff --git a/src/reason-parser/reason_lexer.mll b/src/reason-parser/reason_lexer.mll index ddd9e5bf9..9c26e411c 100644 --- a/src/reason-parser/reason_lexer.mll +++ b/src/reason-parser/reason_lexer.mll @@ -613,10 +613,6 @@ rule token = parse { PREFIXOP(lexeme_operator lexbuf) } | '\\'? ['=' '<' '>' '|' '&' '$'] operator_chars* { INFIXOP0(lexeme_operator lexbuf) } - (* `=\>` is treated especially due to conflicts with the function declaration - syntax *) - | '\\'? "=\\>" - { INFIXOP0(lexeme_operator lexbuf) } | '\\'? '@' operator_chars* { INFIXOP1(lexeme_operator lexbuf) } | '\\'? '^' ('\\' '.')? operator_chars* diff --git a/src/reason-parser/reason_syntax_util.ml b/src/reason-parser/reason_syntax_util.ml index b7e4ac5ae..390277167 100644 --- a/src/reason-parser/reason_syntax_util.ml +++ b/src/reason-parser/reason_syntax_util.ml @@ -148,6 +148,11 @@ let escape_string str = ) str; Buffer.contents buf +let remove_backslashes_for_ml s = + if s.[0] == '\\' then + String.sub s 1 (String.length s - 1) + else s + (* the stuff below contains side-effects and are not used by BuckleScript's vendored version of reason_syntax_util.ml. So we can neglect it *) @@ -393,14 +398,15 @@ let remove_literal_attrs_mapper_maker super = let remove_literal_attrs_mapper = remove_literal_attrs_mapper_maker Ast_mapper.default_mapper +let remove_backslashes_for_ml_mapper = identifier_mapper remove_backslashes_for_ml + (** escape_stars_slashes_mapper escapes all stars and slashes in an AST *) let escape_stars_slashes_mapper = let escape_stars_slashes str = - if (String.contains str '/') || (str = "=>") then + if String.contains str '/' then replace_string "/*" "/\\*" @@ replace_string "*/" "*\\/" @@ replace_string "//" "/\\/" @@ - replace_string "=>" "=\\>" @@ str else str diff --git a/src/reason-parser/reason_syntax_util.mli b/src/reason-parser/reason_syntax_util.mli index 9f289d17c..f9fb43b05 100644 --- a/src/reason-parser/reason_syntax_util.mli +++ b/src/reason-parser/reason_syntax_util.mli @@ -47,6 +47,9 @@ val reason_to_ml_swap_operator_mapper : val ml_to_reason_swap_operator_mapper : Ast_404.Ast_mapper.mapper -> Ast_404.Ast_mapper.mapper +val remove_backslashes_for_ml_mapper : + Ast_404.Ast_mapper.mapper -> Ast_404.Ast_mapper.mapper + val attribute_exists : 'a -> ('a Ast_404.Asttypes.loc * 'b) list -> bool val attributes_conflicted : diff --git a/src/reason-parser/reason_toolchain.ml b/src/reason-parser/reason_toolchain.ml index f60b9fc4e..3e25d0271 100644 --- a/src/reason-parser/reason_toolchain.ml +++ b/src/reason-parser/reason_toolchain.ml @@ -484,8 +484,10 @@ module OCaml_syntax = struct Pprintast.signature formatter (To_current.copy_signature signature) let format_implementation_with_comments (structure, _) formatter = + let mapper = Reason_syntax_util.(remove_literal_attrs_mapper |> remove_backslashes_for_ml_mapper) + in let structure = - Reason_syntax_util.(apply_mapper_to_structure structure remove_literal_attrs_mapper) + Reason_syntax_util.(apply_mapper_to_structure structure mapper) in Pprintast.structure formatter (To_current.copy_structure structure) diff --git a/src/refmt/reason_implementation_printer.ml b/src/refmt/reason_implementation_printer.ml index 966396aa7..6b6dc99b1 100644 --- a/src/refmt/reason_implementation_printer.ml +++ b/src/refmt/reason_implementation_printer.ml @@ -50,8 +50,10 @@ let print printtype filename parsedAsML output_chan output_formatter = ); ) | `Binary -> fun (ast, _) -> + let mapper = Reason_syntax_util.(remove_literal_attrs_mapper |> remove_backslashes_for_ml_mapper) + in let ast = - Reason_syntax_util.(apply_mapper_to_structure ast remove_literal_attrs_mapper) + Reason_syntax_util.(apply_mapper_to_structure ast mapper) in Ast_io.to_channel output_chan filename (Ast_io.Impl ((module OCaml_current),