@@ -15,10 +15,10 @@ type t =
15
15
| Text of string
16
16
| Concat of t list
17
17
| 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 *)
19
19
| LineSuffix of t
20
20
| LineBreak of lineStyle
21
- | Group of {shouldBreak : bool ; doc : t }
21
+ | Group of {mutable shouldBreak : bool ; doc : t }
22
22
| CustomLayout of t list
23
23
| BreakParent
24
24
@@ -43,7 +43,7 @@ let rec _concat acc l =
43
43
let concat l = Concat (_concat [] l)
44
44
45
45
let 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 }
47
47
let lineSuffix d = LineSuffix d
48
48
let group d = Group {shouldBreak = false ; doc = d}
49
49
let breakableGroup ~forceBreak d = Group {shouldBreak = forceBreak; doc = d}
@@ -66,55 +66,52 @@ let rbracket = Text "]"
66
66
let question = Text " ?"
67
67
let tilde = Text " ~"
68
68
let equal = Text " ="
69
- let trailingComma = IfBreaks {yes = comma; no = nil}
69
+ let trailingComma = ifBreaks comma nil
70
70
let doubleQuote = Text " \" "
71
71
72
72
let propagateForcedBreaks doc =
73
73
let rec walk doc = match doc with
74
74
| Text _ | Nil | LineSuffix _ ->
75
- ( false , doc)
75
+ false
76
76
| BreakParent ->
77
- ( true , Nil )
77
+ true
78
78
| LineBreak (Hard | Literal ) ->
79
- ( true , doc)
79
+ true
80
80
| LineBreak (Classic | Soft ) ->
81
- ( false , doc)
81
+ false
82
82
| 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
87
87
if falseForceBreak then
88
- let (_, trueDoc) = walk trueDoc in
89
- (true , trueDoc)
88
+ let _ = walk trueDoc in
89
+ ib.broken < - true ;
90
+ true
90
91
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
95
96
let shouldBreak = forceBreak || childForcesBreak in
96
- (shouldBreak, Group {shouldBreak; doc = newChildren})
97
+ gr.shouldBreak < - shouldBreak;
98
+ shouldBreak
97
99
| 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
104
104
| CustomLayout children ->
105
105
(* When using CustomLayout, we don't want to propagate forced breaks
106
106
* from the children up. By definition it picks the first layout that fits
107
107
* otherwise it takes the last of the list.
108
108
* However we do want to propagate forced breaks in the sublayouts. They
109
109
* 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
115
112
in
116
- let (_, processedDoc) = walk doc in
117
- processedDoc
113
+ let _ = walk doc in
114
+ ()
118
115
119
116
(* See documentation in interface file *)
120
117
let rec willBreak doc = match doc with
@@ -153,6 +150,7 @@ let fits w stack =
153
150
| Break , LineBreak _ -> result := Some true
154
151
| _ , Group {shouldBreak = true ; doc} -> calculate indent Break doc
155
152
| _ , Group {doc} -> calculate indent mode doc
153
+ | _ , IfBreaks {yes = breakDoc ; broken = true } -> calculate indent mode breakDoc
156
154
| Break , IfBreaks {yes = breakDoc } -> calculate indent mode breakDoc
157
155
| Flat , IfBreaks {no = flatDoc } -> calculate indent mode flatDoc
158
156
| _ , Concat docs -> calculateConcat indent mode docs
@@ -180,7 +178,7 @@ let fits w stack =
180
178
calculateAll stack
181
179
182
180
let toString ~width doc =
183
- let doc = propagateForcedBreaks doc in
181
+ propagateForcedBreaks doc;
184
182
let buffer = MiniBuffer. create 1000 in
185
183
186
184
let rec process ~pos lineSuffices stack =
@@ -199,6 +197,8 @@ let toString ~width doc =
199
197
process ~pos lineSuffices (List. append ops rest)
200
198
| Indent doc ->
201
199
process ~pos lineSuffices ((ind + 2 , mode, doc)::rest)
200
+ | IfBreaks {yes = breakDoc ; broken = true } ->
201
+ process ~pos lineSuffices ((ind, mode, breakDoc)::rest)
202
202
| IfBreaks {yes = breakDoc ; no = flatDoc } ->
203
203
if mode = Break then
204
204
process ~pos lineSuffices ((ind, mode, breakDoc)::rest)
@@ -309,6 +309,7 @@ let debug t =
309
309
softLine;
310
310
text " )" ;
311
311
]
312
+ | IfBreaks {yes = trueDoc ; broken = true } -> toDoc trueDoc
312
313
| IfBreaks {yes = trueDoc ; no = falseDoc } ->
313
314
group(
314
315
concat [
0 commit comments