From 6d44206fb229125af336e303e445923705184cdd Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 02:20:57 -0700 Subject: [PATCH 1/8] Fix letop binary printing this was happening after the downgrade so it effectively only worked if you were printing to the console? --- src/reason-parser/reason_pprint_ast.ml | 7 ++++--- src/reason-parser/reason_syntax_util.cppo.ml | 9 +++------ src/reason-parser/reason_syntax_util.cppo.mli | 2 +- src/reason-parser/reason_toolchain_ocaml.ml | 7 +++---- src/refmt/reason_implementation_printer.ml | 6 ------ 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index 802e5d2e6..28f77b091 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -8313,9 +8313,10 @@ let add_explicit_arity_mapper super = { super with Ast_mapper. expr; pat } let preprocessing_mapper = - ml_to_reason_swap_operator_mapper - (escape_stars_slashes_mapper - (add_explicit_arity_mapper Ast_mapper.default_mapper)) + backport_letopt_mapper + (ml_to_reason_swap_operator_mapper + (escape_stars_slashes_mapper + (add_explicit_arity_mapper Ast_mapper.default_mapper))) let core_type ppf x = format_layout ppf diff --git a/src/reason-parser/reason_syntax_util.cppo.ml b/src/reason-parser/reason_syntax_util.cppo.ml index 0e658279b..8cf869672 100644 --- a/src/reason-parser/reason_syntax_util.cppo.ml +++ b/src/reason-parser/reason_syntax_util.cppo.ml @@ -583,9 +583,9 @@ let remove_stylistic_attrs_mapper = remove_stylistic_attrs_mapper_maker Ast_mapper.default_mapper #if OCAML_VERSION >= (4, 8, 0) -let noop_mapper = +let noop_mapper super = let noop = fun _mapper x -> x in - { Ast_mapper.default_mapper with + { super with expr = noop; structure = noop; structure_item = noop; @@ -608,7 +608,7 @@ let backport_letopt_mapper = noop_mapper * * (let+)((and+)(y, b), ((x, a)) => x + a) *) -let backport_letopt_mapper_maker super = +let backport_letopt_mapper super = let open Ast_408 in let open Ast_mapper in { super with @@ -654,9 +654,6 @@ let backport_letopt_mapper_maker super = ])} | _ -> super.expr mapper expr } - -let backport_letopt_mapper = - backport_letopt_mapper_maker Ast_mapper.default_mapper #endif let escape_stars_slashes str = diff --git a/src/reason-parser/reason_syntax_util.cppo.mli b/src/reason-parser/reason_syntax_util.cppo.mli index f90549927..05f46298a 100644 --- a/src/reason-parser/reason_syntax_util.cppo.mli +++ b/src/reason-parser/reason_syntax_util.cppo.mli @@ -38,7 +38,7 @@ val isLineComment : string -> bool val remove_stylistic_attrs_mapper : Ast_mapper.mapper -val backport_letopt_mapper : Ast_mapper.mapper +val backport_letopt_mapper : Ast_mapper.mapper -> Ast_mapper.mapper val escape_stars_slashes : string -> string diff --git a/src/reason-parser/reason_toolchain_ocaml.ml b/src/reason-parser/reason_toolchain_ocaml.ml index 249751171..3700019ec 100644 --- a/src/reason-parser/reason_toolchain_ocaml.ml +++ b/src/reason-parser/reason_toolchain_ocaml.ml @@ -136,10 +136,9 @@ let format_interface_with_comments (signature, _) formatter = (To_current.copy_signature signature) let format_implementation_with_comments (structure, _) formatter = let structure = - Reason_syntax_util.(apply_mapper_to_structure structure remove_stylistic_attrs_mapper) - in - let structure = - Reason_syntax_util.(apply_mapper_to_structure structure backport_letopt_mapper) + Reason_syntax_util.(apply_mapper_to_structure + structure + (backport_letopt_mapper remove_stylistic_attrs_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 6558dd153..b945aa8d4 100644 --- a/src/refmt/reason_implementation_printer.ml +++ b/src/refmt/reason_implementation_printer.ml @@ -53,16 +53,10 @@ let print printtype filename parsedAsML output_chan output_formatter = let ast = Reason_syntax_util.(apply_mapper_to_structure ast remove_stylistic_attrs_mapper) in - let ast = - Reason_syntax_util.(apply_mapper_to_structure ast backport_letopt_mapper) - in Ast_io.to_channel output_chan filename (Ast_io.Impl ((module OCaml_current), Reason_toolchain.To_current.copy_structure ast)) | `AST -> fun (ast, _) -> ( - let ast = - Reason_syntax_util.(apply_mapper_to_structure ast backport_letopt_mapper) - in Printast.implementation output_formatter (Reason_toolchain.To_current.copy_structure ast) ) From 7468aacdbbea9f9b5aed2f6b2cfa85661343c50e Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 08:56:28 -0700 Subject: [PATCH 2/8] fix --- src/reason-parser/reason_pprint_ast.ml | 7 +++---- src/refmt/reason_implementation_printer.ml | 2 +- src/refmt/reason_interface_printer.ml | 5 +++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index 28f77b091..802e5d2e6 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -8313,10 +8313,9 @@ let add_explicit_arity_mapper super = { super with Ast_mapper. expr; pat } let preprocessing_mapper = - backport_letopt_mapper - (ml_to_reason_swap_operator_mapper - (escape_stars_slashes_mapper - (add_explicit_arity_mapper Ast_mapper.default_mapper))) + ml_to_reason_swap_operator_mapper + (escape_stars_slashes_mapper + (add_explicit_arity_mapper Ast_mapper.default_mapper)) let core_type ppf x = format_layout ppf diff --git a/src/refmt/reason_implementation_printer.ml b/src/refmt/reason_implementation_printer.ml index b945aa8d4..2c4e93ee9 100644 --- a/src/refmt/reason_implementation_printer.ml +++ b/src/refmt/reason_implementation_printer.ml @@ -51,7 +51,7 @@ let print printtype filename parsedAsML output_chan output_formatter = ) | `Binary -> fun (ast, _) -> let ast = - Reason_syntax_util.(apply_mapper_to_structure ast remove_stylistic_attrs_mapper) + Reason_syntax_util.(apply_mapper_to_structure ast (backport_letopt_mapper remove_stylistic_attrs_mapper)) in Ast_io.to_channel output_chan filename (Ast_io.Impl ((module OCaml_current), diff --git a/src/refmt/reason_interface_printer.ml b/src/refmt/reason_interface_printer.ml index b0a1875ff..b2bb3899d 100644 --- a/src/refmt/reason_interface_printer.ml +++ b/src/refmt/reason_interface_printer.ml @@ -49,6 +49,9 @@ let print printtype filename parsedAsML output_chan output_formatter = ); ) | `Binary -> fun (ast, _) -> ( + let ast = + Reason_syntax_util.(apply_mapper_to_signature ast remove_stylistic_attrs_mapper) + in Ast_io.to_channel output_chan filename (Ast_io.Intf ((module OCaml_current), Reason_toolchain.To_current.copy_signature ast)) @@ -57,8 +60,6 @@ let print printtype filename parsedAsML output_chan output_formatter = Printast.interface output_formatter (Reason_toolchain.To_current.copy_signature ast) ) - (* If you don't wrap the function in parens, it's a totally different - * meaning #thanksOCaml *) | `None -> (fun _ -> ()) | `ML -> Reason_toolchain.ML.print_interface_with_comments output_formatter | `Reason -> Reason_toolchain.RE.print_interface_with_comments output_formatter From be924d552d59551e221134c908bc668d604f45c7 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 09:42:42 -0700 Subject: [PATCH 3/8] fix ocamlmerlin-reason for letop syntax, add compatibility with ocaml-syntax-shims --- src/reason-merlin/ocamlmerlin_reason.cppo.ml | 6 ++++ src/reason-parser/reason_syntax_util.cppo.ml | 37 ++++++++++++++++++-- src/refmt/reason_interface_printer.ml | 2 +- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/reason-merlin/ocamlmerlin_reason.cppo.ml b/src/reason-merlin/ocamlmerlin_reason.cppo.ml index a6e8e63ef..89415e289 100644 --- a/src/reason-merlin/ocamlmerlin_reason.cppo.ml +++ b/src/reason-merlin/ocamlmerlin_reason.cppo.ml @@ -9,9 +9,15 @@ module Reason_reader = struct let load buffer = buffer let structure str = + let str = + Reason_syntax_util.(apply_mapper_to_structure str (backport_letopt_mapper remove_stylistic_attrs_mapper)) + in Structure (Reason_toolchain.To_current.copy_structure str) let signature sg = + let sg = + Reason_syntax_util.(apply_mapper_to_signature sg (backport_letopt_mapper remove_stylistic_attrs_mapper)) + in Signature (Reason_toolchain.To_current.copy_signature sg) let parse {text; path} = diff --git a/src/reason-parser/reason_syntax_util.cppo.ml b/src/reason-parser/reason_syntax_util.cppo.ml index 8cf869672..91602c517 100644 --- a/src/reason-parser/reason_syntax_util.cppo.ml +++ b/src/reason-parser/reason_syntax_util.cppo.ml @@ -594,6 +594,39 @@ let noop_mapper super = (* Don't need to backport past 4.08 *) let backport_letopt_mapper = noop_mapper #else + (* Adapted from https://github.com/ocaml-ppx/ocaml-syntax-shims, for + * compatibility with OCaml's own backporting. *) + let name = function + | '!' -> "bang" + | '$' -> "dollar" + | '%' -> "percent" + | '&' -> "ampersand" + | '*' -> "star" + | '+' -> "plus" + | '-' -> "minus" + | '/' -> "slash" + | ':' -> "colon" + | '<' -> "lesser" + | '=' -> "equal" + | '>' -> "greater" + | '?' -> "question" + | '@' -> "at" + | '^' -> "circumflex" + | '|' -> "pipe" + | c -> String.make 1 c + + let expand s = + let buf = Buffer.create 128 in + (* "let" or "and" *) + Buffer.add_string buf (String.sub s 0 3); + Buffer.add_string buf "__"; + for i = 3 to String.length s - 1 do + if i > 3 then + Buffer.add_char buf '_'; + Buffer.add_string buf (name s.[i]) + done; + Buffer.contents buf + (** This will convert Pexp_letop into a series of `apply`s to simulate 4.08's behavior. * * For example, @@ -634,7 +667,7 @@ let backport_letopt_mapper super = let (pattern, expr, op) = loop rest in let and_op_ident = Ast_helper.Exp.ident ~loc:op.loc - (Location.mkloc (Longident.Lident op.txt) op.loc) + (Location.mkloc (Longident.Lident (expand op.txt)) op.loc) in ( Ast_helper.Pat.tuple ~loc:pbop_loc [pbop_pat; pattern], @@ -645,7 +678,7 @@ let backport_letopt_mapper super = let (pattern, expr, _) = loop (let_::ands) in let let_op_ident = Ast_helper.Exp.ident ~loc:let_.pbop_op.loc - (Location.mkloc (Longident.Lident let_.pbop_op.txt) let_.pbop_op.loc) + (Location.mkloc (Longident.Lident (expand let_.pbop_op.txt)) let_.pbop_op.loc) in super.expr mapper {expr with pexp_desc = Pexp_apply (let_op_ident, [ diff --git a/src/refmt/reason_interface_printer.ml b/src/refmt/reason_interface_printer.ml index b2bb3899d..5a184633e 100644 --- a/src/refmt/reason_interface_printer.ml +++ b/src/refmt/reason_interface_printer.ml @@ -50,7 +50,7 @@ let print printtype filename parsedAsML output_chan output_formatter = ) | `Binary -> fun (ast, _) -> ( let ast = - Reason_syntax_util.(apply_mapper_to_signature ast remove_stylistic_attrs_mapper) + Reason_syntax_util.(apply_mapper_to_signature ast (backport_letopt_mapper remove_stylistic_attrs_mapper)) in Ast_io.to_channel output_chan filename (Ast_io.Intf ((module OCaml_current), From d02596ae4e9ad9be4f825945b1faaf8ff995ad95 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 10:14:39 -0700 Subject: [PATCH 4/8] expand in the lexer --- src/reason-parser/reason_declarative_lexer.mll | 4 ++-- src/reason-parser/reason_syntax_util.cppo.ml | 7 ++++--- src/reason-parser/reason_syntax_util.cppo.mli | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/reason-parser/reason_declarative_lexer.mll b/src/reason-parser/reason_declarative_lexer.mll index 9da1f3108..720dacaa1 100644 --- a/src/reason-parser/reason_declarative_lexer.mll +++ b/src/reason-parser/reason_declarative_lexer.mll @@ -635,9 +635,9 @@ rule token state = parse | '%' operator_chars* { INFIXOP3 (lexeme_operator lexbuf) } | "let" kwdopchar dotsymbolchar * - { LETOP (lexeme_operator lexbuf) } + { LETOP (Reason_syntax_util.expand_letop_identifier (lexeme_operator lexbuf)) } | "and" kwdopchar dotsymbolchar * - { ANDOP (lexeme_operator lexbuf) } + { ANDOP (Reason_syntax_util.expand_letop_identifier (lexeme_operator lexbuf)) } | eof { EOF } | _ { raise_error diff --git a/src/reason-parser/reason_syntax_util.cppo.ml b/src/reason-parser/reason_syntax_util.cppo.ml index 91602c517..62cb71564 100644 --- a/src/reason-parser/reason_syntax_util.cppo.ml +++ b/src/reason-parser/reason_syntax_util.cppo.ml @@ -593,6 +593,7 @@ let noop_mapper super = signature_item = noop; } (* Don't need to backport past 4.08 *) let backport_letopt_mapper = noop_mapper +let expand_letop_identifier s = s #else (* Adapted from https://github.com/ocaml-ppx/ocaml-syntax-shims, for * compatibility with OCaml's own backporting. *) @@ -615,7 +616,7 @@ let backport_letopt_mapper = noop_mapper | '|' -> "pipe" | c -> String.make 1 c - let expand s = + let expand_letop_identifier s = let buf = Buffer.create 128 in (* "let" or "and" *) Buffer.add_string buf (String.sub s 0 3); @@ -667,7 +668,7 @@ let backport_letopt_mapper super = let (pattern, expr, op) = loop rest in let and_op_ident = Ast_helper.Exp.ident ~loc:op.loc - (Location.mkloc (Longident.Lident (expand op.txt)) op.loc) + (Location.mkloc (Longident.Lident op.txt) op.loc) in ( Ast_helper.Pat.tuple ~loc:pbop_loc [pbop_pat; pattern], @@ -678,7 +679,7 @@ let backport_letopt_mapper super = let (pattern, expr, _) = loop (let_::ands) in let let_op_ident = Ast_helper.Exp.ident ~loc:let_.pbop_op.loc - (Location.mkloc (Longident.Lident (expand let_.pbop_op.txt)) let_.pbop_op.loc) + (Location.mkloc (Longident.Lident let_.pbop_op.txt) let_.pbop_op.loc) in super.expr mapper {expr with pexp_desc = Pexp_apply (let_op_ident, [ diff --git a/src/reason-parser/reason_syntax_util.cppo.mli b/src/reason-parser/reason_syntax_util.cppo.mli index 05f46298a..2b2cbc4cb 100644 --- a/src/reason-parser/reason_syntax_util.cppo.mli +++ b/src/reason-parser/reason_syntax_util.cppo.mli @@ -38,6 +38,8 @@ val isLineComment : string -> bool val remove_stylistic_attrs_mapper : Ast_mapper.mapper +val expand_letop_identifier : string -> string + val backport_letopt_mapper : Ast_mapper.mapper -> Ast_mapper.mapper val escape_stars_slashes : string -> string From 88a5b210944d4455d9f1adec3c3b14d9bda949c0 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 10:54:44 -0700 Subject: [PATCH 5/8] print to letop --- src/reason-parser/reason_pprint_ast.ml | 37 +++----- src/reason-parser/reason_syntax_util.cppo.ml | 95 +++++++++++++++---- src/reason-parser/reason_syntax_util.cppo.mli | 3 + 3 files changed, 93 insertions(+), 42 deletions(-) diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index 802e5d2e6..78dcdff26 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -469,9 +469,6 @@ let unary_plus_prefix_symbols = ["~+"; "~+." ] ;; let infix_symbols = [ '='; '<'; '>'; '@'; '^'; '|'; '&'; '+'; '-'; '*'; '/'; '$'; '%'; '\\'; '#' ] (* this should match "kwdopchar" from reason_declarative_lexer.mll *) -let let_monad_symbols = [ '$'; '&'; '*'; '+'; '-'; '/'; '<'; '='; '>'; '@'; - '^'; '|'; '.'; '!'] - let special_infix_strings = ["asr"; "land"; "lor"; "lsl"; "lsr"; "lxor"; "mod"; "or"; ":="; "!="; "!=="] @@ -482,20 +479,6 @@ let requireIndentFor = [updateToken; ":="] let namedArgSym = "~" -let letop s = - String.length s > 3 - && s.[0] = 'l' - && s.[1] = 'e' - && s.[2] = 't' - && List.mem s.[3] let_monad_symbols - -let andop s = - String.length s > 3 - && s.[0] = 'a' - && s.[1] = 'n' - && s.[2] = 'd' - && List.mem s.[3] let_monad_symbols - let requireNoSpaceFor tok = tok = pipeFirstToken || (tok.[0] = '#' && tok <> "#=") @@ -531,8 +514,8 @@ let printedStringAndFixity = function else AlmostSimplePrefix s ) - | s when letop s -> Letop s - | s when andop s -> Andop s + | s when is_letop s -> Letop s + | s when is_andop s -> Andop s | _ -> Normal @@ -1979,9 +1962,15 @@ let typeApplicationFinalWrapping typeApplicationItems = (* add parentheses to binders when they are in fact infix or prefix operators *) let protectIdentifier txt = - if not (needs_parens txt) then atom txt - else if needs_spaces txt then makeList ~wrap:("(", ")") ~pad:(true, true) [atom txt] - else atom ("(" ^ txt ^ ")") + let txt' = + if is_andop txt || is_letop txt then + Reason_syntax_util.compress_letop_identifier txt + else + txt + in + if not (needs_parens txt) then atom txt' + else if needs_spaces txt then makeList ~wrap:("(", ")") ~pad:(true, true) [atom txt'] + else atom ("(" ^ txt' ^ ")") let protectLongIdentifier longPrefix txt = makeList [longPrefix; atom "."; protectIdentifier txt] @@ -5482,14 +5471,14 @@ let printer = object(self:'self) itemsLayout method letop_bindings { let_; ands } = - let label = let_.pbop_op.txt in + let label = compress_letop_identifier (let_.pbop_op.txt) in let let_item = self#binding_op label let_ in match ands with | [] -> let_item | l -> let and_items = List.map (fun x -> let loc = extractLocBindingOp x in - let layout = self#binding_op x.pbop_op.txt x in + let layout = self#binding_op (compress_letop_identifier x.pbop_op.txt) x in (loc, layout) ) l in diff --git a/src/reason-parser/reason_syntax_util.cppo.ml b/src/reason-parser/reason_syntax_util.cppo.ml index 62cb71564..1c12c38e9 100644 --- a/src/reason-parser/reason_syntax_util.cppo.ml +++ b/src/reason-parser/reason_syntax_util.cppo.ml @@ -582,6 +582,35 @@ let remove_stylistic_attrs_mapper_maker super = let remove_stylistic_attrs_mapper = remove_stylistic_attrs_mapper_maker Ast_mapper.default_mapper +let let_monad_symbols = [ '$'; '&'; '*'; '+'; '-'; '/'; '<'; '='; '>'; '@'; + '^'; '|'; '.'; '!'] + +let is_letop s = + String.length s > 3 + && s.[0] = 'l' + && s.[1] = 'e' + && s.[2] = 't' +#if OCAML_VERSION >= (4, 8, 0) + && List.mem s.[3] let_monad_symbols +#else + && s.[3] = '_' + && s.[4] = '_' + && List.mem s.[5] let_monad_symbols +#endif + +let is_andop s = + String.length s > 3 + && s.[0] = 'a' + && s.[1] = 'n' + && s.[2] = 'd' +#if OCAML_VERSION >= (4, 8, 0) + && List.mem s.[3] let_monad_symbols +#else + && s.[3] = '_' + && s.[4] = '_' + && List.mem s.[5] let_monad_symbols +#endif + #if OCAML_VERSION >= (4, 8, 0) let noop_mapper super = let noop = fun _mapper x -> x in @@ -597,24 +626,54 @@ let expand_letop_identifier s = s #else (* Adapted from https://github.com/ocaml-ppx/ocaml-syntax-shims, for * compatibility with OCaml's own backporting. *) - let name = function - | '!' -> "bang" - | '$' -> "dollar" - | '%' -> "percent" - | '&' -> "ampersand" - | '*' -> "star" - | '+' -> "plus" - | '-' -> "minus" - | '/' -> "slash" - | ':' -> "colon" - | '<' -> "lesser" - | '=' -> "equal" - | '>' -> "greater" - | '?' -> "question" - | '@' -> "at" - | '^' -> "circumflex" - | '|' -> "pipe" - | c -> String.make 1 c + let letop_table, reverse_letop_table = + let create_hashtable n l = + let t = Hashtbl.create n in + let rev_t = Hashtbl.create n in + List.iter (fun (k, v) -> + Hashtbl.add t k v; + Hashtbl.add rev_t v k; + ) l; + t, rev_t + in + create_hashtable 16 [ + '!', "bang" + ; '$', "dollar" + ; '%', "percent" + ; '&', "ampersand" + ; '*', "star" + ; '+', "plus" + ; '-', "minus" + ; '/', "slash" + ; ':', "colon" + ; '<', "lesser" + ; '=', "equal" + ; '>', "greater" + ; '?', "question" + ; '@', "at" + ; '^', "circumflex" + ; '|', "pipe" + ] + + let name s = + try Hashtbl.find letop_table s + with Not_found -> String.make 1 s + + let rev_name s = + try String.make 1 (Hashtbl.find reverse_letop_table s) + with Not_found -> s + + let compress_letop_identifier s = + let buf = Buffer.create 128 in + (* "let" or "and" *) + Buffer.add_string buf (String.sub s 0 3); + let s = String.sub s 5 (String.length s - 5) in + let segments = String.split_on_char '_' s in + List.iter (function + | "" -> Buffer.add_string buf "_" + | segment -> Buffer.add_string buf (rev_name segment)) + segments; + Buffer.contents buf let expand_letop_identifier s = let buf = Buffer.create 128 in diff --git a/src/reason-parser/reason_syntax_util.cppo.mli b/src/reason-parser/reason_syntax_util.cppo.mli index 2b2cbc4cb..5f363a9a7 100644 --- a/src/reason-parser/reason_syntax_util.cppo.mli +++ b/src/reason-parser/reason_syntax_util.cppo.mli @@ -38,6 +38,9 @@ val isLineComment : string -> bool val remove_stylistic_attrs_mapper : Ast_mapper.mapper +val is_letop : string -> bool +val is_andop : string -> bool +val compress_letop_identifier : string -> string val expand_letop_identifier : string -> string val backport_letopt_mapper : Ast_mapper.mapper -> Ast_mapper.mapper From a18a94605c09ddfd56144f2a33ea30887188df1b Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 11:07:17 -0700 Subject: [PATCH 6/8] fix test --- src/reason-parser/reason_syntax_util.cppo.ml | 38 ++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/reason-parser/reason_syntax_util.cppo.ml b/src/reason-parser/reason_syntax_util.cppo.ml index 1c12c38e9..d8538e7c6 100644 --- a/src/reason-parser/reason_syntax_util.cppo.ml +++ b/src/reason-parser/reason_syntax_util.cppo.ml @@ -579,6 +579,15 @@ let remove_stylistic_attrs_mapper_maker super = end; } +let escape_stars_slashes str = + if String.contains str '/' then + replace_string "/*" "/\\*" @@ + replace_string "*/" "*\\/" @@ + replace_string "//" "/\\/" @@ + str + else + str + let remove_stylistic_attrs_mapper = remove_stylistic_attrs_mapper_maker Ast_mapper.default_mapper @@ -586,7 +595,11 @@ let let_monad_symbols = [ '$'; '&'; '*'; '+'; '-'; '/'; '<'; '='; '>'; '@'; '^'; '|'; '.'; '!'] let is_letop s = +#if OCAML_VERSION >= (4, 8, 0) String.length s > 3 +#else + String.length s > 5 +#endif && s.[0] = 'l' && s.[1] = 'e' && s.[2] = 't' @@ -599,7 +612,11 @@ let is_letop s = #endif let is_andop s = +#if OCAML_VERSION >= (4, 8, 0) String.length s > 3 +#else + String.length s > 5 +#endif && s.[0] = 'a' && s.[1] = 'n' && s.[2] = 'd' @@ -623,6 +640,7 @@ let noop_mapper super = (* Don't need to backport past 4.08 *) let backport_letopt_mapper = noop_mapper let expand_letop_identifier s = s +let compress_letop_identifier s = s #else (* Adapted from https://github.com/ocaml-ppx/ocaml-syntax-shims, for * compatibility with OCaml's own backporting. *) @@ -669,11 +687,12 @@ let expand_letop_identifier s = s Buffer.add_string buf (String.sub s 0 3); let s = String.sub s 5 (String.length s - 5) in let segments = String.split_on_char '_' s in - List.iter (function - | "" -> Buffer.add_string buf "_" - | segment -> Buffer.add_string buf (rev_name segment)) - segments; - Buffer.contents buf + let identifier = String.concat "" (List.map (function + | "" -> "_" + | segment -> rev_name segment) segments) + in + Buffer.add_string buf identifier; + escape_stars_slashes (Buffer.contents buf) let expand_letop_identifier s = let buf = Buffer.create 128 in @@ -749,15 +768,6 @@ let backport_letopt_mapper super = } #endif -let escape_stars_slashes str = - if String.contains str '/' then - replace_string "/*" "/\\*" @@ - replace_string "*/" "*\\/" @@ - replace_string "//" "/\\/" @@ - str - else - str - (** escape_stars_slashes_mapper escapes all stars and slashes in an AST *) let escape_stars_slashes_mapper = identifier_mapper escape_stars_slashes From ef4e819969e46cb144a546e3cc4aa44923db6559 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 11:16:26 -0700 Subject: [PATCH 7/8] one more fix --- src/reason-parser/reason_pprint_ast.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index 78dcdff26..5de20f44a 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -1962,15 +1962,16 @@ let typeApplicationFinalWrapping typeApplicationItems = (* add parentheses to binders when they are in fact infix or prefix operators *) let protectIdentifier txt = - let txt' = + let needs_parens = needs_parens txt in + let txt = if is_andop txt || is_letop txt then Reason_syntax_util.compress_letop_identifier txt else txt in - if not (needs_parens txt) then atom txt' - else if needs_spaces txt then makeList ~wrap:("(", ")") ~pad:(true, true) [atom txt'] - else atom ("(" ^ txt' ^ ")") + if not needs_parens then atom txt + else if needs_spaces txt then makeList ~wrap:("(", ")") ~pad:(true, true) [atom txt] + else atom ("(" ^ txt ^ ")") let protectLongIdentifier longPrefix txt = makeList [longPrefix; atom "."; protectIdentifier txt] From 286482590c94e27387c008b4b4a4713da9c53c20 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Wed, 19 Aug 2020 11:21:24 -0700 Subject: [PATCH 8/8] String.split_on_char not available in 4.03 --- src/reason-parser/reason_syntax_util.cppo.ml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/reason-parser/reason_syntax_util.cppo.ml b/src/reason-parser/reason_syntax_util.cppo.ml index d8538e7c6..d7eef8184 100644 --- a/src/reason-parser/reason_syntax_util.cppo.ml +++ b/src/reason-parser/reason_syntax_util.cppo.ml @@ -681,12 +681,24 @@ let compress_letop_identifier s = s try String.make 1 (Hashtbl.find reverse_letop_table s) with Not_found -> s + let split_on_char sep s = + let open String in + let r = ref [] in + let j = ref (length s) in + for i = length s - 1 downto 0 do + if unsafe_get s i = sep then begin + r := sub s (i + 1) (!j - i - 1) :: !r; + j := i + end + done; + sub s 0 !j :: !r + let compress_letop_identifier s = let buf = Buffer.create 128 in (* "let" or "and" *) Buffer.add_string buf (String.sub s 0 3); let s = String.sub s 5 (String.length s - 5) in - let segments = String.split_on_char '_' s in + let segments = split_on_char '_' s in let identifier = String.concat "" (List.map (function | "" -> "_" | segment -> rev_name segment) segments)