write static delegate instead of callback use static delegate instead of
[vala-lang.git] / vala / valainterfacewriter.vala
blob39a598e937093ac00699b1de49c0ee074b17ab79
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.reference_to_value_type ||
305 param.type_reference.takes_ownership) {
306 write_string ("ref ");
307 } else if (param.type_reference.is_out) {
308 write_string ("out ");
310 write_string (param.type_reference.data_type.symbol.get_full_name ());
312 var type_args = param.type_reference.get_type_arguments ();
313 if (!(param.type_reference.data_type is Array) && type_args != null) {
314 write_string ("<");
315 foreach (TypeReference type_arg in type_args) {
316 if (type_arg.takes_ownership) {
317 write_string ("ref ");
319 write_string (type_arg.data_type.symbol.get_full_name ());
321 write_string (">");
324 if (param.type_reference.non_null) {
325 write_string ("!");
328 write_string (" ");
329 write_identifier (param.name);
331 if (param.default_expression != null) {
332 write_string (" = ");
333 write_string (param.default_expression.to_string ());
337 write_string (")");
340 public override void visit_callback (Callback! cb) {
341 if (cb.access == MemberAccessibility.PRIVATE) {
342 return;
345 write_indent ();
346 write_string ("public static delegate ");
348 var type = cb.return_type.data_type;
349 if (type == null) {
350 write_string ("void");
351 } else {
352 if (cb.return_type.transfers_ownership) {
353 write_string ("ref ");
355 write_string (cb.return_type.data_type.symbol.get_full_name ());
358 write_string (" ");
359 write_identifier (cb.name);
361 write_string (" ");
363 write_params (cb.get_parameters ());
365 write_string (";");
367 write_newline ();
370 public override void visit_method (Method! m) {
371 if (m.access == MemberAccessibility.PRIVATE || m.overrides) {
372 return;
375 if (m.no_array_length) {
376 bool array_found = (m.return_type != null && m.return_type.data_type is Array);
377 foreach (FormalParameter param in m.get_parameters ()) {
378 if (param.type_reference != null && param.type_reference.data_type is Array) {
379 array_found = true;
380 break;
383 if (array_found) {
384 write_indent ();
385 write_string ("[NoArrayLength]");
388 if (m.instance_last) {
389 write_indent ();
390 write_string ("[InstanceLast]");
392 if (m.instance_by_reference) {
393 write_indent ();
394 write_string ("[InstanceByReference]");
396 if (m.get_cname () != m.get_default_cname ()) {
397 write_indent ();
398 write_string ("[CCode (cname = \"%s\")]".printf (m.get_cname ()));
401 write_indent ();
402 write_string ("public");
404 if (m is CreationMethod) {
405 write_string (" ");
406 var datatype = (DataType) m.symbol.parent_symbol.node;
407 write_identifier (datatype.name);
409 if (m.name != null) {
410 write_string (".");
411 write_identifier (m.name);
413 } else if (!m.instance) {
414 write_string (" static");
415 } else if (m.is_abstract) {
416 write_string (" abstract");
417 } else if (m.is_virtual) {
418 write_string (" virtual");
421 if (!(m is CreationMethod)) {
422 write_string (" ");
424 var type = m.return_type.data_type;
425 if (type == null) {
426 write_string ("void");
427 } else {
428 if (m.return_type.transfers_ownership) {
429 } else if ((m.return_type.data_type != null && m.return_type.data_type.is_reference_type ()) || m.return_type.type_parameter != null) {
430 write_string ("weak ");
432 write_string (m.return_type.data_type.symbol.get_full_name ());
433 if (m.return_type.non_null) {
434 write_string ("!");
438 write_string (" ");
439 write_identifier (m.name);
442 write_string (" ");
444 write_params (m.get_parameters ());
446 write_string (";");
448 write_newline ();
451 public override void visit_creation_method (CreationMethod! m) {
452 visit_method (m);
455 public override void visit_property (Property! prop) {
456 if (prop.no_accessor_method) {
457 write_indent ();
458 write_string ("[NoAccessorMethod]");
461 write_indent ();
462 write_string ("public ");
463 if (!prop.type_reference.takes_ownership) {
464 write_string ("weak ");
466 write_string (prop.type_reference.data_type.symbol.get_full_name ());
468 var type_args = prop.type_reference.get_type_arguments ();
469 if (!(prop.type_reference.data_type is Array) && type_args != null) {
470 write_string ("<");
471 foreach (TypeReference type_arg in type_args) {
472 if (!type_arg.takes_ownership) {
473 write_string ("weak ");
475 write_string (type_arg.data_type.symbol.get_full_name ());
477 write_string (">");
480 write_string (" ");
481 write_identifier (prop.name);
482 write_string (" {");
483 if (prop.get_accessor != null) {
484 write_string (" get;");
486 if (prop.set_accessor != null) {
487 if (prop.set_accessor.writable) {
488 write_string (" set");
490 if (prop.set_accessor.construction) {
491 write_string (" construct");
493 write_string (";");
495 write_string (" }");
496 write_newline ();
499 public override void visit_signal (Signal! sig) {
500 if (sig.access == MemberAccessibility.PRIVATE) {
501 return;
504 if (sig.has_emitter) {
505 write_indent ();
506 write_string ("[HasEmitter]");
509 write_indent ();
510 write_string ("public signal ");
512 var type = sig.return_type.data_type;
513 if (type == null) {
514 write_string ("void");
515 } else {
516 if (sig.return_type.transfers_ownership) {
517 write_string ("ref ");
519 write_string (sig.return_type.data_type.symbol.get_full_name ());
520 if (sig.return_type.non_null) {
521 write_string ("!");
525 write_string (" ");
526 write_identifier (sig.name);
528 write_string (" ");
530 write_params (sig.get_parameters ());
532 write_string (";");
534 write_newline ();
537 private void write_indent () {
538 int i;
540 if (!bol) {
541 stream.putc ('\n');
544 for (i = 0; i < indent; i++) {
545 stream.putc ('\t');
548 bol = false;
551 private void write_identifier (string! s) {
552 if (s == "base" || s == "callback" || s == "class" ||
553 s == "construct" || s == "flags" || s == "foreach" ||
554 s == "in" || s == "interface" || s == "lock" ||
555 s == "namespace" || s == "out" || s == "ref") {
556 stream.putc ('@');
558 write_string (s);
561 private void write_string (string! s) {
562 stream.printf ("%s", s);
563 bol = false;
566 private void write_newline () {
567 stream.putc ('\n');
568 bol = true;
571 private void write_begin_block () {
572 if (!bol) {
573 stream.putc (' ');
574 } else {
575 write_indent ();
577 stream.putc ('{');
578 write_newline ();
579 indent++;
582 private void write_end_block () {
583 indent--;
584 write_indent ();
585 stream.printf ("}");