Alternate if syntax support
[hiphop-php.git] / hphp / hack / src / parser / full_fidelity_pretty_printer.ml
blobb6a880043a635fc55d6d3e8f2c4b0b05446aaeda
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 space = make_simple (text " ")
199 let rec get_doc node =
200 match syntax node with
201 | Missing -> missing
202 | MarkupSection x ->
203 group_doc (get_doc x.markup_prefix ^|
204 get_doc x.markup_text ^|
205 get_doc x.markup_suffix ^|
206 get_doc x.markup_expression)
207 | MarkupSuffix x ->
208 group_doc (get_doc x.markup_suffix_less_than_question ^^^
209 get_doc x.markup_suffix_name)
211 | Token x -> from_token x
213 | SyntaxList x -> get_from_children x
214 | ErrorSyntax { error_error } -> get_doc error_error
215 | LiteralExpression x ->
216 begin
217 match syntax x.literal_expression with
218 | SyntaxList l -> get_from_children_no_space l
219 | _ -> get_doc x.literal_expression
221 | VariableExpression x -> get_doc x.variable_expression
222 | QualifiedName n -> get_doc n.qualified_name_parts
223 | PipeVariableExpression x -> get_doc x.pipe_variable_expression
224 | ListItem x -> (get_doc x.list_item) ^^^ (get_doc x.list_separator)
225 | EndOfFile { end_of_file_token } -> get_doc end_of_file_token
226 | Script x -> get_doc x.script_declarations
227 | ClassishDeclaration
228 { classish_attribute; classish_modifiers; classish_keyword;
229 classish_name; classish_type_parameters; classish_extends_keyword;
230 classish_extends_list; classish_implements_keyword;
231 classish_implements_list; classish_body } ->
232 let attr = add_break (get_doc classish_attribute) in
233 let preface = group_doc (
234 get_doc classish_modifiers ^|
235 get_doc classish_keyword
236 ) in
238 let name_and_generics =
239 let name = get_doc classish_name in
240 let type_params = get_doc classish_type_parameters in
241 group_doc (indent_doc name type_params indt)
244 let extends =
245 let extends_token = get_doc classish_extends_keyword in
246 let extends_list = get_doc classish_extends_list in
247 group_doc (indent_doc extends_token extends_list indt)
250 let implements =
251 let implements_token = get_doc classish_implements_keyword in
252 let implements_list = get_doc classish_implements_list in
253 group_doc (indent_doc implements_token implements_list indt)
256 let body = get_doc classish_body in
258 (* TODO: Make this better *)
259 attr ^^^
260 group_doc (
261 group_doc (
262 preface ^|
263 name_and_generics
264 ) ^|
265 group_doc (
266 extends ^|
267 implements
268 ) ^|
269 body
271 | ClassishBody x ->
272 let left = get_doc x.classish_body_left_brace in
273 let right = get_doc x.classish_body_right_brace in
274 let body = get_doc x.classish_body_elements in
275 indent_block_no_space left body right indt
276 | XHPRequired { xhp_required_at; xhp_required_keyword } ->
277 let a = get_doc xhp_required_at in
278 let r = get_doc xhp_required_keyword in
279 a ^^^ r
280 | XHPChildrenDeclaration {
281 xhp_children_keyword;
282 xhp_children_expression;
283 xhp_children_semicolon } ->
284 let c = get_doc xhp_children_keyword in
285 let e = get_doc xhp_children_expression in
286 let s = get_doc xhp_children_semicolon in
287 c ^| e ^^^ s
288 | XHPChildrenParenthesizedList {
289 xhp_children_list_left_paren;
290 xhp_children_list_xhp_children;
291 xhp_children_list_right_paren } ->
292 let l = get_doc xhp_children_list_left_paren in
293 let c = get_doc xhp_children_list_xhp_children in
294 let r = get_doc xhp_children_list_right_paren in
295 l ^| c ^| r
296 | XHPCategoryDeclaration {
297 xhp_category_keyword;
298 xhp_category_categories;
299 xhp_category_semicolon } ->
300 let c = get_doc xhp_category_keyword in
301 let l = get_doc xhp_category_categories in
302 let s = get_doc xhp_category_semicolon in
303 c ^| l ^^^ s
304 | XHPEnumType {
305 xhp_enum_optional;
306 xhp_enum_keyword;
307 xhp_enum_left_brace;
308 xhp_enum_values;
309 xhp_enum_right_brace;
310 } ->
311 let o = get_doc xhp_enum_optional in
312 let e = get_doc xhp_enum_keyword in
313 let l = get_doc xhp_enum_left_brace in
314 let v = get_doc xhp_enum_values in
315 let r = get_doc xhp_enum_right_brace in
316 group_doc (o ^| e ^| l ^| v ^| r)
317 | XHPClassAttributeDeclaration {
318 xhp_attribute_keyword;
319 xhp_attribute_attributes;
320 xhp_attribute_semicolon } ->
321 let attr = get_doc xhp_attribute_keyword in
322 let attrs = get_doc xhp_attribute_attributes in
323 let semi = get_doc xhp_attribute_semicolon in
324 group_doc (attr ^| attrs ^^^ semi)
325 | XHPClassAttribute
326 { xhp_attribute_decl_type; xhp_attribute_decl_name;
327 xhp_attribute_decl_initializer; xhp_attribute_decl_required } ->
328 let t = get_doc xhp_attribute_decl_type in
329 let n = get_doc xhp_attribute_decl_name in
330 let i = get_doc xhp_attribute_decl_initializer in
331 let r = get_doc xhp_attribute_decl_required in
332 group_doc (t ^| n ^| i ^| r)
333 | XHPSimpleClassAttribute { xhp_simple_class_attribute_type } ->
334 get_doc xhp_simple_class_attribute_type
335 | TraitUseAliasItem {
336 trait_use_alias_item_aliasing_name;
337 trait_use_alias_item_keyword;
338 trait_use_alias_item_modifiers;
339 trait_use_alias_item_aliased_name;
340 } ->
341 let n = get_doc trait_use_alias_item_aliasing_name in
342 let k = get_doc trait_use_alias_item_keyword in
343 let v = get_doc trait_use_alias_item_modifiers in
344 let ns = get_doc trait_use_alias_item_aliased_name in
345 n ^| k ^| v ^| ns
346 | TraitUsePrecedenceItem {
347 trait_use_precedence_item_name;
348 trait_use_precedence_item_keyword;
349 trait_use_precedence_item_removed_names;
350 } ->
351 let n = get_doc trait_use_precedence_item_name in
352 let k = get_doc trait_use_precedence_item_keyword in
353 let ns = get_doc trait_use_precedence_item_removed_names in
354 n ^| k ^| ns
355 | TraitUseConflictResolution {
356 trait_use_conflict_resolution_keyword;
357 trait_use_conflict_resolution_names;
358 trait_use_conflict_resolution_left_brace;
359 trait_use_conflict_resolution_clauses;
360 trait_use_conflict_resolution_right_brace;
361 } ->
362 let use = get_doc trait_use_conflict_resolution_keyword in
363 let name_list = get_doc trait_use_conflict_resolution_names in
364 let lbrace = get_doc trait_use_conflict_resolution_left_brace in
365 let clauses = get_doc trait_use_conflict_resolution_clauses in
366 let rbrace = get_doc trait_use_conflict_resolution_right_brace in
367 use ^| name_list ^^^ lbrace ^| clauses ^^^ rbrace
368 | TraitUse {
369 trait_use_keyword;
370 trait_use_names;
371 trait_use_semicolon;
372 } ->
373 let use = get_doc trait_use_keyword in
374 let name_list = get_doc trait_use_names in
375 let semi = get_doc trait_use_semicolon in
376 use ^| name_list ^^^ semi
377 | RequireClause x ->
378 let r = get_doc x.require_keyword in
379 let k = get_doc x.require_kind in
380 let n = get_doc x.require_name in
381 let s = get_doc x.require_semicolon in
382 r ^| k ^| n ^^^ s
383 | ConstDeclaration {
384 const_abstract;
385 const_keyword;
386 const_type_specifier;
387 const_declarators;
388 const_semicolon } ->
389 let abstr = get_doc const_abstract in
390 let token = get_doc const_keyword in
391 let ty = get_doc const_type_specifier in
392 let lst = get_doc const_declarators in
393 let semi = get_doc const_semicolon in
394 group_doc (abstr ^| token ^| ty ) ^| lst ^^^ semi
395 | ConstantDeclarator x ->
396 let name = get_doc x.constant_declarator_name in
397 let init = get_doc x.constant_declarator_initializer in
398 group_doc (name ^| init)
399 | TypeConstDeclaration x ->
400 let abstr = get_doc x.type_const_abstract in
401 let const = get_doc x.type_const_keyword in
402 let type_ = get_doc x.type_const_type_keyword in
403 let name = get_doc x.type_const_name in
404 let type_constraint = get_doc x.type_const_type_constraint in
405 let equal = get_doc x.type_const_equal in
406 let type_spec = get_doc x.type_const_type_specifier in
407 let semicolon = get_doc x.type_const_semicolon in
408 group_doc (
409 group_doc (abstr ^| const ^| type_ ^| name) ^|
410 type_constraint ^|
411 equal ^|
412 group_doc (type_spec ^^^ semicolon)
414 | EnumDeclaration {
415 enum_attribute_spec;
416 enum_keyword;
417 enum_name;
418 enum_colon;
419 enum_base;
420 enum_type;
421 enum_left_brace;
422 enum_enumerators;
423 enum_right_brace } ->
424 let attrs = get_doc enum_attribute_spec in
425 let en = get_doc enum_keyword in
426 let na = get_doc enum_name in
427 let co = get_doc enum_colon in
428 let ba = get_doc enum_base in
429 let ty = get_doc enum_type in
430 let lb = get_doc enum_left_brace in
431 let es = get_doc enum_enumerators in
432 let rb = get_doc enum_right_brace in
433 (* TODO: This could be a lot better. Add indentation, etc. *)
434 attrs ^| en ^| na ^| co ^| ba ^| ty ^| lb ^| es ^| rb
435 | Enumerator x ->
436 let n = get_doc x.enumerator_name in
437 let e = get_doc x.enumerator_equal in
438 let v = get_doc x.enumerator_value in
439 let semicolon = get_doc x.enumerator_semicolon in
440 n ^| e ^| v ^^^ semicolon
441 | AliasDeclaration x ->
442 (* TODO: What's the best way to ensure that there's a newline between the
443 attribute and the alias declaration proper? *)
444 let attr = get_doc x.alias_attribute_spec in
445 let a = get_doc x.alias_keyword in
446 let n = get_doc x.alias_name in
447 let generic = get_doc x.alias_generic_parameter in
448 let c = get_doc x.alias_constraint in
449 let e = get_doc x.alias_equal in
450 let t = get_doc x.alias_type in
451 let s = get_doc x.alias_semicolon in
452 attr ^| a ^| n ^| generic ^| c ^| e ^| t ^^^ s
453 | PropertyDeclaration
454 { property_modifiers; property_type;
455 property_declarators; property_semicolon } ->
456 let m = get_doc property_modifiers in
457 let t = get_doc property_type in
458 let d = get_doc property_declarators in
459 let s = get_doc property_semicolon in
460 m ^| t ^| d ^^^ s
461 | PropertyDeclarator { property_name; property_initializer } ->
462 let n = get_doc property_name in
463 let i = get_doc property_initializer in
464 n ^| i
465 | NamespaceDeclaration x ->
466 let t = get_doc x.namespace_keyword in
467 let n = get_doc x.namespace_name in
468 let b = get_doc x.namespace_body in
469 t ^| n ^| b
470 | NamespaceBody x ->
471 let left = get_doc x.namespace_left_brace in
472 let body = get_doc x.namespace_declarations in
473 let right = get_doc x.namespace_right_brace in
474 indent_block_no_space left body right indt |> add_break
475 | NamespaceEmptyBody x ->
476 get_doc x.namespace_semicolon
477 | NamespaceUseDeclaration x ->
478 let u = get_doc x.namespace_use_keyword in
479 let k = get_doc x.namespace_use_kind in
480 let c = get_doc x.namespace_use_clauses in
481 let s = get_doc x.namespace_use_semicolon in
482 u ^| k ^| c ^^^ s
483 | NamespaceUseClause x ->
484 let k = get_doc x.namespace_use_clause_kind in
485 let n = get_doc x.namespace_use_name in
486 let a = get_doc x.namespace_use_as in
487 let l = get_doc x.namespace_use_alias in
488 k ^| n ^| a ^| l
489 | NamespaceGroupUseDeclaration x ->
490 let u = get_doc x.namespace_group_use_keyword in
491 let k = get_doc x.namespace_group_use_kind in
492 let p = get_doc x.namespace_group_use_prefix in
493 let l = get_doc x.namespace_group_use_left_brace in
494 let c = get_doc x.namespace_group_use_clauses in
495 let r = get_doc x.namespace_group_use_right_brace in
496 let s = get_doc x.namespace_group_use_semicolon in
497 u ^| k ^| p ^| l ^| c ^| r ^^^ s
498 | FunctionDeclaration x ->
499 let attr = get_doc x.function_attribute_spec in
500 let header = get_doc x.function_declaration_header in
501 let body = x.function_body in
502 let after_attr = handle_compound_inline_brace header body missing in
503 group_doc (attr ^| after_attr)
504 | FunctionDeclarationHeader
505 { function_modifiers;
506 function_keyword;
507 function_ampersand;
508 function_name;
509 function_type_parameter_list;
510 function_left_paren;
511 function_parameter_list;
512 function_right_paren;
513 function_colon;
514 function_type;
515 function_where_clause }
517 let preface =
518 group_doc (get_doc function_modifiers ^| get_doc function_keyword) in
519 let name_and_generics =
520 let type_params = get_doc function_type_parameter_list in
521 let ampersand = get_doc function_ampersand in
522 let name = get_doc function_name in
523 group_doc (indent_doc (ampersand ^^^ name) type_params indt)
525 let parameters =
526 let left = get_doc function_left_paren in
527 let right = get_doc function_right_paren in
528 let params = get_doc function_parameter_list in
529 indent_block_no_space left params right indt
531 let type_declaration =
532 let fun_colon = get_doc function_colon in
533 let fun_type = get_doc function_type in
534 let where_clause = get_doc function_where_clause in
535 group_doc (fun_colon ^| fun_type ^| where_clause)
537 group_doc (
538 group_doc ( group_doc (preface ^| name_and_generics) ^^| parameters )
539 ^| type_declaration
541 | WhereClause { where_clause_keyword; where_clause_constraints } ->
542 let w = get_doc where_clause_keyword in
543 let c = get_doc where_clause_constraints in
544 w ^| c
545 | WhereConstraint { where_constraint_left_type; where_constraint_operator ;
546 where_constraint_right_type } ->
547 let l = get_doc where_constraint_left_type in
548 let o = get_doc where_constraint_operator in
549 let r = get_doc where_constraint_right_type in
550 l ^| o ^| r
551 | MethodishDeclaration
552 { methodish_attribute; methodish_function_decl_header;
553 methodish_function_body; methodish_semicolon } ->
554 let methodish_attr = get_doc methodish_attribute in
555 let function_header = get_doc methodish_function_decl_header in
556 let body_node = methodish_function_body in
557 let semicolon = get_doc methodish_semicolon in
558 let after_attr =
559 handle_compound_inline_brace function_header body_node missing in
560 let after_attr = after_attr ^^^ semicolon in
561 group_doc (methodish_attr ^| after_attr)
562 | DecoratedExpression x ->
563 let decorator = get_doc x.decorated_expression_decorator in
564 let expression = get_doc x.decorated_expression_expression in
565 group_doc (decorator ^^^ expression)
566 | ParameterDeclaration {
567 parameter_attribute;
568 parameter_visibility;
569 parameter_call_convention;
570 parameter_type;
571 parameter_name;
572 parameter_default_value } ->
573 let attr = get_doc parameter_attribute in
574 let visibility = get_doc parameter_visibility in
575 let callconv = get_doc parameter_call_convention in
576 let parameter_type = get_doc parameter_type in
577 let parameter_name = get_doc parameter_name in
578 let parameter_default = get_doc parameter_default_value in
579 group_doc
580 ( attr ^| visibility ^| callconv ^| parameter_type ^| parameter_name
581 ^| parameter_default )
582 | VariadicParameter {
583 variadic_parameter_call_convention;
584 variadic_parameter_type;
585 variadic_parameter_ellipsis } ->
586 let cc = get_doc variadic_parameter_call_convention in
587 let t = get_doc variadic_parameter_type in
588 let ell = get_doc variadic_parameter_ellipsis in
589 group_doc (cc ^| t ^| ell)
590 | AttributeSpecification {
591 attribute_specification_left_double_angle;
592 attribute_specification_attributes;
593 attribute_specification_right_double_angle } ->
594 let left = get_doc attribute_specification_left_double_angle in
595 let specs = get_doc attribute_specification_attributes in
596 let right = get_doc attribute_specification_right_double_angle in
597 indent_block_no_space left specs right indt
598 | Attribute x ->
599 let name = get_doc x.attribute_name in
600 let left = get_doc x.attribute_left_paren in
601 let right = get_doc x.attribute_right_paren in
602 let values = get_doc x.attribute_values in
603 let left_part = group_doc (name ^^| left) in
604 indent_block_no_space left_part values right indt
605 | InclusionExpression x ->
606 let rq = get_doc x.inclusion_require in
607 let fn = get_doc x.inclusion_filename in
608 rq ^| fn
609 | InclusionDirective x ->
610 let ex = get_doc x.inclusion_expression in
611 let se = get_doc x.inclusion_semicolon in
612 ex ^^^ se
613 | CompoundStatement x ->
614 let left = get_doc x.compound_left_brace in
615 let right = get_doc x.compound_right_brace in
616 let body = get_doc x.compound_statements in
617 indent_block_no_space left body right indt |> add_break
618 | AlternateLoopStatement x ->
619 let left = get_doc x.alternate_loop_opening_colon in
620 let close_keyword = get_doc x.alternate_loop_closing_keyword in
621 let close_semi = get_doc x.alternate_loop_closing_semicolon in
622 let right = group_doc (close_keyword ^^| close_semi) in
623 let body = get_doc x.alternate_loop_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 | AlternateIfStatement
736 { alternate_if_keyword; alternate_if_colon; alternate_if_left_paren;
737 alternate_if_condition; alternate_if_right_paren; alternate_if_statement;
738 alternate_if_elseif_clauses; alternate_if_else_clause;
739 alternate_if_endif_keyword; alternate_if_semicolon }->
740 let keyword = get_doc alternate_if_keyword in
741 let left = get_doc alternate_if_left_paren in
742 let condition = get_doc alternate_if_condition in
743 let right = get_doc alternate_if_right_paren in
744 let colon = get_doc alternate_if_colon in
745 let if_stmt = alternate_if_statement in
746 let elseif_clause = get_doc alternate_if_elseif_clauses in
747 let else_clause = get_doc alternate_if_else_clause in
748 let end_kw = get_doc alternate_if_endif_keyword in
749 let semicolon = get_doc alternate_if_semicolon in
750 let left_part = group_doc (keyword ^^| left) in
751 let right_part = group_doc (right ^^^ colon) in
752 let end_block = group_doc (end_kw ^^^ semicolon) in
753 let start_block = indent_block_no_space left_part condition right_part indt in
754 let if_statement =
755 handle_compound_brace_prefix_indent start_block if_stmt indt in
756 let if_statement = add_break if_statement in
757 group_doc (if_statement ^| elseif_clause ^| else_clause ^| end_block)
758 | AlternateElseifClause
759 { alternate_elseif_keyword; alternate_elseif_left_paren; alternate_elseif_condition;
760 alternate_elseif_right_paren; alternate_elseif_colon; alternate_elseif_statement } ->
761 let keyword = get_doc alternate_elseif_keyword in
762 let left = get_doc alternate_elseif_left_paren in
763 let condition = get_doc alternate_elseif_condition in
764 let right = get_doc alternate_elseif_right_paren in
765 let colon = get_doc alternate_elseif_colon in
766 let elif_statement_syntax = alternate_elseif_statement in
767 let left_part = group_doc (keyword ^^| left) in
768 let right_part = group_doc (right ^^^ colon) in
769 let start_block = indent_block_no_space left_part condition right_part indt in
770 handle_compound_brace_prefix_indent start_block elif_statement_syntax indt
771 |> add_break
772 | AlternateElseClause x ->
773 let keyword = get_doc x.alternate_else_keyword in
774 let statement = x.alternate_else_statement in
775 handle_compound_brace_prefix_indent keyword statement indt
776 |> add_break
777 | TryStatement
778 { try_keyword;
779 try_compound_statement;
780 try_catch_clauses;
781 try_finally_clause } ->
782 let keyword = get_doc try_keyword in
783 let compound_stmt = try_compound_statement in
784 let try_part =
785 handle_compound_brace_prefix_indent keyword compound_stmt indt in
786 let catch_clauses = get_doc try_catch_clauses in
787 let finally_clause = get_doc try_finally_clause in
788 group_doc (try_part ^| catch_clauses ^| finally_clause)
789 |> add_break
790 | CatchClause {
791 catch_keyword;
792 catch_left_paren;
793 catch_type;
794 catch_variable;
795 catch_right_paren;
796 catch_body } ->
797 let keyword = get_doc catch_keyword in
798 let left = get_doc catch_left_paren in
799 let ty = get_doc catch_type in
800 let var = get_doc catch_variable in
801 let param = ty ^| var in
802 let right = get_doc catch_right_paren in
803 let stmt = catch_body in
804 let front_part = group_doc (keyword ^| left) in
805 let before_stmt = indent_block_no_space front_part param right indt in
806 handle_compound_brace_prefix_indent before_stmt stmt indt
807 |> add_break
808 | FinallyClause {
809 finally_keyword;
810 finally_body } ->
811 let keyword = get_doc finally_keyword in
812 handle_compound_brace_prefix_indent keyword finally_body indt
813 |> add_break
814 | DoStatement {
815 do_keyword;
816 do_body;
817 do_while_keyword;
818 do_left_paren;
819 do_condition;
820 do_right_paren;
821 do_semicolon } ->
822 let keyword = get_doc do_keyword in
823 let statement = do_body in
824 let while_keyword = get_doc do_while_keyword in
825 let left = get_doc do_left_paren in
826 let right = get_doc do_right_paren in
827 let condition = get_doc do_condition in
828 let semicolon = get_doc do_semicolon in
829 let statement_part =
830 handle_compound_brace_prefix_indent keyword statement indt |> add_break in
831 let left_part = group_doc (while_keyword ^^| left) in
832 let condition_part = indent_block_no_space left_part condition right indt in
833 group_doc (statement_part ^| condition_part) ^^^ semicolon
834 | ForStatement {
835 for_keyword;
836 for_left_paren;
837 for_initializer;
838 for_first_semicolon;
839 for_control;
840 for_second_semicolon;
841 for_end_of_loop;
842 for_right_paren;
843 for_body } ->
844 let keyword = get_doc for_keyword in
845 let left_paren = get_doc for_left_paren in
846 let initializer_expr = get_doc for_initializer in
847 let first_semicolon = get_doc for_first_semicolon in
848 let control_expr = get_doc for_control in
849 let second_semicolon = get_doc for_second_semicolon in
850 let end_of_loop_expr = get_doc for_end_of_loop in
851 let right_paren = get_doc for_right_paren in
852 let statement = for_body in
853 let left_part = group_doc (keyword ^^| left_paren) in
854 let for_expressions =
855 control_expr ^^^ second_semicolon ^| end_of_loop_expr in
856 let for_expressions = if is_missing for_control
857 then first_semicolon ^^| for_expressions
858 else first_semicolon ^| for_expressions in
859 let for_expressions = group_doc (initializer_expr ^^^ for_expressions) in
860 let start_block =
861 indent_block_no_space left_part for_expressions right_paren indt in
862 handle_compound_brace_prefix_indent start_block statement indt |> add_break
863 | ForeachStatement {
864 foreach_keyword;
865 foreach_left_paren;
866 foreach_collection;
867 foreach_await_keyword;
868 foreach_as;
869 foreach_key;
870 foreach_arrow;
871 foreach_value;
872 foreach_right_paren;
873 foreach_body }->
874 let keyword = get_doc foreach_keyword in
875 let left = get_doc foreach_left_paren in
876 let right = get_doc foreach_right_paren in
877 let collection_name = get_doc foreach_collection in
878 let await_keyword = get_doc foreach_await_keyword in
879 let as_keyword = get_doc foreach_as in
880 let key = get_doc foreach_key in
881 let arrow = get_doc foreach_arrow in
882 let value = get_doc foreach_value in
883 let statement = foreach_body in
884 let left_part = group_doc (keyword ^| left) in
885 let arrow_part = group_doc (group_doc (key ^| arrow) ^| value) in
886 let as_part = group_doc (await_keyword ^| as_keyword) in
887 let as_part = group_doc (collection_name ^| as_part) in
888 let middle_part = group_doc (as_part ^| arrow_part) in
889 let start_block = indent_block_no_space left_part middle_part right indt in
890 handle_compound_brace_prefix_indent start_block statement indt |> add_break
891 | SwitchStatement {
892 switch_keyword;
893 switch_left_paren;
894 switch_expression;
895 switch_right_paren;
896 switch_left_brace;
897 switch_sections;
898 switch_right_brace } ->
899 let keyword = get_doc switch_keyword in
900 let lparen= get_doc switch_left_paren in
901 let expr = get_doc switch_expression in
902 let rparen = get_doc switch_right_paren in
903 let lbrace = get_doc switch_left_brace in
904 let sections = get_doc switch_sections in
905 let rbrace = get_doc switch_right_brace in
906 (* TODO Fix this *)
907 let h = keyword ^| lparen ^| expr ^| rparen ^| space ^| lbrace in
908 let h = add_break h in
909 h ^| sections ^| rbrace
910 | AlternateSwitchStatement {
911 alternate_switch_keyword;
912 alternate_switch_left_paren;
913 alternate_switch_expression;
914 alternate_switch_right_paren;
915 alternate_switch_opening_colon;
916 alternate_switch_sections;
917 alternate_switch_closing_endswitch;
918 alternate_switch_closing_semicolon } ->
919 let keyword = get_doc alternate_switch_keyword in
920 let lparen= get_doc alternate_switch_left_paren in
921 let expr = get_doc alternate_switch_expression in
922 let rparen = get_doc alternate_switch_right_paren in
923 let colon = get_doc alternate_switch_opening_colon in
924 let sections = get_doc alternate_switch_sections in
925 let endswitch = get_doc alternate_switch_closing_endswitch in
926 let semicolon = get_doc alternate_switch_closing_semicolon in
927 let h = keyword ^| lparen ^| expr ^| rparen ^| colon in
928 let h = add_break h in
929 h ^| sections ^| endswitch ^| semicolon
930 | SwitchSection {
931 switch_section_labels;
932 switch_section_statements;
933 switch_section_fallthrough } ->
934 (* TODO Fix this *)
935 let labels = get_doc switch_section_labels in
936 let statements = get_doc switch_section_statements in
937 let fallthrough = get_doc switch_section_fallthrough in
938 (add_break labels) ^| (add_break statements) ^| (add_break fallthrough)
939 | SwitchFallthrough {
940 fallthrough_keyword;
941 fallthrough_semicolon
942 } ->
943 let f = get_doc fallthrough_keyword in
944 let s = get_doc fallthrough_semicolon in
945 f ^^^ s
946 | ScopeResolutionExpression x ->
947 let q = get_doc x.scope_resolution_qualifier in
948 let o = get_doc x.scope_resolution_operator in
949 let n = get_doc x.scope_resolution_name in
950 group_doc (q ^^^ o ^^^ n)
951 | MemberSelectionExpression
952 { member_object; member_operator; member_name } ->
953 let ob = get_doc member_object in
954 let op = get_doc member_operator in
955 let nm = get_doc member_name in
956 group_doc (ob ^^^ op ^^^ nm)
957 | SafeMemberSelectionExpression
958 { safe_member_object; safe_member_operator; safe_member_name } ->
959 let ob = get_doc safe_member_object in
960 let op = get_doc safe_member_operator in
961 let nm = get_doc safe_member_name in
962 group_doc (ob ^^^ op ^^^ nm)
963 | EmbeddedMemberSelectionExpression
964 { embedded_member_object;
965 embedded_member_operator;
966 embedded_member_name } ->
967 let ob = get_doc embedded_member_object in
968 let op = get_doc embedded_member_operator in
969 let nm = get_doc embedded_member_name in
970 group_doc (ob ^^^ op ^^^ nm)
971 | YieldExpression x ->
972 let y = get_doc x.yield_keyword in
973 let o = get_doc x.yield_operand in
974 group_doc (y ^| o)
975 | YieldFromExpression x ->
976 let y = get_doc x.yield_from_yield_keyword in
977 let f = get_doc x.yield_from_from_keyword in
978 let o = get_doc x.yield_from_operand in
979 group_doc (y ^| f ^| o)
980 | CastExpression x ->
981 let l = get_doc x.cast_left_paren in
982 let t = get_doc x.cast_type in
983 let r = get_doc x.cast_right_paren in
984 let o = get_doc x.cast_operand in
985 group_doc (l ^^^ t ^^^ r ^^^ o)
986 | LambdaExpression {
987 lambda_async;
988 lambda_coroutine;
989 lambda_signature;
990 lambda_arrow;
991 lambda_body;
992 } ->
993 let async = get_doc lambda_async in
994 let coroutine = get_doc lambda_coroutine in
995 let signature = get_doc lambda_signature in
996 let arrow = get_doc lambda_arrow in
997 let body = get_doc lambda_body in
998 group_doc (async ^| coroutine ^| signature ^| arrow ^| body)
999 | LambdaSignature
1000 { lambda_left_paren; lambda_parameters; lambda_right_paren;
1001 lambda_colon; lambda_type } ->
1002 let left = get_doc lambda_left_paren in
1003 let params = get_doc lambda_parameters in
1004 let right = get_doc lambda_right_paren in
1005 let colon = get_doc lambda_colon in
1006 let ty = get_doc lambda_type in
1007 group_doc (left ^| params ^| right ^| colon ^| ty)
1008 | AnonymousFunction
1009 { anonymous_static_keyword;
1010 anonymous_async_keyword;
1011 anonymous_coroutine_keyword;
1012 anonymous_function_keyword;
1013 anonymous_left_paren;
1014 anonymous_parameters;
1015 anonymous_right_paren;
1016 anonymous_colon;
1017 anonymous_type;
1018 anonymous_use;
1019 anonymous_body } ->
1020 let static = get_doc anonymous_static_keyword in
1021 let async = get_doc anonymous_async_keyword in
1022 let coroutine = get_doc anonymous_coroutine_keyword in
1023 let fn = get_doc anonymous_function_keyword in
1024 let left = get_doc anonymous_left_paren in
1025 let params = get_doc anonymous_parameters in
1026 let right = get_doc anonymous_right_paren in
1027 let colon = get_doc anonymous_colon in
1028 let return_type = get_doc anonymous_type in
1029 let preface = group_doc ( static ^| async ^| coroutine ^| fn ) in
1030 let parameters = indent_block_no_space left params right indt in
1031 let type_declaration = group_doc (colon ^| return_type) in
1032 let uses = get_doc anonymous_use in
1033 let body = anonymous_body in
1034 let before_body =
1035 group_doc (
1036 group_doc ( group_doc preface ^^| parameters )
1037 ^| type_declaration ^| uses
1038 ) in
1039 handle_compound_inline_brace before_body body missing
1040 | Php7AnonymousFunction
1041 { php7_anonymous_static_keyword;
1042 php7_anonymous_async_keyword;
1043 php7_anonymous_coroutine_keyword;
1044 php7_anonymous_function_keyword;
1045 php7_anonymous_left_paren;
1046 php7_anonymous_parameters;
1047 php7_anonymous_right_paren;
1048 php7_anonymous_colon;
1049 php7_anonymous_type;
1050 php7_anonymous_use;
1051 php7_anonymous_body } ->
1052 let static = get_doc php7_anonymous_static_keyword in
1053 let async = get_doc php7_anonymous_async_keyword in
1054 let coroutine = get_doc php7_anonymous_coroutine_keyword in
1055 let fn = get_doc php7_anonymous_function_keyword in
1056 let left = get_doc php7_anonymous_left_paren in
1057 let params = get_doc php7_anonymous_parameters in
1058 let right = get_doc php7_anonymous_right_paren in
1059 let colon = get_doc php7_anonymous_colon in
1060 let return_type = get_doc php7_anonymous_type in
1061 let preface = group_doc ( static ^| async ^| coroutine ^| fn ) in
1062 let parameters = indent_block_no_space left params right indt in
1063 let type_declaration = group_doc (colon ^| return_type) in
1064 let uses = get_doc php7_anonymous_use in
1065 let body = php7_anonymous_body in
1066 let before_body =
1067 group_doc (
1068 group_doc ( group_doc preface ^^| parameters )
1069 ^| uses ^| type_declaration
1070 ) in
1071 handle_compound_inline_brace before_body body missing
1072 | AnonymousFunctionUseClause x ->
1073 let u = get_doc x.anonymous_use_keyword in
1074 let l = get_doc x.anonymous_use_left_paren in
1075 let v = get_doc x.anonymous_use_variables in
1076 let r = get_doc x.anonymous_use_right_paren in
1077 u ^| l ^^^ v ^^^ r
1078 | PrefixUnaryExpression
1079 { prefix_unary_operator; prefix_unary_operand } ->
1080 if is_separable_prefix prefix_unary_operator then
1081 get_doc prefix_unary_operator ^| get_doc prefix_unary_operand
1082 else
1083 get_doc prefix_unary_operator ^^^ get_doc prefix_unary_operand
1084 | PostfixUnaryExpression
1085 { postfix_unary_operand; postfix_unary_operator } ->
1086 get_doc postfix_unary_operand ^^^ get_doc postfix_unary_operator
1087 | BinaryExpression x ->
1088 let left = get_doc x.binary_left_operand in
1089 let op = get_doc x.binary_operator in
1090 let right = get_doc x.binary_right_operand in
1091 group_doc (left ^| op ^| right)
1092 | InstanceofExpression x ->
1093 let left = get_doc x.instanceof_left_operand in
1094 let op = get_doc x.instanceof_operator in
1095 let right = get_doc x.instanceof_right_operand in
1096 group_doc (left ^| op ^| right)
1097 | IsExpression x ->
1098 let left = get_doc x.is_left_operand in
1099 let op = get_doc x.is_operator in
1100 let right = get_doc x.is_right_operand in
1101 group_doc (left ^| op ^| right)
1102 | ConditionalExpression x ->
1103 let tst = get_doc x.conditional_test in
1104 let qm = get_doc x.conditional_question in
1105 let con = get_doc x.conditional_consequence in
1106 let col = get_doc x.conditional_colon in
1107 let alt = get_doc x.conditional_alternative in
1108 (* TODO: Could this be improved? *)
1109 group_doc ( tst ^| qm ^| con ^| col ^| alt )
1110 | FunctionCallExpression {
1111 function_call_receiver;
1112 function_call_left_paren;
1113 function_call_argument_list;
1114 function_call_right_paren } ->
1115 let receiver = get_doc function_call_receiver in
1116 let lparen = get_doc function_call_left_paren in
1117 let args = get_doc function_call_argument_list in
1118 let rparen = get_doc function_call_right_paren in
1119 receiver ^^^ lparen ^^^ args ^^^ rparen
1120 | FunctionCallWithTypeArgumentsExpression {
1121 function_call_with_type_arguments_receiver;
1122 function_call_with_type_arguments_type_args;
1123 function_call_with_type_arguments_left_paren;
1124 function_call_with_type_arguments_argument_list;
1125 function_call_with_type_arguments_right_paren } ->
1126 let receiver = get_doc function_call_with_type_arguments_receiver in
1127 let tyargs = get_doc function_call_with_type_arguments_type_args in
1128 let lparen = get_doc function_call_with_type_arguments_left_paren in
1129 let args = get_doc function_call_with_type_arguments_argument_list in
1130 let rparen = get_doc function_call_with_type_arguments_right_paren in
1131 receiver ^^^ tyargs ^^^ lparen ^^^ args ^^^ rparen
1132 | EvalExpression {
1133 eval_keyword;
1134 eval_left_paren;
1135 eval_argument;
1136 eval_right_paren } ->
1137 let keyword = get_doc eval_keyword in
1138 let lparen = get_doc eval_left_paren in
1139 let arg = get_doc eval_argument in
1140 let rparen = get_doc eval_right_paren in
1141 keyword ^^^ lparen ^^^ arg ^^^ rparen
1142 | EmptyExpression {
1143 empty_keyword;
1144 empty_left_paren;
1145 empty_argument;
1146 empty_right_paren } ->
1147 let keyword = get_doc empty_keyword in
1148 let lparen = get_doc empty_left_paren in
1149 let arg = get_doc empty_argument in
1150 let rparen = get_doc empty_right_paren in
1151 keyword ^^^ lparen ^^^ arg ^^^ rparen
1152 | IssetExpression {
1153 isset_keyword;
1154 isset_left_paren;
1155 isset_argument_list;
1156 isset_right_paren } ->
1157 let keyword = get_doc isset_keyword in
1158 let lparen = get_doc isset_left_paren in
1159 let args = get_doc isset_argument_list in
1160 let rparen = get_doc isset_right_paren in
1161 keyword ^^^ lparen ^^^ args ^^^ rparen
1162 | HaltCompilerExpression {
1163 halt_compiler_keyword;
1164 halt_compiler_left_paren;
1165 halt_compiler_argument_list;
1166 halt_compiler_right_paren } ->
1167 let keyword = get_doc halt_compiler_keyword in
1168 let lparen = get_doc halt_compiler_left_paren in
1169 let args = get_doc halt_compiler_argument_list in
1170 let rparen = get_doc halt_compiler_right_paren in
1171 keyword ^^^ lparen ^^^ args ^^^ rparen
1172 | DefineExpression {
1173 define_keyword;
1174 define_left_paren;
1175 define_argument_list;
1176 define_right_paren } ->
1177 let keyword = get_doc define_keyword in
1178 let lparen = get_doc define_left_paren in
1179 let args = get_doc define_argument_list in
1180 let rparen = get_doc define_right_paren in
1181 keyword ^^^ lparen ^^^ args ^^^ rparen
1182 | ParenthesizedExpression {
1183 parenthesized_expression_left_paren;
1184 parenthesized_expression_expression;
1185 parenthesized_expression_right_paren } ->
1186 let left = get_doc parenthesized_expression_left_paren in
1187 let expr = get_doc parenthesized_expression_expression in
1188 let right = get_doc parenthesized_expression_right_paren in
1189 indent_block_no_space left expr right indt
1190 | BracedExpression {
1191 braced_expression_left_brace;
1192 braced_expression_expression;
1193 braced_expression_right_brace } ->
1194 let left = get_doc braced_expression_left_brace in
1195 let expr = get_doc braced_expression_expression in
1196 let right = get_doc braced_expression_right_brace in
1197 indent_block_no_space left expr right indt
1198 | EmbeddedBracedExpression {
1199 embedded_braced_expression_left_brace;
1200 embedded_braced_expression_expression;
1201 embedded_braced_expression_right_brace } ->
1202 let left = get_doc embedded_braced_expression_left_brace in
1203 let expr = get_doc embedded_braced_expression_expression in
1204 let right = get_doc embedded_braced_expression_right_brace in
1205 indent_block_no_space left expr right indt
1206 | ListExpression
1207 { list_keyword; list_left_paren; list_members; list_right_paren } ->
1208 let keyword = get_doc list_keyword in
1209 let left_paren = get_doc list_left_paren in
1210 let members = get_doc list_members in
1211 let right_paren = get_doc list_right_paren in
1212 let left = group_doc (keyword ^| left_paren) in
1213 indent_block_no_space left members right_paren indt
1214 | CollectionLiteralExpression x ->
1215 let token = get_doc x.collection_literal_name in
1216 let left_brace = get_doc x.collection_literal_left_brace in
1217 let expression_list = get_doc x.collection_literal_initializers in
1218 let right_brace = get_doc x.collection_literal_right_brace in
1219 token ^| left_brace ^| expression_list ^| right_brace
1220 | ObjectCreationExpression
1221 { object_creation_new_keyword;
1222 object_creation_object } ->
1223 let n = get_doc object_creation_new_keyword in
1224 let o = get_doc object_creation_object in
1225 n ^| o
1226 | ConstructorCall
1227 { constructor_call_type;
1228 constructor_call_left_paren;
1229 constructor_call_argument_list;
1230 constructor_call_right_paren } ->
1231 let c = get_doc constructor_call_type in
1232 let l = get_doc constructor_call_left_paren in
1233 let a = get_doc constructor_call_argument_list in
1234 let r = get_doc constructor_call_right_paren in
1235 c ^^^ l ^^^ a ^^^ r
1236 | AnonymousClass
1237 { anonymous_class_class_keyword;
1238 anonymous_class_left_paren;
1239 anonymous_class_argument_list;
1240 anonymous_class_right_paren;
1241 anonymous_class_extends_keyword;
1242 anonymous_class_extends_list;
1243 anonymous_class_implements_keyword;
1244 anonymous_class_implements_list;
1245 anonymous_class_body } ->
1246 let c = get_doc anonymous_class_class_keyword in
1247 let l = get_doc anonymous_class_left_paren in
1248 let a = get_doc anonymous_class_argument_list in
1249 let r = get_doc anonymous_class_right_paren in
1250 let extends =
1251 let extends_token = get_doc anonymous_class_extends_keyword in
1252 let extends_list = get_doc anonymous_class_extends_list in
1253 group_doc (indent_doc extends_token extends_list indt)
1255 let implements =
1256 let implements_token = get_doc anonymous_class_implements_keyword in
1257 let implements_list = get_doc anonymous_class_implements_list in
1258 group_doc (indent_doc implements_token implements_list indt)
1260 let body = get_doc anonymous_class_body in
1261 group_doc (
1262 c ^^^ l ^^^ a ^^^ r ^|
1263 group_doc (
1264 extends ^|
1265 implements
1266 ) ^|
1267 body
1269 | FieldInitializer
1270 { field_initializer_name; field_initializer_arrow;
1271 field_initializer_value }->
1272 let n = get_doc field_initializer_name in
1273 let a = get_doc field_initializer_arrow in
1274 let v = get_doc field_initializer_value in
1275 n ^| a ^| v
1276 | ShapeExpression
1277 { shape_expression_keyword; shape_expression_left_paren;
1278 shape_expression_fields; shape_expression_right_paren } ->
1279 let sh = get_doc shape_expression_keyword in
1280 let lp = get_doc shape_expression_left_paren in
1281 let fs = get_doc shape_expression_fields in
1282 let rp = get_doc shape_expression_right_paren in
1283 sh ^| lp ^^^ fs ^^^ rp
1284 | TupleExpression
1285 { tuple_expression_keyword; tuple_expression_left_paren;
1286 tuple_expression_items; tuple_expression_right_paren } ->
1287 let tu = get_doc tuple_expression_keyword in
1288 let lp = get_doc tuple_expression_left_paren in
1289 let xs = get_doc tuple_expression_items in
1290 let rp = get_doc tuple_expression_right_paren in
1291 tu ^| lp ^^^ xs ^^^ rp
1292 | ArrayCreationExpression x ->
1293 let left_bracket = get_doc x.array_creation_left_bracket in
1294 let right_bracket = get_doc x.array_creation_right_bracket in
1295 let members = get_doc x.array_creation_members in
1296 indent_block_no_space left_bracket members right_bracket indt
1297 | ArrayIntrinsicExpression {
1298 array_intrinsic_keyword;
1299 array_intrinsic_left_paren;
1300 array_intrinsic_members;
1301 array_intrinsic_right_paren } ->
1302 let keyword = get_doc array_intrinsic_keyword in
1303 let left = get_doc array_intrinsic_left_paren in
1304 let members = get_doc array_intrinsic_members in
1305 let right = get_doc array_intrinsic_right_paren in
1306 let left_part = group_doc (keyword ^^| left) in
1307 indent_block_no_space left_part members right indt
1308 | DarrayIntrinsicExpression {
1309 darray_intrinsic_keyword;
1310 darray_intrinsic_left_bracket;
1311 darray_intrinsic_members;
1312 darray_intrinsic_right_bracket } ->
1313 let keyword = get_doc darray_intrinsic_keyword in
1314 let left = get_doc darray_intrinsic_left_bracket in
1315 let members = get_doc darray_intrinsic_members in
1316 let right = get_doc darray_intrinsic_right_bracket in
1317 let left_part = group_doc (keyword ^^| left) in
1318 indent_block_no_space left_part members right indt
1319 | DictionaryIntrinsicExpression {
1320 dictionary_intrinsic_keyword;
1321 dictionary_intrinsic_left_bracket;
1322 dictionary_intrinsic_members;
1323 dictionary_intrinsic_right_bracket } ->
1324 let keyword = get_doc dictionary_intrinsic_keyword in
1325 let left = get_doc dictionary_intrinsic_left_bracket in
1326 let members = get_doc dictionary_intrinsic_members in
1327 let right = get_doc dictionary_intrinsic_right_bracket in
1328 let left_part = group_doc (keyword ^^| left) in
1329 indent_block_no_space left_part members right indt
1330 | KeysetIntrinsicExpression {
1331 keyset_intrinsic_keyword;
1332 keyset_intrinsic_left_bracket;
1333 keyset_intrinsic_members;
1334 keyset_intrinsic_right_bracket } ->
1335 let keyword = get_doc keyset_intrinsic_keyword in
1336 let left = get_doc keyset_intrinsic_left_bracket in
1337 let members = get_doc keyset_intrinsic_members in
1338 let right = get_doc keyset_intrinsic_right_bracket in
1339 let left_part = group_doc (keyword ^^| left) in
1340 indent_block_no_space left_part members right indt
1341 | VarrayIntrinsicExpression {
1342 varray_intrinsic_keyword;
1343 varray_intrinsic_left_bracket;
1344 varray_intrinsic_members;
1345 varray_intrinsic_right_bracket } ->
1346 let keyword = get_doc varray_intrinsic_keyword in
1347 let left = get_doc varray_intrinsic_left_bracket in
1348 let members = get_doc varray_intrinsic_members in
1349 let right = get_doc varray_intrinsic_right_bracket in
1350 let left_part = group_doc (keyword ^^| left) in
1351 indent_block_no_space left_part members right indt
1352 | VectorIntrinsicExpression {
1353 vector_intrinsic_keyword;
1354 vector_intrinsic_left_bracket;
1355 vector_intrinsic_members;
1356 vector_intrinsic_right_bracket } ->
1357 let keyword = get_doc vector_intrinsic_keyword in
1358 let left = get_doc vector_intrinsic_left_bracket in
1359 let members = get_doc vector_intrinsic_members in
1360 let right = get_doc vector_intrinsic_right_bracket in
1361 let left_part = group_doc (keyword ^^| left) in
1362 indent_block_no_space left_part members right indt
1363 | ElementInitializer x ->
1364 let k = get_doc x.element_key in
1365 let a = get_doc x.element_arrow in
1366 let v = get_doc x.element_value in
1367 k ^| a ^| v
1368 | SubscriptExpression x ->
1369 let receiver = get_doc x.subscript_receiver in
1370 let left = get_doc x.subscript_left_bracket in
1371 let index = get_doc x.subscript_index in
1372 let right = get_doc x.subscript_right_bracket in
1373 receiver ^^^ left ^^^ index ^^^ right
1374 | EmbeddedSubscriptExpression x ->
1375 let receiver = get_doc x.embedded_subscript_receiver in
1376 let left = get_doc x.embedded_subscript_left_bracket in
1377 let index = get_doc x.embedded_subscript_index in
1378 let right = get_doc x.embedded_subscript_right_bracket in
1379 receiver ^^^ left ^^^ index ^^^ right
1380 | AwaitableCreationExpression x ->
1381 let async = get_doc x.awaitable_async in
1382 let coroutine = get_doc x.awaitable_coroutine in
1383 let stmt = x.awaitable_compound_statement in
1384 handle_compound_brace_prefix_indent (async ^| coroutine) stmt indt
1385 | XHPExpression x ->
1386 let left = get_doc x.xhp_open in
1387 let expr = get_doc x.xhp_body in
1388 let right = get_doc x.xhp_close in
1389 left ^^^ expr ^^^ right
1390 | XHPOpen {
1391 xhp_open_left_angle;
1392 xhp_open_name;
1393 xhp_open_attributes;
1394 xhp_open_right_angle } ->
1395 let left = get_doc xhp_open_left_angle in
1396 let name = get_doc xhp_open_name in
1397 let attrs = get_doc xhp_open_attributes in
1398 let right = get_doc xhp_open_right_angle in
1399 group_doc (group_doc (indent_doc (left ^^^ name) attrs indt) ^| right)
1400 | XHPSimpleAttribute {
1401 xhp_simple_attribute_name;
1402 xhp_simple_attribute_equal;
1403 xhp_simple_attribute_expression }->
1404 let name = get_doc xhp_simple_attribute_name in
1405 let equals = get_doc xhp_simple_attribute_equal in
1406 let expr = get_doc xhp_simple_attribute_expression in
1407 group_doc (group_doc (name ^^| equals) ^^| expr)
1408 | XHPSpreadAttribute x ->
1409 let left = get_doc x.xhp_spread_attribute_left_brace in
1410 let spread = get_doc x.xhp_spread_attribute_spread_operator in
1411 let expr = get_doc x.xhp_spread_attribute_expression in
1412 let right = get_doc x.xhp_spread_attribute_right_brace in
1413 left ^^^ spread ^^^ expr ^^^ right
1414 | XHPClose x ->
1415 let left = get_doc x.xhp_close_left_angle in
1416 let name = get_doc x.xhp_close_name in
1417 let right = get_doc x.xhp_close_right_angle in
1418 left ^^^ name ^^^ right
1419 | TypeConstant x ->
1420 let left = get_doc x.type_constant_left_type in
1421 let right = get_doc x.type_constant_right_type in
1422 let separator = get_doc x.type_constant_separator in
1423 left ^^^ separator ^^^ right
1424 | SimpleTypeSpecifier x -> get_doc x.simple_type_specifier
1425 | TypeConstraint { constraint_keyword; constraint_type } ->
1426 let k = get_doc constraint_keyword in
1427 let t = get_doc constraint_type in
1428 k ^| t
1429 | TypeParameter x ->
1430 let variance = get_doc x.type_variance in
1431 let name = get_doc x.type_name in
1432 let constraints = get_doc x.type_constraints in
1433 variance ^^^ name ^| constraints
1434 | NullableTypeSpecifier x ->
1435 let qm = get_doc x.nullable_question in
1436 let ty = get_doc x.nullable_type in
1437 qm ^^^ ty
1438 | SoftTypeSpecifier x ->
1439 let a = get_doc x.soft_at in
1440 let t = get_doc x.soft_type in
1441 a ^^^ t
1442 | GenericTypeSpecifier
1443 { generic_class_type;
1444 generic_argument_list } ->
1445 let name = get_doc generic_class_type in
1446 let argument = get_doc generic_argument_list in
1447 group_doc (indent_doc_no_space name argument indt)
1448 | VarrayTypeSpecifier {
1449 varray_keyword;
1450 varray_left_angle;
1451 varray_type;
1452 varray_trailing_comma;
1453 varray_right_angle
1454 } ->
1455 let ar = get_doc varray_keyword in
1456 let la = get_doc varray_left_angle in
1457 let ty = get_doc varray_type in
1458 let oc = get_doc varray_trailing_comma in
1459 let ra = get_doc varray_right_angle in
1460 ar ^^^ la ^^^ ty ^^^ oc ^^^ ra
1461 | VectorArrayTypeSpecifier {
1462 vector_array_keyword;
1463 vector_array_left_angle;
1464 vector_array_type;
1465 vector_array_right_angle
1466 } ->
1467 let ar = get_doc vector_array_keyword in
1468 let la = get_doc vector_array_left_angle in
1469 let ty = get_doc vector_array_type in
1470 let ra = get_doc vector_array_right_angle in
1471 ar ^^^ la ^^^ ty ^^^ ra
1472 | VectorTypeSpecifier {
1473 vector_type_keyword;
1474 vector_type_left_angle;
1475 vector_type_type;
1476 vector_type_trailing_comma;
1477 vector_type_right_angle;
1478 } ->
1479 let ar = get_doc vector_type_keyword in
1480 let la = get_doc vector_type_left_angle in
1481 let ty = get_doc vector_type_type in
1482 let tr = get_doc vector_type_trailing_comma in
1483 let ra = get_doc vector_type_right_angle in
1484 ar ^^^ la ^^^ ty ^^^ tr ^^^ ra
1485 | KeysetTypeSpecifier {
1486 keyset_type_keyword;
1487 keyset_type_left_angle;
1488 keyset_type_type;
1489 keyset_type_trailing_comma;
1490 keyset_type_right_angle
1491 } ->
1492 let ar = get_doc keyset_type_keyword in
1493 let la = get_doc keyset_type_left_angle in
1494 let ty = get_doc keyset_type_type in
1495 let tr = get_doc keyset_type_trailing_comma in
1496 let ra = get_doc keyset_type_right_angle in
1497 ar ^^^ la ^^^ ty ^^^ tr ^^^ ra
1498 | TupleTypeExplicitSpecifier {
1499 tuple_type_keyword;
1500 tuple_type_left_angle;
1501 tuple_type_types;
1502 tuple_type_right_angle
1503 } ->
1504 let tu = get_doc tuple_type_keyword in
1505 let la = get_doc tuple_type_left_angle in
1506 let ts = get_doc tuple_type_types in
1507 let ra = get_doc tuple_type_right_angle in
1508 tu ^^^ la ^^^ ts ^^^ ra
1509 | DictionaryTypeSpecifier {
1510 dictionary_type_keyword;
1511 dictionary_type_left_angle;
1512 dictionary_type_members;
1513 dictionary_type_right_angle
1514 } ->
1515 let ar = get_doc dictionary_type_keyword in
1516 let la = get_doc dictionary_type_left_angle in
1517 let ms = get_doc dictionary_type_members in
1518 let ra = get_doc dictionary_type_right_angle in
1519 ar ^^^ la ^^^ ms ^^^ ra
1520 | DarrayTypeSpecifier {
1521 darray_keyword;
1522 darray_left_angle;
1523 darray_key;
1524 darray_comma;
1525 darray_value;
1526 darray_trailing_comma;
1527 darray_right_angle
1528 } ->
1529 let ar = get_doc darray_keyword in
1530 let la = get_doc darray_left_angle in
1531 let kt = get_doc darray_key in
1532 let co = get_doc darray_comma in
1533 let vt = get_doc darray_value in
1534 let oc = get_doc darray_trailing_comma in
1535 let ra = get_doc darray_right_angle in
1536 ar ^^^ la ^^^ kt ^^^ co ^| vt ^^^ oc ^^^ ra
1537 | MapArrayTypeSpecifier {
1538 map_array_keyword;
1539 map_array_left_angle;
1540 map_array_key;
1541 map_array_comma;
1542 map_array_value;
1543 map_array_right_angle
1544 } ->
1545 let ar = get_doc map_array_keyword in
1546 let la = get_doc map_array_left_angle in
1547 let kt = get_doc map_array_key in
1548 let co = get_doc map_array_comma in
1549 let vt = get_doc map_array_value in
1550 let ra = get_doc map_array_right_angle in
1551 ar ^^^ la ^^^ kt ^^^ co ^| vt ^^^ ra
1552 | ClosureTypeSpecifier
1553 { closure_outer_left_paren;
1554 closure_coroutine;
1555 closure_function_keyword;
1556 closure_inner_left_paren;
1557 closure_parameter_list;
1558 closure_inner_right_paren;
1559 closure_colon;
1560 closure_return_type;
1561 closure_outer_right_paren } ->
1562 let olp = get_doc closure_outer_left_paren in
1563 let cor = get_doc closure_coroutine in
1564 let fnc = get_doc closure_function_keyword in
1565 let ilp = get_doc closure_inner_left_paren in
1566 let pts = get_doc closure_parameter_list in
1567 let irp = get_doc closure_inner_right_paren in
1568 let col = get_doc closure_colon in
1569 let ret = get_doc closure_return_type in
1570 let orp = get_doc closure_outer_right_paren in
1571 olp ^^^ cor ^| fnc ^^| ilp ^^^ pts ^^^ irp ^^^ col ^^^ ret ^^^ orp
1572 | ClosureParameterTypeSpecifier {
1573 closure_parameter_call_convention;
1574 closure_parameter_type;
1575 } ->
1576 let cc = get_doc closure_parameter_call_convention in
1577 let ty = get_doc closure_parameter_type in
1578 cc ^| ty
1579 | ClassnameTypeSpecifier x ->
1580 let cn = get_doc x.classname_keyword in
1581 let la = get_doc x.classname_left_angle in
1582 let ty = get_doc x.classname_type in
1583 let ra = get_doc x.classname_right_angle in
1584 cn ^^^ la ^^^ ty ^^^ ra
1585 | FieldSpecifier x ->
1586 let q = get_doc x.field_question in
1587 let n = get_doc x.field_name in
1588 let a = get_doc x.field_arrow in
1589 let t = get_doc x.field_type in
1590 q ^| n ^| a ^| t
1591 | ShapeTypeSpecifier
1592 { shape_type_keyword; shape_type_left_paren;
1593 shape_type_fields; shape_type_ellipsis; shape_type_right_paren } ->
1594 let sh = get_doc shape_type_keyword in
1595 let lp = get_doc shape_type_left_paren in
1596 let fs = get_doc shape_type_fields in
1597 let ellipsis = get_doc shape_type_ellipsis in
1598 let rp = get_doc shape_type_right_paren in
1599 sh ^| lp ^^^ fs ^| ellipsis ^^^ rp
1600 | TypeArguments {
1601 type_arguments_left_angle;
1602 type_arguments_types;
1603 type_arguments_right_angle } ->
1604 let left = get_doc type_arguments_left_angle in
1605 let args = get_doc type_arguments_types in
1606 let right = get_doc type_arguments_right_angle in
1607 indent_block_no_space left args right indt
1608 | TypeParameters {
1609 type_parameters_left_angle;
1610 type_parameters_parameters;
1611 type_parameters_right_angle } ->
1612 let left = get_doc type_parameters_left_angle in
1613 let params = get_doc type_parameters_parameters in
1614 let right = get_doc type_parameters_right_angle in
1615 indent_block_no_space left params right indt
1616 | TupleTypeSpecifier x ->
1617 let left = get_doc x.tuple_left_paren in
1618 let types = get_doc x.tuple_types in
1619 let right = get_doc x.tuple_right_paren in
1620 indent_block_no_space left types right indt
1621 (* this ideally should never be called *)
1622 | CaseLabel {
1623 case_keyword;
1624 case_expression;
1625 case_colon } ->
1626 let keyword = get_doc case_keyword in
1627 let expr = get_doc case_expression in
1628 let colon = get_doc case_colon in
1629 keyword ^^^ space ^^^ expr ^^^ colon
1630 | DefaultLabel {
1631 default_keyword;
1632 default_colon } ->
1633 let keyword = get_doc default_keyword in
1634 let colon = get_doc default_colon in
1635 keyword ^^^ colon
1636 | ReturnStatement x ->
1637 let keyword = get_doc x.return_keyword in
1638 let expr = get_doc x.return_expression in
1639 let semicolon = get_doc x.return_semicolon in
1640 let back_part = expr ^^^ semicolon in
1641 group_doc (indent_doc keyword back_part indt)
1642 | GotoLabel {
1643 goto_label_name;
1644 goto_label_colon; } ->
1645 let goto_label_name = get_doc goto_label_name in
1646 let goto_label_colon = get_doc goto_label_colon in
1647 goto_label_name ^^^ goto_label_colon
1648 | GotoStatement {
1649 goto_statement_keyword;
1650 goto_statement_label_name;
1651 goto_statement_semicolon; } ->
1652 let keyword = get_doc goto_statement_keyword in
1653 let label_name = get_doc goto_statement_label_name in
1654 let semicolon = get_doc goto_statement_semicolon in
1655 keyword ^| label_name ^^^ semicolon
1656 | ThrowStatement x ->
1657 let keyword = get_doc x.throw_keyword in
1658 let expr = get_doc x.throw_expression in
1659 let semicolon = get_doc x.throw_semicolon in
1660 let back_part = expr ^^^ semicolon in
1661 group_doc (indent_doc keyword back_part indt)
1662 | BreakStatement x ->
1663 let b = get_doc x.break_keyword in
1664 let l = get_doc x.break_level in
1665 let s = get_doc x.break_semicolon in
1666 if is_missing x.break_level then group_doc (b ^^^ l ^^^ s)
1667 else group_doc (b ^| l ^^^ s)
1668 | ContinueStatement x ->
1669 let c = get_doc x.continue_keyword in
1670 let l = get_doc x.continue_level in
1671 let s = get_doc x.continue_semicolon in
1672 if is_missing x.continue_level then group_doc (c ^^^ l ^^^ s)
1673 else group_doc (c ^| l ^^^ s)
1674 | FunctionStaticStatement {
1675 static_static_keyword;
1676 static_declarations;
1677 static_semicolon } ->
1678 let st = get_doc static_static_keyword in
1679 let ds = get_doc static_declarations in
1680 let se = get_doc static_semicolon in
1681 st ^| ds ^^^ se
1682 | StaticDeclarator
1683 { static_name; static_initializer } ->
1684 let n = get_doc static_name in
1685 let i = get_doc static_initializer in
1686 group_doc (n ^| i)
1687 | EchoStatement x ->
1688 let echo = get_doc x.echo_keyword in
1689 let expr_list = get_doc x.echo_expressions in
1690 let semicolon = get_doc x.echo_semicolon in
1691 echo ^| expr_list ^^^ semicolon
1692 | GlobalStatement {
1693 global_keyword;
1694 global_variables;
1695 global_semicolon } ->
1696 let g = get_doc global_keyword in
1697 let v = get_doc global_variables in
1698 let s = get_doc global_semicolon in
1699 g ^| v ^^^ s
1700 | SimpleInitializer
1701 { simple_initializer_equal; simple_initializer_value } ->
1702 let e = get_doc simple_initializer_equal in
1703 let v = get_doc simple_initializer_value in
1704 group_doc (e ^| v)
1706 (* sep is the compulsory separator separating the children in the list *)
1707 and get_from_children_no_space children =
1708 let fold_fun acc el = acc ^^^ get_doc el in
1709 group_doc (List.fold_left fold_fun (make_simple nil) children)
1710 and get_from_children_with_sep sep children =
1711 let fold_fun acc el = (acc ^^^ sep) ^| get_doc el in
1712 group_doc (List.fold_left fold_fun (make_simple nil) children)
1713 and get_from_children node = get_from_children_with_sep (make_simple nil) node
1714 (* puts [prefix] on the same line as a compound brace. If the statement is not
1715 * compound, put an optional newline and group the result *)
1716 and handle_compound_inline_brace prefix statement postfix =
1717 match syntax statement with
1718 | CompoundStatement compound_stmt ->
1719 let left = get_doc compound_stmt.compound_left_brace in
1720 let right = get_doc compound_stmt.compound_right_brace in
1721 let statement = get_doc compound_stmt.compound_statements in
1722 let prefix = group_doc (prefix ^| left) in
1723 let postfix = group_doc (right ^| postfix) in
1724 indent_block prefix statement postfix indt
1725 | _ -> group_doc (prefix ^| get_doc statement ^| postfix)
1726 (* keep open brace of compound statement on the same line as the prefix.
1727 * If statement is not a compound statement, then indent it with [indt] *)
1728 and handle_compound_brace_prefix_indent prefix statement indt =
1729 if is_compound_statement statement then
1730 handle_compound_inline_brace prefix statement missing
1731 else
1732 group_doc (indent_doc prefix (get_doc statement) indt)
1734 let pretty_print node =
1735 let empty_string = make_simple (text "") in
1736 let to_print = node |> get_doc |> add_break in
1737 let to_print = to_print ^| empty_string in
1738 let to_print = combine to_print in
1739 pretty 0 to_print