Support vfunc_name attribute
[vala-lang.git] / gobject / valagtypemodule.vala
blob6ce84b7509791cbd1301ff3c2e97e8bdfe197257
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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <raffaele@sandrini.ch>
24 using GLib;
26 public class Vala.GTypeModule : GErrorModule {
27 public GTypeModule (CCodeGenerator codegen, CCodeModule? next) {
28 base (codegen, 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) {
36 iface.error = true;
37 Report.error (iface.source_reference, "Interface name `%s' is too short".printf (iface.get_cname ()));
38 return;
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;
46 } else {
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 ());
88 } else {
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));
127 /* create signals */
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 ()) {
134 if (m.is_virtual) {
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;
152 } else {
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 ());
164 } else {
165 source_type_member_declaration.append (type_fun.get_declaration ());
167 source_type_member_definition.append (type_fun.get_definition ());