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