remove obsolete ref modifier and callback keyword
[vala-lang.git] / gobject / valacodegeneratormemberaccess.vala
blobb6c1876d715c6e4f045387bfe39de1a39ad12dee
1 /* valacodegeneratormemberaccess.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 private void process_cmember (MemberAccess! expr, CCodeExpression pub_inst, DataType base_type) {
28 if (expr.symbol_reference.node is Method) {
29 var m = (Method) expr.symbol_reference.node;
31 if (expr.inner is BaseAccess) {
32 if (m.base_interface_method != null) {
33 var base_iface = (Interface) m.base_interface_method.symbol.parent_symbol.node;
34 string parent_iface_var = "%s_%s_parent_iface".printf (current_class.get_lower_case_cname (null), base_iface.get_lower_case_cname (null));
36 expr.ccodenode = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.name);
37 return;
38 } else if (m.base_method != null) {
39 var base_class = (Class) m.base_method.symbol.parent_symbol.node;
40 var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
41 vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
43 expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
44 return;
48 if (m.base_interface_method != null) {
49 expr.ccodenode = new CCodeIdentifier (m.base_interface_method.get_cname ());
50 } else if (m.base_method != null) {
51 expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ());
52 } else {
53 expr.ccodenode = new CCodeIdentifier (m.get_cname ());
55 } else if (expr.symbol_reference.node is ArrayLengthField) {
56 expr.ccodenode = get_array_length_cexpression (expr.inner, 1);
57 } else if (expr.symbol_reference.node is Field) {
58 var f = (Field) expr.symbol_reference.node;
59 if (f.instance) {
60 CCodeExpression typed_inst;
61 if (f.symbol.parent_symbol.node != base_type) {
62 // FIXME: use C cast if debugging disabled
63 typed_inst = new CCodeFunctionCall (new CCodeIdentifier (((DataType) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
64 ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
65 } else {
66 typed_inst = pub_inst;
68 CCodeExpression inst;
69 if (f.access == MemberAccessibility.PRIVATE) {
70 inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
71 } else {
72 inst = typed_inst;
74 if (((DataType) f.symbol.parent_symbol.node).is_reference_type ()) {
75 expr.ccodenode = new CCodeMemberAccess.pointer (inst, f.get_cname ());
76 } else {
77 expr.ccodenode = new CCodeMemberAccess (inst, f.get_cname ());
79 } else {
80 expr.ccodenode = new CCodeIdentifier (f.get_cname ());
82 } else if (expr.symbol_reference.node is Constant) {
83 var c = (Constant) expr.symbol_reference.node;
84 expr.ccodenode = new CCodeIdentifier (c.get_cname ());
85 } else if (expr.symbol_reference.node is Property) {
86 var prop = (Property) expr.symbol_reference.node;
88 if (!prop.no_accessor_method) {
89 var base_property = prop;
90 if (prop.base_property != null) {
91 base_property = prop.base_property;
92 } else if (prop.base_interface_property != null) {
93 base_property = prop.base_interface_property;
95 var base_property_type = (DataType) base_property.symbol.parent_symbol.node;
96 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (base_property_type.get_lower_case_cname (null), base_property.name)));
98 CCodeExpression typed_pub_inst = pub_inst;
100 /* cast if necessary */
101 if (base_property_type != base_type) {
102 // FIXME: use C cast if debugging disabled
103 var ccast = new CCodeFunctionCall (new CCodeIdentifier (base_property_type.get_upper_case_cname (null)));
104 ccast.add_argument (pub_inst);
105 typed_pub_inst = ccast;
108 ccall.add_argument (typed_pub_inst);
109 expr.ccodenode = ccall;
110 } else {
111 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
113 var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
114 ccast.add_argument (pub_inst);
115 ccall.add_argument (ccast);
117 // property name is second argument of g_object_get
118 ccall.add_argument (prop.get_canonical_cconstant ());
121 // we need a temporary variable to save the property value
122 var temp_decl = get_temp_variable_declarator (expr.static_type);
123 temp_vars.prepend (temp_decl);
125 var ctemp = new CCodeIdentifier (temp_decl.name);
126 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
129 ccall.add_argument (new CCodeConstant ("NULL"));
131 var ccomma = new CCodeCommaExpression ();
132 ccomma.append_expression (ccall);
133 ccomma.append_expression (ctemp);
134 expr.ccodenode = ccomma;
136 } else if (expr.symbol_reference.node is EnumValue) {
137 var ev = (EnumValue) expr.symbol_reference.node;
138 expr.ccodenode = new CCodeConstant (ev.get_cname ());
139 } else if (expr.symbol_reference.node is VariableDeclarator) {
140 var decl = (VariableDeclarator) expr.symbol_reference.node;
141 expr.ccodenode = new CCodeIdentifier (get_variable_cname (decl.name));
142 } else if (expr.symbol_reference.node is FormalParameter) {
143 var p = (FormalParameter) expr.symbol_reference.node;
144 if (p.name == "this") {
145 expr.ccodenode = pub_inst;
146 } else {
147 if (p.type_reference.is_out || p.type_reference.is_ref) {
148 expr.ccodenode = new CCodeIdentifier ("(*%s)".printf (p.name));
149 } else {
150 expr.ccodenode = new CCodeIdentifier (p.name);
153 } else if (expr.symbol_reference.node is Signal) {
154 var sig = (Signal) expr.symbol_reference.node;
155 var cl = (DataType) sig.symbol.parent_symbol.node;
157 if (sig.has_emitter) {
158 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
160 /* explicitly use strong reference as ccast
161 * gets unrefed at the end of the inner block
163 CCodeExpression typed_pub_inst = pub_inst;
165 /* cast if necessary */
166 if (cl != base_type) {
167 // FIXME: use C cast if debugging disabled
168 var ccast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
169 ccast.add_argument (pub_inst);
170 typed_pub_inst = ccast;
173 ccall.add_argument (typed_pub_inst);
174 expr.ccodenode = ccall;
175 } else {
176 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
178 // FIXME: use C cast if debugging disabled
179 var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
180 ccast.add_argument (pub_inst);
181 ccall.add_argument (ccast);
183 ccall.add_argument (sig.get_canonical_cconstant ());
185 expr.ccodenode = ccall;
190 public override void visit_member_access (MemberAccess! expr) {
191 CCodeExpression pub_inst = null;
192 DataType base_type = null;
194 if (expr.inner == null) {
195 pub_inst = new CCodeIdentifier ("self");
197 if (current_type_symbol != null) {
198 /* base type is available if this is a type method */
199 base_type = (DataType) current_type_symbol.node;
201 if (!base_type.is_reference_type ()) {
202 pub_inst = new CCodeIdentifier ("(*self)");
205 } else {
206 pub_inst = (CCodeExpression) expr.inner.ccodenode;
208 if (expr.inner.static_type != null) {
209 base_type = expr.inner.static_type.data_type;
213 process_cmember (expr, pub_inst, base_type);
215 visit_expression (expr);