letop-punning for extension nodes#2747
Conversation
|
(note I commented in #2746 that I thought the |
|
Hi @EmileTrotignon - I think this is ready for review. The let%ext change is very similar to the code from the previous PR and should be an easy review. A bit trickier is I noticed that letop-punning=always could lead to errors if the right hand side had associated comments. I believe I found a fix (for both this new code and the existing), but I'm less confident in that part and would appreciate any pointers |
|
This looks good. Where is the fix about comments ? |
|
The way I tackled the comment issue is by copying the location of the rhs into the pattern (starting in efb3931). I’m not sure if this is the recommended way or not, but it does appear to work on the added test cases |
df1653d to
68d651a
Compare
EmileTrotignon
left a comment
There was a problem hiding this comment.
Thanks a lot for the contributing documentation, its a very big improvement.
|
Sorry I reviewed the contribution.md changes in the wrong PR |
|
No worries @EmileTrotignon. I've pushed updates to #2748 (stacked PRs still need a better workflow for github -- the diffs quickly diverge without a lot of ugly force pushing) |
68d651a to
18c3a3f
Compare
18c3a3f to
1fe36f0
Compare
|
This can be merged after a rebase on main |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1fe36f0 to
425ecc4
Compare
|
Rebased :) |
|
Waiting for CI and merging |
|
CI has passed. Thanks for the hand-holding on this feature! |
|
@WardBrian You're very welcome ! If you are interested in contributing further to ocamlformat, maybe we could have a chat about the project. |
|
Sure @EmileTrotignon! I've been a happy user of ocamlformat for years, and this is the first time I found a gap in my needs for it that prompted me to contribute, but I have some spare cycles to do more here or there |
CHANGES: ### Highlight - \* Support OCaml 5.5 syntax (ocaml-ppx/ocamlformat#2772, ocaml-ppx/ocamlformat#2774, ocaml-ppx/ocamlformat#2775, ocaml-ppx/ocamlformat#2777, ocaml-ppx/ocamlformat#2780, ocaml-ppx/ocamlformat#2781, ocaml-ppx/ocamlformat#2782, ocaml-ppx/ocamlformat#2783, @Julow) The update brings several tiny changes, they are listed below. - \* Update Odoc's parser to 3.0 (ocaml-ppx/ocamlformat#2757, @Julow) The indentation of code-blocks containing OCaml code is reduced by 2 to avoid changing the generated documentation. The indentation within code-blocks is now significative in Odoc and shows up in generated documentation. ### Added - Added option `letop-punning` (ocaml-ppx/ocamlformat#2746, @WardBrian) to control whether punning is used in extended binding operators. For example, the code `let+ x = x in ...` can be formatted as `let+ x in ...` when `letop-punning=always`. With `letop-punning=never`, it becomes `let+ x = x in ...`. The default is `preserve`, which will only use punning when it exists in the source. This also applies to `let%ext` bindings (ocaml-ppx/ocamlformat#2747, @WardBrian). - Support the unnamed functor parameters syntax in module types (ocaml-ppx/ocamlformat#2755, ocaml-ppx/ocamlformat#2759, @Julow) ```ocaml module type F = ARG -> S ``` The following lines are now formatted as they are in the source file: ```ocaml module M : (_ : S) -> (_ : S) -> S = N module M : S -> S -> S = N (* The preceding two lines are no longer turned into this: *) module M : (_ : S) (_ : S) -> S = N ``` ### Fixed - Fix dropped comment in `(function _ -> x (* cmt *))` (ocaml-ppx/ocamlformat#2739, @Julow) - \* `cases-matching-exp-indent=compact` does not impact `begin end` nodes that don't have a match inside. (ocaml-ppx/ocamlformat#2742, @EmileTrotignon) ```ocaml (* before *) begin match () with | () -> begin f x end end (* after *) begin match () with | () -> begin f x end end ``` - `Ast_mapper` now iterates on *all* locations inside of Longident.t, instead of only some. (ocaml-ppx/ocamlformat#2737, @v-gb) - Remove line break in `M with module N = N (* cmt *)` (ocaml-ppx/ocamlformat#2779, @Julow) ### Internal - Added information on writing tests to `CONTRIBUTING.md` (ocaml-ppx/ocamlformat#2838, @WardBrian) ### Changed - indentation of the `end` keyword in a match-case is now always at least 2. (ocaml-ppx/ocamlformat#2742, @EmileTrotignon) ```ocaml (* before *) begin match () with | () -> begin match () with | () -> () end end (* after *) begin match () with | () -> begin match () with | () -> () - \* use shortcut `begin end` in `match` cases and `if then else` body. (ocaml-ppx/ocamlformat#2744, @EmileTrotignon) ```ocaml (* before *) match () with | () -> begin match () with | () -> end end (* after *) match () with | () -> begin match () with | () -> end end ``` - \* Set the `ocaml-version` to `5.4` by default (ocaml-ppx/ocamlformat#2750, @EmileTrotignon) The main difference is that the `effect` keyword is recognized without having to add `ocaml-version=5.3` to the configuration. In exchange, code that use `effect` as an identifier must use `ocaml-version=5.2`. - The work to support OCaml 5.5 come with several improvements: + Improve the indentation of `let structure-item` with the `[@ocamlformat "disable"]` attribute. `let structure-item` means `let module`, `let open`, `let include` and `let exception`. + `(let open M in e)[@A]` is turned into `let[@A] open M in e`. + Long `let open ... in` no longer exceed the margin. + Improve indentation of `let structure-item` within parentheses: ```ocaml (* before *) (let module M = M in M.foo) (* after *) (let module M = M in M.foo) ```
CHANGES: ### Highlight - \* Support OCaml 5.5 syntax (ocaml-ppx/ocamlformat#2772, ocaml-ppx/ocamlformat#2774, ocaml-ppx/ocamlformat#2775, ocaml-ppx/ocamlformat#2777, ocaml-ppx/ocamlformat#2780, ocaml-ppx/ocamlformat#2781, ocaml-ppx/ocamlformat#2782, ocaml-ppx/ocamlformat#2783, @Julow) The update brings several tiny changes, they are listed below. - \* Update Odoc's parser to 3.0 (ocaml-ppx/ocamlformat#2757, @Julow) The indentation of code-blocks containing OCaml code is reduced by 2 to avoid changing the generated documentation. The indentation within code-blocks is now significative in Odoc and shows up in generated documentation. ### Added - Added option `letop-punning` (ocaml-ppx/ocamlformat#2746, @WardBrian) to control whether punning is used in extended binding operators. For example, the code `let+ x = x in ...` can be formatted as `let+ x in ...` when `letop-punning=always`. With `letop-punning=never`, it becomes `let+ x = x in ...`. The default is `preserve`, which will only use punning when it exists in the source. This also applies to `let%ext` bindings (ocaml-ppx/ocamlformat#2747, @WardBrian). - Support the unnamed functor parameters syntax in module types (ocaml-ppx/ocamlformat#2755, ocaml-ppx/ocamlformat#2759, @Julow) ```ocaml module type F = ARG -> S ``` The following lines are now formatted as they are in the source file: ```ocaml module M : (_ : S) -> (_ : S) -> S = N module M : S -> S -> S = N (* The preceding two lines are no longer turned into this: *) module M : (_ : S) (_ : S) -> S = N ``` ### Fixed - Fix dropped comment in `(function _ -> x (* cmt *))` (ocaml-ppx/ocamlformat#2739, @Julow) - \* `cases-matching-exp-indent=compact` does not impact `begin end` nodes that don't have a match inside. (ocaml-ppx/ocamlformat#2742, @EmileTrotignon) ```ocaml (* before *) begin match () with | () -> begin f x end end (* after *) begin match () with | () -> begin f x end end ``` - `Ast_mapper` now iterates on *all* locations inside of Longident.t, instead of only some. (ocaml-ppx/ocamlformat#2737, @v-gb) - Remove line break in `M with module N = N (* cmt *)` (ocaml-ppx/ocamlformat#2779, @Julow) ### Internal - Added information on writing tests to `CONTRIBUTING.md` (ocaml-ppx/ocamlformat#2838, @WardBrian) ### Changed - indentation of the `end` keyword in a match-case is now always at least 2. (ocaml-ppx/ocamlformat#2742, @EmileTrotignon) ```ocaml (* before *) begin match () with | () -> begin match () with | () -> () end end (* after *) begin match () with | () -> begin match () with | () -> () - \* use shortcut `begin end` in `match` cases and `if then else` body. (ocaml-ppx/ocamlformat#2744, @EmileTrotignon) ```ocaml (* before *) match () with | () -> begin match () with | () -> end end (* after *) match () with | () -> begin match () with | () -> end end ``` - \* Set the `ocaml-version` to `5.4` by default (ocaml-ppx/ocamlformat#2750, @EmileTrotignon) The main difference is that the `effect` keyword is recognized without having to add `ocaml-version=5.3` to the configuration. In exchange, code that use `effect` as an identifier must use `ocaml-version=5.2`. - The work to support OCaml 5.5 come with several improvements: + Improve the indentation of `let structure-item` with the `[@ocamlformat "disable"]` attribute. `let structure-item` means `let module`, `let open`, `let include` and `let exception`. + `(let open M in e)[@A]` is turned into `let[@A] open M in e`. + Long `let open ... in` no longer exceed the margin. + Improve indentation of `let structure-item` within parentheses: ```ocaml (* before *) (let module M = M in M.foo) (* after *) (let module M = M in M.foo) ```
Follow-on to #2746, this makes it so the letop-punning setting also affects nodes like
let%foo bar = bar in ...The trickiest piece here is that the
ands for these nodes don't have the extension, so I needed to do this at the level ofvalue_bindings, notvalue_bindingThis also fixes an issue with comments when a pun is introduced. As far as I can tell, this was also an issue back in 0.26, when the equivalent of
letop-punning=alwayswas the default behavior.