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
.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) {
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 ());
323 if (param
.type_reference
.non_null
) {
327 if (param
.type_reference
.takes_ownership
) {
332 write_identifier (param
.name
);
334 if (param
.default_expression
!= null) {
335 write_string (" = ");
336 write_string (param
.default_expression
.to_string ());
343 public override void visit_callback (Callback
! cb
) {
344 if (cb
.access
== MemberAccessibility
.PRIVATE
) {
349 write_string ("public static delegate ");
351 var type
= cb
.return_type
.data_type
;
353 write_string ("void");
355 if (cb
.return_type
.transfers_ownership
) {
356 write_string ("ref ");
358 write_string (cb
.return_type
.data_type
.symbol
.get_full_name ());
362 write_identifier (cb
.name
);
366 write_params (cb
.get_parameters ());
373 public override void visit_method (Method
! m
) {
374 if (m
.access
== MemberAccessibility
.PRIVATE
|| m
.overrides
) {
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
) {
388 write_string ("[NoArrayLength]");
391 if (m
.instance_last
) {
393 write_string ("[InstanceLast]");
395 if (m
.instance_by_reference
) {
397 write_string ("[InstanceByReference]");
399 if (m
.get_cname () != m
.get_default_cname ()) {
401 write_string ("[CCode (cname = \"%s\")]".printf (m
.get_cname ()));
405 write_string ("public");
407 if (m is CreationMethod
) {
409 var datatype
= (DataType
) m
.symbol
.parent_symbol
.node
;
410 write_identifier (datatype
.name
);
412 if (m
.name
!= null) {
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
)) {
427 var type
= m
.return_type
.data_type
;
429 write_string ("void");
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
) {
442 write_identifier (m
.name
);
447 write_params (m
.get_parameters ());
454 public override void visit_creation_method (CreationMethod
! m
) {
458 public override void visit_property (Property
! prop
) {
459 if (prop
.no_accessor_method
) {
461 write_string ("[NoAccessorMethod]");
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) {
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 ());
484 write_identifier (prop
.name
);
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");
502 public override void visit_signal (Signal
! sig
) {
503 if (sig
.access
== MemberAccessibility
.PRIVATE
) {
507 if (sig
.has_emitter
) {
509 write_string ("[HasEmitter]");
513 write_string ("public signal ");
515 var type
= sig
.return_type
.data_type
;
517 write_string ("void");
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
) {
529 write_identifier (sig
.name
);
533 write_params (sig
.get_parameters ());
540 private void write_indent () {
547 for (i
= 0; i
< indent
; i
++) {
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") {
564 private void write_string (string! s
) {
565 stream
.printf ("%s", s
);
569 private void write_newline () {
574 private void write_begin_block () {
585 private void write_end_block () {