Index: compiler/valacompiler.vala
===================================================================
--- compiler/valacompiler.vala	(révision 2448)
+++ compiler/valacompiler.vala	(copie de travail)
@@ -305,19 +305,20 @@
 			}
 
 			interface_writer.write_file (context, vapi_filename);
-
-
+			
 			var gir_writer = new GIRWriter ();
-			string gir_filename = "%s.gir".printf (library);
+			string[] split_library = library.split("-");
+			string typelib_namespace = split_library[0];
+			string typelib_version = split_library[1];
 
 			// put .gir file in current directory unless -d has been explicitly specified
-			if (directory != null && !Path.is_absolute (gir_filename)) {
-				gir_filename = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, gir_filename);
+			string typelib_directory = ".";
+			if (directory != null) {
+				typelib_directory = context.directory;
 			}
 
-			gir_writer.write_file (context, gir_filename);
+			gir_writer.write_file (context, typelib_directory, typelib_namespace, typelib_version);
 
-
 			library = null;
 		}
 
Index: gobject/valagirwriter.vala
===================================================================
--- gobject/valagirwriter.vala	(révision 2448)
+++ gobject/valagirwriter.vala	(copie de travail)
@@ -28,12 +28,17 @@
  */
 public class Vala.GIRWriter : CodeVisitor {
 	private CodeContext context;
+	private string directory;
+	private string typelib_namespace;
+	private string typelib_version;
 	
 	FileStream stream;
+	private string full_namespace_name;
 	
 	int indent;
 
 	private TypeSymbol gobject_type;
+	private TypeSymbol string_type;
 
 	/**
 	 * Writes the public interface of the specified code context into the
@@ -42,23 +47,27 @@
 	 * @param context  a code context
 	 * @param filename a relative or absolute filename
 	 */
-	public void write_file (CodeContext context, string filename) {
+	public void write_file (CodeContext context, string directory, string typelib_namespace, string typelib_version) {
 		this.context = context;
+		this.directory = directory;
+		this.typelib_namespace = typelib_namespace;
+		this.typelib_version = typelib_version;
 
 		var root_symbol = context.root;
 		var glib_ns = root_symbol.scope.lookup ("GLib");
 		gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object");
+		string_type = (TypeSymbol) root_symbol.scope.lookup ("string");
 
+		string filename = "%s%c%s-%s.gir".printf (
+			directory, Path.DIR_SEPARATOR, typelib_namespace, typelib_version);
 		stream = FileStream.open (filename, "w");
-
-		stream.printf ("<?xml version=\"1.0\"?>\n");
-
-		stream.printf ("<repository version=\"1.0\">\n");
-
+		
+		write_header(context);
+		
 		context.accept (this);
-
-		stream.printf ("</repository>\n");
-
+		
+		write_footer(context);
+		
 		stream = null;
 	}
 
@@ -72,23 +81,53 @@
 			ns.accept_children (this);
 			return;
 		}
-
+		
+		full_namespace_name = ns.name;
 		if (ns.parent_symbol.name != null) {
-			// nested namespace
-			// not supported in GIR at the moment
-			return;
+			Namespace parent = (Namespace) ns.parent_symbol;
+			while (parent.name != null) {
+				full_namespace_name = parent.name + full_namespace_name;
+				parent = (Namespace) parent.parent_symbol;
+			}
 		}
+		
+		ns.accept_children (this);
+	}
+	
+	private void write_header(CodeContext context) {
+		stream.printf ("<?xml version=\"1.0\"?>\n");
 
+		stream.printf ("<repository version=\"1.0\"");
+		stream.printf (" xmlns=\"http://www.gtk.org/introspection/core/1.0\"");
+		stream.printf (" xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"");
+		stream.printf (" xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
+		stream.printf (">\n");
+		indent++;
+		
+		//TODO Generate includes correctly based on CodeContext
 		write_indent ();
-		stream.printf ("<namespace name=\"%s\" version=\"1.0\">\n", ns.name);
+		stream.printf ("<include name=\"GLib\" version=\"2.0\"/>\n");
+		write_indent ();
+		stream.printf ("<include name=\"GObject\" version=\"2.0\"/>\n");
+		
+		write_indent ();
+		stream.printf ("<namespace name=\"%s\" version=\"%s\">\n", typelib_namespace, typelib_version);
 		indent++;
-
-		ns.accept_children (this);
-
+	}
+	
+	private void write_footer(CodeContext context) {
 		indent--;
 		write_indent ();
 		stream.printf ("</namespace>\n");
+		
+		indent--;
+		stream.printf ("</repository>\n");
 	}
+	
+	private void check_stream() {
+		if (stream == null) {
+		}
+	}
 
 	public override void visit_class (Class cl) {
 		if (cl.external_package) {
@@ -98,13 +137,16 @@
 		if (!check_accessibility (cl)) {
 			return;
 		}
+		
+		check_stream();
 
 		if (cl.is_subtype_of (gobject_type)) {
 			write_indent ();
-			stream.printf ("<class name=\"%s\"", cl.name);
-			stream.printf (" parent=\"%s\"", cl.base_class.get_full_name ());
+			stream.printf ("<class name=\"%s\"", gi_local_type_name (cl));
+			stream.printf (" parent=\"%s\"", gi_type_name (cl.base_class));
 			stream.printf (" glib:type-name=\"%s\"", cl.get_cname ());
 			stream.printf (" glib:get-type=\"%sget_type\"", cl.get_lower_case_cprefix ());
+			write_node_attributes(cl);
 			stream.printf (">\n");
 			indent++;
 
@@ -120,7 +162,7 @@
 						first = false;
 					}
 					write_indent ();
-					stream.printf ("<interface name=\"%s\"/>\n", object_type.type_symbol.get_full_name ());
+					stream.printf ("<interface name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
 				}
 			}
 			if (!first) {
@@ -136,7 +178,8 @@
 			stream.printf ("</class>\n");
 		} else {
 			write_indent ();
-			stream.printf ("<record name=\"%s\"", cl.name);
+			stream.printf ("<record name=\"%s\"", gi_local_type_name (cl));
+			write_node_attributes(cl);
 			stream.printf (">\n");
 			indent++;
 
@@ -157,8 +200,11 @@
 			return;
 		}
 
+		check_stream();
+		
 		write_indent ();
-		stream.printf ("<record name=\"%s\"", st.name);
+		stream.printf ("<record name=\"%s\"", gi_local_type_name (st));
+		write_node_attributes(st);
 		stream.printf (">\n");
 		indent++;
 
@@ -178,12 +224,15 @@
 			return;
 		}
 
+		check_stream();
+		
 		write_indent ();
-		stream.printf ("<interface name=\"%s\"", iface.name);
+		stream.printf ("<interface name=\"%s\"", gi_local_type_name (iface));
+		stream.printf (" glib:type-name=\"%s\"", iface.get_cname ());
 		stream.printf (" glib:get-type=\"%sget_type\"", iface.get_lower_case_cprefix ());
+		write_node_attributes(iface);
 		stream.printf (">\n");
 		indent++;
-
 		// write prerequisites
 		if (iface.get_prerequisites ().size > 0) {
 			write_indent ();
@@ -194,10 +243,10 @@
 				var object_type = (ObjectType) base_type;
 				if (object_type.type_symbol is Class) {
 					write_indent ();
-					stream.printf ("<object name=\"%s\"/>\n", object_type.type_symbol.get_full_name ());
+					stream.printf ("<object name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
 				} else if (object_type.type_symbol is Interface) {
 					write_indent ();
-					stream.printf ("<interface name=\"%s\"/>\n", object_type.type_symbol.get_full_name ());
+					stream.printf ("<interface name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
 				} else {
 					assert_not_reached ();
 				}
@@ -224,9 +273,12 @@
 			return;
 		}
 
+		check_stream();
+		
 		write_indent ();
 		stream.printf ("<enumeration name=\"%s\"", en.name);
 		stream.printf (" c:type=\"%s\"", en.get_cname ());
+		stream.printf (" glib:type-name=\"%s\"", en.get_cname ());
 		stream.printf (" glib:get-type=\"%sget_type\"", en.get_lower_case_cprefix ());
 		stream.printf (">\n");
 		indent++;
@@ -252,6 +304,8 @@
 			return;
 		}
 
+		check_stream();
+		
 		write_indent ();
 		stream.printf ("<errordomain name=\"%s\"", edomain.get_cname ());
 		stream.printf (">\n");
@@ -277,7 +331,7 @@
 		if (!check_accessibility (c)) {
 			return;
 		}
-
+		
 		write_indent ();
 		stream.printf ("<constant name=\"%s\"/>\n", c.get_cname ());
 	}
@@ -292,7 +346,9 @@
 		}
 
 		write_indent ();
-		stream.printf ("<field name=\"%s\">\n", f.get_cname ());
+		stream.printf ("<field name=\"%s\"", f.get_cname ());
+		write_node_attributes(f);
+		stream.printf (">\n");
 		indent++;
 
 		write_type (f.field_type);
@@ -307,7 +363,7 @@
 		stream.printf ("<parameters>\n");
 		indent++;
 
-		if (instance_type != null) {
+		/*if (instance_type != null) {
 			write_indent ();
 			stream.printf ("<parameter name=\"self\">\n");
 			indent++;
@@ -317,7 +373,7 @@
 			indent--;
 			write_indent ();
 			stream.printf ("</parameter>\n");
-		}
+		}*/
 
 		foreach (FormalParameter param in params) {
 			write_indent ();
@@ -338,6 +394,8 @@
 				// normal in paramter
 				if (param.parameter_type.value_owned) {
 					stream.printf (" transfer-ownership=\"full\"");
+				} else {
+					stream.printf (" transfer-ownership=\"none\"");
 				}
 			}
 			stream.printf (">\n");
@@ -390,6 +448,7 @@
 
 		write_indent ();
 		stream.printf ("<method name=\"%s\" c:identifier=\"%s\"", m.name, m.get_cname ());
+		write_node_attributes(m);
 		stream.printf (">\n");
 		indent++;
 
@@ -418,6 +477,7 @@
 
 		write_indent ();
 		stream.printf ("<constructor name=\"%s\" c:identifier=\"%s\"", m.name, m.get_cname ());
+		write_node_attributes(m);
 		stream.printf (">\n");
 		indent++;
 
@@ -443,6 +503,7 @@
 		if (prop.set_accessor != null) {
 			stream.printf (" writable=\"1\"");
 		}
+		write_node_attributes(prop);
 		stream.printf (">\n");
 		indent++;
 
@@ -460,6 +521,7 @@
 		
 		write_indent ();
 		stream.printf ("<glib:signal name=\"%s\"", sig.get_cname ());
+		write_node_attributes(sig);
 		stream.printf (">\n");
 		indent++;
 
@@ -485,6 +547,8 @@
 		stream.printf ("<return-value");
 		if (type.value_owned) {
 			stream.printf (" transfer-ownership=\"full\"");
+		} else {
+			stream.printf (" transfer-ownership=\"none\"");
 		}
 		stream.printf (">\n");
 		indent++;
@@ -511,13 +575,107 @@
 			stream.printf ("</array>\n");
 		} else if (type is VoidType) {
 			write_indent ();
-			stream.printf ("<type name=\"none\"/>\n");
+			stream.printf ("<type name=\"none\" c:type=\"void\"/>\n");
 		} else {
 			write_indent ();
-			stream.printf ("<type name=\"%s\"/>\n", type.to_string ());
+			stream.printf ("<type name=\"%s\" c:type=\"%s\"", gi_type_name (type.data_type), type.get_cname ());
+			Gee.List<DataType> type_arguments = type.get_type_arguments ();
+			if (type_arguments.size == 0) {
+				stream.printf ("/>\n");
+			} else {
+				stream.printf (">\n");
+				indent++;
+				foreach (DataType type_argument in type_arguments) {
+					write_type (type_argument);
+				}
+				indent--;
+				write_indent ();
+				stream.printf ("</type>\n");
+			}
 		}
 	}
