summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--gobject-introspection/gidl.vapi13
-rw-r--r--vapigen/valagidlparser.vala100
3 files changed, 91 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 2d6a23819..30f5924ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
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,
vapi/gdk-x11-2.0.vapi: add gdk-x11-2.0 bindings,
patch by Maciej Piechotka, fixes bug 510336
diff --git a/gobject-introspection/gidl.vapi b/gobject-introspection/gidl.vapi
index 28498a0d8..300a4a5c2 100644
--- a/gobject-introspection/gidl.vapi
+++ b/gobject-introspection/gidl.vapi
@@ -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 {
diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala
index b3ec9dfa9..3e6a4091e 100644
--- a/vapigen/valagidlparser.vala
+++ b/vapigen/valagidlparser.vala
@@ -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 ();