[vala/switch-to-gir] girparser: Postprocess aliases and fix namespace resolver



commit bdb07d4673d305f7d6a54852f79ea3bcfc35a446
Author: Luca Bruno <lethalman88 gmail com>
Date:   Tue Aug 24 12:39:24 2010 +0200

    girparser: Postprocess aliases and fix namespace resolver

 vala/valagirparser.vala |  128 +++++++++++++++++++++++++++++-----------------
 1 files changed, 81 insertions(+), 47 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index fe51bc1..635e655 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -26,12 +26,20 @@ using GLib;
  * Code visitor parsing all Vala source files.
  */
 public class Vala.GirParser : CodeVisitor {
+	class Alias {
+		public SourceReference source_reference;
+		public string name;
+		public DataType base_type;
+		public Namespace parent_namespace;
+	}
+
 	MarkupReader reader;
 
 	CodeContext context;
 	Namespace glib_ns;
 
 	SourceFile current_source_file;
+	Namespace current_namespace;
 	SourceLocation begin;
 	SourceLocation end;
 	MarkupTokenType current_token;
@@ -45,6 +53,8 @@ public class Vala.GirParser : CodeVisitor {
 	HashMap<string,string> gir_namespaces = new HashMap<string,string> (str_hash, str_equal);
 	ArrayList<UnresolvedType> unresolved_namespaced_types = new ArrayList<UnresolvedType> ();
 
+	ArrayList<Alias> aliases = new ArrayList<Alias> ();
+
 	/**
 	 * Parses all .gir source files in the specified code
 	 * context and builds a code tree.
@@ -55,10 +65,27 @@ public class Vala.GirParser : CodeVisitor {
 		this.context = context;
 		glib_ns = context.root.scope.lookup ("GLib") as Namespace;
 		context.accept (this);
+
 		resolve_gir_namespaces ();
+		postprocess_aliases ();
 	}
 
 	public override void visit_source_file (SourceFile source_file) {
+		foreach (var node in source_file.get_nodes ()) {
+			// collect gir namespaces
+			if (node is Namespace) {
+				var ns = (Namespace) node;
+				if (source_file.gir_namespace != null) {
+					gir_namespaces[source_file.gir_namespace] = ns.name;
+				} else {
+					var a = ns.get_attribute ("CCode");
+					if (a != null && a.has_argument ("gir_namespace")) {
+						gir_namespaces[a.get_string ("gir_namespace")] = ns.name;
+					}
+				}
+			}
+		}
+
 		if (source_file.filename.has_suffix (".gir")) {
 			parse_file (source_file);
 		}
@@ -192,19 +219,24 @@ public class Vala.GirParser : CodeVisitor {
 		if (namespace_name == null) {
 			namespace_name = gir_namespace;
 		}
+		current_source_file.gir_namespace = gir_namespace;
+		current_source_file.gir_version = gir_version;
+		if (!(gir_namespace in gir_namespaces)) {
+			gir_namespaces[gir_namespace] = namespace_name;
+		}
 
 		var ns = context.root.scope.lookup (namespace_name) as Namespace;
 		if (ns == null) {
 			ns = new Namespace (namespace_name, get_current_src ());
-			ns.source_reference.file.gir_namespace = gir_namespace;
-			ns.source_reference.file.gir_version = gir_version;
 			new_namespace = true;
 		} else {
-			if (ns.external_package) {
+		 	if (ns.external_package) {
 				ns.attributes = null;
 				ns.source_reference = get_current_src ();
 			}
 		}
+		var old_namespace = current_namespace;
+		current_namespace = ns;
 
 		if (cprefix != null) {
 			ns.add_cprefix (cprefix);
@@ -223,7 +255,8 @@ public class Vala.GirParser : CodeVisitor {
 
 			Symbol sym = null;
 			if (reader.name == "alias") {
-				sym = parse_alias ();
+				var alias = parse_alias ();
+				aliases.add (alias);
 			} else if (reader.name == "enumeration") {
 				if (reader.get_attribute ("glib:error-quark") != null) {
 					sym = parse_error_domain ();
@@ -286,18 +319,21 @@ public class Vala.GirParser : CodeVisitor {
 			ns = null;
 		}
 
+		current_namespace = old_namespace;
 		return ns;
 	}
 
-	Struct parse_alias () {
+	Alias parse_alias () {
+		// alias has no type information
 		start_element ("alias");
-		var st = new Struct (reader.get_attribute ("name"), get_current_src ());
-		st.access = SymbolAccessibility.PUBLIC;
-		st.base_type = parse_type_from_name (reader.get_attribute ("target"));
-		st.external = true;
+		var alias = new Alias ();
+		alias.source_reference = get_current_src ();
+		alias.name = reader.get_attribute ("name");
+		alias.base_type = parse_type_from_name (reader.get_attribute ("target"));
+		alias.parent_namespace = current_namespace;
 		next ();
 		end_element ("alias");
-		return st;
+		return alias;
 	}
 
 	private void calculate_common_prefix (ref string common_prefix, string cname) {
@@ -692,6 +728,37 @@ public class Vala.GirParser : CodeVisitor {
 		}
 	}
 
+	void postprocess_aliases () {
+		foreach (var alias in aliases) {
+			Symbol sym = alias.parent_namespace;
+			if (alias.base_type is UnresolvedType) {
+				var type = (UnresolvedType) alias.base_type;
+				// simulate some basic two-steps of the symbol resolver
+				if (type.unresolved_symbol.inner != null) {
+					var name = type.unresolved_symbol.inner.name;
+					if (name in gir_namespaces) {
+						name = gir_namespaces[name];
+					}
+					sym = context.root.scope.lookup (name);
+				}
+				sym = sym.scope.lookup (type.unresolved_symbol.name);
+			}
+			if (sym == null || sym is Struct) {
+				var st = new Struct (alias.name, alias.source_reference);
+				st.access = SymbolAccessibility.PUBLIC;
+				st.base_type = alias.base_type;
+				st.external = true;
+				alias.parent_namespace.add_struct (st);
+			} else if (sym is Class) {
+				var cl = new Class (alias.name, alias.source_reference);
+				cl.access = SymbolAccessibility.PUBLIC;
+				cl.add_base_type (alias.base_type);
+				cl.external = true;
+				alias.parent_namespace.add_class (cl);
+			}
+		}
+	}
+
 	Class parse_class () {
 		start_element ("class");
 		var cl = new Class (reader.get_attribute ("name"), get_current_src ());
@@ -1379,45 +1446,12 @@ public class Vala.GirParser : CodeVisitor {
 		}
 	}
 
-	string? get_gir_namespace (Namespace ns) {
-		var gir_namespace = ns.source_reference.file.gir_namespace;
-		if (gir_namespace != null) {
-			return gir_namespace;
-		}
-
-		var a = ns.get_attribute ("CCode");
-		if (a.has_argument ("gir_namespace")) {
-			return a.get_string ("gir_namespace");
-		}
-		return null;
-	}
-
-	void collect_gir_namespaces (Namespace ns) {
-		foreach (Namespace sub_ns in ns.get_namespaces ()) {
-			collect_gir_namespaces (sub_ns);
-		}
-		if (ns.name == null) {
-			return;
-		}
-
-		var gir_namespace = get_gir_namespace (ns);
-		if (gir_namespace != null && !(gir_namespace in gir_namespaces)) {
-			gir_namespaces[gir_namespace] = ns.name;
-		}
-	}
-
 	void resolve_gir_namespaces () {
-		collect_gir_namespaces (context.root);
-
 		foreach (var type in unresolved_namespaced_types) {
-			if (type.unresolved_symbol != null) {
-				var symbol = type.unresolved_symbol;
-				while (symbol.inner != null) {
-					if (symbol.name in gir_namespaces) {
-						// map the gir namespace to the vala namespace
-						symbol.name = gir_namespaces[symbol.name];
-					}
-				}
+			var name = type.unresolved_symbol.inner.name;
+			if (name in gir_namespaces) {
+				// map the gir namespace to the vala namespace
+				type.unresolved_symbol.inner.name = gir_namespaces[name];
 			}
 		}
 	}



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