@@ -15,10 +15,10 @@ type t =
1515 | Text of string
1616 | Concat of t list
1717 | Indent of t
18- | IfBreaks of {yes : t ; no : t }
18+ | IfBreaks of {yes : t ; no : t ; mutable broken : bool } (* when broken is true, treat as the yes branch *)
1919 | LineSuffix of t
2020 | LineBreak of lineStyle
21- | Group of {shouldBreak : bool ; doc : t }
21+ | Group of {mutable shouldBreak : bool ; doc : t }
2222 | CustomLayout of t list
2323 | BreakParent
2424
@@ -43,7 +43,7 @@ let rec _concat acc l =
4343let concat l = Concat (_concat [] l)
4444
4545let indent d = Indent d
46- let ifBreaks t f = IfBreaks {yes = t; no = f}
46+ let ifBreaks t f = IfBreaks {yes = t; no = f; broken = false }
4747let lineSuffix d = LineSuffix d
4848let group d = Group {shouldBreak = false ; doc = d}
4949let breakableGroup ~forceBreak d = Group {shouldBreak = forceBreak; doc = d}
@@ -66,55 +66,52 @@ let rbracket = Text "]"
6666let question = Text " ?"
6767let tilde = Text " ~"
6868let equal = Text " ="
69- let trailingComma = IfBreaks {yes = comma; no = nil}
69+ let trailingComma = ifBreaks comma nil
7070let doubleQuote = Text " \" "
7171
7272let propagateForcedBreaks doc =
7373 let rec walk doc = match doc with
7474 | Text _ | Nil | LineSuffix _ ->
75- ( false , doc)
75+ false
7676 | BreakParent ->
77- ( true , Nil )
77+ true
7878 | LineBreak (Hard | Literal ) ->
79- ( true , doc)
79+ true
8080 | LineBreak (Classic | Soft ) ->
81- ( false , doc)
81+ false
8282 | Indent children ->
83- let ( childForcesBreak, newChildren) = walk children in
84- ( childForcesBreak, Indent newChildren)
85- | IfBreaks {yes = trueDoc ; no = falseDoc } ->
86- let ( falseForceBreak, falseDoc) = walk falseDoc in
83+ let childForcesBreak = walk children in
84+ childForcesBreak
85+ | IfBreaks ( {yes = trueDoc ; no = falseDoc } as ib ) ->
86+ let falseForceBreak = walk falseDoc in
8787 if falseForceBreak then
88- let (_, trueDoc) = walk trueDoc in
89- (true , trueDoc)
88+ let _ = walk trueDoc in
89+ ib.broken < - true ;
90+ true
9091 else
91- let forceBreak, trueDoc = walk trueDoc in
92- ( forceBreak, IfBreaks {yes = trueDoc; no = falseDoc})
93- | Group {shouldBreak = forceBreak ; doc = children } ->
94- let ( childForcesBreak, newChildren) = walk children in
92+ let forceBreak = walk trueDoc in
93+ forceBreak
94+ | Group ( {shouldBreak = forceBreak ; doc = children } as gr ) ->
95+ let childForcesBreak = walk children in
9596 let shouldBreak = forceBreak || childForcesBreak in
96- (shouldBreak, Group {shouldBreak; doc = newChildren})
97+ gr.shouldBreak < - shouldBreak;
98+ shouldBreak
9799 | Concat children ->
98- let (forceBreak, newChildren) = List. fold_left (fun (forceBreak , newChildren ) child ->
99- let (childForcesBreak, newChild) = walk child in
100- (forceBreak || childForcesBreak, newChild::newChildren)
101- ) (false , [] ) children
102- in
103- (forceBreak, Concat (List. rev newChildren))
100+ List. fold_left (fun forceBreak child ->
101+ let childForcesBreak = walk child in
102+ forceBreak || childForcesBreak
103+ ) false children
104104 | CustomLayout children ->
105105 (* When using CustomLayout, we don't want to propagate forced breaks
106106 * from the children up. By definition it picks the first layout that fits
107107 * otherwise it takes the last of the list.
108108 * However we do want to propagate forced breaks in the sublayouts. They
109109 * might need to be broken. We just don't propagate them any higher here *)
110- let children = match walk (Concat children) with
111- | (_ , Concat children ) -> children
112- | _ -> assert false
113- in
114- (false , CustomLayout children)
110+ let _ = walk (Concat children) in
111+ false
115112 in
116- let (_, processedDoc) = walk doc in
117- processedDoc
113+ let _ = walk doc in
114+ ()
118115
119116(* See documentation in interface file *)
120117let rec willBreak doc = match doc with
@@ -153,6 +150,7 @@ let fits w stack =
153150 | Break , LineBreak _ -> result := Some true
154151 | _ , Group {shouldBreak = true ; doc} -> calculate indent Break doc
155152 | _ , Group {doc} -> calculate indent mode doc
153+ | _ , IfBreaks {yes = breakDoc ; broken = true } -> calculate indent mode breakDoc
156154 | Break , IfBreaks {yes = breakDoc } -> calculate indent mode breakDoc
157155 | Flat , IfBreaks {no = flatDoc } -> calculate indent mode flatDoc
158156 | _ , Concat docs -> calculateConcat indent mode docs
@@ -180,7 +178,7 @@ let fits w stack =
180178 calculateAll stack
181179
182180let toString ~width doc =
183- let doc = propagateForcedBreaks doc in
181+ propagateForcedBreaks doc;
184182 let buffer = MiniBuffer. create 1000 in
185183
186184 let rec process ~pos lineSuffices stack =
@@ -199,6 +197,8 @@ let toString ~width doc =
199197 process ~pos lineSuffices (List. append ops rest)
200198 | Indent doc ->
201199 process ~pos lineSuffices ((ind + 2 , mode, doc)::rest)
200+ | IfBreaks {yes = breakDoc ; broken = true } ->
201+ process ~pos lineSuffices ((ind, mode, breakDoc)::rest)
202202 | IfBreaks {yes = breakDoc ; no = flatDoc } ->
203203 if mode = Break then
204204 process ~pos lineSuffices ((ind, mode, breakDoc)::rest)
@@ -309,6 +309,7 @@ let debug t =
309309 softLine;
310310 text " )" ;
311311 ]
312+ | IfBreaks {yes = trueDoc ; broken = true } -> toDoc trueDoc
312313 | IfBreaks {yes = trueDoc ; no = falseDoc } ->
313314 group(
314315 concat [
0 commit comments