Allow to interleave visibility and function modifiers
[hiphop-php.git] / hphp / hack / src / parser / full_fidelity_pretty_printer.ml
blob417086ae2f5002d06968e3a89d877570e347a942
1 (**
2 * Copyright (c) 2016, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
9 *)
11 (* The general approach of the pretty printer is to give as much flexibility in
12 * terms of where a newline can occur as possible, while maintaining a sensible
13 * layout that is considerred human readable and "normal"
14 * An optional break is introduced whenever it is possible for a line break to
15 * occur in real life. Small components are grouped together so that each
16 * component decide their layouts individually.
17 * Single line comments is the exception to everything: a newline is forced at
18 * the end of a single line comments even if the line otherwise fits. This rule
19 * overrides the default behaviour of some operators, such as immediate_cons ^^^
20 * which otherwise does not even introduce a break.
21 * Design decisions include:
22 * 1. Each statement is separated from others using a line break
23 * 2. Brackets/parenthesis/braces are either both on different lines with child
24 * or both on the same line with the entire child on one line as well
25 * 3. binary operators can be on different lines with arguments
26 * 4. unary operators must be on the same line as the argument
27 * 5. semicolons have to be on the same line as the last line of the statement
28 * that it ends
31 (* The main data type that is used in the pretty printer is a 5 tuple:
33 * (l_trivia, l_single, doc, r_trivia, r_single)
35 * l_trivia: the doc generated from the leading trivia of the syntax node
36 * l_single: whether the leading trivia contains a single line comment
37 * doc : the doc generated from the main body of the syntax node
38 * r_trivia: the doc generated from trailing trivia of the syntax node
39 * r_single: whether the trailing trivia contains a single line comment
41 open Pretty_printing_library_sig
42 open Limited_width_pretty_printing_library
43 (* utility functions to make combinators look simpler
44 * See Lindig's paper for reference *)
45 module Utility (P : Library) = struct
46 include P
48 let space = text " "
50 let absorb_nil_cons doc1 doc2 delimiter =
51 match doc1, doc2 with
52 | Nil, _ -> doc2
53 | _, Nil -> doc1
54 | _, _ -> doc1 ^^ delimiter ^^ doc2
56 let break_cons doc1 doc2 = absorb_nil_cons doc1 doc2 break
58 let space_cons doc1 doc2 = absorb_nil_cons doc1 doc2 space
60 let choose_cons must is_empty x y =
61 let delimiter =
62 if must then must_break
63 else if is_empty then breakwith ""
64 else break
66 absorb_nil_cons x y delimiter
69 let group_doc (x_lead, x_lead_single, x, x_trail, x_trail_single) =
70 let optional_group = if x = Nil then x else group x in
71 (x_lead, x_lead_single, optional_group, x_trail, x_trail_single)
73 let combine (l_lead, l_lead_single, l, l_trail, l_trail_single) =
74 let front_part = choose_cons l_lead_single false l_lead (group l) in
75 space_cons front_part l_trail
77 (* higher order function to combine two docs with leading and trailing
78 * comments. This function creates a front part and a back part in a fixed
79 * way and takes a function that combines the two parts in different ways *)
80 let doc_combinor x y combinor =
81 let (l_lead, l_lead_single, l, l_trail, l_trail_single) = x in
82 let (r_lead, r_lead_single, r, r_trail, r_trail_single) = y in
83 let front_p = space_cons l l_trail in
84 let end_p = choose_cons r_lead_single false r_lead r in
85 match l, r with
86 | Nil, _ -> (r_lead, r_lead_single, r, r_trail, r_trail_single)
87 | _, Nil -> (l_lead, l_lead_single, l, l_trail, l_trail_single)
88 | _, _ ->
89 (l_lead, l_lead_single, combinor front_p end_p, r_trail, r_trail_single)
91 let doc_cons_opt empty x y =
92 let (_, _, _, _, l_trail_single) = x in
93 let combinor front_part end_part =
94 choose_cons l_trail_single empty front_part end_part in
95 doc_combinor x y combinor
97 let doc_cons = doc_cons_opt false
98 let (^|) = doc_cons
100 let doc_cons_empty = doc_cons_opt true
101 let (^^|) = doc_cons_empty
103 let immediate_cons x y =
104 let (_, _, _, _, l_trail_single) = x in
105 let (_, r_lead_single, _, _, _) = y in
106 let combinor front_part end_part =
107 if l_trail_single || r_lead_single then
108 choose_cons true false front_part end_part
109 else front_part ^^ end_part
111 doc_combinor x y combinor
112 let (^^^) = immediate_cons
114 (* indent [r] by [indent] after [l] using the suitable line break *)
115 let choose_indent_doc empty x y indent =
116 let (_, _, _, _, l_trail_single) = x in
117 let combinor front_part end_part =
118 let break_choice =
119 if l_trail_single then must_break
120 else if empty then breakwith ""
121 else break
123 front_part ^^ nest indent (break_choice ^^ end_part)
125 doc_combinor x y combinor
127 (* put a break before [r] and nest [r] by [indent] in vertical layout *)
128 let indent_doc = choose_indent_doc false
130 let indent_doc_no_space = choose_indent_doc true
132 (* typically we will want to indent block [blk] that is enclosed by
133 * [l] and [r] by amount [indt] *)
134 let indent_block l blk r indt =
135 group_doc (indent_doc l blk indt ^| r)
137 let indent_block_no_space l blk r indt =
138 group_doc ((indent_doc_no_space l blk indt) ^^| r)
140 let add_break (a, b, c, d, e) = (a, b, c, d, true)
143 module LineConf = struct
144 let line_width = 80
146 module Comparator = WidthConstrainedDocComparator(LineConf)
147 module Hh_core = Pretty_printing_library.Make(Comparator)
148 module Printer = Utility(Hh_core)
149 module Syntax = Full_fidelity_editable_syntax
150 module EditableToken = Full_fidelity_editable_token
151 open Syntax
152 open Printer
154 let get_doc_from_trivia trivia_lst allow_break =
155 (* generate a document from a list of trivias. Return the doc, as well
156 * as whether the trivia list contains a single line comment *)
157 let module Trivia = Full_fidelity_editable_trivia in
158 let module Kind = Full_fidelity_trivia_kind in
159 let handle_trivia trivia = match Trivia.kind trivia with
160 | Kind.WhiteSpace -> (nil, false)
161 | Kind.EndOfLine -> (nil, false)
162 | Kind.ExtraTokenError
163 | Kind.Unsafe
164 | Kind.FallThrough
165 | Kind.SingleLineComment ->
166 (* no code after comments *)
167 (text (Trivia.text trivia), true)
168 | Kind.FixMe
169 | Kind.IgnoreError
170 | Kind.UnsafeExpression
171 | Kind.DelimitedComment
172 | Kind.AfterHaltCompiler ->
173 (text (Trivia.text trivia), false)
175 let concat = if allow_break then break_cons else space_cons in
176 let fold_fun x y =
177 let (a, c1) = x in
178 let (b, c2) = y in
179 let result = concat a b in
180 (result, c1 || c2)
182 (* no group here, since all breaks are compulsory. Will group on top level *)
183 List.fold_left fold_fun (nil, false) (List.map handle_trivia trivia_lst)
185 let from_token x =
186 let front_trivias = EditableToken.leading x in
187 let end_trivias = EditableToken.trailing x in
188 let (front_doc, front_single) = get_doc_from_trivia front_trivias true in
189 let (end_doc, end_single) = get_doc_from_trivia end_trivias false in
190 let doc = text (EditableToken.text x) in
191 (front_doc, front_single, doc, end_doc, end_single)
193 (* create a 5-tuple (see top of file) from x with no trivias *)
194 let make_simple x = (nil, false, x, nil, false)
195 let indt = 2
196 let missing = make_simple nil
197 let error_header = make_simple (text "Error:")
198 let space = make_simple (text " ")
199 let colon = make_simple (text ":")
200 let comma = make_simple (text ",")
201 let l_square = make_simple (text "[")
202 let r_square = make_simple (text "]")
203 let question = make_simple (text "?")
204 let ellipsis = make_simple (text "...")
206 let rec get_doc node =
207 match syntax node with
208 | Missing -> missing
209 | MarkupSection x ->
210 group_doc (get_doc x.markup_prefix ^|
211 get_doc x.markup_text ^|
212 get_doc x.markup_suffix ^|
213 get_doc x.markup_expression)
214 | MarkupSuffix x ->
215 group_doc (get_doc x.markup_suffix_less_than_question ^^^
216 get_doc x.markup_suffix_name)
218 | Token x -> from_token x
220 | SyntaxList x -> get_from_children x
221 | ErrorSyntax { error_error } -> get_doc error_error
222 | LiteralExpression x ->
223 begin
224 match syntax x.literal_expression with
225 | SyntaxList l -> get_from_children_no_space l
226 | _ -> get_doc x.literal_expression
228 | VariableExpression x -> get_doc x.variable_expression
229 | QualifiedNameExpression x -> get_doc x.qualified_name_expression
230 | PipeVariableExpression x -> get_doc x.pipe_variable_expression
231 | ListItem x -> (get_doc x.list_item) ^^^ (get_doc x.list_separator)
232 | EndOfFile { end_of_file_token } -> get_doc end_of_file_token
233 | Script x -> get_doc x.script_declarations
234 | ClassishDeclaration
235 { classish_attribute; classish_modifiers; classish_keyword;
236 classish_name; classish_type_parameters; classish_extends_keyword;
237 classish_extends_list; classish_implements_keyword;
238 classish_implements_list; classish_body } ->
239 let attr = add_break (get_doc classish_attribute) in
240 let preface = group_doc (
241 get_doc classish_modifiers ^|
242 get_doc classish_keyword
243 ) in
245 let name_and_generics =
246 let name = get_doc classish_name in
247 let type_params = get_doc classish_type_parameters in
248 group_doc (indent_doc name type_params indt)
251 let extends =
252 let extends_token = get_doc classish_extends_keyword in
253 let extends_list = get_doc classish_extends_list in
254 group_doc (indent_doc extends_token extends_list indt)
257 let implements =
258 let implements_token = get_doc classish_implements_keyword in
259 let implements_list = get_doc classish_implements_list in
260 group_doc (indent_doc implements_token implements_list indt)
263 let body = get_doc classish_body in
265 (* TODO: Make this better *)
266 attr ^^^
267 group_doc (
268 group_doc (
269 preface ^|
270 name_and_generics
271 ) ^|
272 group_doc (
273 extends ^|
274 implements
275 ) ^|
276 body
278 | ClassishBody x ->
279 let left = get_doc x.classish_body_left_brace in
280 let right = get_doc x.classish_body_right_brace in
281 let body = get_doc x.classish_body_elements in
282 indent_block_no_space left body right indt
283 | XHPRequired { xhp_required_at; xhp_required_keyword } ->
284 let a = get_doc xhp_required_at in
285 let r = get_doc xhp_required_keyword in
286 a ^^^ r
287 | XHPChildrenDeclaration {
288 xhp_children_keyword;
289 xhp_children_expression;
290 xhp_children_semicolon } ->
291 let c = get_doc xhp_children_keyword in
292 let e = get_doc xhp_children_expression in
293 let s = get_doc xhp_children_semicolon in
294 c ^| e ^^^ s
295 | XHPChildrenParenthesizedList {
296 xhp_children_list_left_paren;
297 xhp_children_list_xhp_children;
298 xhp_children_list_right_paren } ->
299 let l = get_doc xhp_children_list_left_paren in
300 let c = get_doc xhp_children_list_xhp_children in
301 let r = get_doc xhp_children_list_right_paren in
302 l ^| c ^| r
303 | XHPCategoryDeclaration {
304 xhp_category_keyword;
305 xhp_category_categories;
306 xhp_category_semicolon } ->
307 let c = get_doc xhp_category_keyword in
308 let l = get_doc xhp_category_categories in
309 let s = get_doc xhp_category_semicolon in
310 c ^| l ^^^ s
311 | XHPEnumType {
312 xhp_enum_optional;
313 xhp_enum_keyword;
314 xhp_enum_left_brace;
315 xhp_enum_values;
316 xhp_enum_right_brace;
317 } ->
318 let o = get_doc xhp_enum_optional in
319 let e = get_doc xhp_enum_keyword in
320 let l = get_doc xhp_enum_left_brace in
321 let v = get_doc xhp_enum_values in
322 let r = get_doc xhp_enum_right_brace in
323 group_doc (o ^| e ^| l ^| v ^| r)
324 | XHPClassAttributeDeclaration {
325 xhp_attribute_keyword;
326 xhp_attribute_attributes;
327 xhp_attribute_semicolon } ->
328 let attr = get_doc xhp_attribute_keyword in
329 let attrs = get_doc xhp_attribute_attributes in
330 let semi = get_doc xhp_attribute_semicolon in
331 group_doc (attr ^| attrs ^^^ semi)
332 | XHPClassAttribute
333 { xhp_attribute_decl_type; xhp_attribute_decl_name;
334 xhp_attribute_decl_initializer; xhp_attribute_decl_required } ->
335 let t = get_doc xhp_attribute_decl_type in
336 let n = get_doc xhp_attribute_decl_name in
337 let i = get_doc xhp_attribute_decl_initializer in
338 let r = get_doc xhp_attribute_decl_required in
339 group_doc (t ^| n ^| i ^| r)
340 | XHPSimpleClassAttribute { xhp_simple_class_attribute_type } ->
341 get_doc xhp_simple_class_attribute_type
342 | TraitUseAliasItem {
343 trait_use_alias_item_aliasing_name;
344 trait_use_alias_item_keyword;
345 trait_use_alias_item_modifiers;
346 trait_use_alias_item_aliased_name;
347 } ->
348 let n = get_doc trait_use_alias_item_aliasing_name in
349 let k = get_doc trait_use_alias_item_keyword in
350 let v = get_doc trait_use_alias_item_modifiers in
351 let ns = get_doc trait_use_alias_item_aliased_name in
352 n ^| k ^| v ^| ns
353 | TraitUsePrecedenceItem {
354 trait_use_precedence_item_name;
355 trait_use_precedence_item_keyword;
356 trait_use_precedence_item_removed_names;
357 } ->
358 let n = get_doc trait_use_precedence_item_name in
359 let k = get_doc trait_use_precedence_item_keyword in
360 let ns = get_doc trait_use_precedence_item_removed_names in
361 n ^| k ^| ns
362 | TraitUseConflictResolution {
363 trait_use_conflict_resolution_keyword;
364 trait_use_conflict_resolution_names;
365 trait_use_conflict_resolution_left_brace;
366 trait_use_conflict_resolution_clauses;
367 trait_use_conflict_resolution_right_brace;
368 } ->
369 let use = get_doc trait_use_conflict_resolution_keyword in
370 let name_list = get_doc trait_use_conflict_resolution_names in
371 let lbrace = get_doc trait_use_conflict_resolution_left_brace in
372 let clauses = get_doc trait_use_conflict_resolution_clauses in
373 let rbrace = get_doc trait_use_conflict_resolution_right_brace in
374 use ^| name_list ^^^ lbrace ^| clauses ^^^ rbrace
375 | TraitUse {
376 trait_use_keyword;
377 trait_use_names;
378 trait_use_semicolon;
379 } ->
380 let use = get_doc trait_use_keyword in
381 let name_list = get_doc trait_use_names in
382 let semi = get_doc trait_use_semicolon in
383 use ^| name_list ^^^ semi
384 | RequireClause x ->
385 let r = get_doc x.require_keyword in
386 let k = get_doc x.require_kind in
387 let n = get_doc x.require_name in
388 let s = get_doc x.require_semicolon in
389 r ^| k ^| n ^^^ s
390 | ConstDeclaration {
391 const_abstract;
392 const_keyword;
393 const_type_specifier;
394 const_declarators;
395 const_semicolon } ->
396 let abstr = get_doc const_abstract in
397 let token = get_doc const_keyword in
398 let ty = get_doc const_type_specifier in
399 let lst = get_doc const_declarators in
400 let semi = get_doc const_semicolon in
401 group_doc (abstr ^| token ^| ty ) ^| lst ^^^ semi
402 | ConstantDeclarator x ->
403 let name = get_doc x.constant_declarator_name in
404 let init = get_doc x.constant_declarator_initializer in
405 group_doc (name ^| init)
406 | TypeConstDeclaration x ->
407 let abstr = get_doc x.type_const_abstract in
408 let const = get_doc x.type_const_keyword in
409 let type_ = get_doc x.type_const_type_keyword in
410 let name = get_doc x.type_const_name in
411 let type_constraint = get_doc x.type_const_type_constraint in
412 let equal = get_doc x.type_const_equal in
413 let type_spec = get_doc x.type_const_type_specifier in
414 let semicolon = get_doc x.type_const_semicolon in
415 group_doc (
416 group_doc (abstr ^| const ^| type_ ^| name) ^|
417 type_constraint ^|
418 equal ^|
419 group_doc (type_spec ^^^ semicolon)
421 | EnumDeclaration {
422 enum_attribute_spec;
423 enum_keyword;
424 enum_name;
425 enum_colon;
426 enum_base;
427 enum_type;
428 enum_left_brace;
429 enum_enumerators;
430 enum_right_brace } ->
431 let attrs = get_doc enum_attribute_spec in
432 let en = get_doc enum_keyword in
433 let na = get_doc enum_name in
434 let co = get_doc enum_colon in
435 let ba = get_doc enum_base in
436 let ty = get_doc enum_type in
437 let lb = get_doc enum_left_brace in
438 let es = get_doc enum_enumerators in
439 let rb = get_doc enum_right_brace in
440 (* TODO: This could be a lot better. Add indentation, etc. *)
441 attrs ^| en ^| na ^| co ^| ba ^| ty ^| lb ^| es ^| rb
442 | Enumerator x ->
443 let n = get_doc x.enumerator_name in
444 let e = get_doc x.enumerator_equal in
445 let v = get_doc x.enumerator_value in
446 let semicolon = get_doc x.enumerator_semicolon in
447 n ^| e ^| v ^^^ semicolon
448 | AliasDeclaration x ->
449 (* TODO: What's the best way to ensure that there's a newline between the
450 attribute and the alias declaration proper? *)
451 let attr = get_doc x.alias_attribute_spec in
452 let a = get_doc x.alias_keyword in
453 let n = get_doc x.alias_name in
454 let generic = get_doc x.alias_generic_parameter in
455 let c = get_doc x.alias_constraint in
456 let e = get_doc x.alias_equal in
457 let t = get_doc x.alias_type in
458 let s = get_doc x.alias_semicolon in
459 attr ^| a ^| n ^| generic ^| c ^| e ^| t ^^^ s
460 | PropertyDeclaration
461 { property_modifiers; property_type;
462 property_declarators; property_semicolon } ->
463 let m = get_doc property_modifiers in
464 let t = get_doc property_type in
465 let d = get_doc property_declarators in
466 let s = get_doc property_semicolon in
467 m ^| t ^| d ^^^ s
468 | PropertyDeclarator { property_name; property_initializer } ->
469 let n = get_doc property_name in
470 let i = get_doc property_initializer in
471 n ^| i
472 | NamespaceDeclaration x ->
473 let t = get_doc x.namespace_keyword in
474 let n = get_doc x.namespace_name in
475 let b = get_doc x.namespace_body in
476 t ^| n ^| b
477 | NamespaceBody x ->
478 let left = get_doc x.namespace_left_brace in
479 let body = get_doc x.namespace_declarations in
480 let right = get_doc x.namespace_right_brace in
481 indent_block_no_space left body right indt |> add_break
482 | NamespaceEmptyBody x ->
483 get_doc x.namespace_semicolon
484 | NamespaceUseDeclaration x ->
485 let u = get_doc x.namespace_use_keyword in
486 let k = get_doc x.namespace_use_kind in
487 let c = get_doc x.namespace_use_clauses in
488 let s = get_doc x.namespace_use_semicolon in
489 u ^| k ^| c ^^^ s
490 | NamespaceUseClause x ->
491 let k = get_doc x.namespace_use_clause_kind in
492 let n = get_doc x.namespace_use_name in
493 let a = get_doc x.namespace_use_as in
494 let l = get_doc x.namespace_use_alias in
495 k ^| n ^| a ^| l
496 | NamespaceGroupUseDeclaration x ->
497 let u = get_doc x.namespace_group_use_keyword in
498 let k = get_doc x.namespace_group_use_kind in
499 let p = get_doc x.namespace_group_use_prefix in
500 let l = get_doc x.namespace_group_use_left_brace in
501 let c = get_doc x.namespace_group_use_clauses in
502 let r = get_doc x.namespace_group_use_right_brace in
503 let s = get_doc x.namespace_group_use_semicolon in
504 u ^| k ^| p ^| l ^| c ^| r ^^^ s
505 | FunctionDeclaration x ->
506 let attr = get_doc x.function_attribute_spec in
507 let header = get_doc x.function_declaration_header in
508 let body = x.function_body in
509 let after_attr = handle_compound_inline_brace header body missing in
510 group_doc (attr ^| after_attr)
511 | FunctionDeclarationHeader
512 { function_modifiers;
513 function_keyword;
514 function_ampersand;
515 function_name;
516 function_type_parameter_list;
517 function_left_paren;
518 function_parameter_list;
519 function_right_paren;
520 function_colon;
521 function_type;
522 function_where_clause }
524 let preface =
525 group_doc (get_doc function_modifiers ^| get_doc function_keyword) in
526 let name_and_generics =
527 let type_params = get_doc function_type_parameter_list in
528 let ampersand = get_doc function_ampersand in
529 let name = get_doc function_name in
530 group_doc (indent_doc (ampersand ^^^ name) type_params indt)
532 let parameters =
533 let left = get_doc function_left_paren in
534 let right = get_doc function_right_paren in
535 let params = get_doc function_parameter_list in
536 indent_block_no_space left params right indt
538 let type_declaration =
539 let fun_colon = get_doc function_colon in
540 let fun_type = get_doc function_type in
541 let where_clause = get_doc function_where_clause in
542 group_doc (fun_colon ^| fun_type ^| where_clause)
544 group_doc (
545 group_doc ( group_doc (preface ^| name_and_generics) ^^| parameters )
546 ^| type_declaration
548 | WhereClause { where_clause_keyword; where_clause_constraints } ->
549 let w = get_doc where_clause_keyword in
550 let c = get_doc where_clause_constraints in
551 w ^| c
552 | WhereConstraint { where_constraint_left_type; where_constraint_operator ;
553 where_constraint_right_type } ->
554 let l = get_doc where_constraint_left_type in
555 let o = get_doc where_constraint_operator in
556 let r = get_doc where_constraint_right_type in
557 l ^| o ^| r
558 | MethodishDeclaration
559 { methodish_attribute; methodish_function_decl_header;
560 methodish_function_body; methodish_semicolon } ->
561 let methodish_attr = get_doc methodish_attribute in
562 let function_header = get_doc methodish_function_decl_header in
563 let body_node = methodish_function_body in
564 let semicolon = get_doc methodish_semicolon in
565 let after_attr =
566 handle_compound_inline_brace function_header body_node missing in
567 let after_attr = after_attr ^^^ semicolon in
568 group_doc (methodish_attr ^| after_attr)
569 | DecoratedExpression x ->
570 let decorator = get_doc x.decorated_expression_decorator in
571 let expression = get_doc x.decorated_expression_expression in
572 group_doc (decorator ^^^ expression)
573 | ParameterDeclaration {
574 parameter_attribute;
575 parameter_visibility;
576 parameter_call_convention;
577 parameter_type;
578 parameter_name;
579 parameter_default_value } ->
580 let attr = get_doc parameter_attribute in
581 let visibility = get_doc parameter_visibility in
582 let callconv = get_doc parameter_call_convention in
583 let parameter_type = get_doc parameter_type in
584 let parameter_name = get_doc parameter_name in
585 let parameter_default = get_doc parameter_default_value in
586 group_doc
587 ( attr ^| visibility ^| callconv ^| parameter_type ^| parameter_name
588 ^| parameter_default )
589 | VariadicParameter {
590 variadic_parameter_call_convention;
591 variadic_parameter_type;
592 variadic_parameter_ellipsis } ->
593 let cc = get_doc variadic_parameter_call_convention in
594 let t = get_doc variadic_parameter_type in
595 let ell = get_doc variadic_parameter_ellipsis in
596 group_doc (cc ^| t ^| ell)
597 | AttributeSpecification {
598 attribute_specification_left_double_angle;
599 attribute_specification_attributes;
600 attribute_specification_right_double_angle } ->
601 let left = get_doc attribute_specification_left_double_angle in
602 let specs = get_doc attribute_specification_attributes in
603 let right = get_doc attribute_specification_right_double_angle in
604 indent_block_no_space left specs right indt
605 | Attribute x ->
606 let name = get_doc x.attribute_name in
607 let left = get_doc x.attribute_left_paren in
608 let right = get_doc x.attribute_right_paren in
609 let values = get_doc x.attribute_values in
610 let left_part = group_doc (name ^^| left) in
611 indent_block_no_space left_part values right indt
612 | InclusionExpression x ->
613 let rq = get_doc x.inclusion_require in
614 let fn = get_doc x.inclusion_filename in
615 rq ^| fn
616 | InclusionDirective x ->
617 let ex = get_doc x.inclusion_expression in
618 let se = get_doc x.inclusion_semicolon in
619 ex ^^^ se
620 | CompoundStatement x ->
621 let left = get_doc x.compound_left_brace in
622 let right = get_doc x.compound_right_brace in
623 let body = get_doc x.compound_statements in
624 indent_block_no_space left body right indt |> add_break
625 | ExpressionStatement {
626 expression_statement_expression;
627 expression_statement_semicolon } ->
628 let body = get_doc expression_statement_expression in
629 let semicolon = get_doc expression_statement_semicolon in
630 (* semicolon always follows the last line *)
631 body ^^^ semicolon |> group_doc |> add_break
632 | UnsetStatement {
633 unset_keyword;
634 unset_left_paren;
635 unset_variables;
636 unset_right_paren;
637 unset_semicolon} ->
638 let u = get_doc unset_keyword in
639 let l = get_doc unset_left_paren in
640 let v = get_doc unset_variables in
641 let r = get_doc unset_right_paren in
642 let s = get_doc unset_semicolon in
643 group_doc (u ^^^ l ^^^ v ^^^ r ^^^ s)
644 | WhileStatement
645 { while_keyword; while_left_paren; while_condition; while_right_paren;
646 while_body } ->
647 let keyword = get_doc while_keyword in
648 let left = get_doc while_left_paren in
649 let condition = get_doc while_condition in
650 let right = get_doc while_right_paren in
651 let left_part = group_doc (keyword ^^| left) in
652 let start_block = indent_block_no_space left_part condition right indt in
653 handle_compound_brace_prefix_indent start_block while_body indt
654 |> add_break
655 | DeclareDirectiveStatement
656 { declare_directive_keyword; declare_directive_left_paren;
657 declare_directive_expression; declare_directive_right_paren;
658 declare_directive_semicolon } ->
659 let k = get_doc declare_directive_keyword in
660 let l = get_doc declare_directive_left_paren in
661 let e = get_doc declare_directive_expression in
662 let r = get_doc declare_directive_right_paren in
663 let s = get_doc declare_directive_semicolon in
664 group_doc (k ^^^ l ^^^ e ^^^ r ^^^ s) |> add_break
665 | DeclareBlockStatement
666 { declare_block_keyword; declare_block_left_paren; declare_block_expression;
667 declare_block_right_paren; declare_block_body } ->
668 let keyword = get_doc declare_block_keyword in
669 let left = get_doc declare_block_left_paren in
670 let expression = get_doc declare_block_expression in
671 let right = get_doc declare_block_right_paren in
672 let left_part = group_doc (keyword ^^| left) in
673 let start_block = indent_block_no_space left_part expression right indt in
674 handle_compound_brace_prefix_indent start_block declare_block_body indt
675 |> add_break
676 | UsingStatementBlockScoped
677 { using_block_await_keyword
678 ; using_block_using_keyword
679 ; using_block_left_paren
680 ; using_block_expressions
681 ; using_block_right_paren
682 ; using_block_body } ->
683 let await_keyword = get_doc using_block_await_keyword in
684 let using_keyword = get_doc using_block_using_keyword in
685 let left = get_doc using_block_left_paren in
686 let expressions = get_doc using_block_expressions in
687 let right = get_doc using_block_right_paren in
688 let left_part = group_doc (await_keyword ^| using_keyword ^| left) in
689 let start_block = indent_block_no_space left_part expressions right indt in
690 handle_compound_brace_prefix_indent start_block using_block_body indt
691 |> add_break
692 | UsingStatementFunctionScoped
693 { using_function_await_keyword
694 ; using_function_using_keyword
695 ; using_function_expression
696 ; using_function_semicolon } ->
697 let await_keyword = get_doc using_function_await_keyword in
698 let using_keyword = get_doc using_function_using_keyword in
699 let expression = get_doc using_function_expression in
700 let semi = get_doc using_function_semicolon in
701 group_doc (await_keyword ^| using_keyword ^| expression ^^^ semi)
702 | IfStatement
703 { if_keyword; if_left_paren; if_condition; if_right_paren; if_statement;
704 if_elseif_clauses; if_else_clause }->
705 let keyword = get_doc if_keyword in
706 let left = get_doc if_left_paren in
707 let condition = get_doc if_condition in
708 let right = get_doc if_right_paren in
709 let if_stmt = if_statement in
710 let elseif_clause = get_doc if_elseif_clauses in
711 let else_clause = get_doc if_else_clause in
712 let left_part = group_doc (keyword ^^| left) in
713 let start_block = indent_block_no_space left_part condition right indt in
714 let if_statement =
715 handle_compound_brace_prefix_indent start_block if_stmt indt in
716 let if_statement = add_break if_statement in
717 group_doc (if_statement ^| elseif_clause ^| else_clause)
718 | ElseifClause
719 { elseif_keyword; elseif_left_paren; elseif_condition; elseif_right_paren;
720 elseif_statement } ->
721 let keyword = get_doc elseif_keyword in
722 let left = get_doc elseif_left_paren in
723 let condition = get_doc elseif_condition in
724 let right = get_doc elseif_right_paren in
725 let elif_statement_syntax = elseif_statement in
726 let left_part = group_doc (keyword ^^| left) in
727 let start_block = indent_block_no_space left_part condition right indt in
728 handle_compound_brace_prefix_indent start_block elif_statement_syntax indt
729 |> add_break
730 | ElseClause x ->
731 let keyword = get_doc x.else_keyword in
732 let statement = x.else_statement in
733 handle_compound_brace_prefix_indent keyword statement indt
734 |> add_break
735 | IfEndIfStatement
736 { if_endif_keyword; if_endif_colon; if_endif_left_paren; if_endif_condition;
737 if_endif_right_paren; if_endif_statement; if_endif_elseif_colon_clauses;
738 if_endif_else_colon_clause; if_endif_endif_keyword; if_endif_semicolon }->
739 let keyword = get_doc if_endif_keyword in
740 let left = get_doc if_endif_left_paren in
741 let condition = get_doc if_endif_condition in
742 let right = get_doc if_endif_right_paren in
743 let colon = get_doc if_endif_colon in
744 let if_stmt = if_endif_statement in
745 let elseif_clause = get_doc if_endif_elseif_colon_clauses in
746 let else_clause = get_doc if_endif_else_colon_clause in
747 let end_kw = get_doc if_endif_endif_keyword in
748 let semicolon = get_doc if_endif_semicolon in
749 let left_part = group_doc (keyword ^^| left) in
750 let right_part = group_doc (right ^^^ colon) in
751 let end_block = group_doc (end_kw ^^^ semicolon) in
752 let start_block = indent_block_no_space left_part condition right_part indt in
753 let if_statement =
754 handle_compound_brace_prefix_indent start_block if_stmt indt in
755 let if_statement = add_break if_statement in
756 group_doc (if_statement ^| elseif_clause ^| else_clause ^| end_block)
757 | ElseifColonClause
758 { elseif_colon_keyword; elseif_colon_left_paren; elseif_colon_condition;
759 elseif_colon_right_paren; elseif_colon_colon; elseif_colon_statement } ->
760 let keyword = get_doc elseif_colon_keyword in
761 let left = get_doc elseif_colon_left_paren in
762 let condition = get_doc elseif_colon_condition in
763 let right = get_doc elseif_colon_right_paren in
764 let colon = get_doc elseif_colon_colon in
765 let elif_statement_syntax = elseif_colon_statement in
766 let left_part = group_doc (keyword ^^| left) in
767 let right_part = group_doc (right ^^^ colon) in
768 let start_block = indent_block_no_space left_part condition right_part indt in
769 handle_compound_brace_prefix_indent start_block elif_statement_syntax indt
770 |> add_break
771 | ElseColonClause x ->
772 let keyword = get_doc x.else_colon_keyword in
773 let statement = x.else_colon_statement in
774 handle_compound_brace_prefix_indent keyword statement indt
775 |> add_break
776 | TryStatement
777 { try_keyword;
778 try_compound_statement;
779 try_catch_clauses;
780 try_finally_clause } ->
781 let keyword = get_doc try_keyword in
782 let compound_stmt = try_compound_statement in
783 let try_part =
784 handle_compound_brace_prefix_indent keyword compound_stmt indt in
785 let catch_clauses = get_doc try_catch_clauses in
786 let finally_clause = get_doc try_finally_clause in
787 group_doc (try_part ^| catch_clauses ^| finally_clause)
788 |> add_break
789 | CatchClause {
790 catch_keyword;
791 catch_left_paren;
792 catch_type;
793 catch_variable;
794 catch_right_paren;
795 catch_body } ->
796 let keyword = get_doc catch_keyword in
797 let left = get_doc catch_left_paren in
798 let ty = get_doc catch_type in
799 let var = get_doc catch_variable in
800 let param = ty ^| var in
801 let right = get_doc catch_right_paren in
802 let stmt = catch_body in
803 let front_part = group_doc (keyword ^| left) in
804 let before_stmt = indent_block_no_space front_part param right indt in
805 handle_compound_brace_prefix_indent before_stmt stmt indt
806 |> add_break
807 | FinallyClause {
808 finally_keyword;
809 finally_body } ->
810 let keyword = get_doc finally_keyword in
811 handle_compound_brace_prefix_indent keyword finally_body indt
812 |> add_break
813 | DoStatement {
814 do_keyword;
815 do_body;
816 do_while_keyword;
817 do_left_paren;
818 do_condition;
819 do_right_paren;
820 do_semicolon } ->
821 let keyword = get_doc do_keyword in
822 let statement = do_body in
823 let while_keyword = get_doc do_while_keyword in
824 let left = get_doc do_left_paren in
825 let right = get_doc do_right_paren in
826 let condition = get_doc do_condition in
827 let semicolon = get_doc do_semicolon in
828 let statement_part =
829 handle_compound_brace_prefix_indent keyword statement indt |> add_break in
830 let left_part = group_doc (while_keyword ^^| left) in
831 let condition_part = indent_block_no_space left_part condition right indt in
832 group_doc (statement_part ^| condition_part) ^^^ semicolon
833 | ForStatement {
834 for_keyword;
835 for_left_paren;
836 for_initializer;
837 for_first_semicolon;
838 for_control;
839 for_second_semicolon;
840 for_end_of_loop;
841 for_right_paren;
842 for_body } ->
843 let keyword = get_doc for_keyword in
844 let left_paren = get_doc for_left_paren in
845 let initializer_expr = get_doc for_initializer in
846 let first_semicolon = get_doc for_first_semicolon in
847 let control_expr = get_doc for_control in
848 let second_semicolon = get_doc for_second_semicolon in
849 let end_of_loop_expr = get_doc for_end_of_loop in
850 let right_paren = get_doc for_right_paren in
851 let statement = for_body in
852 let left_part = group_doc (keyword ^^| left_paren) in
853 let for_expressions =
854 control_expr ^^^ second_semicolon ^| end_of_loop_expr in
855 let for_expressions = if is_missing for_control
856 then first_semicolon ^^| for_expressions
857 else first_semicolon ^| for_expressions in
858 let for_expressions = group_doc (initializer_expr ^^^ for_expressions) in
859 let start_block =
860 indent_block_no_space left_part for_expressions right_paren indt in
861 handle_compound_brace_prefix_indent start_block statement indt |> add_break
862 | ForeachStatement {
863 foreach_keyword;
864 foreach_left_paren;
865 foreach_collection;
866 foreach_await_keyword;
867 foreach_as;
868 foreach_key;
869 foreach_arrow;
870 foreach_value;
871 foreach_right_paren;
872 foreach_body }->
873 let keyword = get_doc foreach_keyword in
874 let left = get_doc foreach_left_paren in
875 let right = get_doc foreach_right_paren in
876 let collection_name = get_doc foreach_collection in
877 let await_keyword = get_doc foreach_await_keyword in
878 let as_keyword = get_doc foreach_as in
879 let key = get_doc foreach_key in
880 let arrow = get_doc foreach_arrow in
881 let value = get_doc foreach_value in
882 let statement = foreach_body in
883 let left_part = group_doc (keyword ^| left) in
884 let arrow_part = group_doc (group_doc (key ^| arrow) ^| value) in
885 let as_part = group_doc (await_keyword ^| as_keyword) in
886 let as_part = group_doc (collection_name ^| as_part) in
887 let middle_part = group_doc (as_part ^| arrow_part) in
888 let start_block = indent_block_no_space left_part middle_part right indt in
889 handle_compound_brace_prefix_indent start_block statement indt |> add_break
890 | SwitchStatement {
891 switch_keyword;
892 switch_left_paren;
893 switch_expression;
894 switch_right_paren;
895 switch_left_brace;
896 switch_sections;
897 switch_right_brace } ->
898 let keyword = get_doc switch_keyword in
899 let lparen= get_doc switch_left_paren in
900 let expr = get_doc switch_expression in
901 let rparen = get_doc switch_right_paren in
902 let lbrace = get_doc switch_left_brace in
903 let sections = get_doc switch_sections in
904 let rbrace = get_doc switch_right_brace in
905 (* TODO Fix this *)
906 let h = keyword ^| lparen ^| expr ^| rparen ^| space ^| lbrace in
907 let h = add_break h in
908 h ^| sections ^| rbrace
909 | SwitchSection {
910 switch_section_labels;
911 switch_section_statements;
912 switch_section_fallthrough } ->
913 (* TODO Fix this *)
914 let labels = get_doc switch_section_labels in
915 let statements = get_doc switch_section_statements in
916 let fallthrough = get_doc switch_section_fallthrough in
917 (add_break labels) ^| (add_break statements) ^| (add_break fallthrough)
918 | SwitchFallthrough {
919 fallthrough_keyword;
920 fallthrough_semicolon
921 } ->
922 let f = get_doc fallthrough_keyword in
923 let s = get_doc fallthrough_semicolon in
924 f ^^^ s
925 | ScopeResolutionExpression x ->
926 let q = get_doc x.scope_resolution_qualifier in
927 let o = get_doc x.scope_resolution_operator in
928 let n = get_doc x.scope_resolution_name in
929 group_doc (q ^^^ o ^^^ n)
930 | MemberSelectionExpression
931 { member_object; member_operator; member_name } ->
932 let ob = get_doc member_object in
933 let op = get_doc member_operator in
934 let nm = get_doc member_name in
935 group_doc (ob ^^^ op ^^^ nm)
936 | SafeMemberSelectionExpression
937 { safe_member_object; safe_member_operator; safe_member_name } ->
938 let ob = get_doc safe_member_object in
939 let op = get_doc safe_member_operator in
940 let nm = get_doc safe_member_name in
941 group_doc (ob ^^^ op ^^^ nm)
942 | EmbeddedMemberSelectionExpression
943 { embedded_member_object;
944 embedded_member_operator;
945 embedded_member_name } ->
946 let ob = get_doc embedded_member_object in
947 let op = get_doc embedded_member_operator in
948 let nm = get_doc embedded_member_name in
949 group_doc (ob ^^^ op ^^^ nm)
950 | YieldExpression x ->
951 let y = get_doc x.yield_keyword in
952 let o = get_doc x.yield_operand in
953 group_doc (y ^| o)
954 | YieldFromExpression x ->
955 let y = get_doc x.yield_from_yield_keyword in
956 let f = get_doc x.yield_from_from_keyword in
957 let o = get_doc x.yield_from_operand in
958 group_doc (y ^| f ^| o)
959 | CastExpression x ->
960 let l = get_doc x.cast_left_paren in
961 let t = get_doc x.cast_type in
962 let r = get_doc x.cast_right_paren in
963 let o = get_doc x.cast_operand in
964 group_doc (l ^^^ t ^^^ r ^^^ o)
965 | LambdaExpression {
966 lambda_async;
967 lambda_coroutine;
968 lambda_signature;
969 lambda_arrow;
970 lambda_body;
971 } ->
972 let async = get_doc lambda_async in
973 let coroutine = get_doc lambda_coroutine in
974 let signature = get_doc lambda_signature in
975 let arrow = get_doc lambda_arrow in
976 let body = get_doc lambda_body in
977 group_doc (async ^| coroutine ^| signature ^| arrow ^| body)
978 | LambdaSignature
979 { lambda_left_paren; lambda_parameters; lambda_right_paren;
980 lambda_colon; lambda_type } ->
981 let left = get_doc lambda_left_paren in
982 let params = get_doc lambda_parameters in
983 let right = get_doc lambda_right_paren in
984 let colon = get_doc lambda_colon in
985 let ty = get_doc lambda_type in
986 group_doc (left ^| params ^| right ^| colon ^| ty)
987 | AnonymousFunction
988 { anonymous_static_keyword;
989 anonymous_async_keyword;
990 anonymous_coroutine_keyword;
991 anonymous_function_keyword;
992 anonymous_left_paren;
993 anonymous_parameters;
994 anonymous_right_paren;
995 anonymous_colon;
996 anonymous_type;
997 anonymous_use;
998 anonymous_body } ->
999 let static = get_doc anonymous_static_keyword in
1000 let async = get_doc anonymous_async_keyword in
1001 let coroutine = get_doc anonymous_coroutine_keyword in
1002 let fn = get_doc anonymous_function_keyword in
1003 let left = get_doc anonymous_left_paren in
1004 let params = get_doc anonymous_parameters in
1005 let right = get_doc anonymous_right_paren in
1006 let colon = get_doc anonymous_colon in
1007 let return_type = get_doc anonymous_type in
1008 let preface = group_doc ( static ^| async ^| coroutine ^| fn ) in
1009 let parameters = indent_block_no_space left params right indt in
1010 let type_declaration = group_doc (colon ^| return_type) in
1011 let uses = get_doc anonymous_use in
1012 let body = anonymous_body in
1013 let before_body =
1014 group_doc (
1015 group_doc ( group_doc preface ^^| parameters )
1016 ^| type_declaration ^| uses
1017 ) in
1018 handle_compound_inline_brace before_body body missing
1019 | Php7AnonymousFunction
1020 { php7_anonymous_static_keyword;
1021 php7_anonymous_async_keyword;
1022 php7_anonymous_coroutine_keyword;
1023 php7_anonymous_function_keyword;
1024 php7_anonymous_left_paren;
1025 php7_anonymous_parameters;
1026 php7_anonymous_right_paren;
1027 php7_anonymous_colon;
1028 php7_anonymous_type;
1029 php7_anonymous_use;
1030 php7_anonymous_body } ->
1031 let static = get_doc php7_anonymous_static_keyword in
1032 let async = get_doc php7_anonymous_async_keyword in
1033 let coroutine = get_doc php7_anonymous_coroutine_keyword in
1034 let fn = get_doc php7_anonymous_function_keyword in
1035 let left = get_doc php7_anonymous_left_paren in
1036 let params = get_doc php7_anonymous_parameters in
1037 let right = get_doc php7_anonymous_right_paren in
1038 let colon = get_doc php7_anonymous_colon in
1039 let return_type = get_doc php7_anonymous_type in
1040 let preface = group_doc ( static ^| async ^| coroutine ^| fn ) in
1041 let parameters = indent_block_no_space left params right indt in
1042 let type_declaration = group_doc (colon ^| return_type) in
1043 let uses = get_doc php7_anonymous_use in
1044 let body = php7_anonymous_body in
1045 let before_body =
1046 group_doc (
1047 group_doc ( group_doc preface ^^| parameters )
1048 ^| uses ^| type_declaration
1049 ) in
1050 handle_compound_inline_brace before_body body missing
1051 | AnonymousFunctionUseClause x ->
1052 let u = get_doc x.anonymous_use_keyword in
1053 let l = get_doc x.anonymous_use_left_paren in
1054 let v = get_doc x.anonymous_use_variables in
1055 let r = get_doc x.anonymous_use_right_paren in
1056 u ^| l ^^^ v ^^^ r
1057 | PrefixUnaryExpression
1058 { prefix_unary_operator; prefix_unary_operand } ->
1059 if is_separable_prefix prefix_unary_operator then
1060 get_doc prefix_unary_operator ^| get_doc prefix_unary_operand
1061 else
1062 get_doc prefix_unary_operator ^^^ get_doc prefix_unary_operand
1063 | PostfixUnaryExpression
1064 { postfix_unary_operand; postfix_unary_operator } ->
1065 get_doc postfix_unary_operand ^^^ get_doc postfix_unary_operator
1066 | BinaryExpression x ->
1067 let left = get_doc x.binary_left_operand in
1068 let op = get_doc x.binary_operator in
1069 let right = get_doc x.binary_right_operand in
1070 group_doc (left ^| op ^| right)
1071 | InstanceofExpression x ->
1072 let left = get_doc x.instanceof_left_operand in
1073 let op = get_doc x.instanceof_operator in
1074 let right = get_doc x.instanceof_right_operand in
1075 group_doc (left ^| op ^| right)
1076 | IsExpression x ->
1077 let left = get_doc x.is_left_operand in
1078 let op = get_doc x.is_operator in
1079 let right = get_doc x.is_right_operand in
1080 group_doc (left ^| op ^| right)
1081 | ConditionalExpression x ->
1082 let tst = get_doc x.conditional_test in
1083 let qm = get_doc x.conditional_question in
1084 let con = get_doc x.conditional_consequence in
1085 let col = get_doc x.conditional_colon in
1086 let alt = get_doc x.conditional_alternative in
1087 (* TODO: Could this be improved? *)
1088 group_doc ( tst ^| qm ^| con ^| col ^| alt )
1089 | FunctionCallExpression {
1090 function_call_receiver;
1091 function_call_left_paren;
1092 function_call_argument_list;
1093 function_call_right_paren } ->
1094 let receiver = get_doc function_call_receiver in
1095 let lparen = get_doc function_call_left_paren in
1096 let args = get_doc function_call_argument_list in
1097 let rparen = get_doc function_call_right_paren in
1098 receiver ^^^ lparen ^^^ args ^^^ rparen
1099 | FunctionCallWithTypeArgumentsExpression {
1100 function_call_with_type_arguments_receiver;
1101 function_call_with_type_arguments_type_args;
1102 function_call_with_type_arguments_left_paren;
1103 function_call_with_type_arguments_argument_list;
1104 function_call_with_type_arguments_right_paren } ->
1105 let receiver = get_doc function_call_with_type_arguments_receiver in
1106 let tyargs = get_doc function_call_with_type_arguments_type_args in
1107 let lparen = get_doc function_call_with_type_arguments_left_paren in
1108 let args = get_doc function_call_with_type_arguments_argument_list in
1109 let rparen = get_doc function_call_with_type_arguments_right_paren in
1110 receiver ^^^ tyargs ^^^ lparen ^^^ args ^^^ rparen
1111 | EvalExpression {
1112 eval_keyword;
1113 eval_left_paren;
1114 eval_argument;
1115 eval_right_paren } ->
1116 let keyword = get_doc eval_keyword in
1117 let lparen = get_doc eval_left_paren in
1118 let arg = get_doc eval_argument in
1119 let rparen = get_doc eval_right_paren in
1120 keyword ^^^ lparen ^^^ arg ^^^ rparen
1121 | EmptyExpression {
1122 empty_keyword;
1123 empty_left_paren;
1124 empty_argument;
1125 empty_right_paren } ->
1126 let keyword = get_doc empty_keyword in
1127 let lparen = get_doc empty_left_paren in
1128 let arg = get_doc empty_argument in
1129 let rparen = get_doc empty_right_paren in
1130 keyword ^^^ lparen ^^^ arg ^^^ rparen
1131 | IssetExpression {
1132 isset_keyword;
1133 isset_left_paren;
1134 isset_argument_list;
1135 isset_right_paren } ->
1136 let keyword = get_doc isset_keyword in
1137 let lparen = get_doc isset_left_paren in
1138 let args = get_doc isset_argument_list in
1139 let rparen = get_doc isset_right_paren in
1140 keyword ^^^ lparen ^^^ args ^^^ rparen
1141 | HaltCompilerExpression {
1142 halt_compiler_keyword;
1143 halt_compiler_left_paren;
1144 halt_compiler_argument_list;
1145 halt_compiler_right_paren } ->
1146 let keyword = get_doc halt_compiler_keyword in
1147 let lparen = get_doc halt_compiler_left_paren in
1148 let args = get_doc halt_compiler_argument_list in
1149 let rparen = get_doc halt_compiler_right_paren in
1150 keyword ^^^ lparen ^^^ args ^^^ rparen
1151 | DefineExpression {
1152 define_keyword;
1153 define_left_paren;
1154 define_argument_list;
1155 define_right_paren } ->
1156 let keyword = get_doc define_keyword in
1157 let lparen = get_doc define_left_paren in
1158 let args = get_doc define_argument_list in
1159 let rparen = get_doc define_right_paren in
1160 keyword ^^^ lparen ^^^ args ^^^ rparen
1161 | ParenthesizedExpression {
1162 parenthesized_expression_left_paren;
1163 parenthesized_expression_expression;
1164 parenthesized_expression_right_paren } ->
1165 let left = get_doc parenthesized_expression_left_paren in
1166 let expr = get_doc parenthesized_expression_expression in
1167 let right = get_doc parenthesized_expression_right_paren in
1168 indent_block_no_space left expr right indt
1169 | BracedExpression {
1170 braced_expression_left_brace;
1171 braced_expression_expression;
1172 braced_expression_right_brace } ->
1173 let left = get_doc braced_expression_left_brace in
1174 let expr = get_doc braced_expression_expression in
1175 let right = get_doc braced_expression_right_brace in
1176 indent_block_no_space left expr right indt
1177 | EmbeddedBracedExpression {
1178 embedded_braced_expression_left_brace;
1179 embedded_braced_expression_expression;
1180 embedded_braced_expression_right_brace } ->
1181 let left = get_doc embedded_braced_expression_left_brace in
1182 let expr = get_doc embedded_braced_expression_expression in
1183 let right = get_doc embedded_braced_expression_right_brace in
1184 indent_block_no_space left expr right indt
1185 | ListExpression
1186 { list_keyword; list_left_paren; list_members; list_right_paren } ->
1187 let keyword = get_doc list_keyword in
1188 let left_paren = get_doc list_left_paren in
1189 let members = get_doc list_members in
1190 let right_paren = get_doc list_right_paren in
1191 let left = group_doc (keyword ^| left_paren) in
1192 indent_block_no_space left members right_paren indt
1193 | CollectionLiteralExpression x ->
1194 let token = get_doc x.collection_literal_name in
1195 let left_brace = get_doc x.collection_literal_left_brace in
1196 let expression_list = get_doc x.collection_literal_initializers in
1197 let right_brace = get_doc x.collection_literal_right_brace in
1198 token ^| left_brace ^| expression_list ^| right_brace
1199 | ObjectCreationExpression
1200 { object_creation_new_keyword;
1201 object_creation_object } ->
1202 let n = get_doc object_creation_new_keyword in
1203 let o = get_doc object_creation_object in
1204 n ^| o
1205 | ConstructorCall
1206 { constructor_call_type;
1207 constructor_call_left_paren;
1208 constructor_call_argument_list;
1209 constructor_call_right_paren } ->
1210 let c = get_doc constructor_call_type in
1211 let l = get_doc constructor_call_left_paren in
1212 let a = get_doc constructor_call_argument_list in
1213 let r = get_doc constructor_call_right_paren in
1214 c ^^^ l ^^^ a ^^^ r
1215 | AnonymousClass
1216 { anonymous_class_class_keyword;
1217 anonymous_class_left_paren;
1218 anonymous_class_argument_list;
1219 anonymous_class_right_paren;
1220 anonymous_class_extends_keyword;
1221 anonymous_class_extends_list;
1222 anonymous_class_implements_keyword;
1223 anonymous_class_implements_list;
1224 anonymous_class_body } ->
1225 let c = get_doc anonymous_class_class_keyword in
1226 let l = get_doc anonymous_class_left_paren in
1227 let a = get_doc anonymous_class_argument_list in
1228 let r = get_doc anonymous_class_right_paren in
1229 let extends =
1230 let extends_token = get_doc anonymous_class_extends_keyword in
1231 let extends_list = get_doc anonymous_class_extends_list in
1232 group_doc (indent_doc extends_token extends_list indt)
1234 let implements =
1235 let implements_token = get_doc anonymous_class_implements_keyword in
1236 let implements_list = get_doc anonymous_class_implements_list in
1237 group_doc (indent_doc implements_token implements_list indt)
1239 let body = get_doc anonymous_class_body in
1240 group_doc (
1241 c ^^^ l ^^^ a ^^^ r ^|
1242 group_doc (
1243 extends ^|
1244 implements
1245 ) ^|
1246 body
1248 | FieldInitializer
1249 { field_initializer_name; field_initializer_arrow;
1250 field_initializer_value }->
1251 let n = get_doc field_initializer_name in
1252 let a = get_doc field_initializer_arrow in
1253 let v = get_doc field_initializer_value in
1254 n ^| a ^| v
1255 | ShapeExpression
1256 { shape_expression_keyword; shape_expression_left_paren;
1257 shape_expression_fields; shape_expression_right_paren } ->
1258 let sh = get_doc shape_expression_keyword in
1259 let lp = get_doc shape_expression_left_paren in
1260 let fs = get_doc shape_expression_fields in
1261 let rp = get_doc shape_expression_right_paren in
1262 sh ^| lp ^^^ fs ^^^ rp
1263 | TupleExpression
1264 { tuple_expression_keyword; tuple_expression_left_paren;
1265 tuple_expression_items; tuple_expression_right_paren } ->
1266 let tu = get_doc tuple_expression_keyword in
1267 let lp = get_doc tuple_expression_left_paren in
1268 let xs = get_doc tuple_expression_items in
1269 let rp = get_doc tuple_expression_right_paren in
1270 tu ^| lp ^^^ xs ^^^ rp
1271 | ArrayCreationExpression x ->
1272 let left_bracket = get_doc x.array_creation_left_bracket in
1273 let right_bracket = get_doc x.array_creation_right_bracket in
1274 let members = get_doc x.array_creation_members in
1275 indent_block_no_space left_bracket members right_bracket indt
1276 | ArrayIntrinsicExpression {
1277 array_intrinsic_keyword;
1278 array_intrinsic_left_paren;
1279 array_intrinsic_members;
1280 array_intrinsic_right_paren } ->
1281 let keyword = get_doc array_intrinsic_keyword in
1282 let left = get_doc array_intrinsic_left_paren in
1283 let members = get_doc array_intrinsic_members in
1284 let right = get_doc array_intrinsic_right_paren in
1285 let left_part = group_doc (keyword ^^| left) in
1286 indent_block_no_space left_part members right indt
1287 | DarrayIntrinsicExpression {
1288 darray_intrinsic_keyword;
1289 darray_intrinsic_left_bracket;
1290 darray_intrinsic_members;
1291 darray_intrinsic_right_bracket } ->
1292 let keyword = get_doc darray_intrinsic_keyword in
1293 let left = get_doc darray_intrinsic_left_bracket in
1294 let members = get_doc darray_intrinsic_members in
1295 let right = get_doc darray_intrinsic_right_bracket in
1296 let left_part = group_doc (keyword ^^| left) in
1297 indent_block_no_space left_part members right indt
1298 | DictionaryIntrinsicExpression {
1299 dictionary_intrinsic_keyword;
1300 dictionary_intrinsic_left_bracket;
1301 dictionary_intrinsic_members;
1302 dictionary_intrinsic_right_bracket } ->
1303 let keyword = get_doc dictionary_intrinsic_keyword in
1304 let left = get_doc dictionary_intrinsic_left_bracket in
1305 let members = get_doc dictionary_intrinsic_members in
1306 let right = get_doc dictionary_intrinsic_right_bracket in
1307 let left_part = group_doc (keyword ^^| left) in
1308 indent_block_no_space left_part members right indt
1309 | KeysetIntrinsicExpression {
1310 keyset_intrinsic_keyword;
1311 keyset_intrinsic_left_bracket;
1312 keyset_intrinsic_members;
1313 keyset_intrinsic_right_bracket } ->
1314 let keyword = get_doc keyset_intrinsic_keyword in
1315 let left = get_doc keyset_intrinsic_left_bracket in
1316 let members = get_doc keyset_intrinsic_members in
1317 let right = get_doc keyset_intrinsic_right_bracket in
1318 let left_part = group_doc (keyword ^^| left) in
1319 indent_block_no_space left_part members right indt
1320 | VarrayIntrinsicExpression {
1321 varray_intrinsic_keyword;
1322 varray_intrinsic_left_bracket;
1323 varray_intrinsic_members;
1324 varray_intrinsic_right_bracket } ->
1325 let keyword = get_doc varray_intrinsic_keyword in
1326 let left = get_doc varray_intrinsic_left_bracket in
1327 let members = get_doc varray_intrinsic_members in
1328 let right = get_doc varray_intrinsic_right_bracket in
1329 let left_part = group_doc (keyword ^^| left) in
1330 indent_block_no_space left_part members right indt
1331 | VectorIntrinsicExpression {
1332 vector_intrinsic_keyword;
1333 vector_intrinsic_left_bracket;
1334 vector_intrinsic_members;
1335 vector_intrinsic_right_bracket } ->
1336 let keyword = get_doc vector_intrinsic_keyword in
1337 let left = get_doc vector_intrinsic_left_bracket in
1338 let members = get_doc vector_intrinsic_members in
1339 let right = get_doc vector_intrinsic_right_bracket in
1340 let left_part = group_doc (keyword ^^| left) in
1341 indent_block_no_space left_part members right indt
1342 | ElementInitializer x ->
1343 let k = get_doc x.element_key in
1344 let a = get_doc x.element_arrow in
1345 let v = get_doc x.element_value in
1346 k ^| a ^| v
1347 | SubscriptExpression x ->
1348 let receiver = get_doc x.subscript_receiver in
1349 let left = get_doc x.subscript_left_bracket in
1350 let index = get_doc x.subscript_index in
1351 let right = get_doc x.subscript_right_bracket in
1352 receiver ^^^ left ^^^ index ^^^ right
1353 | EmbeddedSubscriptExpression x ->
1354 let receiver = get_doc x.embedded_subscript_receiver in
1355 let left = get_doc x.embedded_subscript_left_bracket in
1356 let index = get_doc x.embedded_subscript_index in
1357 let right = get_doc x.embedded_subscript_right_bracket in
1358 receiver ^^^ left ^^^ index ^^^ right
1359 | AwaitableCreationExpression x ->
1360 let async = get_doc x.awaitable_async in
1361 let coroutine = get_doc x.awaitable_coroutine in
1362 let stmt = x.awaitable_compound_statement in
1363 handle_compound_brace_prefix_indent (async ^| coroutine) stmt indt
1364 | XHPExpression x ->
1365 let left = get_doc x.xhp_open in
1366 let expr = get_doc x.xhp_body in
1367 let right = get_doc x.xhp_close in
1368 left ^^^ expr ^^^ right
1369 | XHPOpen {
1370 xhp_open_left_angle;
1371 xhp_open_name;
1372 xhp_open_attributes;
1373 xhp_open_right_angle } ->
1374 let left = get_doc xhp_open_left_angle in
1375 let name = get_doc xhp_open_name in
1376 let attrs = get_doc xhp_open_attributes in
1377 let right = get_doc xhp_open_right_angle in
1378 group_doc (group_doc (indent_doc (left ^^^ name) attrs indt) ^| right)
1379 | XHPSimpleAttribute {
1380 xhp_simple_attribute_name;
1381 xhp_simple_attribute_equal;
1382 xhp_simple_attribute_expression }->
1383 let name = get_doc xhp_simple_attribute_name in
1384 let equals = get_doc xhp_simple_attribute_equal in
1385 let expr = get_doc xhp_simple_attribute_expression in
1386 group_doc (group_doc (name ^^| equals) ^^| expr)
1387 | XHPSpreadAttribute x ->
1388 let left = get_doc x.xhp_spread_attribute_left_brace in
1389 let spread = get_doc x.xhp_spread_attribute_spread_operator in
1390 let expr = get_doc x.xhp_spread_attribute_expression in
1391 let right = get_doc x.xhp_spread_attribute_right_brace in
1392 left ^^^ spread ^^^ expr ^^^ right
1393 | XHPClose x ->
1394 let left = get_doc x.xhp_close_left_angle in
1395 let name = get_doc x.xhp_close_name in
1396 let right = get_doc x.xhp_close_right_angle in
1397 left ^^^ name ^^^ right
1398 | TypeConstant x ->
1399 let left = get_doc x.type_constant_left_type in
1400 let right = get_doc x.type_constant_right_type in
1401 let separator = get_doc x.type_constant_separator in
1402 left ^^^ separator ^^^ right
1403 | SimpleTypeSpecifier x -> get_doc x.simple_type_specifier
1404 | TypeConstraint { constraint_keyword; constraint_type } ->
1405 let k = get_doc constraint_keyword in
1406 let t = get_doc constraint_type in
1407 k ^| t
1408 | TypeParameter x ->
1409 let variance = get_doc x.type_variance in
1410 let name = get_doc x.type_name in
1411 let constraints = get_doc x.type_constraints in
1412 variance ^^^ name ^| constraints
1413 | NullableTypeSpecifier x ->
1414 let qm = get_doc x.nullable_question in
1415 let ty = get_doc x.nullable_type in
1416 qm ^^^ ty
1417 | SoftTypeSpecifier x ->
1418 let a = get_doc x.soft_at in
1419 let t = get_doc x.soft_type in
1420 a ^^^ t
1421 | GenericTypeSpecifier
1422 { generic_class_type;
1423 generic_argument_list } ->
1424 let name = get_doc generic_class_type in
1425 let argument = get_doc generic_argument_list in
1426 group_doc (indent_doc_no_space name argument indt)
1427 | VarrayTypeSpecifier {
1428 varray_keyword;
1429 varray_left_angle;
1430 varray_type;
1431 varray_trailing_comma;
1432 varray_right_angle
1433 } ->
1434 let ar = get_doc varray_keyword in
1435 let la = get_doc varray_left_angle in
1436 let ty = get_doc varray_type in
1437 let oc = get_doc varray_trailing_comma in
1438 let ra = get_doc varray_right_angle in
1439 ar ^^^ la ^^^ ty ^^^ oc ^^^ ra
1440 | VectorArrayTypeSpecifier {
1441 vector_array_keyword;
1442 vector_array_left_angle;
1443 vector_array_type;
1444 vector_array_right_angle
1445 } ->
1446 let ar = get_doc vector_array_keyword in
1447 let la = get_doc vector_array_left_angle in
1448 let ty = get_doc vector_array_type in
1449 let ra = get_doc vector_array_right_angle in
1450 ar ^^^ la ^^^ ty ^^^ ra
1451 | VectorTypeSpecifier {
1452 vector_type_keyword;
1453 vector_type_left_angle;
1454 vector_type_type;
1455 vector_type_trailing_comma;
1456 vector_type_right_angle;
1457 } ->
1458 let ar = get_doc vector_type_keyword in
1459 let la = get_doc vector_type_left_angle in
1460 let ty = get_doc vector_type_type in
1461 let tr = get_doc vector_type_trailing_comma in
1462 let ra = get_doc vector_type_right_angle in
1463 ar ^^^ la ^^^ ty ^^^ tr ^^^ ra
1464 | KeysetTypeSpecifier {
1465 keyset_type_keyword;
1466 keyset_type_left_angle;
1467 keyset_type_type;
1468 keyset_type_trailing_comma;
1469 keyset_type_right_angle
1470 } ->
1471 let ar = get_doc keyset_type_keyword in
1472 let la = get_doc keyset_type_left_angle in
1473 let ty = get_doc keyset_type_type in
1474 let tr = get_doc keyset_type_trailing_comma in
1475 let ra = get_doc keyset_type_right_angle in
1476 ar ^^^ la ^^^ ty ^^^ tr ^^^ ra
1477 | TupleTypeExplicitSpecifier {
1478 tuple_type_keyword;
1479 tuple_type_left_angle;
1480 tuple_type_types;
1481 tuple_type_right_angle
1482 } ->
1483 let tu = get_doc tuple_type_keyword in
1484 let la = get_doc tuple_type_left_angle in
1485 let ts = get_doc tuple_type_types in
1486 let ra = get_doc tuple_type_right_angle in
1487 tu ^^^ la ^^^ ts ^^^ ra
1488 | DictionaryTypeSpecifier {
1489 dictionary_type_keyword;
1490 dictionary_type_left_angle;
1491 dictionary_type_members;
1492 dictionary_type_right_angle
1493 } ->
1494 let ar = get_doc dictionary_type_keyword in
1495 let la = get_doc dictionary_type_left_angle in
1496 let ms = get_doc dictionary_type_members in
1497 let ra = get_doc dictionary_type_right_angle in
1498 ar ^^^ la ^^^ ms ^^^ ra
1499 | DarrayTypeSpecifier {
1500 darray_keyword;
1501 darray_left_angle;
1502 darray_key;
1503 darray_comma;
1504 darray_value;
1505 darray_trailing_comma;
1506 darray_right_angle
1507 } ->
1508 let ar = get_doc darray_keyword in
1509 let la = get_doc darray_left_angle in
1510 let kt = get_doc darray_key in
1511 let co = get_doc darray_comma in
1512 let vt = get_doc darray_value in
1513 let oc = get_doc darray_trailing_comma in
1514 let ra = get_doc darray_right_angle in
1515 ar ^^^ la ^^^ kt ^^^ co ^| vt ^^^ oc ^^^ ra
1516 | MapArrayTypeSpecifier {
1517 map_array_keyword;
1518 map_array_left_angle;
1519 map_array_key;
1520 map_array_comma;
1521 map_array_value;
1522 map_array_right_angle
1523 } ->
1524 let ar = get_doc map_array_keyword in
1525 let la = get_doc map_array_left_angle in
1526 let kt = get_doc map_array_key in
1527 let co = get_doc map_array_comma in
1528 let vt = get_doc map_array_value in
1529 let ra = get_doc map_array_right_angle in
1530 ar ^^^ la ^^^ kt ^^^ co ^| vt ^^^ ra
1531 | ClosureTypeSpecifier
1532 { closure_outer_left_paren;
1533 closure_coroutine;
1534 closure_function_keyword;
1535 closure_inner_left_paren;
1536 closure_parameter_list;
1537 closure_inner_right_paren;
1538 closure_colon;
1539 closure_return_type;
1540 closure_outer_right_paren } ->
1541 let olp = get_doc closure_outer_left_paren in
1542 let cor = get_doc closure_coroutine in
1543 let fnc = get_doc closure_function_keyword in
1544 let ilp = get_doc closure_inner_left_paren in
1545 let pts = get_doc closure_parameter_list in
1546 let irp = get_doc closure_inner_right_paren in
1547 let col = get_doc closure_colon in
1548 let ret = get_doc closure_return_type in
1549 let orp = get_doc closure_outer_right_paren in
1550 olp ^^^ cor ^| fnc ^^| ilp ^^^ pts ^^^ irp ^^^ col ^^^ ret ^^^ orp
1551 | ClosureParameterTypeSpecifier {
1552 closure_parameter_call_convention;
1553 closure_parameter_type;
1554 } ->
1555 let cc = get_doc closure_parameter_call_convention in
1556 let ty = get_doc closure_parameter_type in
1557 cc ^| ty
1558 | ClassnameTypeSpecifier x ->
1559 let cn = get_doc x.classname_keyword in
1560 let la = get_doc x.classname_left_angle in
1561 let ty = get_doc x.classname_type in
1562 let ra = get_doc x.classname_right_angle in
1563 cn ^^^ la ^^^ ty ^^^ ra
1564 | FieldSpecifier x ->
1565 let q = get_doc x.field_question in
1566 let n = get_doc x.field_name in
1567 let a = get_doc x.field_arrow in
1568 let t = get_doc x.field_type in
1569 q ^| n ^| a ^| t
1570 | ShapeTypeSpecifier
1571 { shape_type_keyword; shape_type_left_paren;
1572 shape_type_fields; shape_type_ellipsis; shape_type_right_paren } ->
1573 let sh = get_doc shape_type_keyword in
1574 let lp = get_doc shape_type_left_paren in
1575 let fs = get_doc shape_type_fields in
1576 let ellipsis = get_doc shape_type_ellipsis in
1577 let rp = get_doc shape_type_right_paren in
1578 sh ^| lp ^^^ fs ^| ellipsis ^^^ rp
1579 | TypeArguments {
1580 type_arguments_left_angle;
1581 type_arguments_types;
1582 type_arguments_right_angle } ->
1583 let left = get_doc type_arguments_left_angle in
1584 let args = get_doc type_arguments_types in
1585 let right = get_doc type_arguments_right_angle in
1586 indent_block_no_space left args right indt
1587 | TypeParameters {
1588 type_parameters_left_angle;
1589 type_parameters_parameters;
1590 type_parameters_right_angle } ->
1591 let left = get_doc type_parameters_left_angle in
1592 let params = get_doc type_parameters_parameters in
1593 let right = get_doc type_parameters_right_angle in
1594 indent_block_no_space left params right indt
1595 | TupleTypeSpecifier x ->
1596 let left = get_doc x.tuple_left_paren in
1597 let types = get_doc x.tuple_types in
1598 let right = get_doc x.tuple_right_paren in
1599 indent_block_no_space left types right indt
1600 (* this ideally should never be called *)
1601 | CaseLabel {
1602 case_keyword;
1603 case_expression;
1604 case_colon } ->
1605 let keyword = get_doc case_keyword in
1606 let expr = get_doc case_expression in
1607 let colon = get_doc case_colon in
1608 keyword ^^^ space ^^^ expr ^^^ colon
1609 | DefaultLabel {
1610 default_keyword;
1611 default_colon } ->
1612 let keyword = get_doc default_keyword in
1613 let colon = get_doc default_colon in
1614 keyword ^^^ colon
1615 | ReturnStatement x ->
1616 let keyword = get_doc x.return_keyword in
1617 let expr = get_doc x.return_expression in
1618 let semicolon = get_doc x.return_semicolon in
1619 let back_part = expr ^^^ semicolon in
1620 group_doc (indent_doc keyword back_part indt)
1621 | GotoLabel {
1622 goto_label_name;
1623 goto_label_colon; } ->
1624 let goto_label_name = get_doc goto_label_name in
1625 let goto_label_colon = get_doc goto_label_colon in
1626 goto_label_name ^^^ goto_label_colon
1627 | GotoStatement {
1628 goto_statement_keyword;
1629 goto_statement_label_name;
1630 goto_statement_semicolon; } ->
1631 let keyword = get_doc goto_statement_keyword in
1632 let label_name = get_doc goto_statement_label_name in
1633 let semicolon = get_doc goto_statement_semicolon in
1634 keyword ^| label_name ^^^ semicolon
1635 | ThrowStatement x ->
1636 let keyword = get_doc x.throw_keyword in
1637 let expr = get_doc x.throw_expression in
1638 let semicolon = get_doc x.throw_semicolon in
1639 let back_part = expr ^^^ semicolon in
1640 group_doc (indent_doc keyword back_part indt)
1641 | BreakStatement x ->
1642 let b = get_doc x.break_keyword in
1643 let l = get_doc x.break_level in
1644 let s = get_doc x.break_semicolon in
1645 if is_missing x.break_level then group_doc (b ^^^ l ^^^ s)
1646 else group_doc (b ^| l ^^^ s)
1647 | ContinueStatement x ->
1648 let c = get_doc x.continue_keyword in
1649 let l = get_doc x.continue_level in
1650 let s = get_doc x.continue_semicolon in
1651 if is_missing x.continue_level then group_doc (c ^^^ l ^^^ s)
1652 else group_doc (c ^| l ^^^ s)
1653 | FunctionStaticStatement {
1654 static_static_keyword;
1655 static_declarations;
1656 static_semicolon } ->
1657 let st = get_doc static_static_keyword in
1658 let ds = get_doc static_declarations in
1659 let se = get_doc static_semicolon in
1660 st ^| ds ^^^ se
1661 | StaticDeclarator
1662 { static_name; static_initializer } ->
1663 let n = get_doc static_name in
1664 let i = get_doc static_initializer in
1665 group_doc (n ^| i)
1666 | EchoStatement x ->
1667 let echo = get_doc x.echo_keyword in
1668 let expr_list = get_doc x.echo_expressions in
1669 let semicolon = get_doc x.echo_semicolon in
1670 echo ^| expr_list ^^^ semicolon
1671 | GlobalStatement {
1672 global_keyword;
1673 global_variables;
1674 global_semicolon } ->
1675 let g = get_doc global_keyword in
1676 let v = get_doc global_variables in
1677 let s = get_doc global_semicolon in
1678 g ^| v ^^^ s
1679 | SimpleInitializer
1680 { simple_initializer_equal; simple_initializer_value } ->
1681 let e = get_doc simple_initializer_equal in
1682 let v = get_doc simple_initializer_value in
1683 group_doc (e ^| v)
1685 (* sep is the compulsory separator separating the children in the list *)
1686 and get_from_children_no_space children =
1687 let fold_fun acc el = acc ^^^ get_doc el in
1688 group_doc (List.fold_left fold_fun (make_simple nil) children)
1689 and get_from_children_with_sep sep children =
1690 let fold_fun acc el = (acc ^^^ sep) ^| get_doc el in
1691 group_doc (List.fold_left fold_fun (make_simple nil) children)
1692 and get_from_children node = get_from_children_with_sep (make_simple nil) node
1693 (* if it is a compound statement, the curly braces do not need indent *)
1694 and peek_and_decide_indent x default =
1695 match syntax x with
1696 | CompoundStatement _ -> 0
1697 | _ -> default
1698 (* puts [prefix] on the same line as a compound brace. If the statement is not
1699 * compound, put an optional newline and group the result *)
1700 and handle_compound_inline_brace prefix statement postfix =
1701 match syntax statement with
1702 | CompoundStatement compound_stmt ->
1703 let left = get_doc compound_stmt.compound_left_brace in
1704 let right = get_doc compound_stmt.compound_right_brace in
1705 let statement = get_doc compound_stmt.compound_statements in
1706 let prefix = group_doc (prefix ^| left) in
1707 let postfix = group_doc (right ^| postfix) in
1708 indent_block prefix statement postfix indt
1709 | _ -> group_doc (prefix ^| get_doc statement ^| postfix)
1710 (* keep open brace of compound statement on the same line as the prefix.
1711 * If statement is not a compound statement, then indent it with [indt] *)
1712 and handle_compound_brace_prefix_indent prefix statement indt =
1713 if is_compound_statement statement then
1714 handle_compound_inline_brace prefix statement missing
1715 else
1716 group_doc (indent_doc prefix (get_doc statement) indt)
1718 let pretty_print node =
1719 let empty_string = make_simple (text "") in
1720 let to_print = node |> get_doc |> add_break in
1721 let to_print = to_print ^| empty_string in
1722 let to_print = combine to_print in
1723 pretty 0 to_print