Skip to content

Commit 7858f66

Browse files
committed
Merge branch 'MAIN' into pr/2714
2 parents 159d518 + c6c2477 commit 7858f66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+4893
-520
lines changed

CHANGES.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ profile. This started with version 0.26.0.
66

77
## unreleased
88

9+
### Added
10+
11+
- Support for OCaml 5.4 (#2717, #2720, @Julow, @Octachron)
12+
OCamlformat now supports OCaml 5.4 syntax.
13+
Module packing of the form `((module M) : (module S))` are no longer
14+
rewritten to `(module M : S)` because these are now two different syntaxes.
15+
16+
- Added option `module-indent` option (#2711, @HPRIOR) to control the indentation
17+
of items within modules. This affects modules and signatures. For example,
18+
module-indent=4:
19+
```ocaml
20+
module type M = sig
21+
type t
22+
23+
val f : (string * int) list -> int
24+
end
25+
```
926
### Deprecated
1027

1128
- Starting in this release, ocamlformat can use cmdliner >= 2.0.0. When that is
@@ -80,6 +97,9 @@ profile. This started with version 0.26.0.
8097
- Fix a crash where `type%e nonrec t = t` was formatted as `type nonrec%e t = t`,
8198
which is invalid syntax. (#2712, @EmileTrotignon)
8299

100+
- Fix commandline parsing being quadratic in the number of arguments
101+
(#2724, @let-def)
102+
83103
### Changed
84104

85105
- `|> begin`, `~arg:begin`, `begin if`, `lazy begin`, `begin match`,
@@ -1784,3 +1804,4 @@ profile. This started with version 0.26.0.
17841804
## 0.1 (2017-10-19)
17851805

17861806
- Initial release.
1807+

doc/manpage_ocamlformat.mld

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ OPTIONS (CODE FORMATTING STYLE)
295295
the offset of the previous line. The default value is 68. Cannot
296296
be set in attributes.
297297

298+
--module-indent=COLS
299+
Indentation of items within struct ... end and sig ... end (COLS
300+
columns). The default value is 2.
301+
298302
--module-item-spacing={compact|sparse|preserve}
299303
Spacing between items of structures and signatures. compact will
300304
not leave open lines between one-liners of similar sorts. sparse

lib/Ast.ml

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ let longident_is_simple c x =
6161
let rec length x =
6262
match x with
6363
| Longident.Lident x -> String.length x
64-
| Ldot (x, y) -> length x + 1 + String.length y
65-
| Lapply (x, y) -> length x + length y + 3
64+
| Ldot (x, y) -> length x.txt + 1 + String.length y.txt
65+
| Lapply (x, y) -> length x.txt + length y.txt + 3
6666
in
6767
longident_fit_margin c (length x)
6868

@@ -977,14 +977,16 @@ end = struct
977977
| Ptyp_alias (t1, _) | Ptyp_poly (_, t1) -> assert (typ == t1)
978978
| Ptyp_arrow (t, t2) ->
979979
assert (List.exists t ~f:(fun x -> typ == x.pap_type) || typ == t2)
980-
| Ptyp_tuple t1N | Ptyp_constr (_, t1N) -> assert (List.exists t1N ~f)
980+
| Ptyp_tuple t1N ->
981+
assert (List.exists t1N ~f:(fun x -> x.lte_elt == typ))
982+
| Ptyp_constr (_, t1N) -> assert (List.exists t1N ~f)
981983
| Ptyp_variant (r1N, _, _) ->
982984
assert (
983985
List.exists r1N ~f:(function
984986
| {prf_desc= Rtag (_, _, t1N); _} -> List.exists t1N ~f
985987
| {prf_desc= Rinherit t1; _} -> typ == t1 ) )
986988
| Ptyp_open (_, t1) -> assert (t1 == typ)
987-
| Ptyp_package (_, it1N, _) -> assert (List.exists it1N ~f:snd_f)
989+
| Ptyp_package ptyp -> assert (List.exists ptyp.ppt_cstrs ~f:snd_f)
988990
| Ptyp_object (fields, _) ->
989991
assert (
990992
List.exists fields ~f:(function
@@ -1017,15 +1019,20 @@ end = struct
10171019
match ctx.ppat_desc with
10181020
| Ppat_constraint (_, t1) -> assert (typ == t1)
10191021
| Ppat_extension (_, PTyp t) -> assert (typ == t)
1020-
| Ppat_unpack (_, Some (_, l, _)) ->
1021-
assert (List.exists l ~f:(fun (_, t) -> typ == t))
1022+
| Ppat_unpack (_, Some ptyp) ->
1023+
assert (List.exists ptyp.ppt_cstrs ~f:(fun (_, t) -> typ == t))
10221024
| Ppat_record (l, _) ->
10231025
assert (List.exists l ~f:(fun (_, t, _) -> Option.exists t ~f))
1026+
| Ppat_tuple (l, _) ->
1027+
assert (
1028+
List.exists l ~f:(function
1029+
| Lte_constrained_pun x -> x.type_constraint == typ
1030+
| _ -> false ) )
10241031
| _ -> assert false )
10251032
| Exp ctx -> (
10261033
match ctx.pexp_desc with
1027-
| Pexp_pack (_, Some (_, it1N, _), _) ->
1028-
assert (List.exists it1N ~f:snd_f)
1034+
| Pexp_pack (_, Some ptyp, _) ->
1035+
assert (List.exists ptyp.ppt_cstrs ~f:snd_f)
10291036
| Pexp_constraint (_, t1)
10301037
|Pexp_coerce (_, None, t1)
10311038
|Pexp_extension (_, PTyp t1) ->
@@ -1039,6 +1046,16 @@ end = struct
10391046
Option.exists c ~f:check_type_constraint ) )
10401047
| Pexp_let (lbs, _, _) -> assert (check_let_bindings lbs)
10411048
| Pexp_function (_, Some t1, _, _) -> assert (check_type_constraint t1)
1049+
| Pexp_tuple l ->
1050+
assert (
1051+
List.exists l ~f:(function
1052+
| Lte_constrained_pun
1053+
{type_constraint= Pconstraint t | Pcoerce (None, t); _} ->
1054+
t == typ
1055+
| Lte_constrained_pun
1056+
{type_constraint= Pcoerce (Some bty, ty); _} ->
1057+
typ == bty || typ == ty
1058+
| _ -> false ) )
10421059
| _ -> assert false )
10431060
| Fpe _ | Fpc _ -> assert false
10441061
| Vc c -> assert (check_value_constraint c)
@@ -1063,7 +1080,7 @@ end = struct
10631080
| Mod ctx -> (
10641081
match ctx.pmod_desc with
10651082
| Pmod_unpack (_, ty1, ty2) ->
1066-
let f (_, cstrs, _) = List.exists cstrs ~f:(fun (_, x) -> f x) in
1083+
let f ptyp = List.exists ptyp.ppt_cstrs ~f:snd_f in
10671084
assert (Option.exists ty1 ~f || Option.exists ty2 ~f)
10681085
| _ -> assert false )
10691086
| Sig ctx -> (
@@ -1255,7 +1272,12 @@ end = struct
12551272
| Pat ctx -> (
12561273
let f pI = pI == pat in
12571274
match ctx.ppat_desc with
1258-
| Ppat_array p1N | Ppat_list p1N | Ppat_tuple p1N | Ppat_cons p1N ->
1275+
| Ppat_tuple (p1N, _) ->
1276+
assert (
1277+
List.exists p1N ~f:(function
1278+
| Lte_simple s -> f s.lte_elt
1279+
| _ -> false ) )
1280+
| Ppat_array p1N | Ppat_list p1N | Ppat_cons p1N ->
12591281
assert (List.exists p1N ~f)
12601282
| Ppat_record (p1N, _) ->
12611283
assert (List.exists p1N ~f:(fun (_, _, x) -> Option.exists x ~f))
@@ -1423,7 +1445,12 @@ end = struct
14231445
| Pexp_apply (e0, e1N) ->
14241446
(* FAIL *)
14251447
assert (e0 == exp || List.exists e1N ~f:snd_f)
1426-
| Pexp_tuple e1N | Pexp_array e1N | Pexp_list e1N | Pexp_cons e1N ->
1448+
| Pexp_tuple e1N ->
1449+
assert (
1450+
List.exists e1N ~f:(function
1451+
| Lte_simple te -> te.lte_elt == exp
1452+
| _ -> false ) )
1453+
| Pexp_array e1N | Pexp_list e1N | Pexp_cons e1N ->
14271454
assert (List.exists e1N ~f)
14281455
| Pexp_construct (_, e) | Pexp_variant (_, e) ->
14291456
assert (Option.exists e ~f)
@@ -1529,7 +1556,13 @@ end = struct
15291556
&& fit_margin c (width xexp)
15301557
| Pexp_construct (_, Some e0) | Pexp_variant (_, Some e0) ->
15311558
Exp.is_trivial e0
1532-
| Pexp_array e1N | Pexp_list e1N | Pexp_tuple e1N ->
1559+
| Pexp_tuple e1N ->
1560+
List.for_all e1N ~f:(function
1561+
| Lte_pun _ -> true
1562+
| Lte_constrained_pun _ -> false
1563+
| Lte_simple lte -> Exp.is_trivial lte.lte_elt )
1564+
&& fit_margin c (width xexp)
1565+
| Pexp_array e1N | Pexp_list e1N ->
15331566
List.for_all e1N ~f:Exp.is_trivial && fit_margin c (width xexp)
15341567
| Pexp_record (e1N, e0) ->
15351568
Option.for_all e0 ~f:Exp.is_trivial
@@ -1631,8 +1664,9 @@ end = struct
16311664
| {ast= Typ _; _} -> None
16321665
| {ctx= Exp {pexp_desc; _}; ast= Exp exp} -> (
16331666
match pexp_desc with
1634-
| Pexp_tuple (e0 :: _) ->
1667+
| Pexp_tuple (Lte_simple {lte_elt= e0; _} :: _) ->
16351668
Some (Comma, if exp == e0 then Left else Right)
1669+
| Pexp_tuple (_ :: _) -> Some (Comma, Right)
16361670
| Pexp_cons l ->
16371671
Some (ColonColon, if exp == List.last_exn l then Right else Left)
16381672
| Pexp_construct
@@ -1848,6 +1882,9 @@ end = struct
18481882
( Str {pstr_desc= Pstr_exception _; _}
18491883
| Sig {psig_desc= Psig_exception _; _} ) } ->
18501884
true
1885+
| { ast= {ptyp_desc= Ptyp_tuple ({lte_label= Some _; _} :: _); _}
1886+
; ctx= Typ {ptyp_desc= Ptyp_arrow _; _} } ->
1887+
true
18511888
| _ -> (
18521889
match ambig_prec (sub_ast ~ctx (Typ typ)) with
18531890
| `Ambiguous -> true
@@ -2039,6 +2076,9 @@ end = struct
20392076
register_reset (fun () -> Hashtbl.clear memo) ;
20402077
memo
20412078

2079+
let last_tuple_and_simple f l =
2080+
match List.last_exn l with Lte_simple l -> f l.lte_elt | _ -> false
2081+
20422082
(** [exposed cls exp] holds if there is a right-most subexpression of [exp]
20432083
which satisfies [Exp.mem_cls cls] and is not parenthesized. *)
20442084
let rec exposed_right_exp =
@@ -2087,7 +2127,7 @@ end = struct
20872127
|Pexp_try (_, cases, _) ->
20882128
continue (List.last_exn cases).pc_rhs
20892129
| Pexp_apply (_, args) -> continue (snd (List.last_exn args))
2090-
| Pexp_tuple es -> continue (List.last_exn es)
2130+
| Pexp_tuple es -> last_tuple_and_simple continue es
20912131
| Pexp_array _ | Pexp_list _ | Pexp_coerce _ | Pexp_constant _
20922132
|Pexp_constraint _
20932133
|Pexp_construct (_, None)
@@ -2168,7 +2208,7 @@ end = struct
21682208
| Pexp_indexop_access {pia_rhs= rhs; _} -> (
21692209
match rhs with Some e -> continue e | None -> false )
21702210
| Pexp_apply (_, args) -> continue (snd (List.last_exn args))
2171-
| Pexp_tuple es -> continue (List.last_exn es)
2211+
| Pexp_tuple es -> last_tuple_and_simple continue es
21722212
| Pexp_array _ | Pexp_list _ | Pexp_coerce _ | Pexp_constant _
21732213
|Pexp_constraint _
21742214
|Pexp_construct (_, None)
@@ -2220,7 +2260,7 @@ end = struct
22202260
&& Option.value_map ~default:false (prec_ast ctx) ~f:(fun p ->
22212261
Prec.compare p Apply < 0 ) ->
22222262
true
2223-
| Pexp_tuple e1N -> List.last_exn e1N == xexp.ast
2263+
| Pexp_tuple e1N -> last_tuple_and_simple (( == ) xexp.ast) e1N
22242264
| _ -> false
22252265
in
22262266
match ambig_prec (sub_ast ~ctx (Exp exp)) with

lib/Conf.ml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ let conventional_profile from =
9191
; match_indent= elt 0
9292
; match_indent_nested= elt `Never
9393
; max_indent= elt None
94+
; module_indent= elt 2
9495
; module_item_spacing= elt `Compact
9596
; nested_match= elt `Wrap
9697
; ocp_indent_compat= elt false
@@ -160,6 +161,7 @@ let ocamlformat_profile from =
160161
; match_indent= elt 0
161162
; match_indent_nested= elt `Never
162163
; max_indent= elt None
164+
; module_indent= elt 2
163165
; module_item_spacing= elt `Sparse
164166
; nested_match= elt `Wrap
165167
; ocp_indent_compat= elt false
@@ -228,6 +230,7 @@ let janestreet_profile from =
228230
; match_indent= elt 0
229231
; match_indent_nested= elt `Never
230232
; max_indent= elt None
233+
; module_indent= elt 2
231234
; module_item_spacing= elt `Compact
232235
; nested_match= elt `Wrap
233236
; ocp_indent_compat= elt true
@@ -1063,6 +1066,17 @@ module Formatting = struct
10631066
(fun conf elt -> update conf ~f:(fun f -> {f with max_indent= elt}))
10641067
(fun conf -> conf.fmt_opts.max_indent)
10651068

1069+
let module_indent =
1070+
let docv = "COLS" in
1071+
let doc =
1072+
"Indentation of items within struct ... end and sig ... end ($(docv) \
1073+
columns)."
1074+
in
1075+
let names = ["module-indent"] in
1076+
Decl.int ~names ~default ~doc ~docv ~kind
1077+
(fun conf elt -> update conf ~f:(fun f -> {f with module_indent= elt}))
1078+
(fun conf -> conf.fmt_opts.module_indent)
1079+
10661080
let module_item_spacing =
10671081
let doc = "Spacing between items of structures and signatures." in
10681082
let names = ["module-item-spacing"] in
@@ -1344,6 +1358,7 @@ module Formatting = struct
13441358
; elt match_indent
13451359
; elt match_indent_nested
13461360
; elt max_indent
1361+
; elt module_indent
13471362
; elt module_item_spacing
13481363
; elt nested_match
13491364
; elt ocp_indent_compat

lib/Conf_t.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ type fmt_opts =
9999
; match_indent: int elt
100100
; match_indent_nested: [`Always | `Auto | `Never] elt
101101
; max_indent: int option elt
102+
; module_indent: int elt
102103
; module_item_spacing: [`Compact | `Preserve | `Sparse] elt
103104
; nested_match: [`Wrap | `Align] elt
104105
; ocp_indent_compat: bool elt

lib/Conf_t.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ type fmt_opts =
9797
; match_indent: int elt
9898
; match_indent_nested: [`Always | `Auto | `Never] elt
9999
; max_indent: int option elt
100+
; module_indent: int elt
100101
; module_item_spacing: [`Compact | `Preserve | `Sparse] elt
101102
; nested_match: [`Wrap | `Align] elt
102103
; ocp_indent_compat: bool elt (** Try to indent like ocp-indent *)

lib/Exposed.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module Left = struct
1515
let rec core_type typ =
1616
match typ.ptyp_desc with
1717
| Ptyp_arrow (t :: _, _) -> core_type t.pap_type
18-
| Ptyp_tuple l -> core_type (List.hd_exn l)
18+
| Ptyp_tuple l -> core_type (List.hd_exn l).lte_elt
1919
| Ptyp_object _ -> true
2020
| Ptyp_alias (typ, _) -> core_type typ
2121
| _ -> false
@@ -29,7 +29,7 @@ module Right = struct
2929
| {ptyp_desc; _} -> (
3030
match ptyp_desc with
3131
| Ptyp_arrow (_, t) -> core_type t
32-
| Ptyp_tuple l -> core_type (List.last_exn l)
32+
| Ptyp_tuple l -> core_type (List.last_exn l).lte_elt
3333
| Ptyp_object _ -> true
3434
| _ -> false )
3535

0 commit comments

Comments
 (0)