remove obsolete ref modifier and callback keyword
[vala-lang.git] / vala / valainterfacewriter.vala
blobf53e22a4bf6a24ba6e74b759357802473b87150b
1 /* valainterfacewriter.vala
3 * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <rasa@gmx.ch>
24 using GLib;
26 /**
27 * Code visitor generating Vala API file for the public interface.
29 public class Vala.InterfaceWriter : CodeVisitor {
30 private CodeContext context;
32 FileStream stream;
34 int indent;
35 /* at begin of line */
36 bool bol = true;
38 string current_cheader_filename;
40 /**
41 * Writes the public interface of the specified code context into the
42 * specified file.
44 * @param context a code context
45 * @param filename a relative or absolute filename
47 public void write_file (CodeContext! context, string! filename) {
48 this.context = context;
50 stream = FileStream.open (filename, "w");
52 /* we're only interested in non-pkg source files */
53 foreach (SourceFile file in context.get_source_files ()) {
54 if (!file.pkg) {
55 file.accept (this);
59 stream = null;
62 public override void visit_source_file (SourceFile! source_file) {
63 source_file.accept_children (this);
66 public override void visit_namespace (Namespace! ns) {
67 if (ns.name == null) {
68 ns.accept_children (this);
69 return;
72 current_cheader_filename = ns.get_cheader_filename ();
74 write_indent ();
75 write_string ("[CCode (cprefix = \"%s\", lower_case_cprefix = \"%s\", cheader_filename = \"%s\")]".printf (ns.get_cprefix (), ns.get_lower_case_cprefix (), current_cheader_filename));
76 write_newline ();
78 write_indent ();
79 write_string ("namespace ");
80 write_identifier (ns.name);
81 write_begin_block ();
83 ns.accept_children (this);
85 write_end_block ();
86 write_newline ();
89 public override void visit_class (Class! cl) {
90 if (cl.access == MemberAccessibility.PRIVATE) {
91 return;
94 write_indent ();
96 var first = true;
97 string cheaders;
98 foreach (string cheader in cl.get_cheader_filenames ()) {
99 if (first) {
100 cheaders = cheader;
101 first = false;
102 } else {
103 cheaders = "%s, %s".printf (cheaders, cheader);
106 write_string ("[CCode (cheader_filename = \"%s\")]".printf (cheaders));
107 write_newline ();
109 write_indent ();
110 write_string ("public ");
111 if (cl.is_abstract) {
112 write_string ("abstract ");
114 write_string ("class ");
115 write_identifier (cl.name);
117 var base_types = cl.get_base_types ();
118 if (base_types != null) {
119 write_string (" : ");
121 bool first = true;
122 foreach (TypeReference base_type in base_types) {
123 if (!first) {
124 write_string (", ");
125 } else {
126 first = false;
128 write_string (base_type.data_type.symbol.get_full_name ());
131 write_begin_block ();
133 cl.accept_children (this);
135 write_end_block ();
136 write_newline ();
139 public override void visit_struct (Struct! st) {
140 if (st.access == MemberAccessibility.PRIVATE) {
141 return;
144 if (st.is_reference_type ()) {
145 write_indent ();
146 write_string ("[ReferenceType]");
149 write_indent ();
150 write_string ("public struct ");
151 write_identifier (st.name);
152 write_begin_block ();
154 st.accept_children (this);
156 write_end_block ();
157 write_newline ();
160 public override void visit_interface (Interface! iface) {
161 if (iface.access == MemberAccessibility.PRIVATE) {
162 return;
165 write_indent ();
167 var first = true;
168 string cheaders;
169 foreach (string cheader in iface.get_cheader_filenames ()) {
170 if (first) {
171 cheaders = cheader;
172 first = false;
173 } else {
174 cheaders = "%s, %s".printf (cheaders, cheader);
177 write_string ("[CCode (cheader_filename = \"%s\")]".printf (cheaders));
178 write_newline ();
180 write_indent ();
181 write_string ("public ");
182 write_string ("interface ");
183 write_identifier (iface.name);
185 write_begin_block ();
187 iface.accept_children (this);
189 write_end_block ();
190 write_newline ();
193 public override void visit_enum (Enum! en) {
194 if (en.access == MemberAccessibility.PRIVATE) {
195 return;
198 write_indent ();
199 write_string ("[CCode (cprefix = \"%s\")]".printf (en.get_cprefix ()));
201 write_indent ();
202 write_string ("public enum ");
203 write_identifier (en.name);
204 write_begin_block ();
206 en.accept_children (this);
208 write_end_block ();
209 write_newline ();
212 public override void visit_enum_value (EnumValue! ev) {
213 write_indent ();
214 write_identifier (ev.name);
215 write_string (",");
216 write_newline ();
219 public override void visit_flags (Flags! fl) {
220 if (fl.access == MemberAccessibility.PRIVATE) {
221 return;
224 write_indent ();
225 write_string ("[CCode (cprefix = \"%s\")]".printf (fl.get_cprefix ()));
227 write_indent ();
228 write_string ("public flags ");
229 write_identifier (fl.name);
230 write_begin_block ();
232 fl.accept_children (this);
234 write_end_block ();
235 write_newline ();
238 public override void visit_flags_value (FlagsValue! fv) {
239 write_indent ();
240 write_identifier (fv.name);
241 write_string (",");
242 write_newline ();
245 public override void visit_constant (Constant! c) {
246 write_indent ();
247 write_string ("public const ");
248 write_string (c.type_reference.data_type.symbol.get_full_name ());
250 write_string (" ");
251 write_identifier (c.name);
252 write_string (";");
253 write_newline ();
256 public override void visit_field (Field! f) {
257 if (f.access == MemberAccessibility.PRIVATE) {
258 return;
261 write_indent ();
262 write_string ("public ");
263 if (f.type_reference.data_type != null &&
264 f.type_reference.data_type.is_reference_type () &&
265 !f.type_reference.takes_ownership) {
266 write_string ("weak ");
268 write_string (f.type_reference.data_type.symbol.get_full_name ());
270 var type_args = f.type_reference.get_type_arguments ();
271 if (!(f.type_reference.data_type is Array) && type_args != null) {
272 write_string ("<");
273 foreach (TypeReference type_arg in type_args) {
274 if (!type_arg.takes_ownership) {
275 write_string ("weak ");
277 write_string (type_arg.data_type.symbol.get_full_name ());
279 write_string (">");
282 write_string (" ");
283 write_identifier (f.name);
284 write_string (";");
285 write_newline ();
288 private void write_params (List<FormalParameter> params) {
289 write_string ("(");
291 bool first = true;
292 foreach (FormalParameter param in params) {
293 if (!first) {
294 write_string (", ");
295 } else {
296 first = false;
299 if (param.ellipsis) {
300 write_string ("...");
301 continue;
304 if (param.type_reference.is_ref) {
305 write_string ("ref ");
306 } else if (param.type_reference.is_out) {
307 write_string ("out ");
309 write_string (param.type_reference.data_type.symbol.get_full_name ());
311 var type_args = param.type_reference.get_type_arguments ();
312 if (!(param.type_reference.data_type is Array) && type_args != null) {
313 write_string ("<");
314 foreach (TypeReference type_arg in type_args) {
315 if (type_arg.takes_ownership) {
316 write_string ("ref ");
318 write_string (type_arg.data_type.symbol.get_full_name ());
320 write_string (">");
323 if (param.type_reference.non_null) {
324 write_string ("!");
327 if (param.type_reference.takes_ownership) {
328 write_string ("#");
331 write_string (" ");
332 write_identifier (param.name);
334 if (param.default_expression != null) {
335 write_string (" = ");
336 write_string (param.default_expression.to_string ());
340 write_string (")");
343 public override void visit_callback (Callback! cb) {
344 if (cb.access == MemberAccessibility.PRIVATE) {
345 return;
348 write_indent ();
349 write_string ("public static delegate ");
351 var type = cb.return_type.data_type;
352 if (type == null) {
353 write_string ("void");
354 } else {
355 if (cb.return_type.transfers_ownership) {
356 write_string ("ref ");
358 write_string (cb.return_type.data_type.symbol.get_full_name ());
361 write_string (" ");
362 write_identifier (cb.name);
364 write_string (" ");
366 write_params (cb.get_parameters ());
368 write_string (";");
370 write_newline ();
373 public override void visit_method (Method! m) {
374 if (m.access == MemberAccessibility.PRIVATE || m.overrides) {
375 return;
378 if (m.no_array_length) {
379 bool array_found = (m.return_type != null && m.return_type.data_type is Array);
380 foreach (FormalParameter param in m.get_parameters ()) {
381 if (param.type_reference != null && param.type_reference.data_type is Array) {
382 array_found = true;
383 break;
386 if (array_found) {
387 write_indent ();
388 write_string ("[NoArrayLength]");
391 if (m.instance_last) {
392 write_indent ();
393 write_string ("[InstanceLast]");
395 if (m.instance_by_reference) {
396 write_indent ();
397 write_string ("[InstanceByReference]");
399 if (m.get_cname () != m.get_default_cname ()) {
400 write_indent ();
401 write_string ("[CCode (cname = \"%s\")]".printf (m.get_cname ()));
404 write_indent ();
405 write_string ("public");
407 if (m is CreationMethod) {
408 write_string (" ");
409 var datatype = (DataType) m.symbol.parent_symbol.node;
410 write_identifier (datatype.name);
412 if (m.name != null) {
413 write_string (".");
414 write_identifier (m.name);
416 } else if (!m.instance) {
417 write_string (" static");
418 } else if (m.is_abstract) {
419 write_string (" abstract");
420 } else if (m.is_virtual) {
421 write_string (" virtual");
424 if (!(m is CreationMethod)) {
425 write_string (" ");
427 var type = m.return_type.data_type;
428 if (type == null) {
429 write_string ("void");
430 } else {
431 if (m.return_type.transfers_ownership) {
432 } else if ((m.return_type.data_type != null && m.return_type.data_type.is_reference_type ()) || m.return_type.type_parameter != null) {
433 write_string ("weak ");
435 write_string (m.return_type.data_type.symbol.get_full_name ());
436 if (m.return_type.non_null) {
437 write_string ("!");
441 write_string (" ");
442 write_identifier (m.name);
445 write_string (" ");
447 write_params (m.get_parameters ());
449 write_string (";");
451 write_newline ();
454 public override void visit_creation_method (CreationMethod! m) {
455 visit_method (m);
458 public override void visit_property (Property! prop) {
459 if (prop.no_accessor_method) {
460 write_indent ();
461 write_string ("[NoAccessorMethod]");
464 write_indent ();
465 write_string ("public ");
466 if (!prop.type_reference.takes_ownership) {
467 write_string ("weak ");
469 write_string (prop.type_reference.data_type.symbol.get_full_name ());
471 var type_args = prop.type_reference.get_type_arguments ();
472 if (!(prop.type_reference.data_type is Array) && type_args != null) {
473 write_string ("<");
474 foreach (TypeReference type_arg in type_args) {
475 if (!type_arg.takes_ownership) {
476 write_string ("weak ");
478 write_string (type_arg.data_type.symbol.get_full_name ());
480 write_string (">");
483 write_string (" ");
484 write_identifier (prop.name);
485 write_string (" {");
486 if (prop.get_accessor != null) {
487 write_string (" get;");
489 if (prop.set_accessor != null) {
490 if (prop.set_accessor.writable) {
491 write_string (" set");
493 if (prop.set_accessor.construction) {
494 write_string (" construct");
496 write_string (";");
498 write_string (" }");
499 write_newline ();
502 public override void visit_signal (Signal! sig) {
503 if (sig.access == MemberAccessibility.PRIVATE) {
504 return;
507 if (sig.has_emitter) {
508 write_indent ();
509 write_string ("[HasEmitter]");
512 write_indent ();
513 write_string ("public signal ");
515 var type = sig.return_type.data_type;
516 if (type == null) {
517 write_string ("void");
518 } else {
519 if (sig.return_type.transfers_ownership) {
520 write_string ("ref ");
522 write_string (sig.return_type.data_type.symbol.get_full_name ());
523 if (sig.return_type.non_null) {
524 write_string ("!");
528 write_string (" ");
529 write_identifier (sig.name);
531 write_string (" ");
533 write_params (sig.get_parameters ());
535 write_string (";");
537 write_newline ();
540 private void write_indent () {
541 int i;
543 if (!bol) {
544 stream.putc ('\n');
547 for (i = 0; i < indent; i++) {
548 stream.putc ('\t');
551 bol = false;
554 private void write_identifier (string! s) {
555 if (s == "base" || s == "callback" || s == "class" ||
556 s == "construct" || s == "flags" || s == "foreach" ||
557 s == "in" || s == "interface" || s == "lock" ||
558 s == "namespace" || s == "out" || s == "ref") {
559 stream.putc ('@');
561 write_string (s);
564 private void write_string (string! s) {
565 stream.printf ("%s", s);
566 bol = false;
569 private void write_newline () {
570 stream.putc ('\n');
571 bol = true;
574 private void write_begin_block () {
575 if (!bol) {
576 stream.putc (' ');
577 } else {
578 write_indent ();
580 stream.putc ('{');
581 write_newline ();
582 indent++;
585 private void write_end_block () {
586 indent--;
587 write_indent ();
588 stream.printf ("}");