diff --git a/CHANGES.md b/CHANGES.md index 83f0899625..9e078cf01f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ profile. This started with version 0.26.0. - Remove trailing space inside a wrapping empty signature (#2443, @Julow) - Fix extension-point spacing in structures (#2450, @Julow) - \* Consistent break after string constant argument (#2453, @Julow) +- Fix invalid syntax generated with `ocp-indent-compat` (#2445, @Julow) ## 0.26.1 (2023-09-15) diff --git a/lib/Fmt_ast.ml b/lib/Fmt_ast.ml index 54ec5e33dc..466d3cae99 100644 --- a/lib/Fmt_ast.ml +++ b/lib/Fmt_ast.ml @@ -1596,15 +1596,14 @@ and fmt_infix_op_args c ~parens xexp op_args = true | _ -> false in - let fmt_arg ~epi ~very_last xarg = + let fmt_arg ~pro ~very_last xarg = let parens = ((not very_last) && exposed_right_exp Ast.Non_apply xarg.ast) || parenze_exp xarg in if Params.Exp.Infix_op_arg.dock c.conf xarg then - (* Indentation of docked fun or function start before the operator. - Warning: [fmt_expression] doesn't use the [epi] in every case. *) - hovbox 2 (fmt_expression c ~parens ~box:false ~epi xarg) + (* Indentation of docked fun or function start before the operator. *) + hovbox 2 (fmt_expression c ~parens ~box:false ~pro xarg) else let expr_box = match xarg.ast.pexp_desc with @@ -1612,7 +1611,7 @@ and fmt_infix_op_args c ~parens xexp op_args = | _ -> None in hvbox 0 - ( epi + ( pro $ hovbox_if (not very_last) 2 (fmt_expression c ?box:expr_box ~parens xarg) ) in @@ -1623,7 +1622,7 @@ and fmt_infix_op_args c ~parens xexp op_args = (fun ~first ~last (cmts_before, cmts_after, (op, xarg)) -> let very_first = first_grp && first in let very_last = last_grp && last in - let epi, before_arg = + let pro, before_arg = let break = if very_last && is_not_indented xarg then fmt "@ " else fmt_if (not very_first) " " @@ -1633,7 +1632,7 @@ and fmt_infix_op_args c ~parens xexp op_args = | None -> (op $ break, noop) in fmt_opt cmts_before $ before_arg - $ fmt_arg ~epi ~very_last xarg + $ fmt_arg ~pro ~very_last xarg $ fmt_if_k (not last) (break 1 0) ) ) $ fmt_if_k (not last_grp) (break 1 0) in @@ -1667,11 +1666,11 @@ and fmt_pat_cons c ~parens args = Params.Exp.Infix_op_arg.wrap c.conf ~parens ~parens_nested:false (list_fl groups fmt_op_arg_group) -and fmt_match c ?epi ~parens ?ext ctx xexp cs e0 keyword = +and fmt_match c ?pro ~parens ?ext ctx xexp cs e0 keyword = let ctx0 = xexp.ctx in let indent = Params.match_indent c.conf ~parens ~ctx:ctx0 in hvbox indent - ( fmt_opt epi + ( fmt_opt pro $ Params.Exp.wrap c.conf ~parens ~disambiguate:true @@ Params.Align.match_ c.conf ~xexp @@ ( hvbox 0 @@ -1683,8 +1682,8 @@ and fmt_match c ?epi ~parens ?ext ctx xexp cs e0 keyword = $ fmt "@ with" ) $ fmt "@ " $ fmt_cases c ctx cs ) ) -and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) - ?ext ({ast= exp; ctx= ctx0} as xexp) = +and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens + ?(indent_wrap = 0) ?ext ({ast= exp; ctx= ctx0} as xexp) = protect c (Exp exp) @@ let {pexp_desc; pexp_loc; pexp_attributes; _} = exp in @@ -1701,7 +1700,6 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) in hvbox_if box 0 ~name:"expr" @@ fmt_cmts - @@ (fun fmt -> fmt_opt pro $ fmt) @@ match pexp_desc with | Pexp_apply (_, []) -> impossible "not produced by parser" @@ -1725,19 +1723,20 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) ~break in let fmt_grp grp = list grp " ;@ " (fmt_expression c) in - hvbox 0 - (Params.parens_if parens c.conf - ( hvbox c.conf.fmt_opts.extension_indent.v - (wrap "[" "]" - ( str "%" - $ hovbox 2 - ( fmt_str_loc c name $ str " fun " - $ fmt_attributes c ~suf:" " call.pexp_attributes - $ fmt_fun_args c xargs $ fmt_opt fmt_cstr $ fmt "@ ->" - ) - $ fmt "@ " $ fmt_expression c xbody ) ) - $ fmt "@ ;@ " - $ list grps " ;@;<1000 0>" fmt_grp ) ) + pro + $ hvbox 0 + (Params.parens_if parens c.conf + ( hvbox c.conf.fmt_opts.extension_indent.v + (wrap "[" "]" + ( str "%" + $ hovbox 2 + ( fmt_str_loc c name $ str " fun " + $ fmt_attributes c ~suf:" " call.pexp_attributes + $ fmt_fun_args c xargs $ fmt_opt fmt_cstr + $ fmt "@ ->" ) + $ fmt "@ " $ fmt_expression c xbody ) ) + $ fmt "@ ;@ " + $ list grps " ;@;<1000 0>" fmt_grp ) ) | Pexp_infix ( {txt= "|>"; loc} , e0 @@ -1751,20 +1750,21 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) ; _ } ) -> let xargs, xbody = Sugar.fun_ c.cmts (sub_exp ~ctx:(Str pld) retn) in let fmt_cstr, xbody = type_constr_and_body c xbody in - hvbox 0 - (Params.Exp.wrap c.conf ~parens - ( fmt_expression c (sub_exp ~ctx e0) - $ fmt "@\n" - $ Cmts.fmt c loc (fmt "|>@\n") - $ hvbox c.conf.fmt_opts.extension_indent.v - (wrap "[" "]" - ( str "%" - $ hovbox 2 - ( fmt_str_loc c name $ str " fun " - $ fmt_attributes c ~suf:" " retn.pexp_attributes - $ fmt_fun_args c xargs $ fmt_opt fmt_cstr $ fmt "@ ->" - ) - $ fmt "@ " $ fmt_expression c xbody ) ) ) ) + pro + $ hvbox 0 + (Params.Exp.wrap c.conf ~parens + ( fmt_expression c (sub_exp ~ctx e0) + $ fmt "@\n" + $ Cmts.fmt c loc (fmt "|>@\n") + $ hvbox c.conf.fmt_opts.extension_indent.v + (wrap "[" "]" + ( str "%" + $ hovbox 2 + ( fmt_str_loc c name $ str " fun " + $ fmt_attributes c ~suf:" " retn.pexp_attributes + $ fmt_fun_args c xargs $ fmt_opt fmt_cstr + $ fmt "@ ->" ) + $ fmt "@ " $ fmt_expression c xbody ) ) ) ) | Pexp_infix ({txt= ":="; loc}, r, v) when is_simple c.conf (expression_width c) (sub_exp ~ctx r) -> let bol_indent = Params.Indent.assignment_operator_bol c.conf in @@ -1779,19 +1779,20 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) Cmts.fmt_before c loc ~pro:(break 1 indent) ~epi:adj ~adj in let cmts_after = Cmts.fmt_after c loc ~pro:noop ~epi:noop in - Params.parens_if parens c.conf - (hovbox 0 - ( match c.conf.fmt_opts.assignment_operator.v with - | `Begin_line -> - hvbox 0 (fmt_expression c (sub_exp ~ctx r) $ cmts_before) - $ break 1 bol_indent $ fmt ":= " $ cmts_after - $ hvbox 2 (fmt_expression c (sub_exp ~ctx v)) - | `End_line -> - hvbox 0 - ( hvbox 0 (fmt_expression c (sub_exp ~ctx r) $ cmts_before) - $ str " :=" ) - $ fmt "@;<1 2>" $ cmts_after - $ hvbox 2 (fmt_expression c (sub_exp ~ctx v)) ) ) + pro + $ Params.parens_if parens c.conf + (hovbox 0 + ( match c.conf.fmt_opts.assignment_operator.v with + | `Begin_line -> + hvbox 0 (fmt_expression c (sub_exp ~ctx r) $ cmts_before) + $ break 1 bol_indent $ fmt ":= " $ cmts_after + $ hvbox 2 (fmt_expression c (sub_exp ~ctx v)) + | `End_line -> + hvbox 0 + ( hvbox 0 (fmt_expression c (sub_exp ~ctx r) $ cmts_before) + $ str " :=" ) + $ fmt "@;<1 2>" $ cmts_after + $ hvbox 2 (fmt_expression c (sub_exp ~ctx v)) ) ) | Pexp_prefix ({txt= ("~-" | "~-." | "~+" | "~+.") as op; loc}, e1) -> let op = if Location.width loc = String.length op - 1 then @@ -1799,16 +1800,18 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) else op in let spc = fmt_if (Exp.exposed_left e1) "@ " in - Params.parens_if parens c.conf - ( Cmts.fmt c pexp_loc - @@ hvbox 2 (str op $ spc $ fmt_expression c (sub_exp ~ctx e1)) - $ fmt_atrs ) + pro + $ Params.parens_if parens c.conf + ( Cmts.fmt c pexp_loc + @@ hvbox 2 (str op $ spc $ fmt_expression c (sub_exp ~ctx e1)) + $ fmt_atrs ) | Pexp_infix (({txt= id; _} as op), l, ({pexp_desc= Pexp_ident _; _} as r)) when Std_longident.String_id.is_hash_getter id -> - Params.parens_if parens c.conf - ( fmt_expression c (sub_exp ~ctx l) - $ hvbox 0 (fmt_str_loc c op) - $ fmt_expression c (sub_exp ~ctx r) ) + pro + $ Params.parens_if parens c.conf + ( fmt_expression c (sub_exp ~ctx l) + $ hvbox 0 (fmt_str_loc c op) + $ fmt_expression c (sub_exp ~ctx r) ) | Pexp_infix (op, l, ({pexp_desc= Pexp_fun _; pexp_loc; pexp_attributes; _} as r)) when not c.conf.fmt_opts.break_infix_before_func.v -> @@ -1827,27 +1830,28 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) true | _ -> false in - wrap_fits_breaks_if c.conf parens "(" ")" - ( hovbox 0 - (wrap_if has_attr "(" ")" - ( hvbox 2 - ( hvbox indent_wrap - ( fmt_expression ~indent_wrap c (sub_exp ~ctx l) - $ fmt "@;" - $ hovbox 2 - ( hvbox 0 - ( fmt_str_loc c op $ fmt "@ " $ cmts_before - $ fmt_if parens_r "(" $ str "fun " ) - $ fmt_attributes c pexp_attributes ~suf:" " - $ hvbox_if - (not c.conf.fmt_opts.wrap_fun_args.v) - 4 - (fmt_fun_args c xargs $ fmt_opt fmt_cstr) - $ fmt "@ ->" ) ) - $ pre_body ) - $ fmt_or followed_by_infix_op "@;<1000 0>" "@ " - $ body $ fmt_if parens_r ")" $ cmts_after ) ) - $ fmt_atrs ) + pro + $ wrap_fits_breaks_if c.conf parens "(" ")" + ( hovbox 0 + (wrap_if has_attr "(" ")" + ( hvbox 2 + ( hvbox indent_wrap + ( fmt_expression ~indent_wrap c (sub_exp ~ctx l) + $ fmt "@;" + $ hovbox 2 + ( hvbox 0 + ( fmt_str_loc c op $ fmt "@ " $ cmts_before + $ fmt_if parens_r "(" $ str "fun " ) + $ fmt_attributes c pexp_attributes ~suf:" " + $ hvbox_if + (not c.conf.fmt_opts.wrap_fun_args.v) + 4 + (fmt_fun_args c xargs $ fmt_opt fmt_cstr) + $ fmt "@ ->" ) ) + $ pre_body ) + $ fmt_or followed_by_infix_op "@;<1000 0>" "@ " + $ body $ fmt_if parens_r ")" $ cmts_after ) ) + $ fmt_atrs ) | Pexp_infix ( op , l @@ -1858,19 +1862,20 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) let xr = sub_exp ~ctx r in let parens_r = parenze_exp xr in let indent = Params.Indent.function_ c.conf ~parens xr in - Params.parens_if parens c.conf - (hvbox indent - ( hvbox 0 - ( fmt_expression c (sub_exp ~ctx l) - $ fmt "@;" - $ hovbox 2 - ( hvbox 0 - ( fmt_str_loc c op $ fmt "@ " $ cmts_before - $ fmt_if parens_r "( " $ str "function" - $ fmt_extension_suffix c ext ) - $ fmt_attributes c pexp_attributes ) ) - $ fmt "@ " $ fmt_cases c (Exp r) cs $ fmt_if parens_r " )" - $ cmts_after ) ) + pro + $ Params.parens_if parens c.conf + (hvbox indent + ( hvbox 0 + ( fmt_expression c (sub_exp ~ctx l) + $ fmt "@;" + $ hovbox 2 + ( hvbox 0 + ( fmt_str_loc c op $ fmt "@ " $ cmts_before + $ fmt_if parens_r "( " $ str "function" + $ fmt_extension_suffix c ext ) + $ fmt_attributes c pexp_attributes ) ) + $ fmt "@ " $ fmt_cases c (Exp r) cs $ fmt_if parens_r " )" + $ cmts_after ) ) | Pexp_infix _ -> let op_args = Sugar.Exp.infix c.cmts (prec_ast (Exp exp)) xexp in let inner_wrap = parens || has_attr in @@ -1920,18 +1925,20 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) (fmt_before_cmts, fmt_after_cmts, (fmt_op, arg)) | None -> (None, None, (noop, arg)) ) in - hvbox_if outer_wrap 0 - (Params.parens_if outer_wrap c.conf - (hvbox indent_wrap - ( fmt_infix_op_args ~parens:inner_wrap c xexp infix_op_args - $ fmt_atrs ) ) ) + pro + $ hvbox_if outer_wrap 0 + (Params.parens_if outer_wrap c.conf + (hvbox indent_wrap + ( fmt_infix_op_args ~parens:inner_wrap c xexp infix_op_args + $ fmt_atrs ) ) ) | Pexp_prefix (op, e) -> let has_cmts = Cmts.has_before c.cmts e.pexp_loc in - hvbox 2 - (Params.Exp.wrap c.conf ~parens - ( fmt_str_loc c op $ fmt_if has_cmts "@," - $ fmt_expression c ~box (sub_exp ~ctx e) - $ fmt_atrs ) ) + pro + $ hvbox 2 + (Params.Exp.wrap c.conf ~parens + ( fmt_str_loc c op $ fmt_if has_cmts "@," + $ fmt_expression c ~box (sub_exp ~ctx e) + $ fmt_atrs ) ) | Pexp_apply (e0, e1N1) -> ( let wrap = if c.conf.fmt_opts.wrap_fun_args.v then Fn.id else hvbox 2 @@ -1950,8 +1957,7 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) (not c.conf.fmt_opts.ocp_indent_compat.v) || Location.line_difference e0.pexp_loc last_arg.pexp_loc = 0 in - if parens || not dock_fun_arg then (noop, fmt_opt epi) - else (fmt_opt epi, noop) + if parens || not dock_fun_arg then (noop, pro) else (pro, noop) in match last_arg.pexp_desc with | Pexp_fun (_, _, _, eN1_body) @@ -2055,102 +2061,115 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) Fit else Break in - fmt_opt epi $ fmt_if parens "(" + pro $ fmt_if parens "(" $ hvbox 2 ( fmt_args_grouped ~epi:fmt_atrs e0 e1N1 $ fmt_if_k parens (closing_paren c ~force ~offset:(-3)) ) ) | Pexp_array [] -> - hvbox 0 - (Params.parens_if parens c.conf - ( wrap_fits_breaks c.conf "[|" "|]" (Cmts.fmt_within c pexp_loc) - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.parens_if parens c.conf + ( wrap_fits_breaks c.conf "[|" "|]" (Cmts.fmt_within c pexp_loc) + $ fmt_atrs ) ) | Pexp_array e1N -> let p = Params.get_array_expr c.conf in - hvbox_if has_attr 0 - (Params.parens_if parens c.conf - ( p.box - (fmt_expressions c (expression_width c) (sub_exp ~ctx) e1N - (sub_exp ~ctx >> fmt_expression c) - p pexp_loc ) - $ fmt_atrs ) ) + pro + $ hvbox_if has_attr 0 + (Params.parens_if parens c.conf + ( p.box + (fmt_expressions c (expression_width c) (sub_exp ~ctx) e1N + (sub_exp ~ctx >> fmt_expression c) + p pexp_loc ) + $ fmt_atrs ) ) | Pexp_list e1N -> let p = Params.get_list_expr c.conf in let offset = if c.conf.fmt_opts.dock_collection_brackets.v then 0 else 2 in let cmt_break = break 1 offset in - hvbox_if has_attr 0 - (Params.parens_if parens c.conf - ( p.box - (fmt_expressions c (expression_width c) (sub_exp ~ctx) e1N - (fun e -> - let fmt_cmts = Cmts.fmt c ~eol:cmt_break e.pexp_loc in - fmt_cmts @@ (sub_exp ~ctx >> fmt_expression c) e ) - p pexp_loc ) - $ fmt_atrs ) ) + pro + $ hvbox_if has_attr 0 + (Params.parens_if parens c.conf + ( p.box + (fmt_expressions c (expression_width c) (sub_exp ~ctx) e1N + (fun e -> + let fmt_cmts = Cmts.fmt c ~eol:cmt_break e.pexp_loc in + fmt_cmts @@ (sub_exp ~ctx >> fmt_expression c) e ) + p pexp_loc ) + $ fmt_atrs ) ) | Pexp_assert e0 -> let paren_body = if Exp.is_symbol e0 || Exp.is_monadic_binding e0 then not (List.is_empty e0.pexp_attributes) else parenze_exp (sub_exp ~ctx e0) in - hovbox 0 - (Params.parens_if parens c.conf - (hvbox 0 - ( hvbox 2 - ( str "assert" - $ fmt_extension_suffix c ext - $ fmt_or paren_body " (@," "@ " - $ fmt_expression c ~parens:false (sub_exp ~ctx e0) ) - $ fmt_if_k paren_body (closing_paren c) - $ fmt_atrs ) ) ) + pro + $ hovbox 0 + (Params.parens_if parens c.conf + (hvbox 0 + ( hvbox 2 + ( str "assert" + $ fmt_extension_suffix c ext + $ fmt_or paren_body " (@," "@ " + $ fmt_expression c ~parens:false (sub_exp ~ctx e0) ) + $ fmt_if_k paren_body (closing_paren c) + $ fmt_atrs ) ) ) | Pexp_constant const -> - Params.parens_if - (parens || not (List.is_empty pexp_attributes)) - c.conf - (fmt_constant c ?epi const $ fmt_atrs) + pro + $ Params.parens_if + (parens || not (List.is_empty pexp_attributes)) + c.conf + (fmt_constant c const $ fmt_atrs) | Pexp_constraint (e, t) -> - hvbox - (Params.Indent.exp_constraint c.conf) - ( wrap_fits_breaks ~space:false c.conf "(" ")" - ( fmt_expression c (sub_exp ~ctx e) - $ fmt "@ : " - $ fmt_core_type c (sub_typ ~ctx t) ) - $ fmt_atrs ) + pro + $ hvbox + (Params.Indent.exp_constraint c.conf) + ( wrap_fits_breaks ~space:false c.conf "(" ")" + ( fmt_expression c (sub_exp ~ctx e) + $ fmt "@ : " + $ fmt_core_type c (sub_typ ~ctx t) ) + $ fmt_atrs ) | Pexp_construct ({txt= Lident (("()" | "[]") as txt); loc}, None) -> let opn = char txt.[0] and cls = char txt.[1] in - let pro = str " " and epi = str " " in - Cmts.fmt c loc - @@ hvbox 0 - (Params.parens_if parens c.conf - ( wrap_k opn cls (Cmts.fmt_within c ~pro ~epi pexp_loc) - $ fmt_atrs ) ) + pro + $ Cmts.fmt c loc + @@ hvbox 0 + (Params.parens_if parens c.conf + ( wrap_k opn cls + (Cmts.fmt_within c ~pro:(str " ") ~epi:(str " ") pexp_loc) + $ fmt_atrs ) ) | Pexp_construct (lid, None) -> - Params.parens_if parens c.conf (fmt_longident_loc c lid $ fmt_atrs) + pro + $ Params.parens_if parens c.conf (fmt_longident_loc c lid $ fmt_atrs) | Pexp_cons l -> - Cmts.fmt c pexp_loc - ( hvbox indent_wrap - (fmt_infix_op_args c ~parens xexp - (List.mapi l ~f:(fun i e -> - (None, None, (fmt_if (i > 0) "::", sub_exp ~ctx e)) ) ) ) - $ fmt_atrs ) + pro + $ Cmts.fmt c pexp_loc + ( hvbox indent_wrap + (fmt_infix_op_args c ~parens xexp + (List.mapi l ~f:(fun i e -> + (None, None, (fmt_if (i > 0) "::", sub_exp ~ctx e)) ) + ) ) + $ fmt_atrs ) | Pexp_construct (lid, Some arg) -> - Params.parens_if parens c.conf - ( hvbox 2 - ( fmt_longident_loc c lid $ fmt "@ " - $ fmt_expression c (sub_exp ~ctx arg) ) - $ fmt_atrs ) + pro + $ Params.parens_if parens c.conf + ( hvbox 2 + ( fmt_longident_loc c lid $ fmt "@ " + $ fmt_expression c (sub_exp ~ctx arg) ) + $ fmt_atrs ) | Pexp_variant (s, arg) -> - hvbox 2 - (Params.parens_if parens c.conf - ( variant_var c s - $ opt arg (fmt "@ " >$ (sub_exp ~ctx >> fmt_expression c)) - $ fmt_atrs ) ) + pro + $ hvbox 2 + (Params.parens_if parens c.conf + ( variant_var c s + $ opt arg (fmt "@ " >$ (sub_exp ~ctx >> fmt_expression c)) + $ fmt_atrs ) ) | Pexp_field (exp, lid) -> - hvbox 2 - (Params.parens_if parens c.conf - ( fmt_expression c (sub_exp ~ctx exp) - $ fmt "@,." $ fmt_longident_loc c lid $ fmt_atrs ) ) + pro + $ hvbox 2 + (Params.parens_if parens c.conf + ( fmt_expression c (sub_exp ~ctx exp) + $ fmt "@,." $ fmt_longident_loc c lid $ fmt_atrs ) ) | Pexp_newtype _ | Pexp_fun _ -> let xargs, xbody = Sugar.fun_ c.cmts xexp in let fmt_cstr, xbody = type_constr_and_body c xbody in @@ -2177,25 +2196,28 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) and args = fmt_fun_args c xargs in Params.Exp.box_fun_decl_args c.conf ~parens ~kw ~args ~annot:fmt_cstr in - hvbox_if (box || body_is_function) indent - (Params.Exp.wrap c.conf ~parens ~disambiguate:true ~fits_breaks:false - ~offset_closing_paren:(-2) - (hovbox 2 (intro $ str " ->" $ pre_body) $ fmt "@ " $ body) ) + pro + $ hvbox_if (box || body_is_function) indent + (Params.Exp.wrap c.conf ~parens ~disambiguate:true + ~fits_breaks:false ~offset_closing_paren:(-2) + (hovbox 2 (intro $ str " ->" $ pre_body) $ fmt "@ " $ body) ) | Pexp_function cs -> let indent = Params.Indent.function_ c.conf ~parens xexp in - Params.Exp.wrap c.conf ~parens ~disambiguate:true ~fits_breaks:false - @@ Params.Align.function_ c.conf ~parens ~ctx0 ~self:exp - @@ ( hvbox 2 - ( str "function" - $ fmt_extension_suffix c ext - $ fmt_attributes c pexp_attributes ) - $ break 1 indent - $ hvbox 0 (fmt_cases c ctx cs) ) + pro + $ Params.Exp.wrap c.conf ~parens ~disambiguate:true ~fits_breaks:false + @@ Params.Align.function_ c.conf ~parens ~ctx0 ~self:exp + @@ ( hvbox 2 + ( str "function" + $ fmt_extension_suffix c ext + $ fmt_attributes c pexp_attributes ) + $ break 1 indent + $ hvbox 0 (fmt_cases c ctx cs) ) | Pexp_ident {txt; loc} -> let outer_parens = has_attr && parens in - Cmts.fmt c loc - @@ wrap_if outer_parens "(" ")" - @@ (fmt_longident txt $ Cmts.fmt_within c loc $ fmt_atrs) + pro + $ Cmts.fmt c loc + @@ wrap_if outer_parens "(" ")" + @@ (fmt_longident txt $ Cmts.fmt_within c loc $ fmt_atrs) | Pexp_ifthenelse (if_branches, else_) -> let last_loc = match else_ with @@ -2216,66 +2238,72 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) List.rev ((None, sub_exp ~ctx x, []) :: List.rev with_conds) | None -> with_conds in - hvbox 0 - ( Params.Exp.wrap c.conf ~parens:(parens || has_attr) - (hvbox 0 - (list_fl cnd_exps - (fun ~first ~last (xcond, xbch, pexp_attributes) -> - let symbol_parens = Exp.is_symbol xbch.ast in - let parens_bch = parenze_exp xbch && not symbol_parens in - let parens_exp = false in - let p = - Params.get_if_then_else c.conf ~first ~last ~parens_bch - ~parens_prev_bch:!parens_prev_bch ~xcond ~xbch - ~expr_loc:pexp_loc - ~fmt_extension_suffix: - (Option.map ext ~f:(fun _ -> - fmt_extension_suffix c ext ) ) - ~fmt_attributes: - (fmt_attributes c ~pre:Blank pexp_attributes) - ~fmt_cond:(fmt_expression c) - in - parens_prev_bch := parens_bch ; - p.box_branch - ( p.cond - $ p.box_keyword_and_expr - ( p.branch_pro - $ p.wrap_parens - ( fmt_expression c ?box:p.box_expr - ~parens:parens_exp ?pro:p.expr_pro - ?eol:p.expr_eol p.branch_expr - $ p.break_end_branch ) ) ) - $ fmt_if_k (not last) p.space_between_branches ) ) ) - $ fmt_atrs ) + pro + $ hvbox 0 + ( Params.Exp.wrap c.conf ~parens:(parens || has_attr) + (hvbox 0 + (list_fl cnd_exps + (fun ~first ~last (xcond, xbch, pexp_attributes) -> + let symbol_parens = Exp.is_symbol xbch.ast in + let parens_bch = + parenze_exp xbch && not symbol_parens + in + let parens_exp = false in + let p = + Params.get_if_then_else c.conf ~first ~last + ~parens_bch ~parens_prev_bch:!parens_prev_bch + ~xcond ~xbch ~expr_loc:pexp_loc + ~fmt_extension_suffix: + (Option.map ext ~f:(fun _ -> + fmt_extension_suffix c ext ) ) + ~fmt_attributes: + (fmt_attributes c ~pre:Blank pexp_attributes) + ~fmt_cond:(fmt_expression c) + in + parens_prev_bch := parens_bch ; + p.box_branch + ( p.cond + $ p.box_keyword_and_expr + ( p.branch_pro + $ p.wrap_parens + ( fmt_expression c ?box:p.box_expr + ~parens:parens_exp ?pro:p.expr_pro + ?eol:p.expr_eol p.branch_expr + $ p.break_end_branch ) ) ) + $ fmt_if_k (not last) p.space_between_branches ) ) ) + $ fmt_atrs ) | Pexp_let (lbs, body) -> let bindings = Sugar.Let_binding.of_let_bindings c.cmts ~ctx lbs.pvbs_bindings in let fmt_expr = fmt_expression c (sub_exp ~ctx body) in let ext = lbs.pvbs_extension in - fmt_let_bindings c ?ext ~parens ~fmt_atrs ~fmt_expr ~has_attr - lbs.pvbs_rec bindings body + pro + $ fmt_let_bindings c ?ext ~parens ~fmt_atrs ~fmt_expr ~has_attr + lbs.pvbs_rec bindings body | Pexp_letop {let_; ands; body} -> let bd = Sugar.Let_binding.of_binding_ops c.cmts ~ctx (let_ :: ands) in let fmt_expr = fmt_expression c (sub_exp ~ctx body) in - fmt_let_bindings c ?ext ~parens ~fmt_atrs ~fmt_expr ~has_attr - Nonrecursive bd body + pro + $ fmt_let_bindings c ?ext ~parens ~fmt_atrs ~fmt_expr ~has_attr + Nonrecursive bd body | Pexp_letexception (ext_cstr, exp) -> let pre = str "let exception" $ fmt_extension_suffix c ext $ fmt "@ " in - hvbox 0 - ( Params.parens_if - (parens || not (List.is_empty pexp_attributes)) - c.conf - ( hvbox 0 - ( hvbox 2 - (hvbox 2 - (pre $ fmt_extension_constructor c ctx ext_cstr) ) - $ fmt "@ in" ) - $ fmt "@;<1000 0>" - $ fmt_expression c (sub_exp ~ctx exp) ) - $ fmt_atrs ) + pro + $ hvbox 0 + ( Params.parens_if + (parens || not (List.is_empty pexp_attributes)) + c.conf + ( hvbox 0 + ( hvbox 2 + (hvbox 2 + (pre $ fmt_extension_constructor c ctx ext_cstr) ) + $ fmt "@ in" ) + $ fmt "@;<1000 0>" + $ fmt_expression c (sub_exp ~ctx exp) ) + $ fmt_atrs ) | Pexp_letmodule (name, args, pmod, exp) -> let keyword = "let module" in let xbody = sub_mod ~ctx pmod in @@ -2294,18 +2322,19 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) | Pmod_apply _ | Pmod_apply_unit _ -> true | _ -> false in - hvbox 0 - ( Params.parens_if - (parens || not (List.is_empty pexp_attributes)) - c.conf - ( hvbox 2 - (fmt_module c ctx keyword ~eqty:":" name args (Some xbody) - xmty - ~attrs:(Ast_helper.Attr.ext_attrs ?ext ()) - ~epi:(str "in") ~can_sparse ~rec_flag:false ) - $ fmt "@;<1000 0>" - $ fmt_expression c (sub_exp ~ctx exp) ) - $ fmt_atrs ) + pro + $ hvbox 0 + ( Params.parens_if + (parens || not (List.is_empty pexp_attributes)) + c.conf + ( hvbox 2 + (fmt_module c ctx keyword ~eqty:":" name args (Some xbody) + xmty + ~attrs:(Ast_helper.Attr.ext_attrs ?ext ()) + ~epi:(str "in") ~can_sparse ~rec_flag:false ) + $ fmt "@;<1000 0>" + $ fmt_expression c (sub_exp ~ctx exp) ) + $ fmt_atrs ) | Pexp_open (lid, e0) -> let can_skip_parens = (not (Cmts.has_before c.cmts e0.pexp_loc)) @@ -2321,16 +2350,17 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) in let outer_parens = has_attr && parens in let inner_parens = not can_skip_parens in - hovbox 0 - (Params.parens_if outer_parens c.conf - ( hvbox 0 - ( hvbox 0 - ( fmt_longident_loc c lid $ str "." - $ fmt_if inner_parens "(" ) - $ fmt "@;<0 2>" - $ fmt_expression c (sub_exp ~ctx e0) - $ fmt_if_k inner_parens (closing_paren c) ) - $ fmt_atrs ) ) + pro + $ hovbox 0 + (Params.parens_if outer_parens c.conf + ( hvbox 0 + ( hvbox 0 + ( fmt_longident_loc c lid $ str "." + $ fmt_if inner_parens "(" ) + $ fmt "@;<0 2>" + $ fmt_expression c (sub_exp ~ctx e0) + $ fmt_if_k inner_parens (closing_paren c) ) + $ fmt_atrs ) ) | Pexp_letopen ( { popen_override= flag ; popen_expr @@ -2340,28 +2370,29 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) let override = is_override flag in let outer_parens = has_attr && parens in let inner_parens = has_attr || parens in - hovbox 0 - (Params.Exp.wrap c.conf ~parens:outer_parens ~fits_breaks:false - ( hvbox 0 - (Params.Exp.wrap c.conf ~parens:inner_parens - ~fits_breaks:false - (vbox 0 - ( hvbox 0 - ( fmt_module_statement c ~attributes - ~keyword: - ( hvbox 0 - ( str "let" $ break 1 0 - $ Cmts.fmt_before c popen_loc - $ fmt_or override "open!" "open" - $ opt ext (fun _ -> fmt_if override " ") - $ fmt_extension_suffix c ext ) - $ break 1 0 ) - (sub_mod ~ctx popen_expr) - $ Cmts.fmt_after c popen_loc - $ str " in" ) - $ break 1000 0 - $ fmt_expression c (sub_exp ~ctx e0) ) ) ) - $ fmt_atrs ) ) + pro + $ hovbox 0 + (Params.Exp.wrap c.conf ~parens:outer_parens ~fits_breaks:false + ( hvbox 0 + (Params.Exp.wrap c.conf ~parens:inner_parens + ~fits_breaks:false + (vbox 0 + ( hvbox 0 + ( fmt_module_statement c ~attributes + ~keyword: + ( hvbox 0 + ( str "let" $ break 1 0 + $ Cmts.fmt_before c popen_loc + $ fmt_or override "open!" "open" + $ opt ext (fun _ -> fmt_if override " ") + $ fmt_extension_suffix c ext ) + $ break 1 0 ) + (sub_mod ~ctx popen_expr) + $ Cmts.fmt_after c popen_loc + $ str " in" ) + $ break 1000 0 + $ fmt_expression c (sub_exp ~ctx e0) ) ) ) + $ fmt_atrs ) ) | Pexp_try (e0, [{pc_lhs; pc_guard; pc_rhs}]) when Poly.( c.conf.fmt_opts.single_case.v = `Compact @@ -2374,36 +2405,39 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) if c.conf.fmt_opts.leading_nested_match_parens.v then (false, None) else (parenze_exp xpc_rhs, Some false) in - Params.Exp.wrap c.conf ~parens ~disambiguate:true - (hvbox 2 - ( hvbox 0 - ( str "try" - $ fmt_extension_suffix c ext - $ fmt_attributes c pexp_attributes - $ fmt "@;<1 2>" - $ fmt_expression c (sub_exp ~ctx e0) ) - $ break 1 (-2) - $ hvbox 0 - ( hvbox 0 - ( fmt "with@ " $ leading_cmt - $ hvbox 0 - ( fmt_pattern c ~pro:(if_newline "| ") - (sub_pat ~ctx pc_lhs) - $ opt pc_guard (fun g -> - fmt "@ when " - $ fmt_expression c (sub_exp ~ctx g) ) - $ fmt "@ ->" $ fmt_if parens_here " (" ) ) - $ fmt "@;<1 2>" - $ cbox 0 (fmt_expression c ?parens:parens_for_exp xpc_rhs) ) - $ fmt_if parens_here - ( match c.conf.fmt_opts.indicate_multiline_delimiters.v with - | `No -> ")" - | `Space -> " )" - | `Closing_on_separate_line -> "@;<1000 -2>)" ) ) ) + pro + $ Params.Exp.wrap c.conf ~parens ~disambiguate:true + (hvbox 2 + ( hvbox 0 + ( str "try" + $ fmt_extension_suffix c ext + $ fmt_attributes c pexp_attributes + $ fmt "@;<1 2>" + $ fmt_expression c (sub_exp ~ctx e0) ) + $ break 1 (-2) + $ hvbox 0 + ( hvbox 0 + ( fmt "with@ " $ leading_cmt + $ hvbox 0 + ( fmt_pattern c ~pro:(if_newline "| ") + (sub_pat ~ctx pc_lhs) + $ opt pc_guard (fun g -> + fmt "@ when " + $ fmt_expression c (sub_exp ~ctx g) ) + $ fmt "@ ->" $ fmt_if parens_here " (" ) ) + $ fmt "@;<1 2>" + $ cbox 0 (fmt_expression c ?parens:parens_for_exp xpc_rhs) + ) + $ fmt_if parens_here + ( match c.conf.fmt_opts.indicate_multiline_delimiters.v with + | `No -> ")" + | `Space -> " )" + | `Closing_on_separate_line -> "@;<1000 -2>)" ) ) ) | Pexp_match (e0, cs) -> - fmt_match c ?epi ~parens ?ext ctx xexp cs e0 "match" - | Pexp_try (e0, cs) -> fmt_match c ?epi ~parens ?ext ctx xexp cs e0 "try" + fmt_match c ~pro ~parens ?ext ctx xexp cs e0 "match" + | Pexp_try (e0, cs) -> fmt_match c ~pro ~parens ?ext ctx xexp cs e0 "try" | Pexp_pack (me, pt) -> + let outer_pro = pro in let outer_parens = parens && has_attr in let inner_parens = true in let blk = fmt_module_expr c (sub_mod ~ctx me) in @@ -2432,9 +2466,10 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) $ fmt_package_type c ctx cnstrs ) | None -> m in - hvbox 0 - (Params.parens_if outer_parens c.conf - (compose_module ~pro ~epi blk ~f:fmt_mod $ fmt_atrs) ) + outer_pro + $ hvbox 0 + (Params.parens_if outer_parens c.conf + (compose_module ~pro ~epi blk ~f:fmt_mod $ fmt_atrs) ) | Pexp_record (flds, default) -> let fmt_field (lid, (typ1, typ2), exp) = let typ1 = Option.map typ1 ~f:(sub_typ ~ctx) in @@ -2456,13 +2491,15 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) fmt_elements_collection c p1 last_loc pexp_loc fmt_field flds ~pro:(break 1 2) in - hvbox_if has_attr 0 - ( p1.box - ( opt default (fun d -> - hvbox 2 (fmt_expression c (sub_exp ~ctx d) $ fmt "@;<1 -2>") - $ str "with" $ p2.break_after_with ) - $ fmt_fields ) - $ fmt_atrs ) + pro + $ hvbox_if has_attr 0 + ( p1.box + ( opt default (fun d -> + hvbox 2 + (fmt_expression c (sub_exp ~ctx d) $ fmt "@;<1 -2>") + $ str "with" $ p2.break_after_with ) + $ fmt_fields ) + $ fmt_atrs ) | Pexp_extension ( ext , PStr @@ -2474,17 +2511,22 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) ; pstr_loc= _ } ] ) when Source.extension_using_sugar ~name:ext ~payload:e1.pexp_loc && List.length (Sugar.sequence c.cmts xexp) > 1 -> - fmt_sequence ~has_attr c parens (expression_width c) xexp fmt_atrs ~ext + pro + $ fmt_sequence ~has_attr c parens (expression_width c) xexp fmt_atrs + ~ext | Pexp_sequence _ -> - fmt_sequence ~has_attr c parens (expression_width c) xexp fmt_atrs ?ext + pro + $ fmt_sequence ~has_attr c parens (expression_width c) xexp fmt_atrs + ?ext | Pexp_setfield (e1, lid, e2) -> - hvbox 0 - (Params.Exp.wrap c.conf ~parens - ( Params.parens_if has_attr c.conf - ( fmt_expression c (sub_exp ~ctx e1) - $ str "." $ fmt_longident_loc c lid $ fmt_assign_arrow c - $ fmt_expression c (sub_exp ~ctx e2) ) - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.Exp.wrap c.conf ~parens + ( Params.parens_if has_attr c.conf + ( fmt_expression c (sub_exp ~ctx e1) + $ str "." $ fmt_longident_loc c lid $ fmt_assign_arrow c + $ fmt_expression c (sub_exp ~ctx e2) ) + $ fmt_atrs ) ) | Pexp_tuple es -> let parens = match xexp.ctx with @@ -2508,22 +2550,24 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) in let outer_wrap = has_attr && parens in let inner_wrap = has_attr || parens in - hvbox_if outer_wrap 0 - (Params.parens_if outer_wrap c.conf - ( hvbox 0 - (Params.wrap_tuple ~parens:inner_wrap ~no_parens_if_break - c.conf - (list es (Params.comma_sep c.conf) - (sub_exp ~ctx >> fmt_expression c) ) ) - $ fmt_atrs ) ) + pro + $ hvbox_if outer_wrap 0 + (Params.parens_if outer_wrap c.conf + ( hvbox 0 + (Params.wrap_tuple ~parens:inner_wrap ~no_parens_if_break + c.conf + (list es (Params.comma_sep c.conf) + (sub_exp ~ctx >> fmt_expression c) ) ) + $ fmt_atrs ) ) | Pexp_lazy e -> - hvbox 2 - (Params.Exp.wrap c.conf ~parens - ( str "lazy" - $ fmt_extension_suffix c ext - $ fmt "@ " - $ fmt_expression c (sub_exp ~ctx e) - $ fmt_atrs ) ) + pro + $ hvbox 2 + (Params.Exp.wrap c.conf ~parens + ( str "lazy" + $ fmt_extension_suffix c ext + $ fmt "@ " + $ fmt_expression c (sub_exp ~ctx e) + $ fmt_atrs ) ) | Pexp_extension ( ext , PStr @@ -2544,11 +2588,12 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) when Source.extension_using_sugar ~name:ext ~payload:e1.pexp_loc -> let outer_parens = has_attr && parens in let inner_parens = has_attr || parens in - hvbox 0 - (Params.parens_if outer_parens c.conf - ( fmt_expression c ~box ?eol ~parens:inner_parens ~ext - (sub_exp ~ctx:(Str str) e1) - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.parens_if outer_parens c.conf + ( fmt_expression c ~box ?eol ~parens:inner_parens ~ext + (sub_exp ~ctx:(Str str) e1) + $ fmt_atrs ) ) | Pexp_extension ( ext , PStr @@ -2560,77 +2605,86 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) ; pstr_loc= _ } as str ) ] ) when List.is_empty pexp_attributes && Source.extension_using_sugar ~name:ext ~payload:e1.pexp_loc -> - hvbox 0 - ( fmt_expression c ~box ?eol ~parens ~ext (sub_exp ~ctx:(Str str) e1) - $ fmt_atrs ) + pro + $ hvbox 0 + ( fmt_expression c ~box ?eol ~parens ~ext + (sub_exp ~ctx:(Str str) e1) + $ fmt_atrs ) | Pexp_extension ext -> - hvbox 0 - (Params.Exp.wrap c.conf ~parens - ( hvbox c.conf.fmt_opts.extension_indent.v - (fmt_extension c ctx ext) - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.Exp.wrap c.conf ~parens + ( hvbox c.conf.fmt_opts.extension_indent.v + (fmt_extension c ctx ext) + $ fmt_atrs ) ) | Pexp_for (p1, e1, e2, dir, e3) -> - hvbox 0 - (Params.Exp.wrap c.conf ~parens - ( hovbox 0 - ( hvbox 2 - ( hvbox 0 - ( str "for" - $ fmt_extension_suffix c ext - $ fmt "@;<1 2>" - $ hovbox 0 - ( fmt_pattern c (sub_pat ~ctx p1) - $ fmt "@ =@;<1 2>" - $ fmt_expression c (sub_exp ~ctx e1) - $ fmt_direction_flag dir - $ fmt_expression c (sub_exp ~ctx e2) ) - $ fmt "@;do" ) - $ fmt "@;<1000 0>" - $ fmt_expression c (sub_exp ~ctx e3) ) - $ fmt "@;<1000 0>done" ) - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.Exp.wrap c.conf ~parens + ( hovbox 0 + ( hvbox 2 + ( hvbox 0 + ( str "for" + $ fmt_extension_suffix c ext + $ fmt "@;<1 2>" + $ hovbox 0 + ( fmt_pattern c (sub_pat ~ctx p1) + $ fmt "@ =@;<1 2>" + $ fmt_expression c (sub_exp ~ctx e1) + $ fmt_direction_flag dir + $ fmt_expression c (sub_exp ~ctx e2) ) + $ fmt "@;do" ) + $ fmt "@;<1000 0>" + $ fmt_expression c (sub_exp ~ctx e3) ) + $ fmt "@;<1000 0>done" ) + $ fmt_atrs ) ) | Pexp_coerce (e1, t1, t2) -> - hvbox 2 - (Params.parens_if (parens && has_attr) c.conf - ( wrap_fits_breaks ~space:false c.conf "(" ")" - ( fmt_expression c (sub_exp ~ctx e1) - $ opt t1 (fmt "@ : " >$ (sub_typ ~ctx >> fmt_core_type c)) - $ fmt "@ :> " - $ fmt_core_type c (sub_typ ~ctx t2) ) - $ fmt_atrs ) ) + pro + $ hvbox 2 + (Params.parens_if (parens && has_attr) c.conf + ( wrap_fits_breaks ~space:false c.conf "(" ")" + ( fmt_expression c (sub_exp ~ctx e1) + $ opt t1 (fmt "@ : " >$ (sub_typ ~ctx >> fmt_core_type c)) + $ fmt "@ :> " + $ fmt_core_type c (sub_typ ~ctx t2) ) + $ fmt_atrs ) ) | Pexp_while (e1, e2) -> - hvbox 0 - (Params.Exp.wrap c.conf ~parens - ( hovbox 0 - ( hvbox 2 - ( hvbox 0 - ( str "while" - $ fmt_extension_suffix c ext - $ fmt "@;<1 2>" - $ fmt_expression c (sub_exp ~ctx e1) - $ fmt "@;do" ) - $ fmt "@;<1000 0>" - $ fmt_expression c (sub_exp ~ctx e2) ) - $ fmt "@;<1000 0>done" ) - $ fmt_atrs ) ) - | Pexp_unreachable -> str "." + pro + $ hvbox 0 + (Params.Exp.wrap c.conf ~parens + ( hovbox 0 + ( hvbox 2 + ( hvbox 0 + ( str "while" + $ fmt_extension_suffix c ext + $ fmt "@;<1 2>" + $ fmt_expression c (sub_exp ~ctx e1) + $ fmt "@;do" ) + $ fmt "@;<1000 0>" + $ fmt_expression c (sub_exp ~ctx e2) ) + $ fmt "@;<1000 0>done" ) + $ fmt_atrs ) ) + | Pexp_unreachable -> pro $ str "." | Pexp_send (exp, meth) -> - hvbox 2 - (Params.parens_if parens c.conf - ( fmt_expression c (sub_exp ~ctx exp) - $ fmt "@,#" $ fmt_str_loc c meth $ fmt_atrs ) ) + pro + $ hvbox 2 + (Params.parens_if parens c.conf + ( fmt_expression c (sub_exp ~ctx exp) + $ fmt "@,#" $ fmt_str_loc c meth $ fmt_atrs ) ) | Pexp_new {txt; loc} -> - Cmts.fmt c loc - @@ hvbox 2 - (Params.parens_if parens c.conf - ( str "new" - $ fmt_extension_suffix c ext - $ fmt "@ " $ fmt_longident txt $ fmt_atrs ) ) + pro + $ Cmts.fmt c loc + @@ hvbox 2 + (Params.parens_if parens c.conf + ( str "new" + $ fmt_extension_suffix c ext + $ fmt "@ " $ fmt_longident txt $ fmt_atrs ) ) | Pexp_object {pcstr_self; pcstr_fields} -> - hvbox 0 - (Params.parens_if parens c.conf - ( fmt_class_structure c ~ctx ?ext pcstr_self pcstr_fields - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.parens_if parens c.conf + ( fmt_class_structure c ~ctx ?ext pcstr_self pcstr_fields + $ fmt_atrs ) ) | Pexp_override l -> ( let fmt_field ({txt; loc}, f) = let eol = fmt "@;<1 3>" in @@ -2647,26 +2701,29 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) in match l with | [] -> - Params.parens_if parens c.conf - (wrap "{<" ">}" (Cmts.fmt_within c pexp_loc) $ fmt_atrs) + pro + $ Params.parens_if parens c.conf + (wrap "{<" ">}" (Cmts.fmt_within c pexp_loc) $ fmt_atrs) | _ -> - hvbox 0 - (Params.parens_if parens c.conf - ( wrap_fits_breaks ~space:false c.conf "{<" ">}" - (list l "@;<0 1>; " fmt_field) - $ fmt_atrs ) ) ) + pro + $ hvbox 0 + (Params.parens_if parens c.conf + ( wrap_fits_breaks ~space:false c.conf "{<" ">}" + (list l "@;<0 1>; " fmt_field) + $ fmt_atrs ) ) ) | Pexp_setinstvar (name, expr) -> - hvbox 0 - (Params.Exp.wrap c.conf ~parens - ( Params.parens_if has_attr c.conf - ( fmt_str_loc c name $ fmt_assign_arrow c - $ hvbox 2 (fmt_expression c (sub_exp ~ctx expr)) ) - $ fmt_atrs ) ) + pro + $ hvbox 0 + (Params.Exp.wrap c.conf ~parens + ( Params.parens_if has_attr c.conf + ( fmt_str_loc c name $ fmt_assign_arrow c + $ hvbox 2 (fmt_expression c (sub_exp ~ctx expr)) ) + $ fmt_atrs ) ) | Pexp_indexop_access x -> - fmt_indexop_access c ctx ~fmt_atrs ~has_attr ~parens x + pro $ fmt_indexop_access c ctx ~fmt_atrs ~has_attr ~parens x | Pexp_poly _ -> impossible "only used for methods, handled during method formatting" - | Pexp_hole -> hvbox 0 (fmt_hole () $ fmt_atrs) + | Pexp_hole -> pro $ hvbox 0 (fmt_hole () $ fmt_atrs) | Pexp_beginend e -> let wrap_beginend k = let opn = str "begin" $ fmt_extension_suffix c ext @@ -2674,13 +2731,15 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0) hvbox 0 (wrap_k opn cls (wrap_k (break 1 2) (break 1000 0) k) $ fmt_atrs) in - wrap_beginend - @@ fmt_expression c ~box ?pro ?epi ?eol ~parens:false ~indent_wrap ?ext - (sub_exp ~ctx e) + pro + $ wrap_beginend + (fmt_expression c ~box ?eol ~parens:false ~indent_wrap ?ext + (sub_exp ~ctx e) ) | Pexp_parens e -> - hvbox 0 - @@ fmt_expression c ~box ?pro ?epi ?eol ~parens:true ~indent_wrap ?ext - (sub_exp ~ctx e) + pro + $ hvbox 0 + (fmt_expression c ~box ?eol ~parens:true ~indent_wrap ?ext + (sub_exp ~ctx e) ) $ fmt_atrs and fmt_let_bindings c ?ext ~parens ~has_attr ~fmt_atrs ~fmt_expr rec_flag diff --git a/test/passing/dune.inc b/test/passing/dune.inc index 18598598e6..172e04e603 100644 --- a/test/passing/dune.inc +++ b/test/passing/dune.inc @@ -4114,13 +4114,31 @@ (package ocamlformat) (action (diff tests/obuild.ml.err obuild.ml.stderr))) +(rule + (deps tests/.ocamlformat ) + (package ocamlformat) + (action + (with-stdout-to ocp_indent_compat-break_colon_after.ml.stdout + (with-stderr-to ocp_indent_compat-break_colon_after.ml.stderr + (run %{bin:ocamlformat} --margin-check --ocp-indent-compat --break-colon=after %{dep:tests/ocp_indent_compat.ml}))))) + +(rule + (alias runtest) + (package ocamlformat) + (action (diff tests/ocp_indent_compat-break_colon_after.ml.ref ocp_indent_compat-break_colon_after.ml.stdout))) + +(rule + (alias runtest) + (package ocamlformat) + (action (diff tests/ocp_indent_compat-break_colon_after.ml.err ocp_indent_compat-break_colon_after.ml.stderr))) + (rule (deps tests/.ocamlformat ) (package ocamlformat) (action (with-stdout-to ocp_indent_compat.ml.stdout (with-stderr-to ocp_indent_compat.ml.stderr - (run %{bin:ocamlformat} --margin-check %{dep:tests/ocp_indent_compat.ml}))))) + (run %{bin:ocamlformat} --margin-check --ocp-indent-compat --break-colon=before %{dep:tests/ocp_indent_compat.ml}))))) (rule (alias runtest) diff --git a/test/passing/tests/ocp_indent_compat-break_colon_after.ml.opts b/test/passing/tests/ocp_indent_compat-break_colon_after.ml.opts new file mode 100644 index 0000000000..4ebafbf051 --- /dev/null +++ b/test/passing/tests/ocp_indent_compat-break_colon_after.ml.opts @@ -0,0 +1,2 @@ +--ocp-indent-compat +--break-colon=after diff --git a/test/passing/tests/ocp_indent_compat-break_colon_after.ml.ref b/test/passing/tests/ocp_indent_compat-break_colon_after.ml.ref new file mode 100644 index 0000000000..633d0168dc --- /dev/null +++ b/test/passing/tests/ocp_indent_compat-break_colon_after.ml.ref @@ -0,0 +1,93 @@ +(* Bad: unboxing the function type *) +external i : (int -> float[@unboxed]) = "i" "i_nat" + +module type M = sig + val action : action + (** Formatting action: input type and source, and output destination. *) + + val doc_atrs : + (string Location.loc * payload) list + -> (string Location.loc * bool) list option + * (string Location.loc * payload) list + + val transl_modtype_longident + (* from Typemod *) : + (Location.t -> Env.t -> Longident.t -> Path.t) ref + + val transl_modtype_longident + (* foooooooooo fooooooooooooo foooooooooooo foooooooooooooo + foooooooooooooo foooooooooooo *) : + (Location.t -> Env.t -> Longident.t -> Path.t) ref + + val imported_sets_of_closures_table : + Simple_value_approx.function_declarations option Set_of_closures_id.Tbl.t + + type 'a option_decl = + names:string list + -> doc:string + -> section:[`Formatting | `Operational] + -> ?allow_inline:bool + -> (config -> 'a -> config) + -> (config -> 'a) + -> 'a t + + val select : + (* The fsevents context *) + env + -> (* Additional file descriptor to select for reading *) + ?read_fdl:fd_select list + -> (* Additional file descriptor to select for writing *) + ?write_fdl:fd_select list + -> (* Timeout...like Unix.select *) + timeout:float + -> (* The callback for file system events *) + (event list -> unit) + -> unit + + val f : + x:t + (** an extremely long comment about [x] that does not fit on the same + line with [x] *) + -> unit + + val f : + fooooooooooooooooo: + (fooooooooooooooo + -> fooooooooooooooooooo + -> foooooooooooooo + -> foooooooooooooo * fooooooooooooooooo + -> foooooooooooooooo ) + (** an extremely long comment about [x] that does not fit on the same + line with [x] *) + -> unit +end + +let ssmap : + (module MapT + with type key = string + and type data = string + and type map = SSMap.map ) + = + () + +let ssmap : + (module MapT + with type key = string + and type data = string + and type map = SSMap.map ) + -> unit + = + () + +let long_function_name : + type a. a long_long_type -> a -> a -> a -> wrap_wrap_wrap -> unit + = + fun () -> () + +let add_edge target dep = + if target <> dep then ( + Hashtbl.replace edges dep + (target :: (try Hashtbl.find edges dep with Not_found -> [])) ; + Hashtbl.replace edge_count target + (1 + try Hashtbl.find edge_count target with Not_found -> 0) ; + if not (Hashtbl.mem edge_count dep) then Hashtbl.add edge_count dep 0 ) diff --git a/test/passing/tests/ocp_indent_compat.ml b/test/passing/tests/ocp_indent_compat.ml index ea9f32eafb..224fa0e407 100644 --- a/test/passing/tests/ocp_indent_compat.ml +++ b/test/passing/tests/ocp_indent_compat.ml @@ -1,7 +1,3 @@ -[@@@ocamlformat "ocp-indent-compat=true"] - -[@@@ocamlformat "break-colon=before"] - (* Bad: unboxing the function type *) external i : (int -> float[@unboxed]) = "i" "i_nat" @@ -89,64 +85,10 @@ let long_function_name = fun () -> () -[@@@ocamlformat "ocp-indent-compat=false"] - -[@@@ocamlformat "break-colon=after"] - -module type M = sig - val transl_modtype_longident (* from Typemod *) : - (Location.t -> Env.t -> Longident.t -> Path.t) ref - - val transl_modtype_longident - (* foooooooooo fooooooooooooo foooooooooooo foooooooooooooo - foooooooooooooo foooooooooooo *) : - (Location.t -> Env.t -> Longident.t -> Path.t) ref - - val imported_sets_of_closures_table : - Simple_value_approx.function_declarations option Set_of_closures_id.Tbl.t - - val select : - (* The fsevents context *) - env - -> (* Additional file descriptor to select for reading *) - ?read_fdl:fd_select list - -> (* Additional file descriptor to select for writing *) - ?write_fdl:fd_select list - -> (* Timeout...like Unix.select *) - timeout:float - -> (* The callback for file system events *) - (event list -> unit) - -> unit - - val f : - x:t - (** an extremely long comment about [x] that does not fit on the - same line with [x] *) - -> unit - - val f : - fooooooooooooooooo: - ( fooooooooooooooo - -> fooooooooooooooooooo - -> foooooooooooooo - -> foooooooooooooo * fooooooooooooooooo - -> foooooooooooooooo ) - (** an extremely long comment about [x] that does not fit on the - same line with [x] *) - -> unit -end - -let array_fold_transf (f : numbering -> 'a -> numbering * 'b) n (a : 'a array) - : numbering * 'b array = - match Array.length a with 0 -> (n, [||]) | 1 -> x - -let to_clambda_function (id, (function_decl : Flambda.function_declaration)) - : Clambda.ufunction = - (* All that we need in the environment, for translating one closure from a - closed set of closures, is the substitutions for variables bound to the - various closures in the set. Such closures will always be ... *) - x - -let long_function_name : - type a. a long_long_type -> a -> a -> a -> wrap_wrap_wrap -> unit = - fun () -> () +let add_edge target dep = + if target <> dep then ( + Hashtbl.replace edges dep + (target :: (try Hashtbl.find edges dep with Not_found -> [])) ; + Hashtbl.replace edge_count target + (1 + try Hashtbl.find edge_count target with Not_found -> 0) ; + if not (Hashtbl.mem edge_count dep) then Hashtbl.add edge_count dep 0 ) diff --git a/test/passing/tests/ocp_indent_compat.ml.err b/test/passing/tests/ocp_indent_compat.ml.err index 6faa1c0e72..e69de29bb2 100644 --- a/test/passing/tests/ocp_indent_compat.ml.err +++ b/test/passing/tests/ocp_indent_compat.ml.err @@ -1 +0,0 @@ -Warning: tests/ocp_indent_compat.ml:138 exceeds the margin diff --git a/test/passing/tests/ocp_indent_compat.ml.opts b/test/passing/tests/ocp_indent_compat.ml.opts new file mode 100644 index 0000000000..7b22536b8d --- /dev/null +++ b/test/passing/tests/ocp_indent_compat.ml.opts @@ -0,0 +1,2 @@ +--ocp-indent-compat +--break-colon=before