remove obsolete ref modifier and callback keyword
[vala-lang.git] / gobject / valacodegeneratorinterface.vala
blobf07715d98f1e7ca70d4425f9c0ab18d937dca367
1 /* valacodegeneratorinterface.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 public class Vala.CodeGenerator {
27 public override void visit_interface (Interface! iface) {
28 current_symbol = iface.symbol;
29 current_type_symbol = iface.symbol;
31 if (!iface.is_static) {
32 type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ()));
34 header_type_declaration.append (new CCodeNewline ());
35 var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
36 header_type_declaration.append (new CCodeMacroReplacement (iface.get_upper_case_cname ("TYPE_"), macro));
38 macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
39 header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname (null)), macro));
41 macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
42 header_type_declaration.append (new CCodeMacroReplacement ("%s(obj)".printf (iface.get_upper_case_cname ("IS_")), macro));
44 macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_type_cname ());
45 header_type_declaration.append (new CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), macro));
46 header_type_declaration.append (new CCodeNewline ());
49 if (iface.source_reference.file.cycle == null) {
50 header_type_declaration.append (new CCodeTypeDefinition ("struct _%s".printf (iface.get_cname ()), new CCodeVariableDeclarator (iface.get_cname ())));
51 header_type_declaration.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator (iface.get_type_cname ())));
54 type_struct.add_field ("GTypeInterface", "parent");
56 if (iface.source_reference.comment != null) {
57 header_type_definition.append (new CCodeComment (iface.source_reference.comment));
59 header_type_definition.append (type_struct);
62 iface.accept_children (this);
64 if (!iface.is_static) {
65 add_interface_base_init_function (iface);
67 var type_fun = new InterfaceRegisterFunction (iface);
68 type_fun.init_from_type ();
69 header_type_member_declaration.append (type_fun.get_declaration ());
70 source_type_member_definition.append (type_fun.get_definition ());
73 current_type_symbol = null;
76 private CCodeFunctionCall! get_param_spec (Property! prop) {
77 var cspec = new CCodeFunctionCall ();
78 cspec.add_argument (prop.get_canonical_cconstant ());
79 cspec.add_argument (new CCodeConstant ("\"foo\""));
80 cspec.add_argument (new CCodeConstant ("\"bar\""));
81 if (prop.type_reference.data_type is Class || prop.type_reference.data_type is Interface) {
82 cspec.call = new CCodeIdentifier ("g_param_spec_object");
83 cspec.add_argument (new CCodeIdentifier (prop.type_reference.data_type.get_upper_case_cname ("TYPE_")));
84 } else if (prop.type_reference.data_type == string_type.data_type) {
85 cspec.call = new CCodeIdentifier ("g_param_spec_string");
86 cspec.add_argument (new CCodeConstant ("NULL"));
87 } else if (prop.type_reference.data_type == int_type.data_type
88 || prop.type_reference.data_type is Enum) {
89 cspec.call = new CCodeIdentifier ("g_param_spec_int");
90 cspec.add_argument (new CCodeConstant ("G_MININT"));
91 cspec.add_argument (new CCodeConstant ("G_MAXINT"));
92 cspec.add_argument (new CCodeConstant ("0"));
93 } else if (prop.type_reference.data_type == uint_type.data_type) {
94 cspec.call = new CCodeIdentifier ("g_param_spec_uint");
95 cspec.add_argument (new CCodeConstant ("0"));
96 cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
97 cspec.add_argument (new CCodeConstant ("0U"));
98 } else if (prop.type_reference.data_type == long_type.data_type) {
99 cspec.call = new CCodeIdentifier ("g_param_spec_long");
100 cspec.add_argument (new CCodeConstant ("G_MINLONG"));
101 cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
102 cspec.add_argument (new CCodeConstant ("0L"));
103 } else if (prop.type_reference.data_type == ulong_type.data_type) {
104 cspec.call = new CCodeIdentifier ("g_param_spec_ulong");
105 cspec.add_argument (new CCodeConstant ("0"));
106 cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
107 cspec.add_argument (new CCodeConstant ("0UL"));
108 } else if (prop.type_reference.data_type == bool_type.data_type) {
109 cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
110 cspec.add_argument (new CCodeConstant ("FALSE"));
111 } else if (prop.type_reference.data_type == float_type.data_type) {
112 cspec.call = new CCodeIdentifier ("g_param_spec_float");
113 cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
114 cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
115 cspec.add_argument (new CCodeConstant ("0.0F"));
116 } else if (prop.type_reference.data_type == double_type.data_type) {
117 cspec.call = new CCodeIdentifier ("g_param_spec_double");
118 cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
119 cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
120 cspec.add_argument (new CCodeConstant ("0.0"));
121 } else {
122 cspec.call = new CCodeIdentifier ("g_param_spec_pointer");
125 var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
126 if (prop.get_accessor != null) {
127 pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
129 if (prop.set_accessor != null) {
130 pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
131 if (prop.set_accessor.construction) {
132 if (prop.set_accessor.writable) {
133 pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
134 } else {
135 pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
139 cspec.add_argument (new CCodeConstant (pflags));
141 return cspec;
144 private CCodeFunctionCall! get_signal_creation (Signal! sig, DataType! type) {
145 var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
146 csignew.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
147 csignew.add_argument (new CCodeIdentifier (type.get_upper_case_cname ("TYPE_")));
148 csignew.add_argument (new CCodeConstant ("G_SIGNAL_RUN_LAST"));
149 csignew.add_argument (new CCodeConstant ("0"));
150 csignew.add_argument (new CCodeConstant ("NULL"));
151 csignew.add_argument (new CCodeConstant ("NULL"));
153 string marshaller = get_signal_marshaller_function (sig);
155 var marshal_arg = new CCodeIdentifier (marshaller);
156 csignew.add_argument (marshal_arg);
158 var params = sig.get_parameters ();
159 var params_len = params.length ();
160 if (sig.return_type.type_parameter != null) {
161 csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
162 } else if (sig.return_type.data_type == null) {
163 csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
164 } else {
165 csignew.add_argument (new CCodeConstant (sig.return_type.data_type.get_type_id ()));
167 csignew.add_argument (new CCodeConstant ("%d".printf (params_len)));
168 foreach (FormalParameter param in params) {
169 if (param.type_reference.type_parameter != null) {
170 csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
171 } else {
172 csignew.add_argument (new CCodeConstant (param.type_reference.data_type.get_type_id ()));
176 marshal_arg.name = marshaller;
178 return csignew;
181 private void add_interface_base_init_function (Interface! iface) {
182 var base_init = new CCodeFunction ("%s_base_init".printf (iface.get_lower_case_cname (null)), "void");
183 base_init.add_parameter (new CCodeFormalParameter ("iface", "%sIface *".printf (iface.get_cname ())));
184 base_init.modifiers = CCodeModifiers.STATIC;
186 var init_block = new CCodeBlock ();
188 /* make sure not to run the initialization code twice */
189 base_init.block = new CCodeBlock ();
190 var decl = new CCodeDeclaration (bool_type.get_cname ());
191 decl.modifiers |= CCodeModifiers.STATIC;
192 decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("initialized", new CCodeConstant ("FALSE")));
193 base_init.block.add_statement (decl);
194 var cif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("initialized")), init_block);
195 base_init.block.add_statement (cif);
196 init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("initialized"), new CCodeConstant ("TRUE"))));
198 /* create properties */
199 var props = iface.get_properties ();
200 foreach (Property prop in props) {
201 var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_interface_install_property"));
202 cinst.add_argument (new CCodeIdentifier ("iface"));
203 cinst.add_argument (get_param_spec (prop));
205 init_block.add_statement (new CCodeExpressionStatement (cinst));
208 /* create signals */
209 foreach (Signal sig in iface.get_signals ()) {
210 init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, iface)));
213 source_type_member_definition.append (base_init);