-
+	
+	private void write_node_attributes(CodeNode node) {
+		foreach (Attribute attr in node.attributes) {
+			string name = camel_case_to_lower_case(attr.name);
+			stream.printf (" xmlns:%s=\"http://www.gtk.org/introspection/%s/1.0\"", name, name);
+			foreach (string arg_name in attr.args.get_keys()) {
+				string value = null;
+				
+				var arg = attr.args.get (arg_name);
+				if (arg is StringLiteral) {
+					var lit = arg as StringLiteral;
+					if (lit != null) {
+						value = lit.eval ();
+						value.replace("\"", "\\\"");
+					}
+				} else if (arg is RealLiteral) {
+					var lit = (RealLiteral) arg;
+					value = lit.value;
+				} else if (arg is IntegerLiteral) {
+					var lit = (IntegerLiteral) arg;
+					value = lit.value;
+				} else if (arg is UnaryExpression) {
+					var unary = (UnaryExpression) arg;
+					if (unary.operator == UnaryOperator.MINUS) {
+						if (unary.inner is RealLiteral) {
+							var lit = (RealLiteral) unary.inner;
+							value = "-" + lit.value;
+						} else if (unary.inner is IntegerLiteral) {
+							var lit = (IntegerLiteral) unary.inner;
+							value = "-" + lit.value;
+						}
+					}
+				}
+				
+				if (value != null) {
+					stream.printf (" %s:%s=\"%s\"", name, camel_case_to_lower_case(arg_name), value);
+				}
+			}
+		}
+	}
+	
+	private string gi_local_type_name(TypeSymbol type_symbol) {
+		string local_type_name = type_symbol.get_cname();
+		if (local_type_name.has_prefix (typelib_namespace)) {
+			local_type_name = local_type_name.substring
+				(typelib_namespace.length, local_type_name.length - typelib_namespace.length);
+		}
+		return local_type_name;
+	}
+	
+	private string gi_type_name(TypeSymbol type_symbol) {
+		return vala_to_gi_type_name(type_symbol.get_full_name());
+	}
+	
+	private string vala_to_gi_type_name(string name) {
+		if (name == "bool") {
+			return "boolean";
+		} else if (name == "string") {
+			return "utf8";
+		} else if (!name.contains (".")) {
+			return name;
+		} else {
+			string[] split_name = name.split(".");
+			
+			StringBuilder type_name = new StringBuilder();
+			type_name.append(split_name[0]);
+			type_name.append_unichar('.');
+			for (int i = 1; i < split_name.length; i++) {
+				type_name.append(split_name[i]);
+			}
+			
+			if (type_name.str == "GLib.Object") {
+				return "GObject.Object";
+			}
+			return type_name.str;
+		}
+	}
+	
+	private string camel_case_to_lower_case(string name) {
+		return Symbol.camel_case_to_lower_case(name).replace("_", "-");
+	}
+	
 	private bool check_accessibility (Symbol sym) {
 		if (sym.access == SymbolAccessibility.PUBLIC ||
 		    sym.access == SymbolAccessibility.PROTECTED) {
