2007-11-29 Jürg Billeter <j@bitron.ch>
+ * vala/valamemberaccess.vala, gobject/Makefile.am,
+ gobject/valaccodegenerator.vala,
+ gobject/valaccodegeneratormemberaccess.vala,
+ gobject/valaccodemethodbinding.vala: support virtual methods without
+ wrapper with the [NoWrapper] attribute, fixes bug 455874
+
+2007-11-29 Jürg Billeter <j@bitron.ch>
+
* vala/valaaddressofexpression.vala,
vala/valaarraycreationexpression.vala, vala/valaassignment.vala,
vala/valabaseaccess.vala, vala/valabinaryexpression.vala,
valaccodegeneratorsignal.vala \
valaccodegeneratorsourcefile.vala \
valaccodegeneratorstruct.vala \
+ valaccodemethodbinding.vala \
valaclassregisterfunction.vala \
valadbusbindingprovider.vala \
valadbusmethod.vala \
}
public override CodeBinding create_method_binding (Method! node) {
- return null;
+ return new CCodeMethodBinding (this, node);
}
public override CodeBinding create_creation_method_binding (CreationMethod! node) {
if (m.base_interface_method != null) {
expr.ccodenode = new CCodeIdentifier (m.base_interface_method.get_cname ());
} else if (m.base_method != null) {
- expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ());
+ var binding = CCodeMethodBinding.get (m.base_method);
+ if (!binding.has_wrapper) {
+ var inst = pub_inst;
+ if (expr.inner != null && !expr.inner.is_pure ()) {
+ // instance expression has side-effects
+ // store in temp. variable
+ var temp_decl = get_temp_variable_declarator (expr.inner.static_type);
+ temp_vars.insert (0, temp_decl);
+ var ctemp = new CCodeIdentifier (temp_decl.name);
+ inst = new CCodeAssignment (ctemp, pub_inst);
+ expr.inner.ccodenode = ctemp;
+ }
+ var base_class = (Class) m.base_method.parent_symbol;
+ var vclass = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (base_class.get_upper_case_cname (null))));
+ vclass.add_argument (inst);
+ expr.ccodenode = new CCodeMemberAccess.pointer (vclass, m.name);
+ } else {
+ expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ());
+ }
} else {
expr.ccodenode = new CCodeIdentifier (m.get_cname ());
}
--- /dev/null
+/* valaccodemethodbinding.vala
+ *
+ * Copyright (C) 2007 Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * The link between a method and generated code.
+ */
+public class Vala.CCodeMethodBinding : CCodeBinding {
+ public Method! method { get; set; }
+
+ public bool has_wrapper {
+ get { return (method.get_attribute ("NoWrapper") == null); }
+ }
+
+ public CCodeMethodBinding (construct CodeGenerator! codegen, construct Method! method) {
+ }
+
+ public static CCodeMethodBinding! get (Method! method) {
+ return (CCodeMethodBinding) method.code_binding;
+ }
+
+ public override void emit () {
+ }
+}
public override bool is_pure () {
// accessing property could have side-effects
- return false;
+ return (inner == null || inner.is_pure ()) && !(symbol_reference is Property);
}
}