2 * Copyright (c) 2016, Facebook, Inc.
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.
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
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
50 let absorb_nil_cons doc1 doc2 delimiter
=
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
=
62 if must
then must_break
63 else if is_empty
then breakwith
""
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
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
)
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
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
=
119 if l_trail_single
then must_break
120 else if empty
then breakwith
""
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
146 module Comparator
= WidthConstrainedDocComparator
(LineConf
)
147 module Core
= Pretty_printing_library.Make
(Comparator
)
148 module Printer
= Utility
(Core
)
149 module Syntax
= Full_fidelity_editable_syntax
150 module EditableToken
= Full_fidelity_editable_token
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)
164 | Kind.SingleLineComment
->
165 (* no code after comments *)
166 (text
(Trivia.text trivia
), true)
170 | Kind.UnsafeExpression
171 | Kind.DelimitedComment
->
172 (text
(Trivia.text trivia
), false)
174 let concat = if allow_break
then break_cons else space_cons in
178 let result = concat a b
in
181 (* no group here, since all breaks are compulsory. Will group on top level *)
182 List.fold_left
fold_fun (nil
, false) (List.map
handle_trivia trivia_lst
)
185 let front_trivias = EditableToken.leading x
in
186 let end_trivias = EditableToken.trailing x
in
187 let (front_doc
, front_single
) = get_doc_from_trivia front_trivias true in
188 let (end_doc
, end_single
) = get_doc_from_trivia end_trivias false in
189 let doc = text
(EditableToken.text x
) in
190 (front_doc
, front_single
, doc, end_doc
, end_single
)
192 (* create a 5-tuple (see top of file) from x with no trivias *)
193 let make_simple x
= (nil
, false, x
, nil
, false)
195 let missing = make_simple nil
196 let error_header = make_simple (text
"Error:")
197 let space = make_simple (text
" ")
198 let colon = make_simple (text
":")
199 let comma = make_simple (text
",")
200 let l_square = make_simple (text
"[")
201 let r_square = make_simple (text
"]")
202 let question = make_simple (text
"?")
203 let ellipsis = make_simple (text
"...")
205 let rec get_doc node
=
206 match syntax node
with
208 | Token x
-> from_token x
210 | SyntaxList x
-> get_from_children x
211 | ErrorSyntax
{ error_error
} -> get_doc error_error
212 | LiteralExpression x
->
214 match syntax x
.literal_expression
with
215 | SyntaxList l
-> get_from_children_no_space l
216 | _
-> get_doc x
.literal_expression
218 | VariableExpression x
-> get_doc x
.variable_expression
219 | QualifiedNameExpression x
-> get_doc x
.qualified_name_expression
220 | PipeVariableExpression x
-> get_doc x
.pipe_variable_expression
221 | ListItem x
-> (get_doc x
.list_item
) ^^^
(get_doc x
.list_separator
)
222 | EndOfFile
{ end_of_file_token
} -> get_doc end_of_file_token
223 | ScriptHeader x
-> get_doc x
.header_less_than ^^^
224 get_doc x
.header_question ^^^
225 (x
.header_language
|> get_doc |> add_break)
226 | Script x
-> group_doc ( get_doc x
.script_header
227 ^
| get_doc x
.script_declarations
)
228 | ClassishDeclaration
229 { classish_attribute
; classish_modifiers
; classish_keyword
;
230 classish_name
; classish_type_parameters
; classish_extends_keyword
;
231 classish_extends_list
; classish_implements_keyword
;
232 classish_implements_list
; classish_body
} ->
233 let attr = add_break (get_doc classish_attribute
) in
234 let preface = group_doc (
235 get_doc classish_modifiers ^
|
236 get_doc classish_keyword
239 let name_and_generics =
240 let name = get_doc classish_name
in
241 let type_params = get_doc classish_type_parameters
in
242 group_doc (indent_doc name type_params indt)
246 let extends_token = get_doc classish_extends_keyword
in
247 let extends_list = get_doc classish_extends_list
in
248 group_doc (indent_doc extends_token extends_list indt)
252 let implements_token = get_doc classish_implements_keyword
in
253 let implements_list = get_doc classish_implements_list
in
254 group_doc (indent_doc implements_token implements_list indt)
257 let body = get_doc classish_body
in
259 (* TODO: Make this better *)
273 let left = get_doc x
.classish_body_left_brace
in
274 let right = get_doc x
.classish_body_right_brace
in
275 let body = get_doc x
.classish_body_elements
in
276 indent_block_no_space left body right indt
277 | XHPRequired
{ xhp_required_at
; xhp_required_keyword
} ->
278 let a = get_doc xhp_required_at
in
279 let r = get_doc xhp_required_keyword
in
281 | XHPChildrenDeclaration
{
282 xhp_children_keyword
;
283 xhp_children_expression
;
284 xhp_children_semicolon
} ->
285 let c = get_doc xhp_children_keyword
in
286 let e = get_doc xhp_children_expression
in
287 let s = get_doc xhp_children_semicolon
in
289 | XHPChildrenParenthesizedList
{
290 xhp_children_list_left_paren
;
291 xhp_children_list_xhp_children
;
292 xhp_children_list_right_paren
} ->
293 let l = get_doc xhp_children_list_left_paren
in
294 let c = get_doc xhp_children_list_xhp_children
in
295 let r = get_doc xhp_children_list_right_paren
in
297 | XHPCategoryDeclaration
{
298 xhp_category_keyword
;
299 xhp_category_categories
;
300 xhp_category_semicolon
} ->
301 let c = get_doc xhp_category_keyword
in
302 let l = get_doc xhp_category_categories
in
303 let s = get_doc xhp_category_semicolon
in
306 let e = get_doc x
.xhp_enum_keyword
in
307 let l = get_doc x
.xhp_enum_left_brace
in
308 let v = get_doc x
.xhp_enum_values
in
309 let r = get_doc x
.xhp_enum_right_brace
in
310 group_doc (e ^
| l ^
| v ^
| r)
311 | XHPClassAttributeDeclaration
{
312 xhp_attribute_keyword
;
313 xhp_attribute_attributes
;
314 xhp_attribute_semicolon
} ->
315 let attr = get_doc xhp_attribute_keyword
in
316 let attrs = get_doc xhp_attribute_attributes
in
317 let semi = get_doc xhp_attribute_semicolon
in
318 group_doc (attr ^
| attrs ^^^
semi)
320 { xhp_attribute_decl_type
; xhp_attribute_decl_name
;
321 xhp_attribute_decl_initializer
; xhp_attribute_decl_required
} ->
322 let t = get_doc xhp_attribute_decl_type
in
323 let n = get_doc xhp_attribute_decl_name
in
324 let i = get_doc xhp_attribute_decl_initializer
in
325 let r = get_doc xhp_attribute_decl_required
in
326 group_doc (t ^
| n ^
| i ^
| r)
327 | XHPSimpleClassAttribute
{ xhp_simple_class_attribute_type
} ->
328 get_doc xhp_simple_class_attribute_type
332 trait_use_semicolon
} ->
333 let use = get_doc trait_use_keyword
in
334 let name_list = get_doc trait_use_names
in
335 let semi = get_doc trait_use_semicolon
in
336 use ^
| name_list ^^^
semi
338 let r = get_doc x
.require_keyword
in
339 let k = get_doc x
.require_kind
in
340 let n = get_doc x
.require_name
in
341 let s = get_doc x
.require_semicolon
in
346 const_type_specifier
;
349 let abstr = get_doc const_abstract
in
350 let token = get_doc const_keyword
in
351 let ty = get_doc const_type_specifier
in
352 let lst = get_doc const_declarators
in
353 let semi = get_doc const_semicolon
in
354 group_doc (abstr ^
| token ^
| ty ) ^
| lst ^^^
semi
355 | ConstantDeclarator x
->
356 let name = get_doc x
.constant_declarator_name
in
357 let init = get_doc x
.constant_declarator_initializer
in
358 group_doc (name ^
| init)
359 | TypeConstDeclaration x
->
360 let abstr = get_doc x
.type_const_abstract
in
361 let const = get_doc x
.type_const_keyword
in
362 let type_ = get_doc x
.type_const_type_keyword
in
363 let name = get_doc x
.type_const_name
in
364 let type_constraint = get_doc x
.type_const_type_constraint
in
365 let equal = get_doc x
.type_const_equal
in
366 let type_spec = get_doc x
.type_const_type_specifier
in
367 let semicolon = get_doc x
.type_const_semicolon
in
369 group_doc (abstr ^
| const ^
| type_ ^
| name) ^
|
372 group_doc (type_spec ^^^
semicolon)
383 enum_right_brace
} ->
384 let attrs = get_doc enum_attribute_spec
in
385 let en = get_doc enum_keyword
in
386 let na = get_doc enum_name
in
387 let co = get_doc enum_colon
in
388 let ba = get_doc enum_base
in
389 let ty = get_doc enum_type
in
390 let lb = get_doc enum_left_brace
in
391 let es = get_doc enum_enumerators
in
392 let rb = get_doc enum_right_brace
in
393 (* TODO: This could be a lot better. Add indentation, etc. *)
394 attrs ^
| en ^
| na ^
| co ^
| ba ^
| ty ^
| lb ^
| es ^
| rb
396 let n = get_doc x
.enumerator_name
in
397 let e = get_doc x
.enumerator_equal
in
398 let v = get_doc x
.enumerator_value
in
399 let semicolon = get_doc x
.enumerator_semicolon
in
400 n ^
| e ^
| v ^^^
semicolon
401 | AliasDeclaration x
->
402 (* TODO: What's the best way to ensure that there's a newline between the
403 attribute and the alias declaration proper? *)
404 let attr = get_doc x
.alias_attribute_spec
in
405 let a = get_doc x
.alias_keyword
in
406 let n = get_doc x
.alias_name
in
407 let generic = get_doc x
.alias_generic_parameter
in
408 let c = get_doc x
.alias_constraint
in
409 let e = get_doc x
.alias_equal
in
410 let t = get_doc x
.alias_type
in
411 let s = get_doc x
.alias_semicolon
in
412 attr ^
| a ^
| n ^
| generic ^
| c ^
| e ^
| t ^^^
s
413 | PropertyDeclaration
414 { property_modifiers
; property_type
;
415 property_declarators
; property_semicolon
} ->
416 let m = get_doc property_modifiers
in
417 let t = get_doc property_type
in
418 let d = get_doc property_declarators
in
419 let s = get_doc property_semicolon
in
421 | PropertyDeclarator
{ property_name
; property_initializer
} ->
422 let n = get_doc property_name
in
423 let i = get_doc property_initializer
in
425 | NamespaceDeclaration x
->
426 let t = get_doc x
.namespace_keyword
in
427 let n = get_doc x
.namespace_name
in
428 let b = get_doc x
.namespace_body
in
431 let left = get_doc x
.namespace_left_brace
in
432 let body = get_doc x
.namespace_declarations
in
433 let right = get_doc x
.namespace_right_brace
in
434 indent_block_no_space left body right indt |> add_break
435 | NamespaceUseDeclaration x
->
436 let u = get_doc x
.namespace_use_keyword
in
437 let k = get_doc x
.namespace_use_kind
in
438 let c = get_doc x
.namespace_use_clauses
in
439 let s = get_doc x
.namespace_use_semicolon
in
441 | NamespaceUseClause x
->
442 let k = get_doc x
.namespace_use_clause_kind
in
443 let n = get_doc x
.namespace_use_name
in
444 let a = get_doc x
.namespace_use_as
in
445 let l = get_doc x
.namespace_use_alias
in
447 | NamespaceGroupUseDeclaration x
->
448 let u = get_doc x
.namespace_group_use_keyword
in
449 let k = get_doc x
.namespace_group_use_kind
in
450 let p = get_doc x
.namespace_group_use_prefix
in
451 let l = get_doc x
.namespace_group_use_left_brace
in
452 let c = get_doc x
.namespace_group_use_clauses
in
453 let r = get_doc x
.namespace_group_use_right_brace
in
454 let s = get_doc x
.namespace_group_use_semicolon
in
455 u ^
| k ^
| p ^
| l ^
| c ^
| r ^^^
s
456 | FunctionDeclaration x
->
457 let attr = get_doc x
.function_attribute_spec
in
458 let header = get_doc x
.function_declaration_header
in
459 let body = x
.function_body
in
460 let after_attr = handle_compound_inline_brace
header body missing in
461 group_doc (attr ^
| after_attr)
462 | FunctionDeclarationHeader
468 function_type_parameter_list
;
470 function_parameter_list
;
471 function_right_paren
;
474 function_where_clause
}
476 let preface = group_doc (
477 get_doc function_async
478 ^
| get_doc function_coroutine
479 ^
| get_doc function_keyword
481 let name_and_generics =
482 let type_params = get_doc function_type_parameter_list
in
483 let ampersand = get_doc function_ampersand
in
484 let name = get_doc function_name
in
485 group_doc (indent_doc (ampersand ^^^
name) type_params indt)
488 let left = get_doc function_left_paren
in
489 let right = get_doc function_right_paren
in
490 let params = get_doc function_parameter_list
in
491 indent_block_no_space left params right indt
493 let type_declaration =
494 let fun_colon = get_doc function_colon
in
495 let fun_type = get_doc function_type
in
496 let where_clause = get_doc function_where_clause
in
497 group_doc (fun_colon ^
| fun_type ^
| where_clause)
500 group_doc ( group_doc (preface ^
| name_and_generics) ^^
| parameters )
503 | WhereClause
{ where_clause_keyword
; where_clause_constraints
} ->
504 let w = get_doc where_clause_keyword
in
505 let c = get_doc where_clause_constraints
in
507 | WhereConstraint
{ where_constraint_left_type
; where_constraint_operator
;
508 where_constraint_right_type
} ->
509 let l = get_doc where_constraint_left_type
in
510 let o = get_doc where_constraint_operator
in
511 let r = get_doc where_constraint_right_type
in
513 | MethodishDeclaration
514 { methodish_attribute
; methodish_modifiers
; methodish_function_decl_header
;
515 methodish_function_body
; methodish_semicolon
} ->
516 let methodish_attr = get_doc methodish_attribute
in
517 let methodish_modifiers = get_doc methodish_modifiers in
518 let function_header = get_doc methodish_function_decl_header
in
519 let body_node = methodish_function_body
in
520 let semicolon = get_doc methodish_semicolon
in
521 let before_body = group_doc (methodish_modifiers ^
| function_header) in
523 handle_compound_inline_brace
before_body body_node missing in
524 let after_attr = after_attr ^^^
semicolon in
525 group_doc (methodish_attr ^
| after_attr)
526 | DecoratedExpression x
->
527 let decorator = get_doc x
.decorated_expression_decorator
in
528 let expression = get_doc x
.decorated_expression_expression
in
529 group_doc (decorator ^^^
expression)
530 | ParameterDeclaration
{
532 parameter_visibility
;
535 parameter_default_value
} ->
536 let attr = get_doc parameter_attribute
in
537 let visibility = get_doc parameter_visibility
in
538 let parameter_type = get_doc parameter_type in
539 let parameter_name = get_doc parameter_name in
540 let parameter_default = get_doc parameter_default_value
in
542 ( attr ^
| visibility ^
| parameter_type ^
| parameter_name
543 ^
| parameter_default )
544 | VariadicParameter
{ variadic_parameter_ellipsis
} ->
545 get_doc variadic_parameter_ellipsis
546 | AttributeSpecification
{
547 attribute_specification_left_double_angle
;
548 attribute_specification_attributes
;
549 attribute_specification_right_double_angle
} ->
550 let left = get_doc attribute_specification_left_double_angle
in
551 let specs = get_doc attribute_specification_attributes
in
552 let right = get_doc attribute_specification_right_double_angle
in
553 indent_block_no_space left specs right indt
555 let name = get_doc x
.attribute_name
in
556 let left = get_doc x
.attribute_left_paren
in
557 let right = get_doc x
.attribute_right_paren
in
558 let values = get_doc x
.attribute_values
in
559 let left_part = group_doc (name ^^
| left) in
560 indent_block_no_space left_part values right indt
561 | InclusionExpression x
->
562 let rq = get_doc x
.inclusion_require
in
563 let fn = get_doc x
.inclusion_filename
in
565 | InclusionDirective x
->
566 let ex = get_doc x
.inclusion_expression
in
567 let se = get_doc x
.inclusion_semicolon
in
569 | CompoundStatement x
->
570 let left = get_doc x
.compound_left_brace
in
571 let right = get_doc x
.compound_right_brace
in
572 let body = get_doc x
.compound_statements
in
573 indent_block_no_space left body right indt |> add_break
574 | ExpressionStatement
{
575 expression_statement_expression
;
576 expression_statement_semicolon
} ->
577 let body = get_doc expression_statement_expression
in
578 let semicolon = get_doc expression_statement_semicolon
in
579 (* semicolon always follows the last line *)
580 body ^^^
semicolon |> group_doc |> add_break
587 let u = get_doc unset_keyword
in
588 let l = get_doc unset_left_paren
in
589 let v = get_doc unset_variables
in
590 let r = get_doc unset_right_paren
in
591 let s = get_doc unset_semicolon
in
592 group_doc (u ^^^
l ^^^
v ^^^
r ^^^
s)
594 { while_keyword
; while_left_paren
; while_condition
; while_right_paren
;
596 let keyword = get_doc while_keyword
in
597 let left = get_doc while_left_paren
in
598 let condition = get_doc while_condition
in
599 let right = get_doc while_right_paren
in
600 let left_part = group_doc (keyword ^^
| left) in
601 let start_block = indent_block_no_space left_part condition right indt in
602 handle_compound_brace_prefix_indent
start_block while_body
indt
605 { if_keyword
; if_left_paren
; if_condition
; if_right_paren
; if_statement
;
606 if_elseif_clauses
; if_else_clause
}->
607 let keyword = get_doc if_keyword
in
608 let left = get_doc if_left_paren
in
609 let condition = get_doc if_condition
in
610 let right = get_doc if_right_paren
in
611 let if_stmt = if_statement
in
612 let elseif_clause = get_doc if_elseif_clauses
in
613 let else_clause = get_doc if_else_clause
in
614 let left_part = group_doc (keyword ^^
| left) in
615 let start_block = indent_block_no_space left_part condition right indt in
617 handle_compound_brace_prefix_indent
start_block if_stmt indt in
618 let if_statement = add_break if_statement in
619 group_doc (if_statement ^
| elseif_clause ^
| else_clause)
621 { elseif_keyword
; elseif_left_paren
; elseif_condition
; elseif_right_paren
;
622 elseif_statement
} ->
623 let keyword = get_doc elseif_keyword
in
624 let left = get_doc elseif_left_paren
in
625 let condition = get_doc elseif_condition
in
626 let right = get_doc elseif_right_paren
in
627 let elif_statement_syntax = elseif_statement
in
628 let left_part = group_doc (keyword ^^
| left) in
629 let start_block = indent_block_no_space left_part condition right indt in
630 handle_compound_brace_prefix_indent
start_block elif_statement_syntax indt
633 let keyword = get_doc x
.else_keyword
in
634 let statement = x
.else_statement
in
635 handle_compound_brace_prefix_indent
keyword statement indt
639 try_compound_statement
;
641 try_finally_clause
} ->
642 let keyword = get_doc try_keyword
in
643 let compound_stmt = try_compound_statement
in
645 handle_compound_brace_prefix_indent
keyword compound_stmt indt in
646 let catch_clauses = get_doc try_catch_clauses
in
647 let finally_clause = get_doc try_finally_clause
in
648 group_doc (try_part ^
| catch_clauses ^
| finally_clause)
657 let keyword = get_doc catch_keyword
in
658 let left = get_doc catch_left_paren
in
659 let ty = get_doc catch_type
in
660 let var = get_doc catch_variable
in
661 let param = ty ^
| var in
662 let right = get_doc catch_right_paren
in
663 let stmt = catch_body
in
664 let front_part = group_doc (keyword ^
| left) in
665 let before_stmt = indent_block_no_space front_part param right indt in
666 handle_compound_brace_prefix_indent
before_stmt stmt indt
671 let keyword = get_doc finally_keyword
in
672 handle_compound_brace_prefix_indent
keyword finally_body
indt
682 let keyword = get_doc do_keyword
in
683 let statement = do_body
in
684 let while_keyword = get_doc do_while_keyword
in
685 let left = get_doc do_left_paren
in
686 let right = get_doc do_right_paren
in
687 let condition = get_doc do_condition
in
688 let semicolon = get_doc do_semicolon
in
690 handle_compound_brace_prefix_indent
keyword statement indt |> add_break in
691 let left_part = group_doc (while_keyword ^^
| left) in
692 let condition_part = indent_block_no_space left_part condition right indt in
693 group_doc (statement_part ^
| condition_part) ^^^
semicolon
700 for_second_semicolon
;
704 let keyword = get_doc for_keyword
in
705 let left_paren = get_doc for_left_paren
in
706 let initializer_expr = get_doc for_initializer
in
707 let first_semicolon = get_doc for_first_semicolon
in
708 let control_expr = get_doc for_control
in
709 let second_semicolon = get_doc for_second_semicolon
in
710 let end_of_loop_expr = get_doc for_end_of_loop
in
711 let right_paren = get_doc for_right_paren
in
712 let statement = for_body
in
713 let left_part = group_doc (keyword ^^
| left_paren) in
714 let for_expressions =
715 control_expr ^^^
second_semicolon ^
| end_of_loop_expr in
716 let for_expressions = if is_missing for_control
717 then first_semicolon ^^
| for_expressions
718 else first_semicolon ^
| for_expressions in
719 let for_expressions = group_doc (initializer_expr ^^^
for_expressions) in
721 indent_block_no_space left_part for_expressions right_paren indt in
722 handle_compound_brace_prefix_indent
start_block statement indt |> add_break
727 foreach_await_keyword
;
734 let keyword = get_doc foreach_keyword
in
735 let left = get_doc foreach_left_paren
in
736 let right = get_doc foreach_right_paren
in
737 let collection_name = get_doc foreach_collection
in
738 let await_keyword = get_doc foreach_await_keyword
in
739 let as_keyword = get_doc foreach_as
in
740 let key = get_doc foreach_key
in
741 let arrow = get_doc foreach_arrow
in
742 let value = get_doc foreach_value
in
743 let statement = foreach_body
in
744 let left_part = group_doc (keyword ^
| left) in
745 let arrow_part = group_doc (group_doc (key ^
| arrow) ^
| value) in
746 let as_part = group_doc (await_keyword ^
| as_keyword) in
747 let as_part = group_doc (collection_name ^
| as_part) in
748 let middle_part = group_doc (as_part ^
| arrow_part) in
749 let start_block = indent_block_no_space left_part middle_part right indt in
750 handle_compound_brace_prefix_indent
start_block statement indt |> add_break
758 switch_right_brace
} ->
759 let keyword = get_doc switch_keyword
in
760 let lparen= get_doc switch_left_paren
in
761 let expr = get_doc switch_expression
in
762 let rparen = get_doc switch_right_paren
in
763 let lbrace = get_doc switch_left_brace
in
764 let sections = get_doc switch_sections
in
765 let rbrace = get_doc switch_right_brace
in
767 let h = keyword ^
| lparen ^
| expr ^
| rparen ^
| space ^
| lbrace in
768 let h = add_break h in
769 h ^
| sections ^
| rbrace
771 switch_section_labels
;
772 switch_section_statements
;
773 switch_section_fallthrough
} ->
775 let labels = get_doc switch_section_labels
in
776 let statements = get_doc switch_section_statements
in
777 let fallthrough = get_doc switch_section_fallthrough
in
778 (add_break labels) ^
| (add_break statements) ^
| (add_break fallthrough)
779 | SwitchFallthrough
{
781 fallthrough_semicolon
783 let f = get_doc fallthrough_keyword
in
784 let s = get_doc fallthrough_semicolon
in
786 | ScopeResolutionExpression x
->
787 let q = get_doc x
.scope_resolution_qualifier
in
788 let o = get_doc x
.scope_resolution_operator
in
789 let n = get_doc x
.scope_resolution_name
in
790 group_doc (q ^^^
o ^^^
n)
791 | MemberSelectionExpression
792 { member_object
; member_operator
; member_name
} ->
793 let ob = get_doc member_object
in
794 let op = get_doc member_operator
in
795 let nm = get_doc member_name
in
796 group_doc (ob ^^^
op ^^^
nm)
797 | SafeMemberSelectionExpression
798 { safe_member_object
; safe_member_operator
; safe_member_name
} ->
799 let ob = get_doc safe_member_object
in
800 let op = get_doc safe_member_operator
in
801 let nm = get_doc safe_member_name
in
802 group_doc (ob ^^^
op ^^^
nm)
803 | EmbeddedMemberSelectionExpression
804 { embedded_member_object
;
805 embedded_member_operator
;
806 embedded_member_name
} ->
807 let ob = get_doc embedded_member_object
in
808 let op = get_doc embedded_member_operator
in
809 let nm = get_doc embedded_member_name
in
810 group_doc (ob ^^^
op ^^^
nm)
811 | YieldExpression x
->
812 let y = get_doc x
.yield_keyword
in
813 let o = get_doc x
.yield_operand
in
817 print_expression
} ->
818 let t = get_doc print_keyword
in
819 let e = get_doc print_expression
in
821 | CastExpression x
->
822 let l = get_doc x
.cast_left_paren
in
823 let t = get_doc x
.cast_type
in
824 let r = get_doc x
.cast_right_paren
in
825 let o = get_doc x
.cast_operand
in
826 group_doc (l ^^^
t ^^^
r ^^^
o)
834 let async = get_doc lambda_async
in
835 let coroutine = get_doc lambda_coroutine
in
836 let signature = get_doc lambda_signature
in
837 let arrow = get_doc lambda_arrow
in
838 let body = get_doc lambda_body
in
839 group_doc (async ^
| coroutine ^
| signature ^
| arrow ^
| body)
841 { lambda_left_paren
; lambda_parameters
; lambda_right_paren
;
842 lambda_colon
; lambda_type
} ->
843 let left = get_doc lambda_left_paren
in
844 let params = get_doc lambda_parameters
in
845 let right = get_doc lambda_right_paren
in
846 let colon = get_doc lambda_colon
in
847 let ty = get_doc lambda_type
in
848 group_doc (left ^
| params ^
| right ^
| colon ^
| ty)
850 { anonymous_async_keyword
;
851 anonymous_coroutine_keyword
;
852 anonymous_function_keyword
;
853 anonymous_left_paren
;
854 anonymous_parameters
;
855 anonymous_right_paren
;
860 let async = get_doc anonymous_async_keyword
in
861 let coroutine = get_doc anonymous_coroutine_keyword
in
862 let fn = get_doc anonymous_function_keyword
in
863 let left = get_doc anonymous_left_paren
in
864 let params = get_doc anonymous_parameters
in
865 let right = get_doc anonymous_right_paren
in
866 let colon = get_doc anonymous_colon
in
867 let return_type = get_doc anonymous_type
in
868 let preface = group_doc ( async ^
| coroutine ^
| fn ) in
869 let parameters = indent_block_no_space left params right indt in
870 let type_declaration = group_doc (colon ^
| return_type) in
871 let uses = get_doc anonymous_use
in
872 let body = anonymous_body
in
875 group_doc ( group_doc preface ^^
| parameters )
876 ^
| type_declaration ^
| uses
878 handle_compound_inline_brace
before_body body missing
879 | AnonymousFunctionUseClause x
->
880 let u = get_doc x
.anonymous_use_keyword
in
881 let l = get_doc x
.anonymous_use_left_paren
in
882 let v = get_doc x
.anonymous_use_variables
in
883 let r = get_doc x
.anonymous_use_right_paren
in
885 | PrefixUnaryExpression
886 { prefix_unary_operator
; prefix_unary_operand
} ->
887 if is_separable_prefix prefix_unary_operator
then
888 get_doc prefix_unary_operator ^
| get_doc prefix_unary_operand
890 get_doc prefix_unary_operator ^^^
get_doc prefix_unary_operand
891 | PostfixUnaryExpression
892 { postfix_unary_operand
; postfix_unary_operator
} ->
893 get_doc postfix_unary_operand ^^^
get_doc postfix_unary_operator
894 | BinaryExpression x
->
895 let left = get_doc x
.binary_left_operand
in
896 let op = get_doc x
.binary_operator
in
897 let right = get_doc x
.binary_right_operand
in
898 group_doc (left ^
| op ^
| right)
899 | InstanceofExpression x
->
900 let left = get_doc x
.instanceof_left_operand
in
901 let op = get_doc x
.instanceof_operator
in
902 let right = get_doc x
.instanceof_right_operand
in
903 group_doc (left ^
| op ^
| right)
904 | ConditionalExpression x
->
905 let tst = get_doc x
.conditional_test
in
906 let qm = get_doc x
.conditional_question
in
907 let con = get_doc x
.conditional_consequence
in
908 let col = get_doc x
.conditional_colon
in
909 let alt = get_doc x
.conditional_alternative
in
910 (* TODO: Could this be improved? *)
911 group_doc ( tst ^
| qm ^
| con ^
| col ^
| alt )
912 | FunctionCallExpression
{
913 function_call_receiver
;
914 function_call_left_paren
;
915 function_call_argument_list
;
916 function_call_right_paren
} ->
917 let receiver = get_doc function_call_receiver
in
918 let lparen = get_doc function_call_left_paren
in
919 let args = get_doc function_call_argument_list
in
920 let rparen = get_doc function_call_right_paren
in
921 receiver ^^^
lparen ^^^
args ^^^
rparen
926 eval_right_paren
} ->
927 let keyword = get_doc eval_keyword
in
928 let lparen = get_doc eval_left_paren
in
929 let arg = get_doc eval_argument
in
930 let rparen = get_doc eval_right_paren
in
931 keyword ^^^
lparen ^^^
arg ^^^
rparen
936 empty_right_paren
} ->
937 let keyword = get_doc empty_keyword
in
938 let lparen = get_doc empty_left_paren
in
939 let arg = get_doc empty_argument
in
940 let rparen = get_doc empty_right_paren
in
941 keyword ^^^
lparen ^^^
arg ^^^
rparen
946 isset_right_paren
} ->
947 let keyword = get_doc isset_keyword
in
948 let lparen = get_doc isset_left_paren
in
949 let args = get_doc isset_argument_list
in
950 let rparen = get_doc isset_right_paren
in
951 keyword ^^^
lparen ^^^
args ^^^
rparen
955 define_argument_list
;
956 define_right_paren
} ->
957 let keyword = get_doc define_keyword
in
958 let lparen = get_doc define_left_paren
in
959 let args = get_doc define_argument_list
in
960 let rparen = get_doc define_right_paren
in
961 keyword ^^^
lparen ^^^
args ^^^
rparen
962 | ParenthesizedExpression
{
963 parenthesized_expression_left_paren
;
964 parenthesized_expression_expression
;
965 parenthesized_expression_right_paren
} ->
966 let left = get_doc parenthesized_expression_left_paren
in
967 let expr = get_doc parenthesized_expression_expression
in
968 let right = get_doc parenthesized_expression_right_paren
in
969 indent_block_no_space left expr right indt
971 braced_expression_left_brace
;
972 braced_expression_expression
;
973 braced_expression_right_brace
} ->
974 let left = get_doc braced_expression_left_brace
in
975 let expr = get_doc braced_expression_expression
in
976 let right = get_doc braced_expression_right_brace
in
977 indent_block_no_space left expr right indt
978 | EmbeddedBracedExpression
{
979 embedded_braced_expression_left_brace
;
980 embedded_braced_expression_expression
;
981 embedded_braced_expression_right_brace
} ->
982 let left = get_doc embedded_braced_expression_left_brace
in
983 let expr = get_doc embedded_braced_expression_expression
in
984 let right = get_doc embedded_braced_expression_right_brace
in
985 indent_block_no_space left expr right indt
987 { list_keyword
; list_left_paren
; list_members
; list_right_paren
} ->
988 let keyword = get_doc list_keyword
in
989 let left_paren = get_doc list_left_paren
in
990 let members = get_doc list_members
in
991 let right_paren = get_doc list_right_paren
in
992 let left = group_doc (keyword ^
| left_paren) in
993 indent_block_no_space left members right_paren indt
994 | CollectionLiteralExpression x
->
995 let token = get_doc x
.collection_literal_name
in
996 let left_brace = get_doc x
.collection_literal_left_brace
in
997 let expression_list = get_doc x
.collection_literal_initializers
in
998 let right_brace = get_doc x
.collection_literal_right_brace
in
999 token ^
| left_brace ^
| expression_list ^
| right_brace
1000 | ObjectCreationExpression
1001 { object_creation_new_keyword
;
1002 object_creation_type
;
1003 object_creation_left_paren
;
1004 object_creation_argument_list
;
1005 object_creation_right_paren
} ->
1006 let n = get_doc object_creation_new_keyword
in
1007 let c = get_doc object_creation_type
in
1008 let l = get_doc object_creation_left_paren
in
1009 let a = get_doc object_creation_argument_list
in
1010 let r = get_doc object_creation_right_paren
in
1011 n ^
| c ^^^
l ^^^
a ^^^
r
1013 { field_initializer_name
; field_initializer_arrow
;
1014 field_initializer_value
}->
1015 let n = get_doc field_initializer_name
in
1016 let a = get_doc field_initializer_arrow
in
1017 let v = get_doc field_initializer_value
in
1020 { shape_expression_keyword
; shape_expression_left_paren
;
1021 shape_expression_fields
; shape_expression_right_paren
} ->
1022 let sh = get_doc shape_expression_keyword
in
1023 let lp = get_doc shape_expression_left_paren
in
1024 let fs = get_doc shape_expression_fields
in
1025 let rp = get_doc shape_expression_right_paren
in
1026 sh ^
| lp ^^^
fs ^^^
rp
1028 { tuple_expression_keyword
; tuple_expression_left_paren
;
1029 tuple_expression_items
; tuple_expression_right_paren
} ->
1030 let tu = get_doc tuple_expression_keyword
in
1031 let lp = get_doc tuple_expression_left_paren
in
1032 let xs = get_doc tuple_expression_items
in
1033 let rp = get_doc tuple_expression_right_paren
in
1034 tu ^
| lp ^^^
xs ^^^
rp
1035 | ArrayCreationExpression x
->
1036 let left_bracket = get_doc x
.array_creation_left_bracket
in
1037 let right_bracket = get_doc x
.array_creation_right_bracket
in
1038 let members = get_doc x
.array_creation_members
in
1039 indent_block_no_space left_bracket members right_bracket indt
1040 | ArrayIntrinsicExpression
{
1041 array_intrinsic_keyword
;
1042 array_intrinsic_left_paren
;
1043 array_intrinsic_members
;
1044 array_intrinsic_right_paren
} ->
1045 let keyword = get_doc array_intrinsic_keyword
in
1046 let left = get_doc array_intrinsic_left_paren
in
1047 let members = get_doc array_intrinsic_members
in
1048 let right = get_doc array_intrinsic_right_paren
in
1049 let left_part = group_doc (keyword ^^
| left) in
1050 indent_block_no_space left_part members right indt
1051 | DarrayIntrinsicExpression
{
1052 darray_intrinsic_keyword
;
1053 darray_intrinsic_left_bracket
;
1054 darray_intrinsic_members
;
1055 darray_intrinsic_right_bracket
} ->
1056 let keyword = get_doc darray_intrinsic_keyword
in
1057 let left = get_doc darray_intrinsic_left_bracket
in
1058 let members = get_doc darray_intrinsic_members
in
1059 let right = get_doc darray_intrinsic_right_bracket
in
1060 let left_part = group_doc (keyword ^^
| left) in
1061 indent_block_no_space left_part members right indt
1062 | DictionaryIntrinsicExpression
{
1063 dictionary_intrinsic_keyword
;
1064 dictionary_intrinsic_left_bracket
;
1065 dictionary_intrinsic_members
;
1066 dictionary_intrinsic_right_bracket
} ->
1067 let keyword = get_doc dictionary_intrinsic_keyword
in
1068 let left = get_doc dictionary_intrinsic_left_bracket
in
1069 let members = get_doc dictionary_intrinsic_members
in
1070 let right = get_doc dictionary_intrinsic_right_bracket
in
1071 let left_part = group_doc (keyword ^^
| left) in
1072 indent_block_no_space left_part members right indt
1073 | KeysetIntrinsicExpression
{
1074 keyset_intrinsic_keyword
;
1075 keyset_intrinsic_left_bracket
;
1076 keyset_intrinsic_members
;
1077 keyset_intrinsic_right_bracket
} ->
1078 let keyword = get_doc keyset_intrinsic_keyword
in
1079 let left = get_doc keyset_intrinsic_left_bracket
in
1080 let members = get_doc keyset_intrinsic_members
in
1081 let right = get_doc keyset_intrinsic_right_bracket
in
1082 let left_part = group_doc (keyword ^^
| left) in
1083 indent_block_no_space left_part members right indt
1084 | VarrayIntrinsicExpression
{
1085 varray_intrinsic_keyword
;
1086 varray_intrinsic_left_bracket
;
1087 varray_intrinsic_members
;
1088 varray_intrinsic_right_bracket
} ->
1089 let keyword = get_doc varray_intrinsic_keyword
in
1090 let left = get_doc varray_intrinsic_left_bracket
in
1091 let members = get_doc varray_intrinsic_members
in
1092 let right = get_doc varray_intrinsic_right_bracket
in
1093 let left_part = group_doc (keyword ^^
| left) in
1094 indent_block_no_space left_part members right indt
1095 | VectorIntrinsicExpression
{
1096 vector_intrinsic_keyword
;
1097 vector_intrinsic_left_bracket
;
1098 vector_intrinsic_members
;
1099 vector_intrinsic_right_bracket
} ->
1100 let keyword = get_doc vector_intrinsic_keyword
in
1101 let left = get_doc vector_intrinsic_left_bracket
in
1102 let members = get_doc vector_intrinsic_members
in
1103 let right = get_doc vector_intrinsic_right_bracket
in
1104 let left_part = group_doc (keyword ^^
| left) in
1105 indent_block_no_space left_part members right indt
1106 | ElementInitializer x
->
1107 let k = get_doc x
.element_key
in
1108 let a = get_doc x
.element_arrow
in
1109 let v = get_doc x
.element_value
in
1111 | SubscriptExpression x
->
1112 let receiver = get_doc x
.subscript_receiver
in
1113 let left = get_doc x
.subscript_left_bracket
in
1114 let index = get_doc x
.subscript_index
in
1115 let right = get_doc x
.subscript_right_bracket
in
1116 receiver ^^^
left ^^^
index ^^^
right
1117 | EmbeddedSubscriptExpression x
->
1118 let receiver = get_doc x
.embedded_subscript_receiver
in
1119 let left = get_doc x
.embedded_subscript_left_bracket
in
1120 let index = get_doc x
.embedded_subscript_index
in
1121 let right = get_doc x
.embedded_subscript_right_bracket
in
1122 receiver ^^^
left ^^^
index ^^^
right
1123 | AwaitableCreationExpression x
->
1124 let async = get_doc x
.awaitable_async
in
1125 let coroutine = get_doc x
.awaitable_coroutine
in
1126 let stmt = x
.awaitable_compound_statement
in
1127 handle_compound_brace_prefix_indent
(async ^
| coroutine) stmt indt
1128 | XHPExpression x
->
1129 let left = get_doc x
.xhp_open
in
1130 let expr = get_doc x
.xhp_body
in
1131 let right = get_doc x
.xhp_close
in
1132 left ^^^
expr ^^^
right
1134 xhp_open_left_angle
;
1136 xhp_open_attributes
;
1137 xhp_open_right_angle
} ->
1138 let left = get_doc xhp_open_left_angle
in
1139 let name = get_doc xhp_open_name
in
1140 let attrs = get_doc xhp_open_attributes
in
1141 let right = get_doc xhp_open_right_angle
in
1142 group_doc (group_doc (indent_doc (left ^^^
name) attrs indt) ^
| right)
1144 { xhp_attribute_name
; xhp_attribute_equal
; xhp_attribute_expression
}->
1145 let name = get_doc xhp_attribute_name
in
1146 let equals = get_doc xhp_attribute_equal
in
1147 let expr = get_doc xhp_attribute_expression
in
1148 group_doc (group_doc (name ^^
| equals) ^^
| expr)
1150 let left = get_doc x
.xhp_close_left_angle
in
1151 let name = get_doc x
.xhp_close_name
in
1152 let right = get_doc x
.xhp_close_right_angle
in
1153 left ^^^
name ^^^
right
1155 let left = get_doc x
.type_constant_left_type
in
1156 let right = get_doc x
.type_constant_right_type
in
1157 let separator = get_doc x
.type_constant_separator
in
1158 left ^^^
separator ^^^
right
1159 | SimpleTypeSpecifier x
-> get_doc x
.simple_type_specifier
1160 | TypeConstraint
{ constraint_keyword
; constraint_type
} ->
1161 let k = get_doc constraint_keyword
in
1162 let t = get_doc constraint_type
in
1164 | TypeParameter x
->
1165 let variance = get_doc x
.type_variance
in
1166 let name = get_doc x
.type_name
in
1167 let constraints = get_doc x
.type_constraints
in
1168 variance ^^^
name ^
| constraints
1169 | NullableTypeSpecifier x
->
1170 let qm = get_doc x
.nullable_question
in
1171 let ty = get_doc x
.nullable_type
in
1173 | SoftTypeSpecifier x
->
1174 let a = get_doc x
.soft_at
in
1175 let t = get_doc x
.soft_type
in
1177 | GenericTypeSpecifier
1178 { generic_class_type
;
1179 generic_argument_list
} ->
1180 let name = get_doc generic_class_type
in
1181 let argument = get_doc generic_argument_list
in
1182 group_doc (indent_doc_no_space name argument indt)
1183 | VarrayTypeSpecifier
{
1187 varray_optional_comma
;
1190 let ar = get_doc varray_keyword
in
1191 let la = get_doc varray_left_angle
in
1192 let ty = get_doc varray_type
in
1193 let oc = get_doc varray_optional_comma
in
1194 let ra = get_doc varray_right_angle
in
1195 ar ^^^
la ^^^
ty ^^^
oc ^^^
ra
1196 | VectorArrayTypeSpecifier
{
1197 vector_array_keyword
;
1198 vector_array_left_angle
;
1200 vector_array_right_angle
1202 let ar = get_doc vector_array_keyword
in
1203 let la = get_doc vector_array_left_angle
in
1204 let ty = get_doc vector_array_type
in
1205 let ra = get_doc vector_array_right_angle
in
1206 ar ^^^
la ^^^
ty ^^^
ra
1207 | VectorTypeSpecifier
{
1208 vector_type_keyword
;
1209 vector_type_left_angle
;
1211 vector_type_right_angle
1213 let ar = get_doc vector_type_keyword
in
1214 let la = get_doc vector_type_left_angle
in
1215 let ty = get_doc vector_type_type
in
1216 let ra = get_doc vector_type_right_angle
in
1217 ar ^^^
la ^^^
ty ^^^
ra
1218 | KeysetTypeSpecifier
{
1219 keyset_type_keyword
;
1220 keyset_type_left_angle
;
1222 keyset_type_right_angle
1224 let ar = get_doc keyset_type_keyword
in
1225 let la = get_doc keyset_type_left_angle
in
1226 let ty = get_doc keyset_type_type
in
1227 let ra = get_doc keyset_type_right_angle
in
1228 ar ^^^
la ^^^
ty ^^^
ra
1229 | DictionaryTypeSpecifier
{
1230 dictionary_type_keyword
;
1231 dictionary_type_left_angle
;
1232 dictionary_type_members
;
1233 dictionary_type_right_angle
1235 let ar = get_doc dictionary_type_keyword
in
1236 let la = get_doc dictionary_type_left_angle
in
1237 let ms = get_doc dictionary_type_members
in
1238 let ra = get_doc dictionary_type_right_angle
in
1239 ar ^^^
la ^^^
ms ^^^
ra
1240 | DarrayTypeSpecifier
{
1246 darray_optional_comma
;
1249 let ar = get_doc darray_keyword
in
1250 let la = get_doc darray_left_angle
in
1251 let kt = get_doc darray_key
in
1252 let co = get_doc darray_comma
in
1253 let vt = get_doc darray_value
in
1254 let oc = get_doc darray_optional_comma
in
1255 let ra = get_doc darray_right_angle
in
1256 ar ^^^
la ^^^
kt ^^^
co ^
| vt ^^^
oc ^^^
ra
1257 | MapArrayTypeSpecifier
{
1259 map_array_left_angle
;
1263 map_array_right_angle
1265 let ar = get_doc map_array_keyword
in
1266 let la = get_doc map_array_left_angle
in
1267 let kt = get_doc map_array_key
in
1268 let co = get_doc map_array_comma
in
1269 let vt = get_doc map_array_value
in
1270 let ra = get_doc map_array_right_angle
in
1271 ar ^^^
la ^^^
kt ^^^
co ^
| vt ^^^
ra
1272 | ClosureTypeSpecifier
1273 { closure_outer_left_paren
;
1274 closure_function_keyword
;
1275 closure_inner_left_paren
;
1276 closure_parameter_types
;
1277 closure_inner_right_paren
;
1279 closure_return_type
;
1280 closure_outer_right_paren
} ->
1281 let olp = get_doc closure_outer_left_paren
in
1282 let fnc = get_doc closure_function_keyword
in
1283 let ilp = get_doc closure_inner_left_paren
in
1284 let pts = get_doc closure_parameter_types
in
1285 let irp = get_doc closure_inner_right_paren
in
1286 let col = get_doc closure_colon
in
1287 let ret = get_doc closure_return_type
in
1288 let orp = get_doc closure_outer_right_paren
in
1289 olp ^^^
fnc ^^
| ilp ^^^
pts ^^^
irp ^^^
col ^^^
ret ^^^
orp
1290 | ClassnameTypeSpecifier x
->
1291 let cn = get_doc x
.classname_keyword
in
1292 let la = get_doc x
.classname_left_angle
in
1293 let ty = get_doc x
.classname_type
in
1294 let ra = get_doc x
.classname_right_angle
in
1295 cn ^^^
la ^^^
ty ^^^
ra
1296 | FieldSpecifier x
->
1297 let q = get_doc x
.field_question
in
1298 let n = get_doc x
.field_name
in
1299 let a = get_doc x
.field_arrow
in
1300 let t = get_doc x
.field_type
in
1302 | ShapeTypeSpecifier
1303 { shape_type_keyword
; shape_type_left_paren
;
1304 shape_type_fields
; shape_type_ellipsis
; shape_type_right_paren
} ->
1305 let sh = get_doc shape_type_keyword
in
1306 let lp = get_doc shape_type_left_paren
in
1307 let fs = get_doc shape_type_fields
in
1308 let ellipsis = get_doc shape_type_ellipsis
in
1309 let rp = get_doc shape_type_right_paren
in
1310 sh ^
| lp ^^^
fs ^
| ellipsis ^^^
rp
1312 type_arguments_left_angle
;
1313 type_arguments_types
;
1314 type_arguments_right_angle
} ->
1315 let left = get_doc type_arguments_left_angle
in
1316 let args = get_doc type_arguments_types
in
1317 let right = get_doc type_arguments_right_angle
in
1318 indent_block_no_space left args right indt
1320 type_parameters_left_angle
;
1321 type_parameters_parameters
;
1322 type_parameters_right_angle
} ->
1323 let left = get_doc type_parameters_left_angle
in
1324 let params = get_doc type_parameters_parameters
in
1325 let right = get_doc type_parameters_right_angle
in
1326 indent_block_no_space left params right indt
1327 | TupleTypeSpecifier x
->
1328 let left = get_doc x
.tuple_left_paren
in
1329 let types = get_doc x
.tuple_types
in
1330 let right = get_doc x
.tuple_right_paren
in
1331 indent_block_no_space left types right indt
1332 (* this ideally should never be called *)
1337 let keyword = get_doc case_keyword
in
1338 let expr = get_doc case_expression
in
1339 let colon = get_doc case_colon
in
1340 keyword ^^^
space ^^^
expr ^^^
colon
1344 let keyword = get_doc default_keyword
in
1345 let colon = get_doc default_colon
in
1347 | ReturnStatement x
->
1348 let keyword = get_doc x
.return_keyword
in
1349 let expr = get_doc x
.return_expression
in
1350 let semicolon = get_doc x
.return_semicolon
in
1351 let back_part = expr ^^^
semicolon in
1352 group_doc (indent_doc keyword back_part indt)
1355 goto_label_colon
; } ->
1356 let goto_label_name = get_doc goto_label_name in
1357 let goto_label_colon = get_doc goto_label_colon in
1358 goto_label_name ^^^
goto_label_colon
1360 goto_statement_keyword
;
1361 goto_statement_label_name
;
1362 goto_statement_semicolon
; } ->
1363 let keyword = get_doc goto_statement_keyword
in
1364 let label_name = get_doc goto_statement_label_name
in
1365 let semicolon = get_doc goto_statement_semicolon
in
1366 keyword ^
| label_name ^^^
semicolon
1367 | ThrowStatement x
->
1368 let keyword = get_doc x
.throw_keyword
in
1369 let expr = get_doc x
.throw_expression
in
1370 let semicolon = get_doc x
.throw_semicolon
in
1371 let back_part = expr ^^^
semicolon in
1372 group_doc (indent_doc keyword back_part indt)
1373 | BreakStatement x
->
1374 let b = get_doc x
.break_keyword
in
1375 let l = get_doc x
.break_level
in
1376 let s = get_doc x
.break_semicolon
in
1377 if is_missing x
.break_level
then group_doc (b ^^^
l ^^^
s)
1378 else group_doc (b ^
| l ^^^
s)
1379 | ContinueStatement x
->
1380 let c = get_doc x
.continue_keyword
in
1381 let l = get_doc x
.continue_level
in
1382 let s = get_doc x
.continue_semicolon
in
1383 if is_missing x
.continue_level
then group_doc (c ^^^
l ^^^
s)
1384 else group_doc (c ^
| l ^^^
s)
1385 | FunctionStaticStatement
{
1386 static_static_keyword
;
1387 static_declarations
;
1388 static_semicolon
} ->
1389 let st = get_doc static_static_keyword
in
1390 let ds = get_doc static_declarations
in
1391 let se = get_doc static_semicolon
in
1394 { static_name
; static_initializer
} ->
1395 let n = get_doc static_name
in
1396 let i = get_doc static_initializer
in
1398 | EchoStatement x
->
1399 let echo = get_doc x
.echo_keyword
in
1400 let expr_list = get_doc x
.echo_expressions
in
1401 let semicolon = get_doc x
.echo_semicolon
in
1402 echo ^
| expr_list ^^^
semicolon
1406 global_semicolon
} ->
1407 let g = get_doc global_keyword
in
1408 let v = get_doc global_variables
in
1409 let s = get_doc global_semicolon
in
1412 { simple_initializer_equal
; simple_initializer_value
} ->
1413 let e = get_doc simple_initializer_equal
in
1414 let v = get_doc simple_initializer_value
in
1417 (* sep is the compulsory separator separating the children in the list *)
1418 and get_from_children_no_space children
=
1419 let fold_fun acc el
= acc ^^^
get_doc el
in
1420 group_doc (List.fold_left
fold_fun (make_simple nil
) children
)
1421 and get_from_children_with_sep sep children
=
1422 let fold_fun acc el
= (acc ^^^ sep
) ^
| get_doc el
in
1423 group_doc (List.fold_left
fold_fun (make_simple nil
) children
)
1424 and get_from_children node
= get_from_children_with_sep
(make_simple nil
) node
1425 (* if it is a compound statement, the curly braces do not need indent *)
1426 and peek_and_decide_indent x default
=
1428 | CompoundStatement _
-> 0
1430 (* puts [prefix] on the same line as a compound brace. If the statement is not
1431 * compound, put an optional newline and group the result *)
1432 and handle_compound_inline_brace prefix
statement postfix
=
1433 match syntax
statement with
1434 | CompoundStatement
compound_stmt ->
1435 let left = get_doc compound_stmt.compound_left_brace
in
1436 let right = get_doc compound_stmt.compound_right_brace
in
1437 let statement = get_doc compound_stmt.compound_statements
in
1438 let prefix = group_doc (prefix ^
| left) in
1439 let postfix = group_doc (right ^
| postfix) in
1440 indent_block prefix statement postfix indt
1441 | _
-> group_doc (prefix ^
| get_doc statement ^
| postfix)
1442 (* keep open brace of compound statement on the same line as the prefix.
1443 * If statement is not a compound statement, then indent it with [indt] *)
1444 and handle_compound_brace_prefix_indent
prefix statement indt =
1445 if is_compound_statement
statement then
1446 handle_compound_inline_brace
prefix statement missing
1448 group_doc (indent_doc prefix (get_doc statement) indt)
1450 let pretty_print node
=
1451 let empty_string = make_simple (text
"") in
1452 let to_print = node
|> get_doc |> add_break in
1453 let to_print = to_print ^
| empty_string in
1454 let to_print = combine to_print in