gtk+-2.0, gtk+-3.0: Fix gtk_tree_view_column_cell_get_position binding.
[vala-lang.git] / vala / valacodewriter.vala
blob49806e037220f598a2f82ce9db41b32ce0eb4b5b
1 /* valacodewriter.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
4 * Copyright (C) 2006-2008 Raffaele Sandrini
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Author:
21 * Jürg Billeter <j@bitron.ch>
22 * Raffaele Sandrini <raffaele@sandrini.ch>
26 /**
27 * Code visitor generating Vala API file for the public interface.
29 public class Vala.CodeWriter : CodeVisitor {
30 private CodeContext context;
32 FileStream stream;
34 int indent;
35 /* at begin of line */
36 bool bol = true;
38 Scope current_scope;
40 CodeWriterType type;
42 string? override_header = null;
43 string? header_to_override = null;
45 public CodeWriter (CodeWriterType type = CodeWriterType.EXTERNAL) {
46 this.type = type;
49 /**
50 * Allows overriding of a specific cheader in the output
51 * @param original orignal cheader to override
52 * @param replacement cheader to replace original with
54 public void set_cheader_override (string original, string replacement)
56 header_to_override = original;
57 override_header = replacement;
60 /**
61 * Writes the public interface of the specified code context into the
62 * specified file.
64 * @param context a code context
65 * @param filename a relative or absolute filename
67 public void write_file (CodeContext context, string filename) {
68 var file_exists = FileUtils.test (filename, FileTest.EXISTS);
69 var temp_filename = filename + ".valatmp";
70 this.context = context;
72 if (file_exists) {
73 stream = FileStream.open (temp_filename, "w");
74 } else {
75 stream = FileStream.open (filename, "w");
78 if (stream == null) {
79 Report.error (null, "unable to open `%s' for writing".printf (filename));
80 return;
83 var header = context.version_header ?
84 "/* %s generated by %s %s, do not modify. */".printf (Path.get_basename (filename), Environment.get_prgname (), Config.BUILD_VERSION) :
85 "/* %s generated by %s, do not modify. */".printf (Path.get_basename (filename), Environment.get_prgname ());
86 write_string (header);
87 write_newline ();
88 write_newline ();
90 current_scope = context.root.scope;
92 context.accept (this);
94 current_scope = null;
96 stream = null;
98 if (file_exists) {
99 var changed = true;
101 try {
102 var old_file = new MappedFile (filename, false);
103 var new_file = new MappedFile (temp_filename, false);
104 var len = old_file.get_length ();
105 if (len == new_file.get_length ()) {
106 if (Memory.cmp (old_file.get_contents (), new_file.get_contents (), len) == 0) {
107 changed = false;
110 old_file = null;
111 new_file = null;
112 } catch (FileError e) {
113 // assume changed if mmap comparison doesn't work
116 if (changed) {
117 FileUtils.rename (temp_filename, filename);
118 } else {
119 FileUtils.unlink (temp_filename);
125 public override void visit_using_directive (UsingDirective ns) {
126 if (type == CodeWriterType.FAST) {
127 write_string ("using %s;\n".printf (ns.namespace_symbol.name));
131 public override void visit_namespace (Namespace ns) {
132 if (ns.external_package) {
133 return;
136 if (ns.name == null) {
137 ns.accept_children (this);
138 return;
141 write_indent ();
142 write_string ("[CCode (cprefix = \"%s\", lower_case_cprefix = \"%s\"".printf (ns.get_cprefix (), ns.get_lower_case_cprefix ()));
144 if (ns.source_reference != null && ns.parent_symbol == context.root) {
145 // Set GIR information only for the main namespace of the file.
146 if (ns.source_reference.file.gir_namespace != null) {
147 write_string (", ");
148 write_string ("gir_namespace = \"%s\"".printf (ns.source_reference.file.gir_namespace));
150 if (ns.source_reference.file.gir_version != null) {
151 write_string(", ");
152 write_string ("gir_version = \"%s\"".printf (ns.source_reference.file.gir_version));
156 write_string (")]");
157 write_newline ();
159 write_attributes (ns);
161 write_indent ();
162 write_string ("namespace ");
163 write_identifier (ns.name);
164 write_begin_block ();
166 current_scope = ns.scope;
168 visit_sorted (ns.get_namespaces ());
169 visit_sorted (ns.get_classes ());
170 visit_sorted (ns.get_interfaces ());
171 visit_sorted (ns.get_structs ());
172 visit_sorted (ns.get_enums ());
173 visit_sorted (ns.get_error_domains ());
174 visit_sorted (ns.get_delegates ());
175 visit_sorted (ns.get_fields ());
176 visit_sorted (ns.get_constants ());
177 visit_sorted (ns.get_methods ());
179 current_scope = current_scope.parent_scope;
181 write_end_block ();
182 write_newline ();
185 private string get_cheaders (Symbol cl) {
186 bool first = true;
187 string cheaders = "";
188 if (type != CodeWriterType.FAST) {
189 foreach (string cheader in cl.get_cheader_filenames ()) {
190 if (header_to_override != null &&
191 cheader == header_to_override) {
192 cheader = override_header;
194 if (first) {
195 cheaders = cheader;
196 first = false;
197 } else {
198 cheaders = "%s,%s".printf (cheaders, cheader);
202 return cheaders;
205 private void emit_deprecated_attribute (Symbol symbol) {
206 if (symbol.deprecated) {
207 write_indent ();
208 write_string ("[Deprecated");
209 var since = symbol.deprecated_since;
210 var replacement = symbol.replacement;
212 if (since != null || replacement != null) {
213 write_string (" (");
214 if (since != null) {
215 write_string ("since = \"%s\"".printf (since));
217 if (since != null && replacement != null) {
218 write_string (", ");
220 if (replacement != null) {
221 write_string ("replacement = \"%s\"".printf (replacement));
223 write_string (")");
225 write_string ("]");
229 public override void visit_class (Class cl) {
230 if (cl.external_package) {
231 return;
234 if (!check_accessibility (cl)) {
235 return;
238 if (cl.is_compact) {
239 write_indent ();
240 write_string ("[Compact]");
241 write_newline ();
244 if (cl.is_immutable) {
245 write_indent ();
246 write_string ("[Immutable]");
247 write_newline ();
250 emit_deprecated_attribute (cl);
252 write_indent ();
254 write_string ("[CCode (");
256 if (cl.is_reference_counting () && type != CodeWriterType.FAST) {
257 if (cl.base_class == null || cl.base_class.get_ref_function () == null || cl.base_class.get_ref_function () != cl.get_ref_function ()) {
258 write_string ("ref_function = \"%s\", ".printf (cl.get_ref_function ()));
259 if (cl.ref_function_void) {
260 write_string ("ref_function_void = true, ");
263 if (cl.base_class == null || cl.base_class.get_unref_function () == null || cl.base_class.get_unref_function () != cl.get_unref_function ()) {
264 write_string ("unref_function = \"%s\", ".printf (cl.get_unref_function ()));
266 } else {
267 if (cl.get_dup_function () != null) {
268 write_string ("copy_function = \"%s\", ".printf (cl.get_dup_function ()));
270 if (cl.get_free_function () != cl.get_default_free_function ()) {
271 write_string ("free_function = \"%s\", ".printf (cl.get_free_function ()));
275 if (cl.get_cname () != cl.get_default_cname ()) {
276 write_string ("cname = \"%s\", ".printf (cl.get_cname ()));
278 if (cl.const_cname != null) {
279 write_string ("const_cname = \"%s\", ".printf (cl.const_cname));
282 if (cl.type_check_function != null) {
283 write_string ("type_check_function = \"%s\", ".printf (cl.type_check_function ));
286 if (cl.get_type_id () != cl.get_default_type_id ()) {
287 write_string ("type_id = \"%s\", ".printf (cl.get_type_id ()));
290 if (cl.get_param_spec_function () != cl.get_default_param_spec_function ()) {
291 write_string ("param_spec_function = \"%s\", ".printf (cl.get_param_spec_function ()));
294 write_string ("cheader_filename = \"%s\")]".printf (get_cheaders(cl)));
295 write_newline ();
297 write_attributes (cl);
299 write_indent ();
300 write_accessibility (cl);
301 if (cl.is_abstract) {
302 write_string ("abstract ");
304 write_string ("class ");
305 write_identifier (cl.name);
307 var type_params = cl.get_type_parameters ();
308 if (type_params.size > 0) {
309 write_string ("<");
310 bool first = true;
311 foreach (TypeParameter type_param in type_params) {
312 if (first) {
313 first = false;
314 } else {
315 write_string (",");
317 write_identifier (type_param.name);
319 write_string (">");
322 var base_types = cl.get_base_types ();
323 if (base_types.size > 0) {
324 write_string (" : ");
326 bool first = true;
327 foreach (DataType base_type in base_types) {
328 if (!first) {
329 write_string (", ");
330 } else {
331 first = false;
333 write_type (base_type);
336 write_begin_block ();
338 current_scope = cl.scope;
340 visit_sorted (cl.get_classes ());
341 visit_sorted (cl.get_structs ());
342 visit_sorted (cl.get_enums ());
343 visit_sorted (cl.get_delegates ());
344 visit_sorted (cl.get_fields ());
345 visit_sorted (cl.get_constants ());
346 visit_sorted (cl.get_methods ());
347 visit_sorted (cl.get_properties ());
348 visit_sorted (cl.get_signals ());
350 if (cl.constructor != null) {
351 cl.constructor.accept (this);
354 current_scope = current_scope.parent_scope;
356 write_end_block ();
357 write_newline ();
360 void visit_sorted (List<Symbol> symbols) {
361 if (type != CodeWriterType.EXTERNAL) {
362 // order of virtual methods matters for fast vapis
363 foreach (Symbol sym in symbols) {
364 sym.accept (this);
366 return;
369 var sorted_symbols = new ArrayList<Symbol> ();
370 foreach (Symbol sym in symbols) {
371 int left = 0;
372 int right = sorted_symbols.size - 1;
373 if (left > right || sym.name < sorted_symbols[left].name) {
374 sorted_symbols.insert (0, sym);
375 } else if (sym.name > sorted_symbols[right].name) {
376 sorted_symbols.add (sym);
377 } else {
378 while (right - left > 1) {
379 int i = (right + left) / 2;
380 if (sym.name > sorted_symbols[i].name) {
381 left = i;
382 } else {
383 right = i;
386 sorted_symbols.insert (left + 1, sym);
389 foreach (Symbol sym in sorted_symbols) {
390 sym.accept (this);
394 public override void visit_struct (Struct st) {
395 if (st.external_package) {
396 return;
399 if (!check_accessibility (st)) {
400 return;
403 if (st.is_immutable) {
404 write_indent ();
405 write_string ("[Immutable]");
406 write_newline ();
409 emit_deprecated_attribute (st);
411 write_indent ();
413 write_string ("[CCode (");
415 if (st.get_cname () != st.get_default_cname ()) {
416 write_string ("cname = \"%s\", ".printf (st.get_cname ()));
419 if (!st.has_type_id) {
420 write_string ("has_type_id = false, ");
421 } else if (!st.is_simple_type () && st.get_type_id () != "G_TYPE_POINTER") {
422 write_string ("type_id = \"%s\", ".printf (st.get_type_id ()));
425 if (!st.has_copy_function) {
426 write_string ("has_copy_function = false, ");
429 if (!st.has_destroy_function) {
430 write_string ("has_destroy_function = false, ");
433 write_string ("cheader_filename = \"%s\")]".printf (get_cheaders(st)));
434 write_newline ();
436 if (st.is_simple_type ()) {
437 write_indent ();
438 write_string ("[SimpleType]");
439 write_newline ();
442 if (st.is_integer_type ()) {
443 write_indent ();
444 write_string ("[IntegerType (rank = %d)]".printf (st.get_rank ()));
445 write_newline ();
448 if (st.is_floating_type ()) {
449 write_indent ();
450 write_string ("[FloatingType (rank = %d)]".printf (st.get_rank ()));
451 write_newline ();
454 write_attributes (st);
456 write_indent ();
457 write_accessibility (st);
458 write_string ("struct ");
459 write_identifier (st.name);
461 if (st.base_type != null) {
462 write_string (" : ");
463 write_type (st.base_type);
466 write_begin_block ();
468 current_scope = st.scope;
470 foreach (Field field in st.get_fields ()) {
471 field.accept (this);
473 visit_sorted (st.get_constants ());
474 visit_sorted (st.get_methods ());
475 visit_sorted (st.get_properties ());
477 current_scope = current_scope.parent_scope;
479 write_end_block ();
480 write_newline ();
483 public override void visit_interface (Interface iface) {
484 if (iface.external_package) {
485 return;
488 if (!check_accessibility (iface)) {
489 return;
492 emit_deprecated_attribute (iface);
494 write_indent ();
496 write_string ("[CCode (cheader_filename = \"%s\"".printf (get_cheaders(iface)));
497 if (iface.get_lower_case_csuffix () != iface.get_default_lower_case_csuffix ())
498 write_string (", lower_case_csuffix = \"%s\"".printf (iface.get_lower_case_csuffix ()));
499 if (iface.get_type_cname () != iface.get_default_type_cname ())
500 write_string (", type_cname = \"%s\"".printf (iface.get_type_cname ()));
502 write_string (")]");
503 write_newline ();
505 write_attributes (iface);
507 write_indent ();
508 write_accessibility (iface);
509 write_string ("interface ");
510 write_identifier (iface.name);
512 var type_params = iface.get_type_parameters ();
513 if (type_params.size > 0) {
514 write_string ("<");
515 bool first = true;
516 foreach (TypeParameter type_param in type_params) {
517 if (first) {
518 first = false;
519 } else {
520 write_string (",");
522 write_identifier (type_param.name);
524 write_string (">");
527 var prerequisites = iface.get_prerequisites ();
528 if (prerequisites.size > 0) {
529 write_string (" : ");
531 bool first = true;
532 foreach (DataType prerequisite in prerequisites) {
533 if (!first) {
534 write_string (", ");
535 } else {
536 first = false;
538 write_type (prerequisite);
541 write_begin_block ();
543 current_scope = iface.scope;
545 visit_sorted (iface.get_classes ());
546 visit_sorted (iface.get_structs ());
547 visit_sorted (iface.get_enums ());
548 visit_sorted (iface.get_delegates ());
549 visit_sorted (iface.get_fields ());
550 visit_sorted (iface.get_constants ());
551 visit_sorted (iface.get_methods ());
552 visit_sorted (iface.get_properties ());
553 visit_sorted (iface.get_signals ());
555 current_scope = current_scope.parent_scope;
557 write_end_block ();
558 write_newline ();
561 public override void visit_enum (Enum en) {
562 if (en.external_package) {
563 return;
566 if (!check_accessibility (en)) {
567 return;
570 emit_deprecated_attribute (en);
572 write_indent ();
574 write_string ("[CCode (cprefix = \"%s\", ".printf (en.get_cprefix ()));
576 if (!en.has_type_id) {
577 write_string ("has_type_id = false, ");
580 write_string ("cheader_filename = \"%s\")]".printf (get_cheaders(en)));
582 if (en.is_flags) {
583 write_indent ();
584 write_string ("[Flags]");
587 write_attributes (en);
589 write_indent ();
590 write_accessibility (en);
591 write_string ("enum ");
592 write_identifier (en.name);
593 write_begin_block ();
595 bool first = true;
596 foreach (EnumValue ev in en.get_values ()) {
597 if (first) {
598 first = false;
599 } else {
600 write_string (",");
601 write_newline ();
604 if (ev.get_cname () != ev.get_default_cname ()) {
605 write_indent ();
606 write_string ("[CCode (cname = \"%s\")]".printf (ev.get_cname ()));
608 write_indent ();
609 write_identifier (ev.name);
611 if (type == CodeWriterType.FAST && ev.value != null) {
612 write_string(" = ");
613 ev.value.accept (this);
617 if (!first) {
618 if (en.get_methods ().size > 0 || en.get_constants ().size > 0) {
619 write_string (";");
621 write_newline ();
624 current_scope = en.scope;
625 foreach (Method m in en.get_methods ()) {
626 m.accept (this);
628 foreach (Constant c in en.get_constants ()) {
629 c.accept (this);
631 current_scope = current_scope.parent_scope;
633 write_end_block ();
634 write_newline ();
637 public override void visit_error_domain (ErrorDomain edomain) {
638 if (edomain.external_package) {
639 return;
642 if (!check_accessibility (edomain)) {
643 return;
646 emit_deprecated_attribute (edomain);
648 write_indent ();
650 write_string ("[CCode (cprefix = \"%s\", cheader_filename = \"%s\")]".printf (edomain.get_cprefix (), get_cheaders(edomain)));
652 write_attributes (edomain);
654 write_indent ();
655 write_accessibility (edomain);
656 write_string ("errordomain ");
657 write_identifier (edomain.name);
658 write_begin_block ();
660 edomain.accept_children (this);
662 write_end_block ();
663 write_newline ();
666 public override void visit_error_code (ErrorCode ecode) {
667 write_indent ();
668 write_identifier (ecode.name);
669 write_string (",");
670 write_newline ();
673 public override void visit_constant (Constant c) {
674 if (c.external_package) {
675 return;
678 if (!check_accessibility (c)) {
679 return;
682 emit_deprecated_attribute (c);
684 bool custom_cname = (c.get_cname () != c.get_default_cname ());
685 bool custom_cheaders = (c.parent_symbol is Namespace);
686 if (custom_cname || custom_cheaders) {
687 write_indent ();
688 write_string ("[CCode (");
690 if (custom_cname) {
691 write_string ("cname = \"%s\"".printf (c.get_cname ()));
694 if (custom_cheaders) {
695 if (custom_cname) {
696 write_string (", ");
699 write_string ("cheader_filename = \"%s\"".printf (get_cheaders(c)));
702 write_string (")]");
705 write_indent ();
706 write_accessibility (c);
707 write_string ("const ");
709 write_type (c.type_reference);
711 write_string (" ");
712 write_identifier (c.name);
713 if (type == CodeWriterType.FAST && c.value != null) {
714 write_string(" = ");
715 c.value.accept (this);
717 write_string (";");
718 write_newline ();
721 public override void visit_field (Field f) {
722 if (f.external_package) {
723 return;
726 if (!check_accessibility (f)) {
727 return;
730 emit_deprecated_attribute (f);
732 bool custom_cname = (f.get_cname () != f.get_default_cname ());
733 bool custom_ctype = (f.get_ctype () != null);
734 bool custom_cheaders = (f.parent_symbol is Namespace);
735 bool custom_array_length_cname = (f.get_array_length_cname () != null);
736 bool custom_array_length_type = (f.array_length_type != null);
737 if (custom_cname || custom_ctype || custom_cheaders || custom_array_length_cname || custom_array_length_type || (f.no_array_length && f.variable_type is ArrayType)) {
738 write_indent ();
739 write_string ("[CCode (");
741 if (custom_cname) {
742 write_string ("cname = \"%s\"".printf (f.get_cname ()));
745 if (custom_ctype) {
746 if (custom_cname) {
747 write_string (", ");
750 write_string ("type = \"%s\"".printf (f.get_ctype ()));
753 if (custom_cheaders) {
754 if (custom_cname || custom_ctype) {
755 write_string (", ");
758 write_string ("cheader_filename = \"%s\"".printf (get_cheaders(f)));
761 if (f.variable_type is ArrayType) {
762 if (f.no_array_length) {
763 if (custom_cname || custom_ctype || custom_cheaders) {
764 write_string (", ");
767 write_string ("array_length = false");
769 if (f.array_null_terminated) {
770 write_string (", array_null_terminated = true");
772 } else {
773 if (custom_array_length_cname) {
774 if (custom_cname || custom_ctype || custom_cheaders) {
775 write_string (", ");
778 write_string ("array_length_cname = \"%s\"".printf (f.get_array_length_cname ()));
781 if (custom_array_length_type) {
782 if (custom_cname || custom_ctype || custom_cheaders || custom_array_length_cname) {
783 write_string (", ");
786 write_string ("array_length_type = \"%s\"".printf (f.array_length_type));
791 write_string (")]");
794 write_indent ();
795 write_accessibility (f);
797 if (f.binding == MemberBinding.STATIC) {
798 write_string ("static ");
799 } else if (f.binding == MemberBinding.CLASS) {
800 write_string ("class ");
803 if (f.variable_type.is_weak ()) {
804 write_string ("weak ");
807 write_type (f.variable_type);
809 write_string (" ");
810 write_identifier (f.name);
811 write_string (";");
812 write_newline ();
815 private void write_error_domains (List<DataType> error_domains) {
816 if (error_domains.size > 0) {
817 write_string (" throws ");
819 bool first = true;
820 foreach (DataType type in error_domains) {
821 if (!first) {
822 write_string (", ");
823 } else {
824 first = false;
827 write_type (type);
832 // equality comparison with 3 digit precision
833 private bool float_equal (double d1, double d2) {
834 return ((int) (d1 * 1000)) == ((int) (d2 * 1000));
837 private void write_params (List<Parameter> params) {
838 write_string ("(");
840 int i = 1;
841 foreach (Parameter param in params) {
842 if (i > 1) {
843 write_string (", ");
846 if (param.ellipsis) {
847 write_string ("...");
848 continue;
852 var ccode_params = new StringBuilder ();
853 var separator = "";
855 if (!float_equal (param.cparameter_position, i)) {
856 ccode_params.append_printf ("%spos = %g", separator, param.cparameter_position);
857 separator = ", ";
859 if (param.ctype != null) {
860 ccode_params.append_printf ("%stype = \"%s\"", separator, param.ctype);
861 separator = ", ";
863 if (param.no_array_length && param.variable_type is ArrayType) {
864 ccode_params.append_printf ("%sarray_length = false", separator);
865 separator = ", ";
867 if (param.array_null_terminated && param.variable_type is ArrayType) {
868 ccode_params.append_printf ("%sarray_null_terminated = true", separator);
869 separator = ", ";
871 if (param.array_length_type != null && param.variable_type is ArrayType) {
872 ccode_params.append_printf ("%sarray_length_type = \"%s\"", separator, param.array_length_type);
873 separator = ", ";
875 if (param.get_array_length_cname () != null && param.variable_type is ArrayType) {
876 ccode_params.append_printf ("%sarray_length_cname = \"%s\"", separator, param.get_array_length_cname ());
877 separator = ", ";
879 if (!float_equal (param.carray_length_parameter_position, i + 0.1)) {
880 ccode_params.append_printf ("%sarray_length_pos = %g", separator, param.carray_length_parameter_position);
881 separator = ", ";
883 if (!float_equal (param.cdelegate_target_parameter_position, i + 0.1)) {
884 ccode_params.append_printf ("%sdelegate_target_pos = %g", separator, param.cdelegate_target_parameter_position);
885 separator = ", ";
888 if (ccode_params.len > 0) {
889 write_string ("[CCode (%s)] ".printf (ccode_params.str));
892 if (param.params_array) {
893 write_string ("params ");
896 if (param.direction == ParameterDirection.IN) {
897 if (param.variable_type.value_owned) {
898 write_string ("owned ");
900 } else {
901 if (param.direction == ParameterDirection.REF) {
902 write_string ("ref ");
903 } else if (param.direction == ParameterDirection.OUT) {
904 write_string ("out ");
906 if (param.variable_type.is_weak ()) {
907 write_string ("unowned ");
911 write_type (param.variable_type);
913 write_string (" ");
914 write_identifier (param.name);
916 if (param.initializer != null) {
917 write_string (" = ");
918 param.initializer.accept (this);
921 i++;
924 write_string (")");
927 public override void visit_delegate (Delegate cb) {
928 if (cb.external_package) {
929 return;
932 if (!check_accessibility (cb)) {
933 return;
936 emit_deprecated_attribute (cb);
938 write_indent ();
940 write_string ("[CCode (cheader_filename = \"%s\"".printf (get_cheaders(cb)));
942 if (!cb.has_target) {
943 write_string (", has_target = false");
944 } else if (!float_equal (cb.cinstance_parameter_position, -2)) {
945 write_string (", instance_pos = %g".printf (cb.cinstance_parameter_position));
948 write_string (")]");
950 write_indent ();
952 write_accessibility (cb);
953 write_string ("delegate ");
955 write_return_type (cb.return_type);
957 write_string (" ");
958 write_identifier (cb.name);
960 var type_params = cb.get_type_parameters ();
961 if (type_params.size > 0) {
962 write_string ("<");
963 bool first = true;
964 foreach (TypeParameter type_param in type_params) {
965 if (first) {
966 first = false;
967 } else {
968 write_string (",");
970 write_identifier (type_param.name);
972 write_string (">");
975 write_string (" ");
977 write_params (cb.get_parameters ());
979 write_error_domains (cb.get_error_types ());
981 write_string (";");
983 write_newline ();
986 public override void visit_constructor (Constructor c) {
987 if (type != CodeWriterType.DUMP) {
988 return;
991 write_indent ();
992 write_string ("construct");
993 write_code_block (c.body);
994 write_newline ();
997 public override void visit_method (Method m) {
998 if (m.external_package) {
999 return;
1002 // don't write interface implementation unless it's an abstract or virtual method
1003 if (!check_accessibility (m) || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
1004 if (type != CodeWriterType.DUMP) {
1005 return;
1009 if (m.get_attribute ("NoWrapper") != null) {
1010 write_indent ();
1011 write_string ("[NoWrapper]");
1013 if (m.get_attribute ("NoThrow") != null) {
1014 write_indent ();
1015 write_string ("[NoThrow]");
1017 if (m.returns_modified_pointer) {
1018 write_indent ();
1019 write_string ("[ReturnsModifiedPointer]");
1021 if (m.printf_format) {
1022 write_indent ();
1023 write_string ("[PrintfFormat]");
1025 if (m.scanf_format) {
1026 write_indent ();
1027 write_string ("[ScanfFormat]");
1029 if (m.get_attribute ("Print") != null) {
1030 write_indent ();
1031 write_string ("[Print]");
1033 if (m.get_attribute ("NoReturn") != null) {
1034 write_indent ();
1035 write_string ("[NoReturn]");
1038 emit_deprecated_attribute (m);
1040 var ccode_params = new StringBuilder ();
1041 var separator = "";
1043 if (m.get_cname () != m.get_default_cname ()) {
1044 ccode_params.append_printf ("%scname = \"%s\"", separator, m.get_cname ());
1045 separator = ", ";
1047 if (m.parent_symbol is Namespace) {
1048 ccode_params.append_printf ("%scheader_filename = \"%s\"", separator, get_cheaders(m));
1049 separator = ", ";
1051 if (!float_equal (m.cinstance_parameter_position, 0)) {
1052 ccode_params.append_printf ("%sinstance_pos = %g", separator, m.cinstance_parameter_position);
1053 separator = ", ";
1055 if (m.no_array_length && m.return_type is ArrayType) {
1056 ccode_params.append_printf ("%sarray_length = false", separator);
1057 separator = ", ";
1059 if (!float_equal (m.carray_length_parameter_position, -3)) {
1060 ccode_params.append_printf ("%sarray_length_pos = %g", separator, m.carray_length_parameter_position);
1061 separator = ", ";
1063 if (m.array_null_terminated && m.return_type is ArrayType) {
1064 ccode_params.append_printf ("%sarray_null_terminated = true", separator);
1065 separator = ", ";
1067 if (m.array_length_type != null && m.return_type is ArrayType) {
1068 ccode_params.append_printf ("%sarray_length_type = \"%s\"", separator, m.array_length_type);
1069 separator = ", ";
1071 if (!float_equal (m.cdelegate_target_parameter_position, -3)) {
1072 ccode_params.append_printf ("%sdelegate_target_pos = %g", separator, m.cdelegate_target_parameter_position);
1073 separator = ", ";
1075 if (m.vfunc_name != m.name) {
1076 ccode_params.append_printf ("%svfunc_name = \"%s\"", separator, m.vfunc_name);
1077 separator = ", ";
1079 if (m.coroutine && m.get_finish_cname () != m.get_default_finish_cname ()) {
1080 ccode_params.append_printf ("%sfinish_name = \"%s\"", separator, m.get_finish_cname ());
1081 separator = ", ";
1083 if (m.sentinel != m.DEFAULT_SENTINEL) {
1084 ccode_params.append_printf ("%ssentinel = \"%s\"", separator, m.sentinel);
1085 separator = ", ";
1087 var cm = m as CreationMethod;
1088 if (cm != null) {
1089 if (cm.custom_return_type_cname != null) {
1090 ccode_params.append_printf ("%stype = \"%s\"", separator, cm.custom_return_type_cname);
1091 separator = ", ";
1093 if (!m.has_new_function) {
1094 ccode_params.append_printf ("%shas_new_function = false", separator);
1095 separator = ", ";
1097 if (!m.has_construct_function) {
1098 ccode_params.append_printf ("%shas_construct_function = false", separator);
1099 separator = ", ";
1100 } else if (m.name == ".new" && m.get_real_cname () != cm.get_default_construct_function ()) {
1101 ccode_params.append_printf ("%sconstruct_function = \"%s\"", separator, m.get_real_cname ());
1102 separator = ", ";
1106 if (ccode_params.len > 0) {
1107 write_indent ();
1108 write_string ("[CCode (%s)]".printf (ccode_params.str));
1111 write_indent ();
1112 write_accessibility (m);
1114 if (m is CreationMethod) {
1115 if (m.coroutine) {
1116 write_string ("async ");
1119 var datatype = (TypeSymbol) m.parent_symbol;
1120 write_identifier (datatype.name);
1121 if (m.name != ".new") {
1122 write_string (".");
1123 write_identifier (m.name);
1125 write_string (" ");
1126 } else {
1127 if (m.binding == MemberBinding.STATIC) {
1128 write_string ("static ");
1129 } else if (m.binding == MemberBinding.CLASS) {
1130 write_string ("class ");
1131 } else if (m.is_abstract) {
1132 write_string ("abstract ");
1133 } else if (m.is_virtual) {
1134 write_string ("virtual ");
1135 } else if (m.overrides) {
1136 write_string ("override ");
1139 if (m.hides) {
1140 write_string ("new ");
1143 if (m.coroutine) {
1144 write_string ("async ");
1147 write_return_type (m.return_type);
1148 write_string (" ");
1150 write_identifier (m.name);
1152 var type_params = m.get_type_parameters ();
1153 if (type_params.size > 0) {
1154 write_string ("<");
1155 bool first = true;
1156 foreach (TypeParameter type_param in type_params) {
1157 if (first) {
1158 first = false;
1159 } else {
1160 write_string (",");
1162 write_identifier (type_param.name);
1164 write_string (">");
1167 write_string (" ");
1170 write_params (m.get_parameters ());
1172 if (context.profile != Profile.DOVA) {
1173 write_error_domains (m.get_error_types ());
1176 write_code_block (m.body);
1178 write_newline ();
1181 public override void visit_creation_method (CreationMethod m) {
1182 visit_method (m);
1185 public override void visit_property (Property prop) {
1186 if (!check_accessibility (prop) || (prop.base_interface_property != null && !prop.is_abstract && !prop.is_virtual)) {
1187 return;
1190 emit_deprecated_attribute (prop);
1192 if (prop.no_accessor_method) {
1193 write_indent ();
1194 write_string ("[NoAccessorMethod]");
1196 if (prop.property_type is ArrayType && prop.no_array_length) {
1197 write_indent ();
1198 write_string ("[CCode (array_length = false");
1200 if (prop.array_null_terminated) {
1201 write_string (", array_null_terminated = true");
1204 write_string (")]");
1207 write_indent ();
1208 write_accessibility (prop);
1210 if (prop.binding == MemberBinding.STATIC) {
1211 write_string ("static ");
1212 } else if (prop.is_abstract) {
1213 write_string ("abstract ");
1214 } else if (prop.is_virtual) {
1215 write_string ("virtual ");
1216 } else if (prop.overrides) {
1217 write_string ("override ");
1220 write_type (prop.property_type);
1222 write_string (" ");
1223 write_identifier (prop.name);
1224 write_string (" {");
1225 if (prop.get_accessor != null) {
1226 var ccode_params = new StringBuilder ();
1227 var separator = "";
1229 if (prop.get_accessor.get_cname () != prop.get_accessor.get_default_cname ()) {
1230 ccode_params.append_printf ("%scname = \"%s\"", separator, prop.get_accessor.get_cname ());
1231 separator = ", ";
1233 if (ccode_params.len > 0) {
1234 write_indent ();
1235 write_string ("[CCode (%s)]".printf (ccode_params.str));
1238 write_property_accessor_accessibility (prop.get_accessor);
1240 if (context.profile != Profile.DOVA && prop.get_accessor.value_type.is_disposable ()) {
1241 write_string (" owned");
1244 write_string (" get");
1245 write_code_block (prop.get_accessor.body);
1247 if (prop.set_accessor != null) {
1248 var ccode_params = new StringBuilder ();
1249 var separator = "";
1251 if (prop.set_accessor.get_cname () != prop.set_accessor.get_default_cname ()) {
1252 ccode_params.append_printf ("%scname = \"%s\"", separator, prop.set_accessor.get_cname ());
1253 separator = ", ";
1255 if (ccode_params.len > 0) {
1256 write_indent ();
1257 write_string ("[CCode (%s)]".printf (ccode_params.str));
1260 write_property_accessor_accessibility (prop.set_accessor);
1262 if (context.profile != Profile.DOVA && prop.set_accessor.value_type.value_owned) {
1263 write_string (" owned");
1266 if (prop.set_accessor.writable) {
1267 write_string (" set");
1269 if (prop.set_accessor.construction) {
1270 write_string (" construct");
1272 write_code_block (prop.set_accessor.body);
1274 write_string (" }");
1275 write_newline ();
1278 public override void visit_signal (Signal sig) {
1279 if (!check_accessibility (sig)) {
1280 return;
1283 if (sig.has_emitter) {
1284 write_indent ();
1285 write_string ("[HasEmitter]");
1288 emit_deprecated_attribute (sig);
1290 write_indent ();
1291 write_accessibility (sig);
1293 if (sig.is_virtual) {
1294 write_string ("virtual ");
1297 write_string ("signal ");
1299 write_return_type (sig.return_type);
1301 write_string (" ");
1302 write_identifier (sig.name);
1304 write_string (" ");
1306 write_params (sig.get_parameters ());
1308 write_string (";");
1310 write_newline ();
1313 public override void visit_block (Block b) {
1314 write_begin_block ();
1316 foreach (Statement stmt in b.get_statements ()) {
1317 stmt.accept (this);
1320 write_end_block ();
1323 public override void visit_empty_statement (EmptyStatement stmt) {
1326 public override void visit_declaration_statement (DeclarationStatement stmt) {
1327 write_indent ();
1328 stmt.declaration.accept (this);
1329 write_string (";");
1330 write_newline ();
1333 public override void visit_local_variable (LocalVariable local) {
1334 write_type (local.variable_type);
1335 write_string (" ");
1336 write_identifier (local.name);
1337 if (local.initializer != null) {
1338 write_string (" = ");
1339 local.initializer.accept (this);
1343 public override void visit_initializer_list (InitializerList list) {
1344 write_string ("{");
1346 bool first = true;
1347 foreach (Expression initializer in list.get_initializers ()) {
1348 if (!first) {
1349 write_string (", ");
1350 } else {
1351 write_string (" ");
1353 first = false;
1354 initializer.accept (this);
1356 write_string (" }");
1359 public override void visit_expression_statement (ExpressionStatement stmt) {
1360 write_indent ();
1361 stmt.expression.accept (this);
1362 write_string (";");
1363 write_newline ();
1366 public override void visit_if_statement (IfStatement stmt) {
1367 write_indent ();
1368 write_string ("if (");
1369 stmt.condition.accept (this);
1370 write_string (")");
1371 stmt.true_statement.accept (this);
1372 if (stmt.false_statement != null) {
1373 write_string (" else");
1374 stmt.false_statement.accept (this);
1376 write_newline ();
1379 public override void visit_switch_statement (SwitchStatement stmt) {
1380 write_indent ();
1381 write_string ("switch (");
1382 stmt.expression.accept (this);
1383 write_string (") {");
1384 write_newline ();
1386 foreach (SwitchSection section in stmt.get_sections ()) {
1387 section.accept (this);
1390 write_indent ();
1391 write_string ("}");
1392 write_newline ();
1395 public override void visit_switch_section (SwitchSection section) {
1396 foreach (SwitchLabel label in section.get_labels ()) {
1397 label.accept (this);
1400 visit_block (section);
1403 public override void visit_switch_label (SwitchLabel label) {
1404 if (label.expression != null) {
1405 write_indent ();
1406 write_string ("case ");
1407 label.expression.accept (this);
1408 write_string (":");
1409 write_newline ();
1410 } else {
1411 write_indent ();
1412 write_string ("default:");
1413 write_newline ();
1417 public override void visit_loop (Loop stmt) {
1418 write_indent ();
1419 write_string ("loop");
1420 stmt.body.accept (this);
1421 write_newline ();
1424 public override void visit_while_statement (WhileStatement stmt) {
1425 write_indent ();
1426 write_string ("while (");
1427 stmt.condition.accept (this);
1428 write_string (")");
1429 stmt.body.accept (this);
1430 write_newline ();
1433 public override void visit_do_statement (DoStatement stmt) {
1434 write_indent ();
1435 write_string ("do");
1436 stmt.body.accept (this);
1437 write_string ("while (");
1438 stmt.condition.accept (this);
1439 write_string (");");
1440 write_newline ();
1443 public override void visit_for_statement (ForStatement stmt) {
1444 write_indent ();
1445 write_string ("for (");
1447 bool first = true;
1448 foreach (Expression initializer in stmt.get_initializer ()) {
1449 if (!first) {
1450 write_string (", ");
1452 first = false;
1453 initializer.accept (this);
1455 write_string ("; ");
1457 stmt.condition.accept (this);
1458 write_string ("; ");
1460 first = true;
1461 foreach (Expression iterator in stmt.get_iterator ()) {
1462 if (!first) {
1463 write_string (", ");
1465 first = false;
1466 iterator.accept (this);
1469 write_string (")");
1470 stmt.body.accept (this);
1471 write_newline ();
1474 public override void visit_foreach_statement (ForeachStatement stmt) {
1477 public override void visit_break_statement (BreakStatement stmt) {
1478 write_indent ();
1479 write_string ("break;");
1480 write_newline ();
1483 public override void visit_continue_statement (ContinueStatement stmt) {
1484 write_indent ();
1485 write_string ("continue;");
1486 write_newline ();
1489 public override void visit_return_statement (ReturnStatement stmt) {
1490 write_indent ();
1491 write_string ("return");
1492 if (stmt.return_expression != null) {
1493 write_string (" ");
1494 stmt.return_expression.accept (this);
1496 write_string (";");
1497 write_newline ();
1500 public override void visit_yield_statement (YieldStatement y) {
1501 write_indent ();
1502 write_string ("yield");
1503 if (y.yield_expression != null) {
1504 write_string (" ");
1505 y.yield_expression.accept (this);
1507 write_string (";");
1508 write_newline ();
1511 public override void visit_throw_statement (ThrowStatement stmt) {
1512 write_indent ();
1513 write_string ("throw");
1514 if (stmt.error_expression != null) {
1515 write_string (" ");
1516 stmt.error_expression.accept (this);
1518 write_string (";");
1519 write_newline ();
1522 public override void visit_try_statement (TryStatement stmt) {
1523 write_indent ();
1524 write_string ("try");
1525 stmt.body.accept (this);
1526 foreach (var clause in stmt.get_catch_clauses ()) {
1527 clause.accept (this);
1529 if (stmt.finally_body != null) {
1530 write_string (" finally");
1531 stmt.finally_body.accept (this);
1533 write_newline ();
1536 public override void visit_catch_clause (CatchClause clause) {
1537 var type_name = clause.error_type == null ? "GLib.Error" : clause.error_type.to_string ();
1538 var var_name = clause.variable_name == null ? "_" : clause.variable_name;
1539 write_string (" catch (%s %s)".printf (type_name, var_name));
1540 clause.body.accept (this);
1543 public override void visit_lock_statement (LockStatement stmt) {
1544 write_indent ();
1545 write_string ("lock (");
1546 stmt.resource.accept (this);
1547 write_string (")");
1548 if (stmt.body == null) {
1549 write_string (";");
1550 } else {
1551 stmt.body.accept (this);
1553 write_newline ();
1556 public override void visit_delete_statement (DeleteStatement stmt) {
1557 write_indent ();
1558 write_string ("delete ");
1559 stmt.expression.accept (this);
1560 write_string (";");
1561 write_newline ();
1564 public override void visit_array_creation_expression (ArrayCreationExpression expr) {
1565 write_string ("new ");
1566 write_type (expr.element_type);
1567 write_string ("[");
1569 bool first = true;
1570 foreach (Expression size in expr.get_sizes ()) {
1571 if (!first) {
1572 write_string (", ");
1574 first = false;
1576 size.accept (this);
1579 write_string ("]");
1581 if (expr.initializer_list != null) {
1582 write_string (" ");
1583 expr.initializer_list.accept (this);
1587 public override void visit_boolean_literal (BooleanLiteral lit) {
1588 write_string (lit.value.to_string ());
1591 public override void visit_character_literal (CharacterLiteral lit) {
1592 write_string (lit.value);
1595 public override void visit_integer_literal (IntegerLiteral lit) {
1596 write_string (lit.value);
1599 public override void visit_real_literal (RealLiteral lit) {
1600 write_string (lit.value);
1603 public override void visit_string_literal (StringLiteral lit) {
1604 write_string (lit.value);
1607 public override void visit_null_literal (NullLiteral lit) {
1608 write_string ("null");
1611 public override void visit_member_access (MemberAccess expr) {
1612 if (expr.inner != null) {
1613 expr.inner.accept (this);
1614 write_string (".");
1616 write_identifier (expr.member_name);
1619 public override void visit_method_call (MethodCall expr) {
1620 expr.call.accept (this);
1621 write_string (" (");
1623 bool first = true;
1624 foreach (Expression arg in expr.get_argument_list ()) {
1625 if (!first) {
1626 write_string (", ");
1628 first = false;
1630 arg.accept (this);
1633 write_string (")");
1636 public override void visit_element_access (ElementAccess expr) {
1637 expr.container.accept (this);
1638 write_string ("[");
1640 bool first = true;
1641 foreach (Expression index in expr.get_indices ()) {
1642 if (!first) {
1643 write_string (", ");
1645 first = false;
1647 index.accept (this);
1650 write_string ("]");
1653 public override void visit_slice_expression (SliceExpression expr) {
1654 expr.container.accept (this);
1655 write_string ("[");
1656 expr.start.accept (this);
1657 write_string (":");
1658 expr.stop.accept (this);
1659 write_string ("]");
1662 public override void visit_base_access (BaseAccess expr) {
1663 write_string ("base");
1666 public override void visit_postfix_expression (PostfixExpression expr) {
1667 expr.inner.accept (this);
1668 if (expr.increment) {
1669 write_string ("++");
1670 } else {
1671 write_string ("--");
1675 public override void visit_object_creation_expression (ObjectCreationExpression expr) {
1676 if (!expr.struct_creation) {
1677 write_string ("new ");
1680 write_type (expr.type_reference);
1682 if (expr.symbol_reference.name != ".new") {
1683 write_string (".");
1684 write_string (expr.symbol_reference.name);
1687 write_string (" (");
1689 bool first = true;
1690 foreach (Expression arg in expr.get_argument_list ()) {
1691 if (!first) {
1692 write_string (", ");
1694 first = false;
1696 arg.accept (this);
1699 write_string (")");
1702 public override void visit_sizeof_expression (SizeofExpression expr) {
1703 write_string ("sizeof (");
1704 write_type (expr.type_reference);
1705 write_string (")");
1708 public override void visit_typeof_expression (TypeofExpression expr) {
1709 write_string ("typeof (");
1710 write_type (expr.type_reference);
1711 write_string (")");
1714 public override void visit_unary_expression (UnaryExpression expr) {
1715 switch (expr.operator) {
1716 case UnaryOperator.PLUS:
1717 write_string ("+");
1718 break;
1719 case UnaryOperator.MINUS:
1720 write_string ("-");
1721 break;
1722 case UnaryOperator.LOGICAL_NEGATION:
1723 write_string ("!");
1724 break;
1725 case UnaryOperator.BITWISE_COMPLEMENT:
1726 write_string ("~");
1727 break;
1728 case UnaryOperator.INCREMENT:
1729 write_string ("++");
1730 break;
1731 case UnaryOperator.DECREMENT:
1732 write_string ("--");
1733 break;
1734 case UnaryOperator.REF:
1735 write_string ("ref ");
1736 break;
1737 case UnaryOperator.OUT:
1738 write_string ("out ");
1739 break;
1740 default:
1741 assert_not_reached ();
1743 expr.inner.accept (this);
1746 public override void visit_cast_expression (CastExpression expr) {
1747 if (expr.is_non_null_cast) {
1748 write_string ("(!) ");
1749 expr.inner.accept (this);
1750 return;
1753 if (!expr.is_silent_cast) {
1754 write_string ("(");
1755 write_type (expr.type_reference);
1756 write_string (") ");
1759 expr.inner.accept (this);
1761 if (expr.is_silent_cast) {
1762 write_string (" as ");
1763 write_type (expr.type_reference);
1767 public override void visit_pointer_indirection (PointerIndirection expr) {
1768 write_string ("*");
1769 expr.inner.accept (this);
1772 public override void visit_addressof_expression (AddressofExpression expr) {
1773 write_string ("&");
1774 expr.inner.accept (this);
1777 public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) {
1778 write_string ("(owned) ");
1779 expr.inner.accept (this);
1782 public override void visit_binary_expression (BinaryExpression expr) {
1783 expr.left.accept (this);
1785 switch (expr.operator) {
1786 case BinaryOperator.PLUS:
1787 write_string (" + ");
1788 break;
1789 case BinaryOperator.MINUS:
1790 write_string (" - ");
1791 break;
1792 case BinaryOperator.MUL:
1793 write_string (" * ");
1794 break;
1795 case BinaryOperator.DIV:
1796 write_string (" / ");
1797 break;
1798 case BinaryOperator.MOD:
1799 write_string (" % ");
1800 break;
1801 case BinaryOperator.SHIFT_LEFT:
1802 write_string (" << ");
1803 break;
1804 case BinaryOperator.SHIFT_RIGHT:
1805 write_string (" >> ");
1806 break;
1807 case BinaryOperator.LESS_THAN:
1808 write_string (" < ");
1809 break;
1810 case BinaryOperator.GREATER_THAN:
1811 write_string (" > ");
1812 break;
1813 case BinaryOperator.LESS_THAN_OR_EQUAL:
1814 write_string (" <= ");
1815 break;
1816 case BinaryOperator.GREATER_THAN_OR_EQUAL:
1817 write_string (" >= ");
1818 break;
1819 case BinaryOperator.EQUALITY:
1820 write_string (" == ");
1821 break;
1822 case BinaryOperator.INEQUALITY:
1823 write_string (" != ");
1824 break;
1825 case BinaryOperator.BITWISE_AND:
1826 write_string (" & ");
1827 break;
1828 case BinaryOperator.BITWISE_OR:
1829 write_string (" | ");
1830 break;
1831 case BinaryOperator.BITWISE_XOR:
1832 write_string (" ^ ");
1833 break;
1834 case BinaryOperator.AND:
1835 write_string (" && ");
1836 break;
1837 case BinaryOperator.OR:
1838 write_string (" || ");
1839 break;
1840 case BinaryOperator.IN:
1841 write_string (" in ");
1842 break;
1843 case BinaryOperator.COALESCE:
1844 write_string (" ?? ");
1845 break;
1846 default:
1847 assert_not_reached ();
1850 expr.right.accept (this);
1853 public override void visit_type_check (TypeCheck expr) {
1854 expr.expression.accept (this);
1855 write_string (" is ");
1856 write_type (expr.type_reference);
1859 public override void visit_conditional_expression (ConditionalExpression expr) {
1860 expr.condition.accept (this);
1861 write_string ("?");
1862 expr.true_expression.accept (this);
1863 write_string (":");
1864 expr.false_expression.accept (this);
1867 public override void visit_lambda_expression (LambdaExpression expr) {
1868 write_string ("(");
1869 var params = expr.get_parameters ();
1870 if (params.size != 0) {
1871 for (var i = 0; i < params.size - 1; ++ i) {
1872 write_string (params[i]);
1873 write_string (", ");
1875 write_string (params[params.size - 1]);
1877 write_string (") =>");
1878 if (expr.statement_body != null) {
1879 expr.statement_body.accept (this);
1880 } else if (expr.expression_body != null) {
1881 expr.expression_body.accept (this);
1885 public override void visit_assignment (Assignment a) {
1886 a.left.accept (this);
1887 write_string (" = ");
1888 a.right.accept (this);
1891 private void write_indent () {
1892 int i;
1894 if (!bol) {
1895 stream.putc ('\n');
1898 for (i = 0; i < indent; i++) {
1899 stream.putc ('\t');
1902 bol = false;
1905 private void write_identifier (string s) {
1906 char* id = (char*)s;
1907 int id_length = (int)s.length;
1908 if (context.profile != Profile.DOVA &&
1909 (Vala.Scanner.get_identifier_or_keyword (id, id_length) != Vala.TokenType.IDENTIFIER ||
1910 s.get_char ().isdigit ())) {
1911 stream.putc ('@');
1913 write_string (s);
1916 private void write_return_type (DataType type) {
1917 if (type.is_weak ()) {
1918 write_string ("unowned ");
1921 write_type (type);
1924 private void write_type (DataType type) {
1925 write_string (type.to_qualified_string (current_scope));
1928 private void write_string (string s) {
1929 stream.printf ("%s", s);
1930 bol = false;
1933 private void write_newline () {
1934 stream.putc ('\n');
1935 bol = true;
1938 void write_code_block (Block? block) {
1939 if (block == null || type != CodeWriterType.DUMP) {
1940 write_string (";");
1941 return;
1944 block.accept (this);
1947 private void write_begin_block () {
1948 if (!bol) {
1949 stream.putc (' ');
1950 } else {
1951 write_indent ();
1953 stream.putc ('{');
1954 write_newline ();
1955 indent++;
1958 private void write_end_block () {
1959 indent--;
1960 write_indent ();
1961 stream.printf ("}");
1964 private bool check_accessibility (Symbol sym) {
1965 switch (type) {
1966 case CodeWriterType.EXTERNAL:
1967 return sym.access == SymbolAccessibility.PUBLIC ||
1968 sym.access == SymbolAccessibility.PROTECTED;
1970 case CodeWriterType.INTERNAL:
1971 case CodeWriterType.FAST:
1972 return sym.access == SymbolAccessibility.INTERNAL ||
1973 sym.access == SymbolAccessibility.PUBLIC ||
1974 sym.access == SymbolAccessibility.PROTECTED;
1976 case CodeWriterType.DUMP:
1977 return true;
1979 default:
1980 assert_not_reached ();
1984 private void write_attributes (CodeNode node) {
1985 foreach (Attribute attr in node.attributes) {
1986 if (!filter_attribute (attr)) {
1987 write_indent ();
1988 stream.printf ("[%s", attr.name);
1990 var keys = attr.args.get_keys ();
1991 if (keys.size != 0) {
1992 stream.printf (" (");
1994 string separator = "";
1995 foreach (string arg_name in keys) {
1996 stream.printf ("%s%s = %s", separator, arg_name, attr.args.get (arg_name));
1997 separator = ", ";
2000 stream.printf (")");
2002 stream.printf ("]");
2003 write_newline ();
2008 private bool filter_attribute (Attribute attr) {
2009 if (attr.name == "CCode"
2010 || attr.name == "Compact" || attr.name == "Immutable"
2011 || attr.name == "SimpleType" || attr.name == "IntegerType" || attr.name == "FloatingType"
2012 || attr.name == "Flags") {
2013 return true;
2015 return false;
2018 private void write_accessibility (Symbol sym) {
2019 if (sym.access == SymbolAccessibility.PUBLIC) {
2020 write_string ("public ");
2021 } else if (sym.access == SymbolAccessibility.PROTECTED) {
2022 write_string ("protected ");
2023 } else if (sym.access == SymbolAccessibility.INTERNAL) {
2024 write_string ("internal ");
2025 } else if (sym.access == SymbolAccessibility.PRIVATE) {
2026 write_string ("private ");
2029 if (type != CodeWriterType.EXTERNAL && sym.external && !sym.external_package) {
2030 write_string ("extern ");
2034 void write_property_accessor_accessibility (Symbol sym) {
2035 if (sym.access == SymbolAccessibility.PROTECTED) {
2036 write_string (" protected");
2037 } else if (sym.access == SymbolAccessibility.INTERNAL) {
2038 write_string (" internal");
2039 } else if (sym.access == SymbolAccessibility.PRIVATE) {
2040 write_string (" private");
2045 public enum Vala.CodeWriterType {
2046 EXTERNAL,
2047 INTERNAL,
2048 FAST,
2049 DUMP