1 /* valagtypemodule.vala
3 * Copyright (C) 2006-2008 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.1 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 <raffaele@sandrini.ch>
26 public class Vala
.GTypeModule
: GErrorModule
{
27 public GTypeModule (CCodeGenerator codegen
, CCodeModule? next
) {
31 public override void visit_interface (Interface iface
) {
32 current_symbol
= iface
;
33 current_type_symbol
= iface
;
35 if (iface
.get_cname().len () < 3) {
37 Report
.error (iface
.source_reference
, "Interface name `%s' is too short".printf (iface
.get_cname ()));
41 CCodeFragment decl_frag
;
42 CCodeFragment def_frag
;
43 if (iface
.access
!= SymbolAccessibility
.PRIVATE
) {
44 decl_frag
= header_type_declaration
;
45 def_frag
= header_type_definition
;
47 decl_frag
= source_type_declaration
;
48 def_frag
= source_type_definition
;
51 type_struct
= new
CCodeStruct ("_%s".printf (iface
.get_type_cname ()));
53 decl_frag
.append (new
CCodeNewline ());
54 var macro
= "(%s_get_type ())".printf (iface
.get_lower_case_cname (null));
55 decl_frag
.append (new
CCodeMacroReplacement (iface
.get_type_id (), macro
));
57 macro
= "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface
.get_type_id (), iface
.get_cname ());
58 decl_frag
.append (new
CCodeMacroReplacement ("%s(obj)".printf (iface
.get_upper_case_cname (null)), macro
));
60 macro
= "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface
.get_type_id ());
61 decl_frag
.append (new
CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (iface
)), macro
));
63 macro
= "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface
.get_type_id (), iface
.get_type_cname ());
64 decl_frag
.append (new
CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface
.get_upper_case_cname (null)), macro
));
65 decl_frag
.append (new
CCodeNewline ());
68 if (iface
.source_reference
.file
.cycle
== null) {
69 decl_frag
.append (new
CCodeTypeDefinition ("struct _%s".printf (iface
.get_cname ()), new
CCodeVariableDeclarator (iface
.get_cname ())));
70 decl_frag
.append (new
CCodeTypeDefinition ("struct %s".printf (type_struct
.name
), new
CCodeVariableDeclarator (iface
.get_type_cname ())));
73 type_struct
.add_field ("GTypeInterface", "parent_iface");
75 if (iface
.source_reference
.comment
!= null) {
76 def_frag
.append (new
CCodeComment (iface
.source_reference
.comment
));
78 def_frag
.append (type_struct
);
80 iface
.accept_children (codegen
);
82 add_interface_base_init_function (iface
);
84 var type_fun
= new
InterfaceRegisterFunction (iface
, context
);
85 type_fun
.init_from_type ();
86 if (iface
.access
!= SymbolAccessibility
.PRIVATE
) {
87 header_type_member_declaration
.append (type_fun
.get_declaration ());
89 source_type_member_declaration
.append (type_fun
.get_declaration ());
91 source_type_member_definition
.append (type_fun
.get_definition ());
93 current_type_symbol
= null;
96 private void add_interface_base_init_function (Interface iface
) {
97 var base_init
= new
CCodeFunction ("%s_base_init".printf (iface
.get_lower_case_cname (null)), "void");
98 base_init
.add_parameter (new
CCodeFormalParameter ("iface", "%sIface *".printf (iface
.get_cname ())));
99 base_init
.modifiers
= CCodeModifiers
.STATIC
;
101 var init_block
= new
CCodeBlock ();
103 /* make sure not to run the initialization code twice */
104 base_init
.block
= new
CCodeBlock ();
105 var decl
= new
CCodeDeclaration (bool_type
.get_cname ());
106 decl
.modifiers
|= CCodeModifiers
.STATIC
;
107 decl
.add_declarator (new
CCodeVariableDeclarator ("initialized", new
CCodeConstant ("FALSE")));
108 base_init
.block
.add_statement (decl
);
109 var cif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("initialized")), init_block
);
110 base_init
.block
.add_statement (cif
);
111 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("initialized"), new
CCodeConstant ("TRUE"))));
113 if (iface
.is_subtype_of (gobject_type
)) {
114 /* create properties */
115 var props
= iface
.get_properties ();
116 foreach (Property prop
in props
) {
117 if (prop
.is_abstract
) {
118 var cinst
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_interface_install_property"));
119 cinst
.add_argument (new
CCodeIdentifier ("iface"));
120 cinst
.add_argument (head
.get_param_spec (prop
));
122 init_block
.add_statement (new
CCodeExpressionStatement (cinst
));
128 foreach (Signal sig
in iface
.get_signals ()) {
129 init_block
.add_statement (new
CCodeExpressionStatement (head
.get_signal_creation (sig
, iface
)));
132 // connect default implementations
133 foreach (Method m
in iface
.get_methods ()) {
135 var ciface
= new
CCodeIdentifier ("iface");
136 var cname
= m
.get_real_cname ();
137 base_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.vfunc_name
), new
CCodeIdentifier (cname
))));
141 init_block
.add_statement (head
.register_dbus_info (iface
));
143 source_type_member_definition
.append (base_init
);
146 public override void visit_struct (Struct st
) {
147 base.visit_struct (st
);
149 CCodeFragment decl_frag
;
150 if (st
.access
!= SymbolAccessibility
.PRIVATE
) {
151 decl_frag
= header_type_declaration
;
153 decl_frag
= source_type_declaration
;
156 decl_frag
.append (new
CCodeNewline ());
157 var macro
= "(%s_get_type ())".printf (st
.get_lower_case_cname (null));
158 decl_frag
.append (new
CCodeMacroReplacement (st
.get_type_id (), macro
));
160 var type_fun
= new
StructRegisterFunction (st
, context
);
161 type_fun
.init_from_type (false);
162 if (st
.access
!= SymbolAccessibility
.PRIVATE
) {
163 header_type_member_declaration
.append (type_fun
.get_declaration ());
165 source_type_member_declaration
.append (type_fun
.get_declaration ());
167 source_type_member_definition
.append (type_fun
.get_definition ());