]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
improve support for virtual methods, based on patch by Michael Lawrence,
authorJuerg Billeter <j@bitron.ch>
Sat, 2 Feb 2008 13:40:06 +0000 (13:40 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 2 Feb 2008 13:40:06 +0000 (13:40 +0000)
2008-02-02  Juerg Billeter  <j@bitron.ch>

* gobject-introspection/gidl.vapi, vapigen/valagidlparser.vala:
  improve support for virtual methods,
  based on patch by Michael Lawrence, fixes bug 452019

svn path=/trunk/; revision=950

ChangeLog
gobject-introspection/gidl.vapi
vapigen/valagidlparser.vala

index 2d6a2381962524225d758602e5120a052997171d..30f5924ea7fb7c91beab658668cb77600f9bfec5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-02-02  Jürg Billeter  <j@bitron.ch>
+
+       * gobject-introspection/gidl.vapi, vapigen/valagidlparser.vala:
+         improve support for virtual methods,
+         based on patch by Michael Lawrence, fixes bug 452019
+
 2008-02-02  Jürg Billeter  <j@bitron.ch>
 
        * vapi/Makefile.am, vapi/packages/gdk-x11-2.0/, vapi/gdk-x11-2.0.deps,
index 28498a0d8aef4b23ded56204ee083bd8a5364c6b..300a4a5c269d7c25f39b7cc228800dbcf356a195 100644 (file)
@@ -78,6 +78,19 @@ namespace GLib {
                public IdlNodeParam result;
                public List<IdlNodeParam> parameters;
        }
+
+       [CCode (free_function = "g_idl_node_free", cheader_filename = "gidlnode.h")]
+       public class IdlNodeVFunc 
+       {
+               public bool must_chain_up;
+               public bool must_be_implemented;
+               public bool must_not_be_implemented;
+               public bool is_class_closure;
+                   
+               public List<IdlNodeParam> parameters;
+               public IdlNodeParam result;
+               public int offset;
+       }
        
        [CCode (free_function = "g_idl_node_free", cheader_filename = "gidlnode.h")]
        public class IdlNodeSignal {
index b3ec9dfa9003be1d43fcf94df373440a9cad690c..3e6a4091eee96af38ba61a24aecb8275549fd599 100644 (file)
@@ -799,9 +799,13 @@ public class Vala.GIdlParser : CodeVisitor {
                current_data_type = cl;
                
                current_type_symbol_set = new HashSet<string> (str_hash, str_equal);
+               var current_type_func_map = new HashMap<string,weak IdlNodeFunction> (str_hash, str_equal);
                var current_type_vfunc_map = new HashMap<string,string> (str_hash, str_equal);
                
                foreach (weak IdlNode member in node.members) {
+                       if (member.type == IdlNodeTypeId.FUNCTION) {
+                               current_type_func_map.set (member.name, (IdlNodeFunction) member);
+                       }
                        if (member.type == IdlNodeTypeId.VFUNC) {
                                current_type_vfunc_map.set (member.name, "1");
                        }
@@ -809,9 +813,15 @@ public class Vala.GIdlParser : CodeVisitor {
 
                foreach (weak IdlNode member in node.members) {
                        if (member.type == IdlNodeTypeId.FUNCTION) {
-                               bool is_virtual = current_type_vfunc_map.get (member.name) != null;
-                               
-                               var m = parse_function ((IdlNodeFunction) member, is_virtual);
+                               // Ignore if vfunc (handled below) 
+                               if (!current_type_vfunc_map.contains (member.name)) {
+                                       var m = parse_function ((IdlNodeFunction) member);
+                                       if (m != null) {
+                                               cl.add_method (m);
+                                       }
+                               }
+                       } else if (member.type == IdlNodeTypeId.VFUNC) {
+                               var m = parse_virtual ((IdlNodeVFunc) member, current_type_func_map.get (member.name));
                                if (m != null) {
                                        cl.add_method (m);
                                }
@@ -887,8 +897,13 @@ public class Vala.GIdlParser : CodeVisitor {
 
                current_data_type = iface;
 
+               var current_type_func_map = new HashMap<string,weak IdlNodeFunction> (str_hash, str_equal);
                var current_type_vfunc_map = new HashMap<string,string> (str_hash, str_equal);
+
                foreach (weak IdlNode member in node.members) {
+                       if (member.type == IdlNodeTypeId.FUNCTION) {
+                               current_type_func_map.set (member.name, (IdlNodeFunction) member);
+                       }
                        if (member.type == IdlNodeTypeId.VFUNC) {
                                current_type_vfunc_map.set (member.name, "1");
                        }
@@ -896,9 +911,15 @@ public class Vala.GIdlParser : CodeVisitor {
 
                foreach (weak IdlNode member in node.members) {
                        if (member.type == IdlNodeTypeId.FUNCTION) {
-                               bool is_virtual = current_type_vfunc_map.get (member.name) != null;
-                               
-                               var m = parse_function ((IdlNodeFunction) member, is_virtual, true);
+                               // Ignore if vfunc (handled below) 
+                               if (!current_type_vfunc_map.contains (member.name)) {
+                                       var m = parse_function ((IdlNodeFunction) member, true);
+                                       if (m != null) {
+                                               iface.add_method (m);
+                                       }
+                               }
+                       } else if (member.type == IdlNodeTypeId.VFUNC) {
+                               var m = parse_virtual ((IdlNodeVFunc) member, current_type_func_map.get (member.name), true);
                                if (m != null) {
                                        iface.add_method (m);
                                }
@@ -1116,21 +1137,15 @@ public class Vala.GIdlParser : CodeVisitor {
                return type;
        }
        
-       private Method parse_function (IdlNodeFunction! f, bool is_virtual = false, bool is_interface = false) {
-               weak IdlNode node = (IdlNode) f;
-               
-               if (f.deprecated) {
-                       return null;
-               }
-       
+       private Method create_method (string name, string symbol, IdlNodeParam res, GLib.List<IdlNodeParam> parameters, bool is_constructor, bool is_interface) {
                UnresolvedType return_type = null;
-               if (f.result != null) {
-                       return_type = parse_param (f.result);
+               if (res != null) {
+                       return_type = parse_param (res);
                }
                
                Method m;
-               if (!is_interface && (f.is_constructor || node.name.has_prefix ("new"))) {
-                       m = new CreationMethod (null, node.name, current_source_reference);
+               if (!is_interface && (is_constructor || name.has_prefix ("new"))) {
+                       m = new CreationMethod (null, name, current_source_reference);
                        if (m.name == "new") {
                                m.name = null;
                        } else if (m.name.has_prefix ("new_")) {
@@ -1138,25 +1153,22 @@ public class Vala.GIdlParser : CodeVisitor {
                        }
                } else {
                        if (return_type.type_name == "void") {
-                               m = new Method (node.name, new VoidType (), current_source_reference);
+                               m = new Method (name, new VoidType (), current_source_reference);
                        } else {
-                               m = new Method (node.name, return_type, current_source_reference);
+                               m = new Method (name, return_type, current_source_reference);
                        }
                }
                m.access = SymbolAccessibility.PUBLIC;
 
-               m.is_virtual = is_virtual && !is_interface;
-               m.is_abstract = is_virtual && is_interface;
-               
                // GIDL generator can't provide array parameter information yet
                m.no_array_length = true;
                
                if (current_type_symbol_set != null) {
-                       current_type_symbol_set.add (node.name);
+                       current_type_symbol_set.add (name);
                }
                
                if (current_data_type != null) {
-                       var sig_attributes = get_attributes ("%s::%s".printf (current_data_type.get_cname (), node.name));
+                       var sig_attributes = get_attributes ("%s::%s".printf (current_data_type.get_cname (), name));
                        if (sig_attributes != null) {
                                foreach (string attr in sig_attributes) {
                                        var nv = attr.split ("=", 2);
@@ -1170,7 +1182,7 @@ public class Vala.GIdlParser : CodeVisitor {
                bool add_ellipsis = false;
                bool suppress_throws = false;
 
-               var attributes = get_attributes (f.symbol);
+               var attributes = get_attributes (symbol);
                if (attributes != null) {
                        foreach (string attr in attributes) {
                                var nv = attr.split ("=", 2);
@@ -1204,12 +1216,12 @@ public class Vala.GIdlParser : CodeVisitor {
                        }
                }
                
-               m.set_cname (f.symbol);
+               m.set_cname (symbol);
                
                bool first = true;
                FormalParameter last_param = null;
                UnresolvedType last_param_type = null;
-               foreach (weak IdlNodeParam param in f.parameters) {
+               foreach (weak IdlNodeParam param in parameters) {
                        weak IdlNode param_node = (IdlNode) param;
                        
                        if (first) {
@@ -1241,7 +1253,7 @@ public class Vala.GIdlParser : CodeVisitor {
                        var p = new FormalParameter (param_name, param_type);
                        m.add_parameter (p);
 
-                       var attributes = get_attributes ("%s.%s".printf (f.symbol, param_node.name));
+                       var attributes = get_attributes ("%s.%s".printf (symbol, param_node.name));
                        if (attributes != null) {
                                foreach (string attr in attributes) {
                                        var nv = attr.split ("=", 2);
@@ -1293,6 +1305,38 @@ public class Vala.GIdlParser : CodeVisitor {
                
                return m;
        }
+
+       private Method parse_function (IdlNodeFunction! f, bool is_interface = false) {
+               weak IdlNode node = (IdlNode) f;
+               
+               if (f.deprecated) {
+                       return null;
+               }
+       
+               return create_method (node.name, f.symbol, f.result, f.parameters, f.is_constructor, is_interface);
+       }
+
+       private Method parse_virtual (IdlNodeVFunc! v, IdlNodeFunction? func, bool is_interface = false) {
+               weak IdlNode node = (IdlNode) v;
+               string symbol = "%s%s".printf (current_data_type.get_lower_case_cprefix(), node.name);
+
+               if (func != null) {
+                       symbol = func.symbol;
+               }
+
+               Method m = create_method (node.name, symbol, v.result, func != null ? func.parameters : v.parameters, false, is_interface);
+               if (m != null) {
+                       m.instance = true;
+                       m.is_virtual = !is_interface;
+                       m.is_abstract = is_interface;
+
+                       if (func == null) {
+                               m.attributes.append (new Attribute ("NoWrapper", null));
+                       }
+               }
+
+               return m;
+       }
        
        private string! fix_prop_name (string name) {
                var str = new String ();