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
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <rasa@gmx.ch>
27 * Code visitor generating Vala API file for the public interface.
29 public class Vala
.InterfaceWriter
: CodeVisitor
{
30 private CodeContext context
;
35 /* at begin of line */
38 string current_cheader_filename
;
41 * Writes the public interface of the specified code context into the
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 ()) {
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
);
72 current_cheader_filename
= ns
.get_cheader_filename ();
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
));
79 write_string ("namespace ");
80 write_identifier (ns
.name
);
83 ns
.accept_children (this
);
89 public override void visit_class (Class
! cl
) {
90 if (cl
.access
== MemberAccessibility
.PRIVATE
) {
98 foreach (string cheader
in cl
.get_cheader_filenames ()) {
103 cheaders
= "%s, %s".printf (cheaders
, cheader
);
106 write_string ("[CCode (cheader_filename = \"%s\")]".printf (cheaders
));
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 (" : ");
122 foreach (TypeReference base_type
in base_types
) {
128 write_string (base_type
.data_type
.symbol
.get_full_name ());
131 write_begin_block ();
133 cl
.accept_children (this
);
139 public override void visit_struct (Struct
! st
) {
140 if (st
.access
== MemberAccessibility
.PRIVATE
) {
144 if (st
.is_reference_type ()) {
146 write_string ("[ReferenceType]");
150 write_string ("public struct ");
151 write_identifier (st
.name
);
152 write_begin_block ();
154 st
.accept_children (this
);
160 public override void visit_interface (Interface
! iface
) {
161 if (iface
.access
== MemberAccessibility
.PRIVATE
) {
169 foreach (string cheader
in iface
.get_cheader_filenames ()) {
174 cheaders
= "%s, %s".printf (cheaders
, cheader
);
177 write_string ("[CCode (cheader_filename = \"%s\")]".printf (cheaders
));
181 write_string ("public ");
182 write_string ("interface ");
183 write_identifier (iface
.name
);
185 write_begin_block ();
187 iface
.accept_children (this
);
193 public override void visit_enum (Enum
! en
) {
194 if (en
.access
== MemberAccessibility
.PRIVATE
) {
199 write_string ("[CCode (cprefix = \"%s\")]".printf (en
.get_cprefix ()));
202 write_string ("public enum ");
203 write_identifier (en
.name
);
204 write_begin_block ();
206 en
.accept_children (this
);
212 public override void visit_enum_value (EnumValue
! ev
) {
214 write_identifier (ev
.name
);
219 public override void visit_flags (Flags
! fl
) {
220 if (fl
.access
== MemberAccessibility
.PRIVATE
) {
225 write_string ("[CCode (cprefix = \"%s\")]".printf (fl
.get_cprefix ()));
228 write_string ("public flags ");
229 write_identifier (fl
.name
);
230 write_begin_block ();
232 fl
.accept_children (this
);
238 public override void visit_flags_value (FlagsValue
! fv
) {
240 write_identifier (fv
.name
);
245 public override void visit_constant (Constant
! c
) {
247 write_string ("public const ");
248 write_string (c
.type_reference
.data_type
.symbol
.get_full_name ());
251 write_identifier (c
.name
);
256 public override void visit_field (Field
! f
) {
257 if (f
.access
== MemberAccessibility
.PRIVATE
) {
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) {
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 ());
283 write_identifier (f
.name
);
288 private void write_params (List
<FormalParameter
> params
) {
292 foreach (FormalParameter param
in params
) {
299 if (param
.ellipsis
) {
300 write_string ("...");
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) {
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 ());
324 if (param
.type_reference
.non_null
) {
329 write_identifier (param
.name
);
331 if (param
.default_expression
!= null) {
332 write_string (" = ");
333 write_string (param
.default_expression
.to_string ());
340 public override void visit_callback (Callback
! cb
) {
341 if (cb
.access
== MemberAccessibility
.PRIVATE
) {
346 write_string ("public static delegate ");
348 var type
= cb
.return_type
.data_type
;
350 write_string ("void");
352 if (cb
.return_type
.transfers_ownership
) {
353 write_string ("ref ");
355 write_string (cb
.return_type
.data_type
.symbol
.get_full_name ());
359 write_identifier (cb
.name
);
363 write_params (cb
.get_parameters ());
370 public override void visit_method (Method
! m
) {
371 if (m
.access
== MemberAccessibility
.PRIVATE
|| m
.overrides
) {
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
) {
385 write_string ("[NoArrayLength]");
388 if (m
.instance_last
) {
390 write_string ("[InstanceLast]");
392 if (m
.instance_by_reference
) {
394 write_string ("[InstanceByReference]");
396 if (m
.get_cname () != m
.get_default_cname ()) {
398 write_string ("[CCode (cname = \"%s\")]".printf (m
.get_cname ()));
402 write_string ("public");
404 if (m is CreationMethod
) {
406 var datatype
= (DataType
) m
.symbol
.parent_symbol
.node
;
407 write_identifier (datatype
.name
);
409 if (m
.name
!= null) {
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
)) {
424 var type
= m
.return_type
.data_type
;
426 write_string ("void");
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
) {
439 write_identifier (m
.name
);
444 write_params (m
.get_parameters ());
451 public override void visit_creation_method (CreationMethod
! m
) {
455 public override void visit_property (Property
! prop
) {
456 if (prop
.no_accessor_method
) {
458 write_string ("[NoAccessorMethod]");
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) {
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 ());
481 write_identifier (prop
.name
);
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");
499 public override void visit_signal (Signal
! sig
) {
500 if (sig
.access
== MemberAccessibility
.PRIVATE
) {
504 if (sig
.has_emitter
) {
506 write_string ("[HasEmitter]");
510 write_string ("public signal ");
512 var type
= sig
.return_type
.data_type
;
514 write_string ("void");
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
) {
526 write_identifier (sig
.name
);
530 write_params (sig
.get_parameters ());
537 private void write_indent () {
544 for (i
= 0; i
< indent
; i
++) {
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") {
561 private void write_string (string! s
) {
562 stream
.printf ("%s", s
);
566 private void write_newline () {
571 private void write_begin_block () {
582 private void write_end_block () {