[vala/switch-to-gir] girparser: Support reparenting referenceable symbols



commit 50f4ebf42d4bbecd5f9bf505b135c1d7cf3e766a
Author: Luca Bruno <lethalman88 gmail com>
Date:   Sat Aug 28 15:15:48 2010 +0200

    girparser: Support reparenting referenceable symbols

 vala/valagirparser.vala |  125 ++++++++++++++++++++++++++---------------------
 1 files changed, 69 insertions(+), 56 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 6075b47..7bfc443 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -482,6 +482,8 @@ public class Vala.GirParser : CodeVisitor {
 	HashMap<string,ArrayList<SymbolInfo>> current_symbols_info;
 
 	HashMap<UnresolvedSymbol,Symbol> 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<UnresolvedSymbol,ArrayList<Symbol>> symbol_reparent_map = new HashMap<UnresolvedSymbol,ArrayList<Symbol>> (unresolved_symbol_hash, unresolved_symbol_equal);
 	HashMap<Namespace,ArrayList<Method>> namespace_methods = new HashMap<Namespace,ArrayList<Method>> ();
@@ -522,7 +524,7 @@ public class Vala.GirParser : CodeVisitor {
 				}
 				if (gir_namespace != null && gir_namespace != ns.name) {
 					var map_from = new UnresolvedSymbol (null, gir_namespace);
-					add_symbol_mapping (map_from, ns);
+					set_symbol_mapping (map_from, ns);
 				}
 			}
 		}
