[vala/switch-to-gir: 15/34] girparser: Postprocess gtype callbacks and fix them for gir 1.0
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/switch-to-gir: 15/34] girparser: Postprocess gtype callbacks and fix them for gir 1.0
- Date: Sun, 29 Aug 2010 22:24:06 +0000 (UTC)
commit 7d49dd6a6aa0413dbe22f64000ab39aadda1ceae
Author: Luca Bruno <lucabru src gnome org>
Date: Sun Aug 29 13:31:58 2010 +0200
girparser: Postprocess gtype callbacks and fix them for gir 1.0
vala/valagirparser.vala | 135 +++++++++++++++++++++++++++++++++--------------
1 files changed, 96 insertions(+), 39 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 66da5ca..c5f263c 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -463,12 +463,19 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ class CallbackScope {
+ public Namespace parent_namespace;
+ public UnresolvedSymbol gtype_struct_for;
+ }
+
MarkupReader reader;
CodeContext context;
Namespace glib_ns;
SourceFile current_source_file;
+ Namespace current_namespace;
+ string current_gtype_struct_for;
SourceLocation begin;
SourceLocation end;
MarkupTokenType current_token;
@@ -480,7 +487,7 @@ public class Vala.GirParser : CodeVisitor {
ArrayList<UnresolvedSymbol> unresolved_gir_symbols = new ArrayList<UnresolvedSymbol> ();
- HashMap<string,ArrayList<Method>> gtype_callbacks = new HashMap<string,ArrayList<Method>> (str_hash, str_equal);
+ HashMap<CallbackScope,ArrayList<Delegate>> gtype_callbacks = new HashMap<CallbackScope,ArrayList<Delegate>> (callback_scope_hash, callback_scope_equal);
/**
* Parses all .gir source files in the specified code
@@ -494,6 +501,8 @@ public class Vala.GirParser : CodeVisitor {
context.accept (this);
resolve_gir_symbols ();
+
+ postprocess_gtype_callbacks ();
}
public override void visit_source_file (SourceFile source_file) {
@@ -625,6 +634,22 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ void assume_parameter_names (Signal sig, Symbol sym) {
+ Iterator<FormalParameter> iter;
+ if (sym is Method) {
+ iter = ((Method) sym).get_parameters ().iterator ();
+ } else {
+ iter = ((Delegate) sym).get_parameters ().iterator ();
+ }
+ foreach (var param in sig.get_parameters ()) {
+ if (!iter.next ()) {
+ // unreachable for valid GIR
+ break;
+ }
+ param.name = iter.get ().name;
+ }
+ }
+
void parse_repository () {
start_element ("repository");
next ();
@@ -728,6 +753,9 @@ public class Vala.GirParser : CodeVisitor {
set_symbol_mapping (new UnresolvedSymbol (null, gir_namespace), ns);
}
+ var old_namespace = current_namespace;
+ current_namespace = ns;
+
if (cprefix != null) {
ns.add_cprefix (cprefix);
ns.set_lower_case_cprefix (Symbol.camel_case_to_lower_case (cprefix) + "_");
@@ -802,7 +830,7 @@ public class Vala.GirParser : CodeVisitor {
}
end_element ("namespace");
- postprocess_gtype_callbacks (ns);
+ current_namespace = old_namespace;
if (!new_namespace) {
ns = null;
@@ -1136,7 +1164,7 @@ public class Vala.GirParser : CodeVisitor {
var st = new Struct (reader.get_attribute ("name"), get_current_src ());
st.external = true;
- string glib_is_gtype_struct_for = reader.get_attribute ("glib:is-gtype-struct-for");
+ current_gtype_struct_for = reader.get_attribute ("glib:is-gtype-struct-for");
st.access = SymbolAccessibility.PUBLIC;
next ();
@@ -1148,17 +1176,6 @@ public class Vala.GirParser : CodeVisitor {
if (reader.name == "field") {
st.add_field (parse_field ());
- } else if (reader.name == "callback") {
- if (glib_is_gtype_struct_for != null) {
- ArrayList<Method> callbacks = gtype_callbacks.get (glib_is_gtype_struct_for);
- if (callbacks == null) {
- callbacks = new ArrayList<Method> ();
- gtype_callbacks.set (glib_is_gtype_struct_for, callbacks);
- }
- callbacks.add (parse_method ("callback"));
- } else {
- parse_callback ();
- }
} else if (reader.name == "constructor") {
parse_constructor ();
} else if (reader.name == "method") {
@@ -1181,31 +1198,6 @@ public class Vala.GirParser : CodeVisitor {
return st;
}
- void postprocess_gtype_callbacks (Namespace ns) {
- foreach (string gtype_name in gtype_callbacks.get_keys ()) {
- var gtype = ns.scope.lookup (gtype_name) as ObjectTypeSymbol;
- ArrayList<Method> callbacks = gtype_callbacks.get (gtype_name);
- foreach (Method m in callbacks) {
- var symbol = gtype.scope.lookup (m.name);
- if (symbol == null) {
- continue;
- } else if (symbol is Method) {
- var meth = (Method) symbol;
- if (gtype is Class) {
- meth.is_virtual = true;
- } else if (gtype is Interface) {
- meth.is_abstract = true;
- }
- } else if (symbol is Signal) {
- var sig = (Signal) symbol;
- sig.is_virtual = true;
- } else {
- Report.error (get_current_src (), "unknown member type `%s' in `%s'".printf (m.name, gtype.name));
- }
- }
- }
- }
-
Class parse_class () {
start_element ("class");
var cl = new Class (reader.get_attribute ("name"), get_current_src ());
@@ -1475,6 +1467,18 @@ public class Vala.GirParser : CodeVisitor {
string allow_none = reader.get_attribute ("allow-none");
next ();
var type = parse_type ();
+ if (type is DelegateType && current_gtype_struct_for != null) {
+ // virtual
+ var callback_scope = new CallbackScope ();
+ callback_scope.parent_namespace = current_namespace;
+ callback_scope.gtype_struct_for = parse_symbol_from_string (current_gtype_struct_for);
+ ArrayList<Delegate> callbacks = gtype_callbacks.get (callback_scope);
+ if (callbacks == null) {
+ callbacks = new ArrayList<Delegate> ();
+ gtype_callbacks.set (callback_scope, callbacks);
+ }
+ callbacks.add (((DelegateType) type).delegate_symbol);
+ }
var field = new Field (name, type, null, get_current_src ());
field.access = SymbolAccessibility.PUBLIC;
if (allow_none == "1") {
@@ -1894,6 +1898,59 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ Symbol? resolve_symbol (Scope parent_scope, UnresolvedSymbol unresolved_symbol) {
+ // simple symbol resolver, enough for gir
+ if (unresolved_symbol.inner == null) {
+ var scope = parent_scope;
+ while (scope != null) {
+ var sym = scope.lookup (unresolved_symbol.name);
+ if (sym != null) {
+ return sym;
+ }
+ scope = scope.parent_scope;
+ }
+ } else {
+ var inner = resolve_symbol (parent_scope, unresolved_symbol.inner);
+ if (inner != null) {
+ return inner.scope.lookup (unresolved_symbol.name);
+ }
+ }
+ return null;
+ }
+
+ void postprocess_gtype_callbacks () {
+ foreach (CallbackScope callback_scope in gtype_callbacks.get_keys ()) {
+ var gtype = resolve_symbol (callback_scope.parent_namespace.scope, callback_scope.gtype_struct_for) as ObjectTypeSymbol;
+ if (gtype == null) {
+ Report.error (null, "unknown symbol `%s'".printf (callback_scope.gtype_struct_for.to_string ()));
+ continue;
+ }
+ ArrayList<Delegate> callbacks = gtype_callbacks.get (callback_scope);
+ foreach (Delegate d in callbacks) {
+ var symbol = gtype.scope.lookup (d.name);
+ if (symbol == null) {
+ continue;
+ } else if (symbol is Method) {
+ var meth = (Method) symbol;
+ if (gtype is Class) {
+ meth.is_virtual = true;
+ } else if (gtype is Interface) {
+ meth.is_abstract = true;
+ }
+ } else if (symbol is Signal) {
+ var sig = (Signal) symbol;
+ sig.is_virtual = true;
+ assume_parameter_names (sig, d);
+ } else if (symbol is Property) {
+ var prop = (Property) symbol;
+ prop.is_virtual = true;
+ } else {
+ Report.error (get_current_src (), "unknown member type `%s' in `%s'".printf (d.name, gtype.name));
+ }
+ }
+ }
+ }
+
/* Hash and equal functions */
static uint unresolved_symbol_hash (void *ptr) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]