Skip to content

Commit 30f7454

Browse files
committed
Fix performance of expressionFitsOnRestOfLine
1 parent b6ae20c commit 30f7454

File tree

2 files changed

+67
-34
lines changed

2 files changed

+67
-34
lines changed

tools/src/prettier_printer.ml

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ module CodePrinter = struct
2222
The idea is that we capture events in a context type.
2323
Doing this allows us to reason about the current state of the writer
2424
and whether the next expression fits on the current line or not.
25-
2625
*)
2726

2827
type writerEvents =
@@ -31,27 +30,39 @@ module CodePrinter = struct
3130
| IndentBy of int
3231
| UnindentBy of int
3332

33+
type writerMode = Standard | TrySingleLine | ConfirmedMultiline
34+
35+
(* Type representing the writer context during code printing
36+
37+
- [indent_size] is the configured indentation size, typically 2
38+
- [max_line_length] is the maximum line length before we break the line
39+
- [current_indent] is the current indentation size
40+
- [current_line_column] is the characters written on the current line
41+
- [line_count] is the number of lines written
42+
- [events] is the write events in reverse order, head event is last written
43+
- [mode] is the current writer mode (Standard or SingleLine)
44+
*)
3445
type context = {
3546
indent_size: int;
3647
max_line_length: int;
3748
current_indent: int;
3849
current_line_column: int;
39-
events: writerEvents list;
4050
line_count: int;
41-
nesting_level: int;
51+
events: writerEvents list;
52+
mode: writerMode;
4253
}
4354

4455
type appendEvents = context -> context
4556

4657
let emptyContext =
4758
{
4859
indent_size = 2;
49-
max_line_length = 80;
60+
max_line_length = 120;
5061
current_indent = 0;
5162
current_line_column = 0;
52-
events = [];
5363
line_count = 0;
54-
nesting_level = 0;
64+
events = [];
65+
mode = Standard;
5566
}
5667

5768
(** Fold all the events in context into text *)
@@ -76,22 +87,30 @@ module CodePrinter = struct
7687
Buffer.contents buf
7788

7889
let debug_context (ctx : context) =
79-
Format.printf "Current indent: %d, Current line: %d, Events: %d\n"
80-
ctx.current_indent ctx.line_count (List.length ctx.events);
90+
let mode =
91+
match ctx.mode with
92+
| Standard -> "Standard"
93+
| TrySingleLine _ -> "TrySingleLine"
94+
| ConfirmedMultiline -> "ConfirmedMultiline"
95+
in
96+
Format.printf
97+
"Current indent: %d, Current column: %d, # Lines: %d Events: %d, Mode: %s\n"
98+
ctx.current_indent ctx.current_line_column ctx.line_count
99+
(List.length ctx.events) mode;
81100
ctx
82101

83-
let increase_nesting ctx = {ctx with nesting_level = ctx.nesting_level + 1}
84-
85-
let decrease_nesting ctx =
86-
{ctx with nesting_level = max 0 (ctx.nesting_level - 1)}
87-
88-
(* Type representing the writer context during code printing
89-
90-
- [indent_size] is the configured indentation size, typically 2
91-
- [current_indent] is the current indentation size
92-
- [current_line_column] is the characters written on the current line
93-
- [events] is the write events in reverse order, head event is last written
94-
*)
102+
let updateMode (newlineWasAdded : bool) (ctx : context) =
103+
match ctx.mode with
104+
| Standard -> ctx
105+
| ConfirmedMultiline -> ctx
106+
| TrySingleLine ->
107+
{
108+
ctx with
109+
mode =
110+
(if newlineWasAdded || ctx.current_line_column > ctx.max_line_length
111+
then ConfirmedMultiline
112+
else TrySingleLine);
113+
}
95114

96115
let id x = x
97116

@@ -102,9 +121,14 @@ module CodePrinter = struct
102121
events = Write str :: ctx.events;
103122
current_line_column = ctx.current_line_column + String.length str;
104123
}
124+
|> updateMode false
105125

106126
(** compose two context transforming functions *)
107-
let ( +> ) f g ctx = g (f ctx)
127+
let ( +> ) f g ctx =
128+
let fCtx = f ctx in
129+
match fCtx.mode with
130+
| ConfirmedMultiline -> fCtx
131+
| _ -> g fCtx
108132

109133
let sepNln ctx =
110134
{
@@ -113,6 +137,8 @@ module CodePrinter = struct
113137
current_line_column = ctx.current_indent;
114138
line_count = ctx.line_count + 1;
115139
}
140+
|> updateMode true
141+
116142
let sepSpace ctx = !-" " ctx
117143
let sepComma ctx = !-", " ctx
118144
let sepSemi ctx = !-"; " ctx
@@ -156,13 +182,20 @@ module CodePrinter = struct
156182

157183
let expressionFitsOnRestOfLine (f : appendEvents) (fallback : appendEvents)
158184
(ctx : context) =
159-
(* create a short context and check if the expression fits on the current line *)
160-
let shortCtx = f ctx in
161-
if
162-
ctx.line_count == shortCtx.line_count
163-
&& shortCtx.current_line_column <= ctx.max_line_length
164-
then shortCtx
165-
else fallback ctx
185+
match ctx.mode with
186+
| ConfirmedMultiline -> ctx
187+
| _ -> (
188+
let shortCtx =
189+
match ctx.mode with
190+
| Standard -> {ctx with mode = TrySingleLine}
191+
| _ -> ctx
192+
in
193+
let resultCtx = f shortCtx in
194+
match resultCtx.mode with
195+
| ConfirmedMultiline -> fallback ctx
196+
| TrySingleLine -> {resultCtx with mode = ctx.mode}
197+
| Standard ->
198+
failwith "Unexpected Standard mode after trying SingleLine mode")
166199

167200
let rec genOak (oak : oak) : appendEvents =
168201
match oak with
@@ -240,6 +273,11 @@ module CodePrinter = struct
240273
expressionFitsOnRestOfLine short long
241274
end
242275

276+
(*
277+
Interpret using ocaml /home/nojaf/projects/rescript-vscode/tools/src/prettier_printer.ml
278+
*)
279+
280+
(*
243281
open DSL
244282
245283
let oak =
@@ -271,10 +309,6 @@ let oak =
271309
{name = "foo"; value = Ident "baaaaaaaaaaaaaaaaar"};
272310
]
273311
274-
(* let _ =
312+
let _ =
275313
CodePrinter.genOak oak {CodePrinter.emptyContext with max_line_length = 20}
276314
|> CodePrinter.dump |> Format.printf "%s\n" *)
277-
278-
(*
279-
Interpret using ocaml /home/nojaf/projects/rescript-vscode/tools/src/prettier_printer.ml
280-
*)

tools/src/print_tast.ml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,4 @@ let print_type_expr (typ : Types.type_expr) : string =
182182

183183
let print_full (full : SharedTypes.full) : string =
184184
CodePrinter.genOak (Transform.mk_full full) CodePrinter.emptyContext
185-
|> CodePrinter.debug_context
186185
|> CodePrinter.dump

0 commit comments

Comments
 (0)