support virtual methods without wrapper with the [NoWrapper] attribute,
authorJuerg Billeter <j@bitron.ch>
Thu, 29 Nov 2007 20:31:43 +0000 (20:31 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 29 Nov 2007 20:31:43 +0000 (20:31 +0000)
2007-11-29  Juerg 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

svn path=/trunk/; revision=740

ChangeLog
gobject/Makefile.am
gobject/valaccodegenerator.vala
gobject/valaccodegeneratormemberaccess.vala
gobject/valaccodemethodbinding.vala [new file with mode: 0644]
vala/valamemberaccess.vala

index e95b9b2..03824bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 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,
index 3464877..ed08457 100644 (file)
@@ -27,6 +27,7 @@ libvala_la_VALASOURCES = \
        valaccodegeneratorsignal.vala \
        valaccodegeneratorsourcefile.vala \
        valaccodegeneratorstruct.vala \
+       valaccodemethodbinding.vala \
        valaclassregisterfunction.vala \
        valadbusbindingprovider.vala \
        valadbusmethod.vala \
index 5e65a6c..12d8047 100644 (file)
@@ -2863,7 +2863,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
        }
 
        public override CodeBinding create_method_binding (Method! node) {
-               return null;
+               return new CCodeMethodBinding (this, node);
        }
 
        public override CodeBinding create_creation_method_binding (CreationMethod! node) {
index d658854..5934181 100644 (file)
@@ -48,7 +48,25 @@ public class Vala.CCodeGenerator {
                        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 ());
                        }
diff --git a/gobject/valaccodemethodbinding.vala b/gobject/valaccodemethodbinding.vala
new file mode 100644 (file)
index 0000000..32bf1b3
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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 () {
+       }
+}
index 60a1954..56e5284 100644 (file)
@@ -116,6 +116,6 @@ public class Vala.MemberAccess : Expression {
 
        public override bool is_pure () {
                // accessing property could have side-effects
-               return false;
+               return (inner == null || inner.is_pure ()) && !(symbol_reference is Property);
        }
 }