[vala/switch-to-gir: 14/34] girparser: Postprocess symbols remapping
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/switch-to-gir: 14/34] girparser: Postprocess symbols remapping
- Date: Sun, 29 Aug 2010 16:20:54 +0000 (UTC)
commit 043dba3c13ced44c57b85ddc105a586a44af7ff7
Author: Luca Bruno <lucabru src gnome org>
Date: Sun Aug 29 13:22:37 2010 +0200
girparser: Postprocess symbols remapping
vala/valagirparser.vala | 158 ++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 144 insertions(+), 14 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index cea46da..66da5ca 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -475,6 +475,11 @@ public class Vala.GirParser : CodeVisitor {
string[] cheader_filenames;
+ HashMap<UnresolvedSymbol,Symbol> unresolved_symbols_map = new HashMap<UnresolvedSymbol,Symbol> (unresolved_symbol_hash, unresolved_symbol_equal);
+ HashMap<Symbol,Symbol> concrete_symbols_map = new HashMap<Symbol,Symbol> ();
+
+ ArrayList<UnresolvedSymbol> unresolved_gir_symbols = new ArrayList<UnresolvedSymbol> ();
+
HashMap<string,ArrayList<Method>> gtype_callbacks = new HashMap<string,ArrayList<Method>> (str_hash, str_equal);
/**
@@ -487,9 +492,30 @@ public class Vala.GirParser : CodeVisitor {
this.context = context;
glib_ns = context.root.scope.lookup ("GLib") as Namespace;
context.accept (this);
+
+ resolve_gir_symbols ();
}
public override void visit_source_file (SourceFile source_file) {
+ // collect gir namespaces
+ foreach (var node in source_file.get_nodes ()) {
+ if (node is Namespace) {
+ var ns = (Namespace) node;
+ var gir_namespace = source_file.gir_namespace;
+ if (gir_namespace == null) {
+ var a = ns.get_attribute ("CCode");
+ if (a != null && a.has_argument ("gir_namespace")) {
+ gir_namespace = a.get_string ("gir_namespace");
+ }
+ }
+ if (gir_namespace != null && gir_namespace != ns.name) {
+ var map_from = new UnresolvedSymbol (null, gir_namespace);
+ set_symbol_mapping (map_from, ns);
+ break;
+ }
+ }
+ }
+
if (source_file.filename.has_suffix (".gir")) {
parse_file (source_file);
}
@@ -576,6 +602,29 @@ public class Vala.GirParser : CodeVisitor {
return sym;
}
+ UnresolvedSymbol get_unresolved_symbol (Symbol symbol) {
+ if (symbol is UnresolvedSymbol) {
+ return (UnresolvedSymbol) symbol;
+ }
+ var sym = new UnresolvedSymbol (null, symbol.name);
+ var result = sym;
+ var cur = symbol.parent_node as Symbol;
+ while (cur != null && cur.name != null) {
+ sym = new UnresolvedSymbol (sym, cur.name);
+ cur = cur.parent_node as Symbol;
+ }
+ return result;
+ }
+
+ void set_symbol_mapping (Symbol map_from, Symbol map_to) {
+ // last mapping is the most up-to-date
+ if (map_from is UnresolvedSymbol) {
+ unresolved_symbols_map[(UnresolvedSymbol) map_from] = map_to;
+ } else {
+ concrete_symbols_map[map_from] = map_to;
+ }
+ }
+
void parse_repository () {
start_element ("repository");
next ();
@@ -655,7 +704,16 @@ public class Vala.GirParser : CodeVisitor {
start_element ("namespace");
bool new_namespace = false;
- string namespace_name = transform_namespace_name (reader.get_attribute ("name"));
+ string? cprefix = reader.get_attribute ("c:prefix");
+ string namespace_name = cprefix;
+ string gir_namespace = reader.get_attribute ("name");
+ string gir_version = reader.get_attribute ("version");
+ if (namespace_name == null) {
+ namespace_name = gir_namespace;
+ }
+ current_source_file.gir_namespace = gir_namespace;
+ current_source_file.gir_version = gir_version;
+
var ns = context.root.scope.lookup (namespace_name) as Namespace;
if (ns == null) {
ns = new Namespace (namespace_name, get_current_src ());
@@ -666,8 +724,10 @@ public class Vala.GirParser : CodeVisitor {
ns.source_reference = get_current_src ();
}
}
+ if (gir_namespace != ns.name) {
+ set_symbol_mapping (new UnresolvedSymbol (null, gir_namespace), ns);
+ }
- string? cprefix = reader.get_attribute ("c:prefix");
if (cprefix != null) {
ns.add_cprefix (cprefix);
ns.set_lower_case_cprefix (Symbol.camel_case_to_lower_case (cprefix) + "_");
@@ -1037,6 +1097,7 @@ public class Vala.GirParser : CodeVisitor {
} else if (type_name == "GObject.Strv") {
type = new ArrayType (new UnresolvedType.from_symbol (new UnresolvedSymbol (null, "string")), 1, get_current_src ());
} else {
+ bool known_type = true;
if (type_name == "utf8") {
type_name = "string";
} else if (type_name == "boolean") {
@@ -1057,25 +1118,19 @@ public class Vala.GirParser : CodeVisitor {
type_name = "GLib.Datalist";
} else if (type_name == "Atk.ImplementorIface") {
type_name = "Atk.Implementor";
+ } else {
+ known_type = false;
}
var sym = parse_symbol_from_string (type_name, get_current_src ());
type = new UnresolvedType.from_symbol (sym, get_current_src ());
+ if (!known_type) {
+ unresolved_gir_symbols.add (sym);
+ }
}
return type;
}
- string transform_namespace_name (string gir_module_name) {
- if (gir_module_name == "GObject") {
- return "GLib";
- } else if (gir_module_name == "Gio") {
- return "GLib";
- } else if (gir_module_name == "GModule") {
- return "GLib";
- }
- return gir_module_name;
- }
-
Struct parse_record () {
start_element ("record");
var st = new Struct (reader.get_attribute ("name"), get_current_src ());
@@ -1801,5 +1856,80 @@ public class Vala.GirParser : CodeVisitor {
end_element ("constant");
return c;
}
-}
+ /* Post-parsing */
+
+ void resolve_gir_symbols () {
+ // we are remapping unresolved symbols, so create them from concrete symbols
+ foreach (var map_from in concrete_symbols_map.get_keys ()) {
+ unresolved_symbols_map[get_unresolved_symbol(map_from)] = concrete_symbols_map[map_from];
+ }
+
+ // gir has simple namespaces, we won't get deeper than 2 levels here, except reparenting
+ foreach (var map_from in unresolved_gir_symbols) {
+ while (map_from != null) {
+ var map_to = unresolved_symbols_map[map_from];
+ if (map_to != null) {
+ // remap the original symbol to match the target
+ map_from.inner = null;
+ map_from.name = map_to.name;
+ if (map_to is UnresolvedSymbol) {
+ var umap_to = (UnresolvedSymbol) map_to;
+ while (umap_to.inner != null) {
+ umap_to = umap_to.inner;
+ map_from.inner = new UnresolvedSymbol (null, umap_to.name);
+ map_from = map_from.inner;
+ }
+ } else {
+ while (map_to.parent_symbol != null && map_to.parent_symbol != context.root) {
+ map_to = map_to.parent_symbol;
+ map_from.inner = new UnresolvedSymbol (null, map_to.name);
+ map_from = map_from.inner;
+ }
+ }
+ break;
+ }
+ map_from = map_from.inner;
+ }
+ }
+ }
+
+ /* Hash and equal functions */
+
+ static uint unresolved_symbol_hash (void *ptr) {
+ var sym = (UnresolvedSymbol) ptr;
+ var builder = new StringBuilder ();
+ while (sym != null) {
+ builder.append (sym.name);
+ sym = sym.inner;
+ }
+ return builder.str.hash ();
+ }
+
+ static bool unresolved_symbol_equal (void *ptr1, void *ptr2) {
+ var sym1 = (UnresolvedSymbol) ptr1;
+ var sym2 = (UnresolvedSymbol) ptr2;
+ while (sym1 != sym2) {
+ if (sym1 == null || sym2 == null) {
+ return false;
+ }
+ if (sym1.name != sym2.name) {
+ return false;
+ }
+ sym1 = sym1.inner;
+ sym2 = sym2.inner;
+ }
+ return true;
+ }
+
+ static uint callback_scope_hash (void *ptr) {
+ var cs = (CallbackScope) ptr;
+ return unresolved_symbol_hash (cs.gtype_struct_for);
+ }
+
+ static bool callback_scope_equal (void *ptr1, void *ptr2) {
+ var cs1 = (CallbackScope) ptr1;
+ var cs2 = (CallbackScope) ptr2;
+ return cs1.parent_namespace == cs2.parent_namespace && unresolved_symbol_equal (cs1.gtype_struct_for, cs2.gtype_struct_for);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]