1use std::fmt::Write;
35
36use once_cell::sync::Lazy;
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum IndentStyle {
41 None,
43 Tabs {
46 tab_size: u32,
48 count: u32,
50 },
51 Spaces {
53 count: u32,
55 },
56}
57
58impl IndentStyle {
59 pub fn write<F>(&self, f: &mut F, levels: u32) -> std::fmt::Result
61 where
62 F: Write + ?Sized,
63 {
64 match self {
65 Self::None => {}
66 Self::Tabs { count, .. } => {
67 for _ in 0..count * levels {
68 f.write_char('\t')?;
69 }
70 }
71 Self::Spaces { count, .. } => {
72 for _ in 0..count * levels {
73 f.write_char(' ')?;
74 }
75 }
76 }
77
78 Ok(())
79 }
80}
81
82impl Default for IndentStyle {
83 fn default() -> Self {
84 Self::Spaces { count: 4 }
85 }
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub enum Whitespace {
91 None,
93 Space,
95 Newline,
97}
98
99impl Whitespace {
100 pub fn write<F>(&self, f: &mut F, state: &mut FormattingState) -> std::fmt::Result
102 where
103 F: Write + ?Sized,
104 {
105 match self {
106 Self::None => Ok(()),
107 Self::Space => f.write_char(' '),
108 Self::Newline => state.new_line(true),
109 }
110 }
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
115pub struct FormattingSettings {
116 pub indent_style: IndentStyle,
118 pub space_before_open_block: bool,
120 pub newline_after_open_block: bool,
122 pub newline_before_close_block: bool,
124 pub newline_after_close_block: bool,
126 pub newline_after_collapsed_statement: bool,
128 pub newline_before_collapsed_statement: bool,
130 pub struct_field_separator: Whitespace,
132 pub struct_declaration_terminator: Whitespace,
134 pub declaration_terminator: Whitespace,
136 pub case_label_terminator: Whitespace,
138 pub spaces_around_binary_ops: bool,
140 pub statement_terminator: Whitespace,
142 pub function_definition_terminator: Whitespace,
144 pub collapse_single_item_compound_statements: bool,
147 pub space_before_else: bool,
149 pub space_after_list_separator: bool,
151 pub space_after_for_statement_separator: bool,
153 pub spaces_surrounding_initializer_list_expressions: bool,
156 pub spaces_surrounding_statement_parentheses: bool,
158}
159
160impl FormattingSettings {
161 pub fn minifying() -> Self {
164 Self {
165 indent_style: IndentStyle::None,
166 space_before_open_block: false,
167 newline_after_open_block: false,
168 newline_before_close_block: false,
169 newline_after_close_block: false,
170 newline_after_collapsed_statement: false,
171 newline_before_collapsed_statement: false,
172 struct_field_separator: Whitespace::None,
173 struct_declaration_terminator: Whitespace::None,
174 declaration_terminator: Whitespace::None,
175 case_label_terminator: Whitespace::None,
176 spaces_around_binary_ops: false,
177 statement_terminator: Whitespace::None,
178 function_definition_terminator: Whitespace::None,
179 collapse_single_item_compound_statements: true,
180 space_before_else: false,
181 space_after_list_separator: false,
182 space_after_for_statement_separator: false,
183 spaces_surrounding_initializer_list_expressions: false,
184 spaces_surrounding_statement_parentheses: false,
185 }
186 }
187}
188
189impl Default for FormattingSettings {
190 fn default() -> Self {
191 Self {
192 indent_style: IndentStyle::default(),
193 space_before_open_block: true,
194 newline_after_open_block: true,
195 newline_before_close_block: true,
196 newline_after_close_block: true,
197 newline_after_collapsed_statement: true,
198 newline_before_collapsed_statement: true,
199 struct_field_separator: Whitespace::Newline,
200 struct_declaration_terminator: Whitespace::Newline,
201 declaration_terminator: Whitespace::Newline,
202 case_label_terminator: Whitespace::Newline,
203 spaces_around_binary_ops: true,
204 statement_terminator: Whitespace::Newline,
205 function_definition_terminator: Whitespace::Newline,
206 collapse_single_item_compound_statements: false,
207 space_before_else: true,
208 space_after_list_separator: true,
209 space_after_for_statement_separator: true,
210 spaces_surrounding_initializer_list_expressions: true,
211 spaces_surrounding_statement_parentheses: true,
212 }
213 }
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
218pub struct FormattingState<'s> {
219 pub settings: &'s FormattingSettings,
221 indentation_level: u32,
222 new_line_pending: bool,
223 in_function_definition_statement: bool,
224 last_flush_line_flushed_line: bool,
225 is_first_external_declaration: bool,
226}
227
228impl<'s> FormattingState<'s> {
229 fn write_indent<F>(&self, f: &mut F) -> std::fmt::Result
230 where
231 F: Write + ?Sized,
232 {
233 self.settings.indent_style.write(f, self.indentation_level)
234 }
235
236 fn write_line<F>(&mut self, f: &mut F) -> std::fmt::Result
237 where
238 F: Write + ?Sized,
239 {
240 f.write_char('\n')?;
241 self.write_indent(f)
242 }
243
244 pub fn new_line(&mut self, required: bool) -> std::fmt::Result {
246 if required {
247 self.new_line_pending = true;
248 }
249
250 Ok(())
251 }
252
253 pub fn consume_newline(&mut self) {
255 self.new_line_pending = false;
256 }
257
258 pub fn flush_line<F>(&mut self, f: &mut F) -> std::fmt::Result
260 where
261 F: Write + ?Sized,
262 {
263 if self.new_line_pending {
264 self.write_line(f)?;
265 self.new_line_pending = false;
266 self.last_flush_line_flushed_line = true;
267 } else {
268 self.last_flush_line_flushed_line = false;
269 }
270
271 Ok(())
272 }
273
274 pub fn move_to_empty_line<F>(&mut self, f: &mut F) -> std::fmt::Result
278 where
279 F: Write + ?Sized,
280 {
281 if !self.is_first_external_declaration && !self.last_flush_line_flushed_line {
282 self.new_line(true)?;
283 self.write_line(f)?;
284 }
285
286 Ok(())
287 }
288
289 pub fn flush_space<F>(&mut self, f: &mut F) -> std::fmt::Result
291 where
292 F: Write + ?Sized,
293 {
294 if self.new_line_pending {
295 f.write_char(' ')?;
296 self.new_line_pending = false;
297 }
298
299 Ok(())
300 }
301
302 pub fn enter_compound_statement_block<F>(&mut self, f: &mut F) -> std::fmt::Result
304 where
305 F: Write + ?Sized,
306 {
307 if self.settings.space_before_open_block && self.in_function_definition_statement {
309 f.write_char(' ')?;
310 }
311
312 self.enter_block_inner(f)
313 }
314
315 pub fn enter_external_declaration<F>(&mut self, f: &mut F) -> std::fmt::Result
317 where
318 F: Write + ?Sized,
319 {
320 self.flush_line(f)
321 }
322
323 pub fn exit_external_declaration(&mut self) {
325 self.is_first_external_declaration = false;
326 }
327
328 pub fn enter_block<F>(&mut self, f: &mut F) -> std::fmt::Result
330 where
331 F: Write + ?Sized,
332 {
333 if self.settings.space_before_open_block {
335 f.write_char(' ')?;
336 }
337
338 self.enter_block_inner(f)
339 }
340
341 fn enter_block_inner<F>(&mut self, f: &mut F) -> std::fmt::Result
343 where
344 F: Write + ?Sized,
345 {
346 f.write_char('{')?;
348
349 self.indentation_level += 1;
351 self.new_line(self.settings.newline_after_open_block)?;
352
353 Ok(())
354 }
355
356 pub fn exit_block<F>(&mut self, f: &mut F) -> std::fmt::Result
358 where
359 F: Write + ?Sized,
360 {
361 self.indentation_level -= 1;
363
364 self.new_line(self.settings.newline_before_close_block)?;
366
367 self.flush_line(f)?;
369
370 f.write_char('}')?;
372
373 self.new_line(self.settings.newline_after_close_block)?;
375
376 Ok(())
377 }
378
379 pub fn enter_function_definition_statement(&mut self) {
381 self.in_function_definition_statement = true;
382 }
383
384 pub fn consume_function_definition_statement(&mut self) {
386 self.in_function_definition_statement = false;
387 }
388
389 pub fn enter_collapsed_compound_statement(&mut self) -> std::fmt::Result {
391 self.indentation_level += 1;
393
394 if self.settings.newline_before_collapsed_statement {
396 self.new_line(self.settings.newline_before_collapsed_statement)?;
397 }
398
399 Ok(())
400 }
401
402 pub fn exit_collapsed_compound_statement(&mut self) -> std::fmt::Result {
404 self.indentation_level -= 1;
406
407 if self.settings.newline_after_collapsed_statement {
409 self.new_line(self.settings.newline_after_collapsed_statement)?;
410 }
411
412 Ok(())
413 }
414
415 pub fn enter_initializer_list<F>(&mut self, f: &mut F) -> std::fmt::Result
417 where
418 F: Write + ?Sized,
419 {
420 f.write_char('{')?;
421
422 if self
423 .settings
424 .spaces_surrounding_initializer_list_expressions
425 {
426 f.write_char(' ')?;
427 }
428
429 Ok(())
430 }
431
432 pub fn end_initializer_list<F>(&mut self, f: &mut F) -> std::fmt::Result
434 where
435 F: Write + ?Sized,
436 {
437 if self
438 .settings
439 .spaces_surrounding_initializer_list_expressions
440 {
441 f.write_char(' ')?;
442 }
443
444 f.write_char('}')
445 }
446
447 pub fn enter_case_label<F>(&mut self, f: &mut F) -> std::fmt::Result
449 where
450 F: Write + ?Sized,
451 {
452 f.write_char(':')?;
453 self.settings.case_label_terminator.write(f, self)
454 }
455
456 pub fn write_else<F>(&mut self, f: &mut F) -> std::fmt::Result
458 where
459 F: Write + ?Sized,
460 {
461 if self.settings.space_before_else {
462 f.write_char(' ')?;
463 }
464
465 f.write_str("else ")
466 }
467
468 pub fn write_struct_field_separator<F>(&mut self, f: &mut F) -> std::fmt::Result
470 where
471 F: Write + ?Sized,
472 {
473 f.write_char(';')?;
474 self.settings.struct_field_separator.write(f, self)
475 }
476
477 pub fn write_list_separator<F>(&mut self, f: &mut F) -> std::fmt::Result
479 where
480 F: Write + ?Sized,
481 {
482 f.write_char(',')?;
483 if self.settings.space_after_list_separator {
484 f.write_char(' ')?;
485 }
486
487 Ok(())
488 }
489
490 pub fn write_for_statement_separator<F>(&mut self, f: &mut F) -> std::fmt::Result
492 where
493 F: Write + ?Sized,
494 {
495 f.write_char(';')?;
496 if self.settings.space_after_for_statement_separator {
497 f.write_char(' ')?;
498 }
499
500 Ok(())
501 }
502
503 pub fn write_struct_declaration_terminator<F>(&mut self, f: &mut F) -> std::fmt::Result
505 where
506 F: Write + ?Sized,
507 {
508 f.write_char(';')?;
509 self.settings.struct_declaration_terminator.write(f, self)
510 }
511
512 pub fn write_declaration_terminator<F>(&mut self, f: &mut F) -> std::fmt::Result
514 where
515 F: Write + ?Sized,
516 {
517 f.write_char(';')?;
518 self.settings.declaration_terminator.write(f, self)
519 }
520
521 pub fn write_binary_op<F>(&self, f: &mut F, op: &str) -> std::fmt::Result
523 where
524 F: Write + ?Sized,
525 {
526 if self.settings.spaces_around_binary_ops {
527 f.write_char(' ')?;
528 }
529
530 f.write_str(op)?;
531
532 if self.settings.spaces_around_binary_ops {
533 f.write_char(' ')?;
534 }
535
536 Ok(())
537 }
538
539 pub fn write_statement_terminator<F>(&mut self, f: &mut F) -> std::fmt::Result
541 where
542 F: Write + ?Sized,
543 {
544 f.write_char(';')?;
545 self.settings.statement_terminator.write(f, self)
546 }
547
548 pub fn write_function_definition_terminator<F>(&mut self, f: &mut F) -> std::fmt::Result
550 where
551 F: Write + ?Sized,
552 {
553 self.settings.function_definition_terminator.write(f, self)
554 }
555
556 pub fn write_statement_opening_parenthesis<F>(&mut self, f: &mut F) -> std::fmt::Result
558 where
559 F: Write + ?Sized,
560 {
561 if self.settings.spaces_surrounding_statement_parentheses {
562 f.write_char(' ')?;
563 }
564
565 f.write_char('(')
566 }
567
568 pub fn write_statement_closing_parenthesis<F>(&mut self, f: &mut F) -> std::fmt::Result
570 where
571 F: Write + ?Sized,
572 {
573 f.write_char(')')?;
574
575 if self.settings.spaces_surrounding_statement_parentheses {
576 f.write_char(' ')?;
577 }
578
579 Ok(())
580 }
581}
582
583impl<'s> From<&'s FormattingSettings> for FormattingState<'s> {
584 fn from(settings: &'s FormattingSettings) -> Self {
585 Self {
586 settings,
587 indentation_level: 0,
588 new_line_pending: false,
589 in_function_definition_statement: false,
590 last_flush_line_flushed_line: false,
591 is_first_external_declaration: true,
592 }
593 }
594}
595
596static DEFAULT_SETTINGS: Lazy<FormattingSettings> = Lazy::new(FormattingSettings::default);
597
598impl Default for FormattingState<'static> {
599 fn default() -> Self {
600 Self {
601 settings: &DEFAULT_SETTINGS,
602 indentation_level: 0,
603 new_line_pending: false,
604 in_function_definition_statement: false,
605 last_flush_line_flushed_line: false,
606 is_first_external_declaration: true,
607 }
608 }
609}
610
611use crate::ast;
612
613trait HasPrecedence {
615 fn precedence(&self) -> u32;
617}
618
619impl HasPrecedence for ast::ExprData {
620 fn precedence(&self) -> u32 {
621 match self {
622 Self::Variable(_)
624 | Self::IntConst(_)
625 | Self::UIntConst(_)
626 | Self::BoolConst(_)
627 | Self::FloatConst(_)
628 | Self::DoubleConst(_) => 0,
629 Self::Unary(op, _) => op.precedence(),
631 Self::Binary(op, _, _) => op.precedence(),
632 Self::Ternary(_, _, _) => 15,
633 Self::Assignment(_, op, _) => op.precedence(),
634 Self::Bracket(_, _)
635 | Self::FunCall(_, _)
636 | Self::Dot(_, _)
637 | Self::PostInc(_)
638 | Self::PostDec(_) => 2,
639 Self::Comma(_, _) => 17,
640 }
641 }
642}
643
644impl HasPrecedence for ast::UnaryOpData {
645 fn precedence(&self) -> u32 {
646 3
647 }
648}
649
650impl HasPrecedence for ast::BinaryOpData {
651 fn precedence(&self) -> u32 {
652 match self {
653 Self::Mult | Self::Div | Self::Mod => 4,
654 Self::Add | Self::Sub => 5,
655 Self::LShift | Self::RShift => 6,
656 Self::Lt | Self::Gt | Self::Lte | Self::Gte => 7,
657 Self::Equal | Self::NonEqual => 8,
658 Self::BitAnd => 9,
659 Self::BitXor => 10,
660 Self::BitOr => 11,
661 Self::And => 12,
662 Self::Xor => 13,
663 Self::Or => 14,
664 }
665 }
666}
667
668impl HasPrecedence for ast::AssignmentOp {
669 fn precedence(&self) -> u32 {
670 16
671 }
672}
673
674pub fn show_identifier<F>(
676 f: &mut F,
677 i: &ast::Identifier,
678 _: &mut FormattingState<'_>,
679) -> std::fmt::Result
680where
681 F: Write + ?Sized,
682{
683 f.write_str(&i.0)
684}
685
686pub fn show_type_name<F>(
688 f: &mut F,
689 t: &ast::TypeName,
690 _: &mut FormattingState<'_>,
691) -> std::fmt::Result
692where
693 F: Write + ?Sized,
694{
695 f.write_str(&t.0)
696}
697
698pub fn show_type_specifier_non_array<F>(
700 f: &mut F,
701 t: &ast::TypeSpecifierNonArray,
702 state: &mut FormattingState<'_>,
703) -> std::fmt::Result
704where
705 F: Write + ?Sized,
706{
707 match **t {
708 ast::TypeSpecifierNonArrayData::Void => f.write_str("void"),
709 ast::TypeSpecifierNonArrayData::Bool => f.write_str("bool"),
710 ast::TypeSpecifierNonArrayData::Int => f.write_str("int"),
711 ast::TypeSpecifierNonArrayData::UInt => f.write_str("uint"),
712 ast::TypeSpecifierNonArrayData::Float => f.write_str("float"),
713 ast::TypeSpecifierNonArrayData::Double => f.write_str("double"),
714 ast::TypeSpecifierNonArrayData::Vec2 => f.write_str("vec2"),
715 ast::TypeSpecifierNonArrayData::Vec3 => f.write_str("vec3"),
716 ast::TypeSpecifierNonArrayData::Vec4 => f.write_str("vec4"),
717 ast::TypeSpecifierNonArrayData::DVec2 => f.write_str("dvec2"),
718 ast::TypeSpecifierNonArrayData::DVec3 => f.write_str("dvec3"),
719 ast::TypeSpecifierNonArrayData::DVec4 => f.write_str("dvec4"),
720 ast::TypeSpecifierNonArrayData::BVec2 => f.write_str("bvec2"),
721 ast::TypeSpecifierNonArrayData::BVec3 => f.write_str("bvec3"),
722 ast::TypeSpecifierNonArrayData::BVec4 => f.write_str("bvec4"),
723 ast::TypeSpecifierNonArrayData::IVec2 => f.write_str("ivec2"),
724 ast::TypeSpecifierNonArrayData::IVec3 => f.write_str("ivec3"),
725 ast::TypeSpecifierNonArrayData::IVec4 => f.write_str("ivec4"),
726 ast::TypeSpecifierNonArrayData::UVec2 => f.write_str("uvec2"),
727 ast::TypeSpecifierNonArrayData::UVec3 => f.write_str("uvec3"),
728 ast::TypeSpecifierNonArrayData::UVec4 => f.write_str("uvec4"),
729 ast::TypeSpecifierNonArrayData::Mat2 => f.write_str("mat2"),
730 ast::TypeSpecifierNonArrayData::Mat3 => f.write_str("mat3"),
731 ast::TypeSpecifierNonArrayData::Mat4 => f.write_str("mat4"),
732 ast::TypeSpecifierNonArrayData::Mat22 => f.write_str("mat2x2"),
733 ast::TypeSpecifierNonArrayData::Mat23 => f.write_str("mat2x3"),
734 ast::TypeSpecifierNonArrayData::Mat24 => f.write_str("mat2x4"),
735 ast::TypeSpecifierNonArrayData::Mat32 => f.write_str("mat3x2"),
736 ast::TypeSpecifierNonArrayData::Mat33 => f.write_str("mat3x3"),
737 ast::TypeSpecifierNonArrayData::Mat34 => f.write_str("mat3x4"),
738 ast::TypeSpecifierNonArrayData::Mat42 => f.write_str("mat4x2"),
739 ast::TypeSpecifierNonArrayData::Mat43 => f.write_str("mat4x3"),
740 ast::TypeSpecifierNonArrayData::Mat44 => f.write_str("mat4x4"),
741 ast::TypeSpecifierNonArrayData::DMat2 => f.write_str("dmat2"),
742 ast::TypeSpecifierNonArrayData::DMat3 => f.write_str("dmat3"),
743 ast::TypeSpecifierNonArrayData::DMat4 => f.write_str("dmat4"),
744 ast::TypeSpecifierNonArrayData::DMat22 => f.write_str("dmat2x2"),
745 ast::TypeSpecifierNonArrayData::DMat23 => f.write_str("dmat2x3"),
746 ast::TypeSpecifierNonArrayData::DMat24 => f.write_str("dmat2x4"),
747 ast::TypeSpecifierNonArrayData::DMat32 => f.write_str("dmat3x2"),
748 ast::TypeSpecifierNonArrayData::DMat33 => f.write_str("dmat3x3"),
749 ast::TypeSpecifierNonArrayData::DMat34 => f.write_str("dmat3x4"),
750 ast::TypeSpecifierNonArrayData::DMat42 => f.write_str("dmat4x2"),
751 ast::TypeSpecifierNonArrayData::DMat43 => f.write_str("dmat4x3"),
752 ast::TypeSpecifierNonArrayData::DMat44 => f.write_str("dmat4x4"),
753 ast::TypeSpecifierNonArrayData::Sampler1D => f.write_str("sampler1D"),
754 ast::TypeSpecifierNonArrayData::Image1D => f.write_str("image1D"),
755 ast::TypeSpecifierNonArrayData::Sampler2D => f.write_str("sampler2D"),
756 ast::TypeSpecifierNonArrayData::Image2D => f.write_str("image2D"),
757 ast::TypeSpecifierNonArrayData::Sampler3D => f.write_str("sampler3D"),
758 ast::TypeSpecifierNonArrayData::Image3D => f.write_str("image3D"),
759 ast::TypeSpecifierNonArrayData::SamplerCube => f.write_str("samplerCube"),
760 ast::TypeSpecifierNonArrayData::ImageCube => f.write_str("imageCube"),
761 ast::TypeSpecifierNonArrayData::Sampler2DRect => f.write_str("sampler2DRect"),
762 ast::TypeSpecifierNonArrayData::Image2DRect => f.write_str("image2DRect"),
763 ast::TypeSpecifierNonArrayData::Sampler1DArray => f.write_str("sampler1DArray"),
764 ast::TypeSpecifierNonArrayData::Image1DArray => f.write_str("image1DArray"),
765 ast::TypeSpecifierNonArrayData::Sampler2DArray => f.write_str("sampler2DArray"),
766 ast::TypeSpecifierNonArrayData::Image2DArray => f.write_str("image2DArray"),
767 ast::TypeSpecifierNonArrayData::SamplerBuffer => f.write_str("samplerBuffer"),
768 ast::TypeSpecifierNonArrayData::ImageBuffer => f.write_str("imageBuffer"),
769 ast::TypeSpecifierNonArrayData::Sampler2DMs => f.write_str("sampler2DMS"),
770 ast::TypeSpecifierNonArrayData::Image2DMs => f.write_str("image2DMS"),
771 ast::TypeSpecifierNonArrayData::Sampler2DMsArray => f.write_str("sampler2DMSArray"),
772 ast::TypeSpecifierNonArrayData::Image2DMsArray => f.write_str("image2DMSArray"),
773 ast::TypeSpecifierNonArrayData::SamplerCubeArray => f.write_str("samplerCubeArray"),
774 ast::TypeSpecifierNonArrayData::ImageCubeArray => f.write_str("imageCubeArray"),
775 ast::TypeSpecifierNonArrayData::Sampler1DShadow => f.write_str("sampler1DShadow"),
776 ast::TypeSpecifierNonArrayData::Sampler2DShadow => f.write_str("sampler2DShadow"),
777 ast::TypeSpecifierNonArrayData::Sampler2DRectShadow => f.write_str("sampler2DRectShadow"),
778 ast::TypeSpecifierNonArrayData::Sampler1DArrayShadow => f.write_str("sampler1DArrayShadow"),
779 ast::TypeSpecifierNonArrayData::Sampler2DArrayShadow => f.write_str("sampler2DArrayShadow"),
780 ast::TypeSpecifierNonArrayData::SamplerCubeShadow => f.write_str("samplerCubeShadow"),
781 ast::TypeSpecifierNonArrayData::SamplerCubeArrayShadow => {
782 f.write_str("samplerCubeArrayShadow")
783 }
784 ast::TypeSpecifierNonArrayData::ISampler1D => f.write_str("isampler1D"),
785 ast::TypeSpecifierNonArrayData::IImage1D => f.write_str("iimage1D"),
786 ast::TypeSpecifierNonArrayData::ISampler2D => f.write_str("isampler2D"),
787 ast::TypeSpecifierNonArrayData::IImage2D => f.write_str("iimage2D"),
788 ast::TypeSpecifierNonArrayData::ISampler3D => f.write_str("isampler3D"),
789 ast::TypeSpecifierNonArrayData::IImage3D => f.write_str("iimage3D"),
790 ast::TypeSpecifierNonArrayData::ISamplerCube => f.write_str("isamplerCube"),
791 ast::TypeSpecifierNonArrayData::IImageCube => f.write_str("iimageCube"),
792 ast::TypeSpecifierNonArrayData::ISampler2DRect => f.write_str("isampler2DRect"),
793 ast::TypeSpecifierNonArrayData::IImage2DRect => f.write_str("iimage2DRect"),
794 ast::TypeSpecifierNonArrayData::ISampler1DArray => f.write_str("isampler1DArray"),
795 ast::TypeSpecifierNonArrayData::IImage1DArray => f.write_str("iimage1DArray"),
796 ast::TypeSpecifierNonArrayData::ISampler2DArray => f.write_str("isampler2DArray"),
797 ast::TypeSpecifierNonArrayData::IImage2DArray => f.write_str("iimage2DArray"),
798 ast::TypeSpecifierNonArrayData::ISamplerBuffer => f.write_str("isamplerBuffer"),
799 ast::TypeSpecifierNonArrayData::IImageBuffer => f.write_str("iimageBuffer"),
800 ast::TypeSpecifierNonArrayData::ISampler2DMs => f.write_str("isampler2MS"),
801 ast::TypeSpecifierNonArrayData::IImage2DMs => f.write_str("iimage2DMS"),
802 ast::TypeSpecifierNonArrayData::ISampler2DMsArray => f.write_str("isampler2DMSArray"),
803 ast::TypeSpecifierNonArrayData::IImage2DMsArray => f.write_str("iimage2DMSArray"),
804 ast::TypeSpecifierNonArrayData::ISamplerCubeArray => f.write_str("isamplerCubeArray"),
805 ast::TypeSpecifierNonArrayData::IImageCubeArray => f.write_str("iimageCubeArray"),
806 ast::TypeSpecifierNonArrayData::AtomicUInt => f.write_str("atomic_uint"),
807 ast::TypeSpecifierNonArrayData::USampler1D => f.write_str("usampler1D"),
808 ast::TypeSpecifierNonArrayData::UImage1D => f.write_str("uimage1D"),
809 ast::TypeSpecifierNonArrayData::USampler2D => f.write_str("usampler2D"),
810 ast::TypeSpecifierNonArrayData::UImage2D => f.write_str("uimage2D"),
811 ast::TypeSpecifierNonArrayData::USampler3D => f.write_str("usampler3D"),
812 ast::TypeSpecifierNonArrayData::UImage3D => f.write_str("uimage3D"),
813 ast::TypeSpecifierNonArrayData::USamplerCube => f.write_str("usamplerCube"),
814 ast::TypeSpecifierNonArrayData::UImageCube => f.write_str("uimageCube"),
815 ast::TypeSpecifierNonArrayData::USampler2DRect => f.write_str("usampler2DRect"),
816 ast::TypeSpecifierNonArrayData::UImage2DRect => f.write_str("uimage2DRect"),
817 ast::TypeSpecifierNonArrayData::USampler1DArray => f.write_str("usampler1DArray"),
818 ast::TypeSpecifierNonArrayData::UImage1DArray => f.write_str("uimage1DArray"),
819 ast::TypeSpecifierNonArrayData::USampler2DArray => f.write_str("usampler2DArray"),
820 ast::TypeSpecifierNonArrayData::UImage2DArray => f.write_str("uimage2DArray"),
821 ast::TypeSpecifierNonArrayData::USamplerBuffer => f.write_str("usamplerBuffer"),
822 ast::TypeSpecifierNonArrayData::UImageBuffer => f.write_str("uimageBuffer"),
823 ast::TypeSpecifierNonArrayData::USampler2DMs => f.write_str("usampler2DMS"),
824 ast::TypeSpecifierNonArrayData::UImage2DMs => f.write_str("uimage2DMS"),
825 ast::TypeSpecifierNonArrayData::USampler2DMsArray => f.write_str("usamplerDMSArray"),
826 ast::TypeSpecifierNonArrayData::UImage2DMsArray => f.write_str("uimage2DMSArray"),
827 ast::TypeSpecifierNonArrayData::USamplerCubeArray => f.write_str("usamplerCubeArray"),
828 ast::TypeSpecifierNonArrayData::UImageCubeArray => f.write_str("uimageCubeArray"),
829 ast::TypeSpecifierNonArrayData::Texture1D => f.write_str("texture1D"),
830 ast::TypeSpecifierNonArrayData::Texture2D => f.write_str("texture2D"),
831 ast::TypeSpecifierNonArrayData::Texture3D => f.write_str("texture3D"),
832 ast::TypeSpecifierNonArrayData::TextureCube => f.write_str("textureCube"),
833 ast::TypeSpecifierNonArrayData::Texture2DRect => f.write_str("texture2DRect"),
834 ast::TypeSpecifierNonArrayData::Texture1DArray => f.write_str("texture1DArray"),
835 ast::TypeSpecifierNonArrayData::Texture2DArray => f.write_str("texture2DArray"),
836 ast::TypeSpecifierNonArrayData::TextureBuffer => f.write_str("textureBuffer"),
837 ast::TypeSpecifierNonArrayData::Texture2DMs => f.write_str("texture2DMS"),
838 ast::TypeSpecifierNonArrayData::Texture2DMsArray => f.write_str("texture2DMSArray"),
839 ast::TypeSpecifierNonArrayData::TextureCubeArray => f.write_str("textureCubeArray"),
840 ast::TypeSpecifierNonArrayData::ITexture1D => f.write_str("itexture1D"),
841 ast::TypeSpecifierNonArrayData::ITexture2D => f.write_str("itexture2D"),
842 ast::TypeSpecifierNonArrayData::ITexture3D => f.write_str("itexture3D"),
843 ast::TypeSpecifierNonArrayData::ITextureCube => f.write_str("itextureCube"),
844 ast::TypeSpecifierNonArrayData::ITexture2DRect => f.write_str("itexture2DRect"),
845 ast::TypeSpecifierNonArrayData::ITexture1DArray => f.write_str("itexture1DArray"),
846 ast::TypeSpecifierNonArrayData::ITexture2DArray => f.write_str("itexture2DArray"),
847 ast::TypeSpecifierNonArrayData::ITextureBuffer => f.write_str("itextureBuffer"),
848 ast::TypeSpecifierNonArrayData::ITexture2DMs => f.write_str("itexture2DMS"),
849 ast::TypeSpecifierNonArrayData::ITexture2DMsArray => f.write_str("itexture2DMSArray"),
850 ast::TypeSpecifierNonArrayData::ITextureCubeArray => f.write_str("itextureCubeArray"),
851 ast::TypeSpecifierNonArrayData::Sampler => f.write_str("sampler"),
852 ast::TypeSpecifierNonArrayData::SamplerShadow => f.write_str("samplerShadow"),
853 ast::TypeSpecifierNonArrayData::SubpassInput => f.write_str("subpassInput"),
854 ast::TypeSpecifierNonArrayData::ISubpassInput => f.write_str("isubpassInput"),
855 ast::TypeSpecifierNonArrayData::USubpassInput => f.write_str("usubpassInput"),
856 ast::TypeSpecifierNonArrayData::SubpassInputMs => f.write_str("subpassInputMS"),
857 ast::TypeSpecifierNonArrayData::ISubpassInputMs => f.write_str("isubpassInputMS"),
858 ast::TypeSpecifierNonArrayData::USubpassInputMs => f.write_str("usubpassInputMS"),
859 ast::TypeSpecifierNonArrayData::Struct(ref st) => show_struct_non_declaration(f, st, state),
860 ast::TypeSpecifierNonArrayData::TypeName(ref tn) => show_type_name(f, tn, state),
861 }
862}
863
864pub fn show_type_specifier<F>(
866 f: &mut F,
867 t: &ast::TypeSpecifier,
868 state: &mut FormattingState<'_>,
869) -> std::fmt::Result
870where
871 F: Write + ?Sized,
872{
873 show_type_specifier_non_array(f, &t.ty, state)?;
874
875 if let Some(ref arr_spec) = t.array_specifier {
876 show_array_spec(f, arr_spec, state)?;
877 }
878
879 Ok(())
880}
881
882pub fn show_fully_specified_type<F>(
884 f: &mut F,
885 t: &ast::FullySpecifiedType,
886 state: &mut FormattingState<'_>,
887) -> std::fmt::Result
888where
889 F: Write + ?Sized,
890{
891 if let Some(ref qual) = t.qualifier {
892 show_type_qualifier(f, qual, state)?;
893 f.write_char(' ')?;
894 }
895
896 show_type_specifier(f, &t.ty, state)
897}
898
899pub fn show_struct_non_declaration<F>(
901 f: &mut F,
902 st: &ast::StructSpecifier,
903 state: &mut FormattingState<'_>,
904) -> std::fmt::Result
905where
906 F: Write + ?Sized,
907{
908 f.write_str("struct ")?;
909
910 if let Some(ref name) = st.name {
911 write!(f, "{}", name)?;
912 }
913
914 state.enter_block(f)?;
915
916 for field in &st.fields {
917 state.flush_line(f)?;
918 show_struct_field(f, field, state)?;
919 state.write_struct_field_separator(f)?;
920 }
921
922 state.exit_block(f)?;
923
924 Ok(())
925}
926
927pub fn show_struct<F>(
929 f: &mut F,
930 st: &ast::StructSpecifier,
931 state: &mut FormattingState<'_>,
932) -> std::fmt::Result
933where
934 F: Write + ?Sized,
935{
936 show_struct_non_declaration(f, st, state)?;
937 state.write_struct_declaration_terminator(f)
938}
939
940pub fn show_struct_field<F>(
942 f: &mut F,
943 field: &ast::StructFieldSpecifier,
944 state: &mut FormattingState<'_>,
945) -> std::fmt::Result
946where
947 F: Write + ?Sized,
948{
949 if let Some(ref qual) = field.qualifier {
950 show_type_qualifier(f, qual, state)?;
951 f.write_char(' ')?;
952 }
953
954 show_type_specifier(f, &field.ty, state)?;
955 f.write_char(' ')?;
956
957 let mut identifiers = field.identifiers.iter();
959 let identifier = identifiers.next().unwrap();
960
961 show_arrayed_identifier(f, identifier, state)?;
962
963 for identifier in identifiers {
965 state.write_list_separator(f)?;
966 show_arrayed_identifier(f, identifier, state)?;
967 }
968
969 Ok(())
970}
971
972pub fn show_array_spec<F>(
974 f: &mut F,
975 a: &ast::ArraySpecifier,
976 state: &mut FormattingState<'_>,
977) -> std::fmt::Result
978where
979 F: Write + ?Sized,
980{
981 for dimension in &a.dimensions {
982 match **dimension {
983 ast::ArraySpecifierDimensionData::Unsized => f.write_str("[]")?,
984 ast::ArraySpecifierDimensionData::ExplicitlySized(ref e) => {
985 f.write_char('[')?;
986 show_expr(f, e, state)?;
987 f.write_char(']')?
988 }
989 }
990 }
991
992 Ok(())
993}
994
995pub fn show_arrayed_identifier<F>(
997 f: &mut F,
998 a: &ast::ArrayedIdentifier,
999 state: &mut FormattingState<'_>,
1000) -> std::fmt::Result
1001where
1002 F: Write + ?Sized,
1003{
1004 write!(f, "{}", a.ident)?;
1005
1006 if let Some(ref arr_spec) = a.array_spec {
1007 show_array_spec(f, arr_spec, state)?;
1008 }
1009
1010 Ok(())
1011}
1012
1013pub fn show_type_qualifier<F>(
1015 f: &mut F,
1016 q: &ast::TypeQualifier,
1017 state: &mut FormattingState<'_>,
1018) -> std::fmt::Result
1019where
1020 F: Write + ?Sized,
1021{
1022 let mut qualifiers = q.qualifiers.iter();
1023 let first = qualifiers.next().unwrap();
1024
1025 show_type_qualifier_spec(f, first, state)?;
1026
1027 for qual_spec in qualifiers {
1028 f.write_char(' ')?;
1029 show_type_qualifier_spec(f, qual_spec, state)?;
1030 }
1031
1032 Ok(())
1033}
1034
1035pub fn show_type_qualifier_spec<F>(
1037 f: &mut F,
1038 q: &ast::TypeQualifierSpec,
1039 state: &mut FormattingState<'_>,
1040) -> std::fmt::Result
1041where
1042 F: Write + ?Sized,
1043{
1044 match **q {
1045 ast::TypeQualifierSpecData::Storage(ref st) => show_storage_qualifier(f, st, state),
1046 ast::TypeQualifierSpecData::Layout(ref l) => show_layout_qualifier(f, l, state),
1047 ast::TypeQualifierSpecData::Precision(ref p) => show_precision_qualifier(f, p, state),
1048 ast::TypeQualifierSpecData::Interpolation(ref i) => {
1049 show_interpolation_qualifier(f, i, state)
1050 }
1051 ast::TypeQualifierSpecData::Invariant => f.write_str("invariant"),
1052 ast::TypeQualifierSpecData::Precise => f.write_str("precise"),
1053 }
1054}
1055
1056pub fn show_storage_qualifier<F>(
1058 f: &mut F,
1059 q: &ast::StorageQualifier,
1060 state: &mut FormattingState<'_>,
1061) -> std::fmt::Result
1062where
1063 F: Write + ?Sized,
1064{
1065 match **q {
1066 ast::StorageQualifierData::Const => f.write_str("const"),
1067 ast::StorageQualifierData::InOut => f.write_str("inout"),
1068 ast::StorageQualifierData::In => f.write_str("in"),
1069 ast::StorageQualifierData::Out => f.write_str("out"),
1070 ast::StorageQualifierData::Centroid => f.write_str("centroid"),
1071 ast::StorageQualifierData::Patch => f.write_str("patch"),
1072 ast::StorageQualifierData::Sample => f.write_str("sample"),
1073 ast::StorageQualifierData::Uniform => f.write_str("uniform"),
1074 ast::StorageQualifierData::Buffer => f.write_str("buffer"),
1075 ast::StorageQualifierData::Shared => f.write_str("shared"),
1076 ast::StorageQualifierData::Coherent => f.write_str("coherent"),
1077 ast::StorageQualifierData::Volatile => f.write_str("volatile"),
1078 ast::StorageQualifierData::Restrict => f.write_str("restrict"),
1079 ast::StorageQualifierData::ReadOnly => f.write_str("readonly"),
1080 ast::StorageQualifierData::WriteOnly => f.write_str("writeonly"),
1081 ast::StorageQualifierData::Attribute => f.write_str("attribute"),
1082 ast::StorageQualifierData::Varying => f.write_str("varying"),
1083 ast::StorageQualifierData::Subroutine(ref n) => show_subroutine(f, n, state),
1084 }
1085}
1086
1087pub fn show_subroutine<F>(
1089 f: &mut F,
1090 types: &[ast::TypeSpecifier],
1091 state: &mut FormattingState<'_>,
1092) -> std::fmt::Result
1093where
1094 F: Write + ?Sized,
1095{
1096 f.write_str("subroutine")?;
1097
1098 if !types.is_empty() {
1099 f.write_char('(')?;
1100
1101 let mut types_iter = types.iter();
1102 let first = types_iter.next().unwrap();
1103
1104 show_type_specifier(f, first, state)?;
1105
1106 for type_name in types_iter {
1107 state.write_list_separator(f)?;
1108 show_type_specifier(f, type_name, state)?;
1109 }
1110
1111 f.write_char(')')?;
1112 }
1113
1114 Ok(())
1115}
1116
1117pub fn show_layout_qualifier<F>(
1119 f: &mut F,
1120 l: &ast::LayoutQualifier,
1121 state: &mut FormattingState<'_>,
1122) -> std::fmt::Result
1123where
1124 F: Write + ?Sized,
1125{
1126 let mut qualifiers = l.ids.iter();
1127 let first = qualifiers.next().unwrap();
1128
1129 f.write_str("layout(")?;
1130 show_layout_qualifier_spec(f, first, state)?;
1131
1132 for qual_spec in qualifiers {
1133 state.write_list_separator(f)?;
1134 show_layout_qualifier_spec(f, qual_spec, state)?;
1135 }
1136
1137 f.write_char(')')
1138}
1139
1140pub fn show_layout_qualifier_spec<F>(
1142 f: &mut F,
1143 l: &ast::LayoutQualifierSpec,
1144 state: &mut FormattingState<'_>,
1145) -> std::fmt::Result
1146where
1147 F: Write + ?Sized,
1148{
1149 match **l {
1150 ast::LayoutQualifierSpecData::Identifier(ref i, Some(ref e)) => {
1151 write!(f, "{i}")?;
1152 state.write_binary_op(f, "=")?;
1153 show_expr(f, e, state)
1154 }
1155 ast::LayoutQualifierSpecData::Identifier(ref i, None) => show_identifier(f, i, state),
1156 ast::LayoutQualifierSpecData::Shared => f.write_str("shared"),
1157 }
1158}
1159
1160pub fn show_precision_qualifier<F>(
1162 f: &mut F,
1163 p: &ast::PrecisionQualifier,
1164 _: &mut FormattingState<'_>,
1165) -> std::fmt::Result
1166where
1167 F: Write + ?Sized,
1168{
1169 match **p {
1170 ast::PrecisionQualifierData::High => f.write_str("highp"),
1171 ast::PrecisionQualifierData::Medium => f.write_str("mediump"),
1172 ast::PrecisionQualifierData::Low => f.write_str("lowp"),
1173 }
1174}
1175
1176pub fn show_interpolation_qualifier<F>(
1178 f: &mut F,
1179 i: &ast::InterpolationQualifier,
1180 _: &mut FormattingState<'_>,
1181) -> std::fmt::Result
1182where
1183 F: Write + ?Sized,
1184{
1185 match **i {
1186 ast::InterpolationQualifierData::Smooth => f.write_str("smooth"),
1187 ast::InterpolationQualifierData::Flat => f.write_str("flat"),
1188 ast::InterpolationQualifierData::NoPerspective => f.write_str("noperspective"),
1189 }
1190}
1191
1192pub fn show_float<F>(f: &mut F, x: f32, _: &mut FormattingState<'_>) -> std::fmt::Result
1194where
1195 F: Write + ?Sized,
1196{
1197 if x.fract() == 0. {
1198 write!(f, "{}.", x)
1199 } else {
1200 write!(f, "{}", x)
1201 }
1202}
1203
1204pub fn show_double<F>(f: &mut F, x: f64, _: &mut FormattingState<'_>) -> std::fmt::Result
1206where
1207 F: Write + ?Sized,
1208{
1209 if x.fract() == 0. {
1210 write!(f, "{}.lf", x)
1211 } else {
1212 write!(f, "{}lf", x)
1213 }
1214}
1215
1216pub fn show_expr<F>(
1218 f: &mut F,
1219 expr: &ast::Expr,
1220 state: &mut FormattingState<'_>,
1221) -> std::fmt::Result
1222where
1223 F: Write + ?Sized,
1224{
1225 match **expr {
1226 ast::ExprData::Variable(ref i) => show_identifier(f, i, state),
1227 ast::ExprData::IntConst(ref x) => write!(f, "{}", x),
1228 ast::ExprData::UIntConst(ref x) => write!(f, "{}u", x),
1229 ast::ExprData::BoolConst(ref x) => write!(f, "{}", x),
1230 ast::ExprData::FloatConst(ref x) => show_float(f, *x, state),
1231 ast::ExprData::DoubleConst(ref x) => show_double(f, *x, state),
1232 ast::ExprData::Unary(ref op, ref e) => {
1233 show_unary_op(f, op, state)?;
1235
1236 if e.precedence() > op.precedence() {
1237 f.write_char('(')?;
1238 show_expr(f, e, state)?;
1239 f.write_char(')')
1240 } else if let ast::ExprData::Unary(eop, _) = &***e {
1241 if eop == op && (**eop == ast::UnaryOpData::Add || **eop == ast::UnaryOpData::Minus)
1243 {
1244 f.write_char('(')?;
1245 show_expr(f, e, state)?;
1246 f.write_char(')')
1247 } else {
1248 show_expr(f, e, state)
1249 }
1250 } else {
1251 show_expr(f, e, state)
1252 }
1253 }
1254 ast::ExprData::Binary(ref op, ref l, ref r) => {
1255 if l.precedence() <= op.precedence() {
1258 show_expr(f, l, state)?;
1259 } else {
1260 f.write_char('(')?;
1261 show_expr(f, l, state)?;
1262 f.write_char(')')?;
1263 }
1264
1265 show_binary_op(f, op, state)?;
1266
1267 if r.precedence() < op.precedence() {
1268 show_expr(f, r, state)
1269 } else {
1270 f.write_char('(')?;
1271 show_expr(f, r, state)?;
1272 f.write_char(')')
1273 }
1274 }
1275 ast::ExprData::Ternary(ref c, ref st, ref e) => {
1276 if c.precedence() < expr.precedence() {
1279 show_expr(f, c, state)?;
1280 } else {
1281 f.write_char('(')?;
1282 show_expr(f, c, state)?;
1283 f.write_char(')')?;
1284 }
1285 state.write_binary_op(f, "?")?;
1286 show_expr(f, st, state)?;
1287 state.write_binary_op(f, ":")?;
1288 if e.precedence() <= expr.precedence() {
1289 show_expr(f, e, state)
1290 } else {
1291 f.write_char('(')?;
1292 show_expr(f, e, state)?;
1293 f.write_char(')')
1294 }
1295 }
1296 ast::ExprData::Assignment(ref v, ref op, ref e) => {
1297 if v.precedence() < op.precedence() {
1300 show_expr(f, v, state)?;
1301 } else {
1302 f.write_char('(')?;
1303 show_expr(f, v, state)?;
1304 f.write_char(')')?;
1305 }
1306
1307 show_assignment_op(f, op, state)?;
1308
1309 if e.precedence() <= op.precedence() {
1310 show_expr(f, e, state)
1311 } else {
1312 f.write_char('(')?;
1313 show_expr(f, e, state)?;
1314 f.write_char(')')
1315 }
1316 }
1317 ast::ExprData::Bracket(ref e, ref a) => {
1318 if e.precedence() <= expr.precedence() {
1321 show_expr(f, e, state)?;
1322 } else {
1323 f.write_char('(')?;
1324 show_expr(f, e, state)?;
1325 f.write_char(')')?;
1326 }
1327
1328 f.write_char('[')?;
1329 show_expr(f, a, state)?;
1330 f.write_char(']')
1331 }
1332 ast::ExprData::FunCall(ref fun, ref args) => {
1333 show_function_identifier(f, fun, state)?;
1334 f.write_char('(')?;
1335
1336 if !args.is_empty() {
1337 let mut args_iter = args.iter();
1338 let first = args_iter.next().unwrap();
1339 show_expr(f, first, state)?;
1340
1341 for e in args_iter {
1342 state.write_list_separator(f)?;
1343 show_expr(f, e, state)?;
1344 }
1345 }
1346
1347 f.write_char(')')
1348 }
1349 ast::ExprData::Dot(ref e, ref i) => {
1350 if e.precedence() <= expr.precedence() {
1353 show_expr(f, e, state)?;
1354 } else {
1355 f.write_char('(')?;
1356 show_expr(f, e, state)?;
1357 f.write_char(')')?;
1358 }
1359 f.write_char('.')?;
1360 show_identifier(f, i, state)
1361 }
1362 ast::ExprData::PostInc(ref e) => {
1363 if e.precedence() < expr.precedence() {
1366 show_expr(f, e, state)?;
1367 } else {
1368 f.write_char('(')?;
1369 show_expr(f, e, state)?;
1370 f.write_char(')')?;
1371 }
1372
1373 f.write_str("++")
1374 }
1375 ast::ExprData::PostDec(ref e) => {
1376 if e.precedence() < expr.precedence() {
1379 show_expr(f, e, state)?;
1380 } else {
1381 f.write_char('(')?;
1382 show_expr(f, e, state)?;
1383 f.write_char(')')?;
1384 }
1385
1386 f.write_str("--")
1387 }
1388 ast::ExprData::Comma(ref a, ref b) => {
1389 if a.precedence() <= expr.precedence() {
1392 show_expr(f, a, state)?;
1393 } else {
1394 f.write_char('(')?;
1395 show_expr(f, a, state)?;
1396 f.write_char(')')?;
1397 }
1398
1399 state.write_list_separator(f)?;
1400
1401 if b.precedence() < expr.precedence() {
1402 show_expr(f, b, state)
1403 } else {
1404 f.write_char('(')?;
1405 show_expr(f, b, state)?;
1406 f.write_char(')')
1407 }
1408 }
1409 }
1410}
1411
1412pub fn show_path<F>(f: &mut F, path: &ast::Path, _: &mut FormattingState<'_>) -> std::fmt::Result
1414where
1415 F: Write + ?Sized,
1416{
1417 match **path {
1418 ast::PathData::Absolute(ref s) => write!(f, "<{}>", s),
1419 ast::PathData::Relative(ref s) => write!(f, "\"{}\"", s),
1420 }
1421}
1422
1423pub fn show_unary_op<F>(
1425 f: &mut F,
1426 op: &ast::UnaryOp,
1427 _: &mut FormattingState<'_>,
1428) -> std::fmt::Result
1429where
1430 F: Write + ?Sized,
1431{
1432 match **op {
1433 ast::UnaryOpData::Inc => f.write_str("++"),
1434 ast::UnaryOpData::Dec => f.write_str("--"),
1435 ast::UnaryOpData::Add => f.write_str("+"),
1436 ast::UnaryOpData::Minus => f.write_str("-"),
1437 ast::UnaryOpData::Not => f.write_str("!"),
1438 ast::UnaryOpData::Complement => f.write_str("~"),
1439 }
1440}
1441
1442pub fn show_binary_op<F>(
1444 f: &mut F,
1445 op: &ast::BinaryOp,
1446 state: &mut FormattingState<'_>,
1447) -> std::fmt::Result
1448where
1449 F: Write + ?Sized,
1450{
1451 match **op {
1452 ast::BinaryOpData::Or => state.write_binary_op(f, "||"),
1453 ast::BinaryOpData::Xor => state.write_binary_op(f, "^^"),
1454 ast::BinaryOpData::And => state.write_binary_op(f, "&&"),
1455 ast::BinaryOpData::BitOr => state.write_binary_op(f, "|"),
1456 ast::BinaryOpData::BitXor => state.write_binary_op(f, "^"),
1457 ast::BinaryOpData::BitAnd => state.write_binary_op(f, "&"),
1458 ast::BinaryOpData::Equal => state.write_binary_op(f, "=="),
1459 ast::BinaryOpData::NonEqual => state.write_binary_op(f, "!="),
1460 ast::BinaryOpData::Lt => state.write_binary_op(f, "<"),
1461 ast::BinaryOpData::Gt => state.write_binary_op(f, ">"),
1462 ast::BinaryOpData::Lte => state.write_binary_op(f, "<="),
1463 ast::BinaryOpData::Gte => state.write_binary_op(f, ">="),
1464 ast::BinaryOpData::LShift => state.write_binary_op(f, "<<"),
1465 ast::BinaryOpData::RShift => state.write_binary_op(f, ">>"),
1466 ast::BinaryOpData::Add => state.write_binary_op(f, "+"),
1467 ast::BinaryOpData::Sub => state.write_binary_op(f, "-"),
1468 ast::BinaryOpData::Mult => state.write_binary_op(f, "*"),
1469 ast::BinaryOpData::Div => state.write_binary_op(f, "/"),
1470 ast::BinaryOpData::Mod => state.write_binary_op(f, "%"),
1471 }
1472}
1473
1474pub fn show_assignment_op<F>(
1476 f: &mut F,
1477 op: &ast::AssignmentOp,
1478 state: &mut FormattingState<'_>,
1479) -> std::fmt::Result
1480where
1481 F: Write + ?Sized,
1482{
1483 match **op {
1484 ast::AssignmentOpData::Equal => state.write_binary_op(f, "="),
1485 ast::AssignmentOpData::Mult => state.write_binary_op(f, "*="),
1486 ast::AssignmentOpData::Div => state.write_binary_op(f, "/="),
1487 ast::AssignmentOpData::Mod => state.write_binary_op(f, "%="),
1488 ast::AssignmentOpData::Add => state.write_binary_op(f, "+="),
1489 ast::AssignmentOpData::Sub => state.write_binary_op(f, "-="),
1490 ast::AssignmentOpData::LShift => state.write_binary_op(f, "<<="),
1491 ast::AssignmentOpData::RShift => state.write_binary_op(f, ">>="),
1492 ast::AssignmentOpData::And => state.write_binary_op(f, "&="),
1493 ast::AssignmentOpData::Xor => state.write_binary_op(f, "^="),
1494 ast::AssignmentOpData::Or => state.write_binary_op(f, "|="),
1495 }
1496}
1497
1498pub fn show_function_identifier<F>(
1500 f: &mut F,
1501 i: &ast::FunIdentifier,
1502 state: &mut FormattingState<'_>,
1503) -> std::fmt::Result
1504where
1505 F: Write + ?Sized,
1506{
1507 match **i {
1508 ast::FunIdentifierData::TypeSpecifier(ref n) => show_type_specifier(f, n, state),
1509 ast::FunIdentifierData::Expr(ref e) => show_expr(f, e, state),
1510 }
1511}
1512
1513pub fn show_declaration<F>(
1515 f: &mut F,
1516 d: &ast::Declaration,
1517 state: &mut FormattingState<'_>,
1518) -> std::fmt::Result
1519where
1520 F: Write + ?Sized,
1521{
1522 match **d {
1523 ast::DeclarationData::FunctionPrototype(ref proto) => {
1524 show_function_prototype(f, proto, state)?;
1525 }
1526 ast::DeclarationData::InitDeclaratorList(ref list) => {
1527 show_init_declarator_list(f, list, state)?;
1528 }
1529 ast::DeclarationData::Precision(ref qual, ref ty) => {
1530 f.write_str("precision ")?;
1531 show_precision_qualifier(f, qual, state)?;
1532 f.write_str(" ")?;
1533 show_type_specifier(f, ty, state)?;
1534 }
1535 ast::DeclarationData::Block(ref block) => {
1536 show_block(f, block, state)?;
1537 }
1538 ast::DeclarationData::Invariant(ref ident) => {
1539 f.write_str("invariant")?;
1540 f.write_char(' ')?;
1541 show_identifier(f, ident, state)?;
1542 }
1543 ast::DeclarationData::TypeOnly(ref q) => {
1544 show_type_qualifier(f, q, state)?;
1545 }
1546 }
1547
1548 state.write_declaration_terminator(f)
1549}
1550
1551pub fn show_function_prototype<F>(
1553 f: &mut F,
1554 fp: &ast::FunctionPrototype,
1555 state: &mut FormattingState<'_>,
1556) -> std::fmt::Result
1557where
1558 F: Write + ?Sized,
1559{
1560 show_fully_specified_type(f, &fp.ty, state)?;
1561 f.write_char(' ')?;
1562 show_identifier(f, &fp.name, state)?;
1563
1564 f.write_char('(')?;
1565
1566 if !fp.parameters.is_empty() {
1567 let mut iter = fp.parameters.iter();
1568 let first = iter.next().unwrap();
1569 show_function_parameter_declaration(f, first, state)?;
1570
1571 for param in iter {
1572 state.write_list_separator(f)?;
1573 show_function_parameter_declaration(f, param, state)?;
1574 }
1575 }
1576
1577 f.write_char(')')
1578}
1579pub fn show_function_parameter_declaration<F>(
1581 f: &mut F,
1582 p: &ast::FunctionParameterDeclaration,
1583 state: &mut FormattingState<'_>,
1584) -> std::fmt::Result
1585where
1586 F: Write + ?Sized,
1587{
1588 match **p {
1589 ast::FunctionParameterDeclarationData::Named(ref qual, ref fpd) => {
1590 if let Some(ref q) = *qual {
1591 show_type_qualifier(f, q, state)?;
1592 f.write_char(' ')?;
1593 }
1594
1595 show_function_parameter_declarator(f, fpd, state)
1596 }
1597 ast::FunctionParameterDeclarationData::Unnamed(ref qual, ref ty) => {
1598 if let Some(ref q) = *qual {
1599 show_type_qualifier(f, q, state)?;
1600 f.write_char(' ')?;
1601 }
1602
1603 show_type_specifier(f, ty, state)
1604 }
1605 }
1606}
1607
1608pub fn show_function_parameter_declarator<F>(
1610 f: &mut F,
1611 p: &ast::FunctionParameterDeclarator,
1612 state: &mut FormattingState<'_>,
1613) -> std::fmt::Result
1614where
1615 F: Write + ?Sized,
1616{
1617 show_type_specifier(f, &p.ty, state)?;
1618 f.write_char(' ')?;
1619 show_arrayed_identifier(f, &p.ident, state)
1620}
1621
1622pub fn show_init_declarator_list<F>(
1624 f: &mut F,
1625 i: &ast::InitDeclaratorList,
1626 state: &mut FormattingState<'_>,
1627) -> std::fmt::Result
1628where
1629 F: Write + ?Sized,
1630{
1631 show_single_declaration(f, &i.head, state)?;
1632
1633 for decl in &i.tail {
1634 state.write_list_separator(f)?;
1635 show_single_declaration_no_type(f, decl, state)?;
1636 }
1637
1638 Ok(())
1639}
1640
1641pub fn show_single_declaration<F>(
1643 f: &mut F,
1644 d: &ast::SingleDeclaration,
1645 state: &mut FormattingState<'_>,
1646) -> std::fmt::Result
1647where
1648 F: Write + ?Sized,
1649{
1650 show_fully_specified_type(f, &d.ty, state)?;
1651
1652 if let Some(ref name) = d.name {
1653 f.write_char(' ')?;
1654 show_identifier(f, name, state)?;
1655 }
1656
1657 if let Some(ref arr_spec) = d.array_specifier {
1658 show_array_spec(f, arr_spec, state)?;
1659 }
1660
1661 if let Some(ref initializer) = d.initializer {
1662 state.write_binary_op(f, "=")?;
1663 show_initializer(f, initializer, state)?;
1664 }
1665
1666 Ok(())
1667}
1668
1669pub fn show_single_declaration_no_type<F>(
1671 f: &mut F,
1672 d: &ast::SingleDeclarationNoType,
1673 state: &mut FormattingState<'_>,
1674) -> std::fmt::Result
1675where
1676 F: Write + ?Sized,
1677{
1678 show_arrayed_identifier(f, &d.ident, state)?;
1679
1680 if let Some(ref initializer) = d.initializer {
1681 state.write_binary_op(f, "=")?;
1682 show_initializer(f, initializer, state)?;
1683 }
1684
1685 Ok(())
1686}
1687
1688pub fn show_initializer<F>(
1690 f: &mut F,
1691 i: &ast::Initializer,
1692 state: &mut FormattingState<'_>,
1693) -> std::fmt::Result
1694where
1695 F: Write + ?Sized,
1696{
1697 match **i {
1698 ast::InitializerData::Simple(ref e) => show_expr(f, e, state),
1699 ast::InitializerData::List(ref list) => {
1700 let mut iter = list.iter();
1701 let first = iter.next().unwrap();
1702
1703 state.enter_initializer_list(f)?;
1704
1705 show_initializer(f, first, state)?;
1706
1707 for ini in iter {
1708 state.write_list_separator(f)?;
1709 show_initializer(f, ini, state)?;
1710 }
1711
1712 state.end_initializer_list(f)
1713 }
1714 }
1715}
1716
1717pub fn show_block<F>(f: &mut F, b: &ast::Block, state: &mut FormattingState<'_>) -> std::fmt::Result
1719where
1720 F: Write + ?Sized,
1721{
1722 show_type_qualifier(f, &b.qualifier, state)?;
1723 f.write_char(' ')?;
1724 show_identifier(f, &b.name, state)?;
1725
1726 state.enter_block(f)?;
1727
1728 for field in &b.fields {
1729 state.flush_line(f)?;
1730 show_struct_field(f, field, state)?;
1731 state.write_struct_field_separator(f)?;
1732 }
1733
1734 state.exit_block(f)?;
1735
1736 if let Some(ref ident) = b.identifier {
1737 show_arrayed_identifier(f, ident, state)?;
1738 }
1739
1740 Ok(())
1741}
1742
1743pub fn show_function_definition<F>(
1745 f: &mut F,
1746 fd: &ast::FunctionDefinition,
1747 state: &mut FormattingState<'_>,
1748) -> std::fmt::Result
1749where
1750 F: Write + ?Sized,
1751{
1752 show_function_prototype(f, &fd.prototype, state)?;
1753 state.enter_function_definition_statement();
1754 show_compound_statement(f, &fd.statement, state)?;
1755 state.flush_line(f)?;
1756 state.write_function_definition_terminator(f)
1757}
1758
1759pub fn show_compound_statement<F>(
1761 f: &mut F,
1762 cst: &ast::CompoundStatement,
1763 state: &mut FormattingState<'_>,
1764) -> std::fmt::Result
1765where
1766 F: Write + ?Sized,
1767{
1768 let collapse = !state.in_function_definition_statement
1770 && state.settings.collapse_single_item_compound_statements
1771 && cst.statement_list.len() == 1;
1772
1773 if collapse {
1774 state.enter_collapsed_compound_statement()?;
1775 } else {
1776 state.enter_compound_statement_block(f)?;
1777 }
1778
1779 state.consume_function_definition_statement();
1781
1782 for st in &cst.statement_list {
1783 show_statement(f, st, state)?;
1784 }
1785
1786 if collapse {
1787 state.exit_collapsed_compound_statement()?;
1788 } else {
1789 state.exit_block(f)?;
1790 }
1791
1792 Ok(())
1793}
1794
1795pub fn show_statement<F>(
1797 f: &mut F,
1798 st: &ast::Statement,
1799 state: &mut FormattingState<'_>,
1800) -> std::fmt::Result
1801where
1802 F: Write + ?Sized,
1803{
1804 state.flush_line(f)?;
1805
1806 match **st {
1807 ast::StatementData::Declaration(ref d) => show_declaration(f, d, state),
1808 ast::StatementData::Expression(ref e) => show_expression_statement(f, e, state),
1809 ast::StatementData::Selection(ref st) => show_selection_statement(f, st, state),
1810 ast::StatementData::Switch(ref st) => show_switch_statement(f, st, state),
1811 ast::StatementData::CaseLabel(ref cl) => show_case_label(f, cl, state),
1812 ast::StatementData::Iteration(ref i) => show_iteration_statement(f, i, state),
1813 ast::StatementData::Jump(ref j) => show_jump_statement(f, j, state),
1814 ast::StatementData::Compound(ref c) => show_compound_statement(f, c, state),
1815 }
1816}
1817
1818pub fn show_expression_statement<F>(
1820 f: &mut F,
1821 est: &ast::ExprStatement,
1822 state: &mut FormattingState<'_>,
1823) -> std::fmt::Result
1824where
1825 F: Write + ?Sized,
1826{
1827 if let Some(ref e) = est.0 {
1828 show_expr(f, e, state)?;
1829 }
1830
1831 state.write_statement_terminator(f)
1832}
1833
1834pub fn show_selection_statement<F>(
1836 f: &mut F,
1837 sst: &ast::SelectionStatement,
1838 state: &mut FormattingState<'_>,
1839) -> std::fmt::Result
1840where
1841 F: Write + ?Sized,
1842{
1843 f.write_str("if")?;
1844 state.write_statement_opening_parenthesis(f)?;
1845 show_expr(f, &sst.cond, state)?;
1846 state.write_statement_closing_parenthesis(f)?;
1847 show_selection_rest_statement(f, &sst.rest, state)
1848}
1849
1850pub fn show_selection_rest_statement<F>(
1852 f: &mut F,
1853 sst: &ast::SelectionRestStatement,
1854 state: &mut FormattingState<'_>,
1855) -> std::fmt::Result
1856where
1857 F: Write + ?Sized,
1858{
1859 match **sst {
1860 ast::SelectionRestStatementData::Statement(ref if_st) => show_statement(f, if_st, state),
1861 ast::SelectionRestStatementData::Else(ref if_st, ref else_st) => {
1862 show_statement(f, if_st, state)?;
1863 state.write_else(f)?;
1864 state.consume_newline();
1867 show_statement(f, else_st, state)
1868 }
1869 }
1870}
1871
1872pub fn show_switch_statement<F>(
1874 f: &mut F,
1875 sst: &ast::SwitchStatement,
1876 state: &mut FormattingState<'_>,
1877) -> std::fmt::Result
1878where
1879 F: Write + ?Sized,
1880{
1881 f.write_str("switch")?;
1882 state.write_statement_opening_parenthesis(f)?;
1883 show_expr(f, &sst.head, state)?;
1884 f.write_char(')')?;
1887
1888 state.enter_block(f)?;
1889
1890 for st in &sst.body {
1891 show_statement(f, st, state)?;
1892 }
1893
1894 state.exit_block(f)
1895}
1896
1897pub fn show_case_label<F>(
1899 f: &mut F,
1900 cl: &ast::CaseLabel,
1901 state: &mut FormattingState<'_>,
1902) -> std::fmt::Result
1903where
1904 F: Write + ?Sized,
1905{
1906 match **cl {
1907 ast::CaseLabelData::Case(ref e) => {
1908 f.write_str("case ")?;
1909 show_expr(f, e, state)?;
1910 state.enter_case_label(f)
1911 }
1912 ast::CaseLabelData::Def => {
1913 f.write_str("default")?;
1914 state.enter_case_label(f)
1915 }
1916 }
1917}
1918
1919pub fn show_iteration_statement<F>(
1921 f: &mut F,
1922 ist: &ast::IterationStatement,
1923 state: &mut FormattingState<'_>,
1924) -> std::fmt::Result
1925where
1926 F: Write + ?Sized,
1927{
1928 match **ist {
1929 ast::IterationStatementData::While(ref cond, ref body) => {
1930 f.write_str("while")?;
1931 state.write_statement_opening_parenthesis(f)?;
1932 show_condition(f, cond, state)?;
1933 state.write_statement_closing_parenthesis(f)?;
1934 show_statement(f, body, state)
1935 }
1936 ast::IterationStatementData::DoWhile(ref body, ref cond) => {
1937 f.write_str("do ")?;
1938 show_statement(f, body, state)?;
1939 f.write_str(" while")?;
1940 state.write_statement_opening_parenthesis(f)?;
1941 show_expr(f, cond, state)?;
1942 f.write_char(')')?;
1945 state.write_statement_terminator(f)
1946 }
1947 ast::IterationStatementData::For(ref init, ref rest, ref body) => {
1948 f.write_str("for")?;
1949 state.write_statement_opening_parenthesis(f)?;
1950 show_for_init_statement(f, init, state)?;
1951 state.flush_space(f)?;
1952 show_for_rest_statement(f, rest, state)?;
1953 state.write_statement_closing_parenthesis(f)?;
1954 show_statement(f, body, state)
1955 }
1956 }
1957}
1958
1959pub fn show_condition<F>(
1961 f: &mut F,
1962 c: &ast::Condition,
1963 state: &mut FormattingState<'_>,
1964) -> std::fmt::Result
1965where
1966 F: Write + ?Sized,
1967{
1968 match **c {
1969 ast::ConditionData::Expr(ref e) => show_expr(f, e, state),
1970 ast::ConditionData::Assignment(ref ty, ref name, ref initializer) => {
1971 show_fully_specified_type(f, ty, state)?;
1972 f.write_char(' ')?;
1973 show_identifier(f, name, state)?;
1974 state.write_binary_op(f, "=")?;
1975 show_initializer(f, initializer, state)
1976 }
1977 }
1978}
1979
1980pub fn show_for_init_statement<F>(
1982 f: &mut F,
1983 i: &ast::ForInitStatement,
1984 state: &mut FormattingState<'_>,
1985) -> std::fmt::Result
1986where
1987 F: Write + ?Sized,
1988{
1989 match **i {
1990 ast::ForInitStatementData::Expression(ref expr) => {
1991 if let Some(ref e) = *expr {
1992 show_expr(f, e, state)?;
1993 }
1994
1995 state.write_for_statement_separator(f)
1996 }
1997 ast::ForInitStatementData::Declaration(ref d) => show_declaration(f, d, state),
1998 }
1999}
2000
2001pub fn show_for_rest_statement<F>(
2003 f: &mut F,
2004 r: &ast::ForRestStatement,
2005 state: &mut FormattingState<'_>,
2006) -> std::fmt::Result
2007where
2008 F: Write + ?Sized,
2009{
2010 if let Some(ref cond) = r.condition {
2011 show_condition(f, cond, state)?;
2012 }
2013
2014 state.write_for_statement_separator(f)?;
2015
2016 if let Some(ref e) = r.post_expr {
2017 show_expr(f, e, state)?;
2018 }
2019
2020 Ok(())
2021}
2022
2023pub fn show_jump_statement<F>(
2025 f: &mut F,
2026 j: &ast::JumpStatement,
2027 state: &mut FormattingState<'_>,
2028) -> std::fmt::Result
2029where
2030 F: Write + ?Sized,
2031{
2032 match **j {
2033 ast::JumpStatementData::Continue => f.write_str("continue")?,
2034 ast::JumpStatementData::Break => f.write_str("break")?,
2035 ast::JumpStatementData::Discard => f.write_str("discard")?,
2036 ast::JumpStatementData::Return(ref e) => {
2037 f.write_str("return")?;
2038 if let Some(e) = e {
2039 f.write_char(' ')?;
2040 show_expr(f, e, state)?;
2041 }
2042 }
2043 }
2044
2045 state.write_statement_terminator(f)
2046}
2047
2048pub fn show_preprocessor<F>(
2050 f: &mut F,
2051 pp: &ast::Preprocessor,
2052 state: &mut FormattingState<'_>,
2053) -> std::fmt::Result
2054where
2055 F: Write + ?Sized,
2056{
2057 state.move_to_empty_line(f)?;
2060
2061 match **pp {
2062 ast::PreprocessorData::Define(ref pd) => show_preprocessor_define(f, pd, state)?,
2063 ast::PreprocessorData::Else => show_preprocessor_else(f, state)?,
2064 ast::PreprocessorData::ElseIf(ref pei) => show_preprocessor_elseif(f, pei, state)?,
2065 ast::PreprocessorData::EndIf => show_preprocessor_endif(f, state)?,
2066 ast::PreprocessorData::Error(ref pe) => show_preprocessor_error(f, pe, state)?,
2067 ast::PreprocessorData::If(ref pi) => show_preprocessor_if(f, pi, state)?,
2068 ast::PreprocessorData::IfDef(ref pid) => show_preprocessor_ifdef(f, pid, state)?,
2069 ast::PreprocessorData::IfNDef(ref pind) => show_preprocessor_ifndef(f, pind, state)?,
2070 ast::PreprocessorData::Include(ref pi) => show_preprocessor_include(f, pi, state)?,
2071 ast::PreprocessorData::Line(ref pl) => show_preprocessor_line(f, pl, state)?,
2072 ast::PreprocessorData::Pragma(ref pp) => show_preprocessor_pragma(f, pp, state)?,
2073 ast::PreprocessorData::Undef(ref pu) => show_preprocessor_undef(f, pu, state)?,
2074 ast::PreprocessorData::Version(ref pv) => show_preprocessor_version(f, pv, state)?,
2075 ast::PreprocessorData::Extension(ref pe) => show_preprocessor_extension(f, pe, state)?,
2076 }
2077
2078 state.new_line(true)
2080}
2081
2082pub fn show_preprocessor_define<F>(
2084 f: &mut F,
2085 pd: &ast::PreprocessorDefine,
2086 _: &mut FormattingState<'_>,
2087) -> std::fmt::Result
2088where
2089 F: Write + ?Sized,
2090{
2091 match **pd {
2092 ast::PreprocessorDefineData::ObjectLike {
2093 ref ident,
2094 ref value,
2095 } => write!(f, "#define {} {}", ident, value),
2096
2097 ast::PreprocessorDefineData::FunctionLike {
2098 ref ident,
2099 ref args,
2100 ref value,
2101 } => {
2102 write!(f, "#define {}(", ident)?;
2103
2104 if !args.is_empty() {
2105 write!(f, "{}", &args[0])?;
2106
2107 for arg in &args[1..args.len()] {
2108 write!(f, ", {}", arg)?;
2109 }
2110 }
2111
2112 write!(f, ") {}", value)
2113 }
2114 }
2115}
2116
2117pub fn show_preprocessor_else<F>(f: &mut F, _: &mut FormattingState<'_>) -> std::fmt::Result
2119where
2120 F: Write + ?Sized,
2121{
2122 f.write_str("#else")
2123}
2124
2125pub fn show_preprocessor_elseif<F>(
2127 f: &mut F,
2128 pei: &ast::PreprocessorElseIf,
2129 _: &mut FormattingState<'_>,
2130) -> std::fmt::Result
2131where
2132 F: Write + ?Sized,
2133{
2134 write!(f, "#elif {}", pei.condition)
2135}
2136
2137pub fn show_preprocessor_error<F>(
2139 f: &mut F,
2140 pe: &ast::PreprocessorError,
2141 _: &mut FormattingState<'_>,
2142) -> std::fmt::Result
2143where
2144 F: Write + ?Sized,
2145{
2146 write!(f, "#error {}", pe.message)
2147}
2148
2149pub fn show_preprocessor_endif<F>(f: &mut F, _: &mut FormattingState<'_>) -> std::fmt::Result
2151where
2152 F: Write + ?Sized,
2153{
2154 f.write_str("#endif")
2155}
2156
2157pub fn show_preprocessor_if<F>(
2159 f: &mut F,
2160 pi: &ast::PreprocessorIf,
2161 _: &mut FormattingState<'_>,
2162) -> std::fmt::Result
2163where
2164 F: Write + ?Sized,
2165{
2166 write!(f, "#if {}", pi.condition)
2167}
2168
2169pub fn show_preprocessor_ifdef<F>(
2171 f: &mut F,
2172 pid: &ast::PreprocessorIfDef,
2173 state: &mut FormattingState<'_>,
2174) -> std::fmt::Result
2175where
2176 F: Write + ?Sized,
2177{
2178 f.write_str("#ifdef ")?;
2179 show_identifier(f, &pid.ident, state)
2180}
2181
2182pub fn show_preprocessor_ifndef<F>(
2184 f: &mut F,
2185 pind: &ast::PreprocessorIfNDef,
2186 state: &mut FormattingState<'_>,
2187) -> std::fmt::Result
2188where
2189 F: Write + ?Sized,
2190{
2191 f.write_str("#ifndef ")?;
2192 show_identifier(f, &pind.ident, state)
2193}
2194
2195pub fn show_preprocessor_include<F>(
2197 f: &mut F,
2198 pi: &ast::PreprocessorInclude,
2199 state: &mut FormattingState<'_>,
2200) -> std::fmt::Result
2201where
2202 F: Write + ?Sized,
2203{
2204 f.write_str("#include ")?;
2205 show_path(f, &pi.path, state)
2206}
2207
2208pub fn show_preprocessor_line<F>(
2210 f: &mut F,
2211 pl: &ast::PreprocessorLine,
2212 _: &mut FormattingState<'_>,
2213) -> std::fmt::Result
2214where
2215 F: Write + ?Sized,
2216{
2217 write!(f, "#line {}", pl.line)?;
2218 if let Some(source_string_number) = pl.source_string_number {
2219 write!(f, " {}", source_string_number)?;
2220 }
2221 Ok(())
2222}
2223
2224pub fn show_preprocessor_pragma<F>(
2226 f: &mut F,
2227 pp: &ast::PreprocessorPragma,
2228 _: &mut FormattingState<'_>,
2229) -> std::fmt::Result
2230where
2231 F: Write + ?Sized,
2232{
2233 write!(f, "#pragma {}", pp.command)
2234}
2235
2236pub fn show_preprocessor_undef<F>(
2238 f: &mut F,
2239 pud: &ast::PreprocessorUndef,
2240 state: &mut FormattingState<'_>,
2241) -> std::fmt::Result
2242where
2243 F: Write + ?Sized,
2244{
2245 f.write_str("#undef ")?;
2246 show_identifier(f, &pud.name, state)
2247}
2248
2249pub fn show_preprocessor_version<F>(
2251 f: &mut F,
2252 pv: &ast::PreprocessorVersion,
2253 _: &mut FormattingState<'_>,
2254) -> std::fmt::Result
2255where
2256 F: Write + ?Sized,
2257{
2258 write!(f, "#version {}", pv.version)?;
2259
2260 if let Some(ref profile) = pv.profile {
2261 match **profile {
2262 ast::PreprocessorVersionProfileData::Core => {
2263 f.write_str(" core")?;
2264 }
2265 ast::PreprocessorVersionProfileData::Compatibility => {
2266 f.write_str(" compatibility")?;
2267 }
2268 ast::PreprocessorVersionProfileData::Es => {
2269 f.write_str(" es")?;
2270 }
2271 }
2272 }
2273
2274 Ok(())
2275}
2276
2277pub fn show_preprocessor_extension<F>(
2279 f: &mut F,
2280 pe: &ast::PreprocessorExtension,
2281 _: &mut FormattingState<'_>,
2282) -> std::fmt::Result
2283where
2284 F: Write + ?Sized,
2285{
2286 f.write_str("#extension ")?;
2287
2288 match *pe.name {
2289 ast::PreprocessorExtensionNameData::All => {
2290 f.write_str("all")?;
2291 }
2292 ast::PreprocessorExtensionNameData::Specific(ref n) => {
2293 f.write_str(n)?;
2294 }
2295 }
2296
2297 if let Some(ref behavior) = pe.behavior {
2298 match **behavior {
2299 ast::PreprocessorExtensionBehaviorData::Require => {
2300 f.write_str(" : require")?;
2301 }
2302 ast::PreprocessorExtensionBehaviorData::Enable => {
2303 f.write_str(" : enable")?;
2304 }
2305 ast::PreprocessorExtensionBehaviorData::Warn => {
2306 f.write_str(" : warn")?;
2307 }
2308 ast::PreprocessorExtensionBehaviorData::Disable => {
2309 f.write_str(" : disable")?;
2310 }
2311 }
2312 }
2313
2314 Ok(())
2315}
2316
2317pub fn show_external_declaration<F>(
2319 f: &mut F,
2320 ed: &ast::ExternalDeclaration,
2321 state: &mut FormattingState<'_>,
2322) -> std::fmt::Result
2323where
2324 F: Write + ?Sized,
2325{
2326 state.enter_external_declaration(f)?;
2327
2328 match **ed {
2329 ast::ExternalDeclarationData::Preprocessor(ref pp) => show_preprocessor(f, pp, state)?,
2330 ast::ExternalDeclarationData::FunctionDefinition(ref fd) => {
2331 show_function_definition(f, fd, state)?
2332 }
2333 ast::ExternalDeclarationData::Declaration(ref d) => show_declaration(f, d, state)?,
2334 }
2335
2336 state.exit_external_declaration();
2337
2338 Ok(())
2339}
2340
2341pub fn show_translation_unit<F>(
2343 f: &mut F,
2344 tu: &ast::TranslationUnit,
2345 mut state: FormattingState<'_>,
2346) -> std::fmt::Result
2347where
2348 F: Write + ?Sized,
2349{
2350 for ed in &tu.0 {
2351 show_external_declaration(f, ed, &mut state)?;
2352 }
2353
2354 Ok(())
2355}
2356
2357#[cfg(test)]
2358mod tests {
2359 use super::*;
2360 use crate::parse::{DefaultLexer, Parsable, ParseError};
2361 use expect_test::{expect, Expect};
2362 use glsl_lang_lexer::HasLexerError;
2363
2364 fn check_expr(src: &str, expected: Expect) {
2365 let expr = ast::Expr::parse(src).unwrap();
2366 let actual = to_string(&expr);
2367 expected.assert_eq(&actual);
2368 }
2369
2370 fn to_string(e: &ast::Expr) -> String {
2371 let mut state = String::new();
2372 show_expr(&mut state, e, &mut FormattingState::default()).unwrap();
2373 state
2374 }
2375
2376 #[cfg(not(feature = "lexer-full"))]
2377 fn parse_tu_with_preprocessor_directives(
2378 source: &str,
2379 ) -> Result<ast::TranslationUnit, ParseError<<DefaultLexer as HasLexerError>::Error>> {
2380 ast::TranslationUnit::parse(source)
2381 }
2382
2383 #[cfg(feature = "lexer-full")]
2384 fn parse_tu_with_preprocessor_directives(
2385 source: &str,
2386 ) -> Result<ast::TranslationUnit, ParseError<<DefaultLexer as HasLexerError>::Error>> {
2387 <ast::TranslationUnit as crate::parse::DefaultParse>::parse_with_options(
2388 source,
2389 &Default::default(),
2390 )
2391 .map(|(mut tu, _parse, iter)| {
2392 iter.into_directives().inject(&mut tu);
2393 tu
2394 })
2395 }
2396
2397 #[test]
2398 fn unary_parentheses() {
2399 check_expr("-a", expect![["-a"]]);
2400 check_expr("-(a + b)", expect![[r#"-(a + b)"#]]);
2401 check_expr("-a.x", expect![["-a.x"]]);
2402
2403 check_expr("-(-a)", expect![["-(-a)"]]);
2404 check_expr("+(+a)", expect![["+(+a)"]]);
2405 check_expr("~~a", expect![["~~a"]]);
2406 check_expr("--a", expect![["--a"]]);
2407 check_expr("++a", expect![["++a"]]);
2408 check_expr("+-a", expect![["+-a"]]);
2409 }
2410
2411 #[test]
2412 fn binary_parentheses() {
2413 check_expr("a + b", expect![[r#"a + b"#]]);
2414 check_expr("a * b + c", expect![[r#"a * b + c"#]]);
2415 check_expr("(a + b) * c", expect![[r#"(a + b) * c"#]]);
2416 check_expr("a + (b * c)", expect![[r#"a + b * c"#]]);
2417 check_expr("a * (b + c)", expect![[r#"a * (b + c)"#]]);
2418 check_expr("(a * b) * c", expect![[r#"a * b * c"#]]);
2419 check_expr("a * (b * c)", expect![[r#"a * (b * c)"#]]);
2420 check_expr("a&&b&&c", expect![[r#"a && b && c"#]]);
2421 check_expr(
2422 "n - p > 0. && u.y < n && u.y > p",
2423 expect![[r#"n - p > 0. && u.y < n && u.y > p"#]],
2424 );
2425 }
2426
2427 #[test]
2428 fn ternary_parentheses() {
2429 check_expr("a ? b : c ? d : e", expect![["a ? b : c ? d : e"]]);
2430 check_expr("(a ? b : c) ? d : e", expect![["(a ? b : c) ? d : e"]]);
2431 }
2432
2433 #[test]
2434 fn assignment_parentheses() {
2435 check_expr("a = b = c", expect![["a = b = c"]]);
2436 check_expr("(a = b) = c", expect![["(a = b) = c"]]);
2437 }
2438
2439 #[test]
2440 fn dot_parentheses() {
2441 check_expr("a.x", expect![["a.x"]]);
2442 check_expr("(a + b).x", expect![[r#"(a + b).x"#]]);
2443 }
2444
2445 #[test]
2446 fn array_indexes() {
2447 check_expr("arr[0][0]", expect![["arr[0][0]"]]);
2448 }
2449
2450 #[test]
2451 fn test_single_statement_function_is_not_collapsed() {
2452 const SRC: &str = r#"vec2 main() {
2453return vec2(0., 0.);
2454}
2455"#;
2456
2457 let mut s = String::new();
2458 show_function_definition(
2459 &mut s,
2460 &ast::FunctionDefinition::parse(SRC).unwrap(),
2461 &mut FormattingState::from(&FormattingSettings {
2462 collapse_single_item_compound_statements: true,
2463 ..Default::default()
2464 }),
2465 )
2466 .unwrap();
2467
2468 let expected = expect![[r#"
2469 vec2 main() {
2470 return vec2(0., 0.);
2471 }
2472 "#]];
2473
2474 expected.assert_eq(&s);
2475 }
2476
2477 #[test]
2478 fn test_minifying_statement_collapse() {
2479 const SRC: &str = r#"
2480 vec2 main() {
2481 if (110 == 110) {
2482 return vec2(0., 0.);
2483 } else {
2484 return vec2(1., 1.);
2485 }
2486 }
2487 "#;
2488
2489 let mut s = String::new();
2490 show_function_definition(
2491 &mut s,
2492 &ast::FunctionDefinition::parse(SRC).unwrap(),
2493 &mut FormattingState::from(&FormattingSettings {
2494 collapse_single_item_compound_statements: true,
2495 newline_after_collapsed_statement: false,
2496 newline_before_collapsed_statement: false,
2497 ..Default::default()
2498 }),
2499 )
2500 .unwrap();
2501
2502 let expected = expect![[r#"
2503 vec2 main() {
2504 if (110 == 110) return vec2(0., 0.); else return vec2(1., 1.);
2505 }
2506 "#]];
2507
2508 expected.assert_eq(&s);
2509 }
2510
2511 #[test]
2512 fn test_pretty_statement_collapse() {
2513 const SRC: &str = r#"
2514 vec2 main() {
2515 if (110 == 110) {
2516 return vec2(0., 0.);
2517 } else {
2518 return vec2(1., 1.);
2519 }
2520 }
2521 "#;
2522
2523 let mut s = String::new();
2524 show_function_definition(
2525 &mut s,
2526 &ast::FunctionDefinition::parse(SRC).unwrap(),
2527 &mut FormattingState::from(&FormattingSettings {
2528 collapse_single_item_compound_statements: true,
2529 statement_terminator: Whitespace::None,
2530 newline_after_collapsed_statement: true,
2531 newline_before_collapsed_statement: true,
2532 ..Default::default()
2533 }),
2534 )
2535 .unwrap();
2536
2537 let expected = expect![[r#"
2538 vec2 main() {
2539 if (110 == 110)
2540 return vec2(0., 0.); else
2541 return vec2(1., 1.);
2542 }
2543 "#]];
2544
2545 expected.assert_eq(&s);
2546 }
2547
2548 #[test]
2549 fn test_parentheses() {
2550 const SRC: &str = r#"
2551 vec2 main() {
2552 float n = 0.;
2553 float p = 0.;
2554 float u = vec2(0., 0.);
2555 if (n-p>0.&&u.y<n&&u.y>p) {}
2556 return u;
2557 }
2558 "#;
2559
2560 let mut s = String::new();
2561 show_function_definition(
2562 &mut s,
2563 &ast::FunctionDefinition::parse(SRC).unwrap(),
2564 &mut FormattingState::default(),
2565 )
2566 .unwrap();
2567
2568 let expected = expect![[r#"
2569 vec2 main() {
2570 float n = 0.;
2571 float p = 0.;
2572 float u = vec2(0., 0.);
2573 if (n - p > 0. && u.y < n && u.y > p) {
2574 }
2575 return u;
2576 }
2577 "#]];
2578
2579 expected.assert_eq(&s);
2580 }
2581
2582 #[test]
2583 fn roundtrip_glsl_complex_expr() {
2584 use lang_util::node::NodeContent;
2585
2586 let zero = ast::ExprData::DoubleConst(0.);
2587 let ray = ast::ExprData::Variable("ray".into_node());
2588 let raydir = ast::ExprData::Dot(Box::new(ray.into()), "dir".into_node());
2589 let vec4 = ast::ExprData::FunCall(
2590 ast::FunIdentifierData::TypeSpecifier(Box::new(
2591 ast::TypeSpecifierData::from(ast::TypeSpecifierNonArrayData::Vec4).into(),
2592 ))
2593 .into(),
2594 vec![raydir.into(), zero.into()],
2595 );
2596 let view = ast::ExprData::variable("view");
2597 let iview = ast::ExprData::FunCall(
2598 ast::FunIdentifierData::ident("inverse").into(),
2599 vec![view.into()],
2600 );
2601 let mul = ast::ExprData::Binary(
2602 ast::BinaryOpData::Mult.into(),
2603 Box::new(iview.into()),
2604 Box::new(vec4.into()),
2605 );
2606 let xyz = ast::ExprData::Dot(Box::new(mul.into()), "xyz".into_node());
2607 let input = ast::ExprData::FunCall(
2608 ast::FunIdentifierData::ident("normalize").into(),
2609 vec![xyz.into()],
2610 )
2611 .into();
2612
2613 let mut output = String::new();
2614 show_expr(&mut output, &input, &mut FormattingState::default()).unwrap();
2615
2616 let back = ast::Expr::parse(&output).unwrap();
2617 assert_eq!(back, input, "intermediate source '{}'", output);
2618 }
2619
2620 #[test]
2621 fn block_decl_formatting() {
2622 let src = r#"uniform Global { float param; float param2; };"#;
2623
2624 let mut s = String::new();
2625 show_external_declaration(
2626 &mut s,
2627 &ast::TranslationUnit::parse(src).unwrap().0[0],
2628 &mut FormattingState::default(),
2629 )
2630 .unwrap();
2631
2632 let expected = expect![[r#"
2633 uniform Global {
2634 float param;
2635 float param2;
2636 };"#]];
2637
2638 expected.assert_eq(&s);
2639 }
2640
2641 #[test]
2642 fn list_separator_formatting() {
2643 let src = r#"void main(vec2 x, vec3 y) {}"#;
2644
2645 let mut s = String::new();
2646 show_function_definition(
2647 &mut s,
2648 &ast::FunctionDefinition::parse(src).unwrap(),
2649 &mut FormattingState::from(&FormattingSettings {
2650 space_after_list_separator: false,
2651 ..Default::default()
2652 }),
2653 )
2654 .unwrap();
2655
2656 let expected = expect![[r#"
2657 void main(vec2 x,vec3 y) {
2658 }
2659 "#]];
2660
2661 expected.assert_eq(&s);
2662 }
2663
2664 #[test]
2665 fn preprocessor_directives_are_always_put_in_newlines() {
2666 let src = r#"
2667 #version 110
2668 vec3 u;
2669 vec3 v;
2670 #pragma "hi"
2671 vec3 w;
2672 "#;
2673
2674 let mut s = String::new();
2675 show_translation_unit(
2676 &mut s,
2677 &parse_tu_with_preprocessor_directives(src).unwrap(),
2678 FormattingState::from(&FormattingSettings {
2679 declaration_terminator: Whitespace::None,
2680 ..Default::default()
2681 }),
2682 )
2683 .unwrap();
2684
2685 let expected = expect![[r#"
2686 #version 110
2687 vec3 u;vec3 v;
2688 #pragma "hi"
2689 vec3 w;"#]];
2690
2691 expected.assert_eq(&s);
2692 }
2693
2694 static COMPLEX_GLSL_SOURCE: &str = r#"
2695 void main(smooth vec2[][] x, vec3 y) {
2696 if (var1)
2697 return a;
2698 else
2699 return b;
2700
2701 if (var2) {
2702 return --c;
2703 } else if (var3) {
2704 {
2705 vec2 x;
2706 vec2 y;
2707 }
2708
2709 return d++;
2710 } else {
2711 return q;
2712 }
2713
2714 const float e[3] = float[3](5.0, 7.2, 1.1);
2715 int f[2] = { 3, 4, };
2716
2717 switch (x) {
2718 case 0:
2719 ++x;
2720 break;
2721 case 1:
2722 return;
2723 default:
2724 discard;
2725 }
2726
2727 while (x) --x;
2728
2729 do {
2730 --y;
2731 } while (y);
2732
2733 for (x = 0; x < 5; ++x) {
2734 continue;
2735 }
2736 }
2737 "#;
2738
2739 #[test]
2740 fn complex_pretty_formatting() {
2741 let mut s = String::new();
2742 show_function_definition(
2743 &mut s,
2744 &ast::FunctionDefinition::parse(COMPLEX_GLSL_SOURCE).unwrap(),
2745 &mut FormattingState::from(&FormattingSettings::default()),
2746 )
2747 .unwrap();
2748
2749 let expected = expect![[r#"
2750 void main(smooth vec2[][] x, vec3 y) {
2751 if (var1) return a; else return b;
2752 if (var2) {
2753 return --c;
2754 } else if (var3) {
2755 {
2756 vec2 x;
2757 vec2 y;
2758 }
2759 return d++;
2760 } else {
2761 return q;
2762 }
2763 const float e[3] = float[3](5., 7.2, 1.1);
2764 int f[2] = { 3, 4 };
2765 switch (x) {
2766 case 0:
2767 ++x;
2768 break;
2769 case 1:
2770 return;
2771 default:
2772 discard;
2773 }
2774 while (x) --x;
2775 do {
2776 --y;
2777 } while (y);
2778 for (x = 0; x < 5; ++x) {
2779 continue;
2780 }
2781 }
2782 "#]];
2783
2784 expected.assert_eq(&s);
2785 }
2786
2787 #[test]
2788 fn preprocessor_directives_are_always_put_in_newlines_2() {
2789 let src = r#"
2790 vec3 u;
2791 #version 110
2792 "#;
2793
2794 let mut s = String::new();
2795 show_translation_unit(
2796 &mut s,
2797 &parse_tu_with_preprocessor_directives(src).unwrap(),
2798 FormattingState::from(&FormattingSettings {
2799 declaration_terminator: Whitespace::None,
2800 ..Default::default()
2801 }),
2802 )
2803 .unwrap();
2804
2805 let expected = expect![[r#"
2806 vec3 u;
2807 #version 110"#]];
2808
2809 expected.assert_eq(&s);
2810 }
2811
2812 #[test]
2813 fn complex_minifying_formatting() {
2814 let mut s = String::new();
2815 show_function_definition(
2816 &mut s,
2817 &ast::FunctionDefinition::parse(COMPLEX_GLSL_SOURCE).unwrap(),
2818 &mut FormattingState::from(&FormattingSettings::minifying()),
2819 )
2820 .unwrap();
2821
2822 let expected = expect!["void main(smooth vec2[][] x,vec3 y){if(var1)return a;else return b;if(var2)return --c;else if(var3){{vec2 x;vec2 y;}return d++;}else return q;const float e[3]=float[3](5.,7.2,1.1);int f[2]={3,4};switch(x){case 0:++x;break;case 1:return;default:discard;}while(x)--x;do --y; while(y);for(x=0;x<5;++x)continue;}"];
2823
2824 expected.assert_eq(&s);
2825 }
2826}