@@ -636,6 +638,20 @@ 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;
+	}
+
 	bool parse_type_arguments_from_string (DataType parent_type, string type_arguments, SourceReference? source_reference = null) {
 		int type_arguments_length = (int) type_arguments.length;
 		GLib.StringBuilder current = new GLib.StringBuilder.sized (type_arguments_length);
@@ -758,9 +774,12 @@ public class Vala.GirParser : CodeVisitor {
 		return type;
 	}
 
-	void add_symbol_mapping (UnresolvedSymbol map_from, Symbol map_to) {
-		if (!(map_from in symbols_map)) {
-			symbols_map[map_from] = map_to;
+	void set_symbol_mapping (Symbol map_from, Symbol map_to) {
+		// last mapping is the most up-to-date
+		if (map_from is UnresolvedSymbol) {
+			symbols_map[(UnresolvedSymbol) map_from] = map_to;
+		} else {
+			concrete_symbols_map[map_from] = map_to;
 		}
 	}
 
@@ -857,14 +876,7 @@ public class Vala.GirParser : CodeVisitor {
 		return name;
 	}
 
-	bool element_can_add () {
-		if (metadata.has_argument (ArgumentType.PARENT) || metadata.get_bool (ArgumentType.HIDDEN)) {
-			return false;
-		}
-		return true;
-	}
-
-	void element_process_symbol (Symbol symbol) {
+	void postprocess_symbol (Symbol symbol, Metadata metadata) {
 		// deprecation
 		symbol.replacement = metadata.get_string (ArgumentType.REPLACEMENT);
 		symbol.deprecated_since = element_get_string ("deprecated-version", ArgumentType.DEPRECATED_SINCE);
@@ -879,6 +891,11 @@ public class Vala.GirParser : CodeVisitor {
 				symbol_reparent_map[target_symbol] = reparent_list;
 			}
 			reparent_list.add (symbol);
+
+			// if referenceable, map unresolved references to point to the new place
+			if (symbol is Namespace || symbol is TypeSymbol) {
+				set_symbol_mapping (symbol, new UnresolvedSymbol (target_symbol, symbol.name));
+			}
 		}
 	}
 
@@ -962,19 +979,25 @@ public class Vala.GirParser : CodeVisitor {
 		return false;
 	}
 
-	void merge_and_add (Symbol container) {
-		var add_list = new ArrayList<Symbol> ();
+	void merge_add_process (Symbol container) {
+		var add_list = new ArrayList<SymbolInfo> ();
 		foreach (var name in current_symbols_info.get_keys ()) {
 			var colliding = current_symbols_info[name];
 			foreach (var info in colliding) {
 				if (!merge (container, info, colliding)) {
-					add_list.add (info.symbol);
+					add_list.add (info);
 				}
 			}
 		}
 
-		foreach (var sym in add_list) {
-			add_symbol_to_container (container, sym);
+		foreach (var info in add_list) {
+			if (info.metadata.get_bool (ArgumentType.HIDDEN)) {
+				continue;
+			}
+			if (!(info.metadata.has_argument (ArgumentType.PARENT))) {
+				add_symbol_to_container (container, info.symbol);
+			}
+			postprocess_symbol (info.symbol, info.metadata);
 		}
 	}
 
@@ -1083,7 +1106,7 @@ public class Vala.GirParser : CodeVisitor {
 			}
 		}
 		if (gir_namespace != ns.name) {
-			add_symbol_mapping (new UnresolvedSymbol (null, gir_namespace), ns);
+			set_symbol_mapping (new UnresolvedSymbol (null, gir_namespace), ns);
 		}
 
 		var old_namespace = current_namespace;
@@ -1111,6 +1134,8 @@ public class Vala.GirParser : CodeVisitor {
 			current_namespace_methods = new ArrayList<Method> ();
 			namespace_methods[ns] = current_namespace_methods;
 		}
+		var old_symbols_info = current_symbols_info;
+		current_symbols_info = new HashMap<string,ArrayList<SymbolInfo>> (str_hash, str_equal);
 		while (current_token == MarkupTokenType.START_ELEMENT) {
 			if (!push_metadata ()) {
 				skip_element ();
@@ -1123,67 +1148,52 @@ public class Vala.GirParser : CodeVisitor {
 				aliases.add (alias);
 			} else if (reader.name == "enumeration") {
 				if (reader.get_attribute ("glib:error-quark") != null) {
-					sym = parse_error_domain ();
+					add_symbol_info (parse_error_domain ());
 				} else {
-					sym = parse_enumeration ();
+					add_symbol_info (parse_enumeration ());
 				}
 			} else if (reader.name == "bitfield") {
-				sym = parse_bitfield ();
+				add_symbol_info (parse_bitfield ());
 			} else if (reader.name == "function") {
 				current_namespace_methods.add (parse_method ("function"));
 			} else if (reader.name == "callback") {
-				sym = parse_callback ();
+				add_symbol_info (parse_callback ());
 			} else if (reader.name == "record") {
 				if (reader.get_attribute ("glib:get-type") != null) {
-					sym = parse_boxed ();
+					add_symbol_info (parse_boxed ());
 				} else {
-					sym = parse_record ();
+					var record = parse_record ();
+					if (record != null) {
+						add_symbol_info (record);
+					}
 				}
 			} else if (reader.name == "class") {
-				sym = parse_class ();
+				add_symbol_info (parse_class ());
 			} else if (reader.name == "interface") {
-				sym = parse_interface ();
+				add_symbol_info (parse_interface ());
 			} else if (reader.name == "glib:boxed") {
-				sym = parse_boxed ();
+				add_symbol_info (parse_boxed ());
 			} else if (reader.name == "union") {
-				sym = parse_union ();
+				add_symbol_info (parse_union ());
 			} else if (reader.name == "constant") {
-				sym = parse_constant ();
+				add_symbol_info (parse_constant ());
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `namespace'".printf (reader.name));
 				skip_element ();
 			}
 
-			if (sym != null && element_can_add ()) {
-				if (sym is Class) {
-					ns.add_class ((Class) sym);
-				} else if (sym is Interface) {
-					ns.add_interface ((Interface) sym);
-				} else if (sym is Struct) {
-					ns.add_struct ((Struct) sym);
-				} else if (sym is Enum) {
-					ns.add_enum ((Enum) sym);
-				} else if (sym is ErrorDomain) {
-					ns.add_error_domain ((ErrorDomain) sym);
-				} else if (sym is Delegate) {
-					ns.add_delegate ((Delegate) sym);
-				} else if (sym is Method) {
-					ns.add_method ((Method) sym);
-				} else if (sym is Constant) {
-					ns.add_constant ((Constant) sym);
-				}
-			}
-
 			pop_metadata ();
 		}
 		end_element ("namespace");
 
+		merge_add_process (ns);
+		current_symbols_info = old_symbols_info;
+		current_namespace = old_namespace;
+
 		if (!new_namespace) {
 			ns = null;
 		}
-
-		current_namespace = old_namespace;
 		return ns;
 	}
 
@@ -1656,7 +1666,7 @@ public class Vala.GirParser : CodeVisitor {
 			pop_metadata ();
 		}
 
-		merge_and_add (cl);
+		merge_add_process (cl);
 		current_symbols_info = old_symbols_info;
 
 		handle_async_methods (cl);
@@ -1711,7 +1721,7 @@ public class Vala.GirParser : CodeVisitor {
 			pop_metadata ();
 		}
 
-		merge_and_add (iface);
+		merge_add_process (iface);
 		current_symbols_info = old_symbols_info;
 
 		handle_async_methods (iface);
@@ -2078,7 +2088,6 @@ public class Vala.GirParser : CodeVisitor {
 			s.add_error_type (new ErrorType (null, null));
 		}
 
-		element_process_symbol (s);
 		end_element (element_name);
 		return s;
 	}
@@ -2210,7 +2219,6 @@ public class Vala.GirParser : CodeVisitor {
 		var c = new Constant (name, type, null, get_current_src ());
 		c.access = SymbolAccessibility.PUBLIC;
 		c.external = true;
-		element_process_symbol (c);
 		end_element ("constant");
 		return c;
 	}
@@ -2218,7 +2226,12 @@ public class Vala.GirParser : CodeVisitor {
 	/* Post-parsing */
 
 	void resolve_gir_symbols () {
-		// gir has simple namespaces, we won't get deeper than 2 levels here
+		// we are remapping unresolved symbols, so create them from concrete symbols
+		foreach (var map_from in concrete_symbols_map.get_keys ()) {
+			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 = symbols_map[map_from];



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]