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 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
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
165 | Kind.SingleLineComment
->
166 (* no code after comments *)
167 (text
(Trivia.text trivia
), true)
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
179 let result = concat a b
in
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
)
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)
196 let missing = make_simple nil
197 let space = make_simple (text
" ")
199 let rec get_doc node
=
200 match syntax node
with
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
)
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
->
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
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)
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)
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 *)
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
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
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
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
309 xhp_enum_right_brace
;
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)
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
;
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
346 | TraitUsePrecedenceItem
{
347 trait_use_precedence_item_name
;
348 trait_use_precedence_item_keyword
;
349 trait_use_precedence_item_removed_names
;
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
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
;
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
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
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
386 const_type_specifier
;
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
409 group_doc (abstr ^
| const ^
| type_ ^
| name) ^
|
412 group_doc (type_spec ^^^
semicolon)
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
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
461 | PropertyDeclarator
{ property_name
; property_initializer
} ->
462 let n = get_doc property_name
in
463 let i = get_doc property_initializer
in
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
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
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
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
;
509 function_type_parameter_list
;
511 function_parameter_list
;
512 function_right_paren
;
515 function_where_clause
}
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)
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)
538 group_doc ( group_doc (preface ^
| name_and_generics) ^^
| parameters )
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
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
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
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
{
568 parameter_visibility
;
569 parameter_call_convention
;
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
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
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
609 | InclusionDirective x
->
610 let ex = get_doc x
.inclusion_expression
in
611 let se = get_doc x
.inclusion_semicolon
in
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
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)
645 { while_keyword
; while_left_paren
; while_condition
; while_right_paren
;
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
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
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
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)
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
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)
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
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
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
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
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
779 try_compound_statement
;
781 try_finally_clause
} ->
782 let keyword = get_doc try_keyword
in
783 let compound_stmt = try_compound_statement
in
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)
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
811 let keyword = get_doc finally_keyword
in
812 handle_compound_brace_prefix_indent
keyword finally_body
indt
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
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
840 for_second_semicolon
;
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
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
867 foreach_await_keyword
;
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
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
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
931 switch_section_labels
;
932 switch_section_statements
;
933 switch_section_fallthrough
} ->
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
{
941 fallthrough_semicolon
943 let f = get_doc fallthrough_keyword
in
944 let s = get_doc fallthrough_semicolon
in
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
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)
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)
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)
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
;
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
1036 group_doc ( group_doc preface ^^
| parameters )
1037 ^
| type_declaration ^
| uses
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
;
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
1068 group_doc ( group_doc preface ^^
| parameters )
1069 ^
| uses ^
| type_declaration
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
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
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)
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
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
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
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
{
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
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
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
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
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)
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
1262 c ^^^
l ^^^
a ^^^
r ^
|
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
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
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
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
1391 xhp_open_left_angle
;
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
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
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
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
1438 | SoftTypeSpecifier x
->
1439 let a = get_doc x
.soft_at
in
1440 let t = get_doc x
.soft_type
in
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
{
1452 varray_trailing_comma
;
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
;
1465 vector_array_right_angle
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
;
1476 vector_type_trailing_comma
;
1477 vector_type_right_angle
;
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
;
1489 keyset_type_trailing_comma
;
1490 keyset_type_right_angle
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
{
1500 tuple_type_left_angle
;
1502 tuple_type_right_angle
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
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
{
1526 darray_trailing_comma
;
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
{
1539 map_array_left_angle
;
1543 map_array_right_angle
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
;
1555 closure_function_keyword
;
1556 closure_inner_left_paren
;
1557 closure_parameter_list
;
1558 closure_inner_right_paren
;
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
;
1576 let cc = get_doc closure_parameter_call_convention
in
1577 let ty = get_doc closure_parameter_type
in
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
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
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
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 *)
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
1633 let keyword = get_doc default_keyword
in
1634 let colon = get_doc default_colon
in
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)
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
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
1683 { static_name
; static_initializer
} ->
1684 let n = get_doc static_name
in
1685 let i = get_doc static_initializer
in
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
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
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
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
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