From: Rob Taylor Date: Sun, 31 Jan 2010 16:11:00 +0000 (+0000) Subject: GIR Namespace support X-Git-Tag: 0.7.10~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7dcc676f1782a18fccfdf5203ef809e4aa6c19c9;p=thirdparty%2Fvala.git GIR Namespace support This patch introduces two new CCode annotations for use in VAPI files, gir_namespace and gir_version. This allows us to correctly map vala namespaces to gobject-introspection namespaces when generating GIR files. The mapping is actually done on a SourceFile level. This allows us to work around cases where one vala namespace maps into multiple GIR namespaces (in particular, GLib vs GLib and GObject). In the absense of annotations, the old 'guess it' method will be applied. This commit also adds annotations to some core vapis. Fixes bug 584683. --- diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala index 5d1ca71e9..122bba154 100644 --- a/codegen/valagirwriter.vala +++ b/codegen/valagirwriter.vala @@ -37,6 +37,69 @@ public class Vala.GIRWriter : CodeVisitor { private TypeSymbol gobject_type; + private class ExternalNamespaceWriter : CodeVisitor { + private struct GIRNamespace { + public GIRNamespace (string ns, string version) { + this.ns = ns; this.version = version; + } + public string ns; + public string version; + public bool equal (GIRNamespace g) { + return ((ns == g.ns) && (version == g.version)); + } + } + private ArrayList externals = new ArrayList ((EqualFunc) GIRNamespace.equal); + private string gir_namespace; + private string gir_version; + private GIRWriter gir_writer; + private bool in_source_file = false; + + public ExternalNamespaceWriter (GIRWriter gir_writer, string gir_namespace, string gir_version) { + this.gir_writer = gir_writer; + this.gir_namespace = gir_namespace; + this.gir_version = gir_version; + } + + public override void visit_namespace (Namespace ns) { + if (!in_source_file) { + return; + } + + if (ns.name == null) { + ns.accept_children (this); + return; + } + + if (!ns.external_package) { + ns.source_reference.file.gir_namespace = gir_namespace; + ns.source_reference.file.gir_version = gir_version; + return; + } + + if (ns.source_reference.file.gir_namespace != null) { + GIRNamespace external = GIRNamespace (ns.source_reference.file.gir_namespace, ns.source_reference.file.gir_version); + if (!externals.contains (external)) { + externals.add (external); + } + } else { + Report.warning (ns.source_reference, "Namespace %s does not have a GIR namespace and version annotation".printf (ns.name)); + } + } + + + public override void visit_source_file (SourceFile sf) { + in_source_file = true; + sf.accept_children (this); + in_source_file = false; + } + + public void write_externals() { + foreach (var i in externals) { + gir_writer.write_gir_include(i.ns, i.version); + } + } + } + /** * Writes the public interface of the specified code context into the * specified file. @@ -66,9 +129,9 @@ public class Vala.GIRWriter : CodeVisitor { stream.printf (">\n"); indent++; - // FIXME: find a way to include everything - write_gir_include ("GLib", "2.0"); - write_gir_include ("GObject", "2.0"); + ExternalNamespaceWriter env = new ExternalNamespaceWriter (this, gir_namespace, gir_version); + context.accept (env); + env.write_externals(); write_package (package); @@ -80,7 +143,7 @@ public class Vala.GIRWriter : CodeVisitor { stream = null; } - private void write_gir_include (string name, string version) { + internal void write_gir_include (string name, string version) { write_indent (); stream.printf ("\n", name, version); } @@ -862,6 +925,13 @@ public class Vala.GIRWriter : CodeVisitor { } private string gi_type_name (TypeSymbol type_symbol) { + Symbol parent = type_symbol.parent_symbol; + if (parent is Namespace) { + Namespace ns = parent as Namespace; + if (ns.name != null && type_symbol.source_reference.file.gir_namespace != null) { + return "%s.%s".printf (type_symbol.source_reference.file.gir_namespace, type_symbol.name); + } + } return vala_to_gi_type_name (type_symbol.get_full_name()); } @@ -881,10 +951,6 @@ public class Vala.GIRWriter : CodeVisitor { 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; } } diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala index 71e70589b..78429d1e7 100644 --- a/compiler/valacompiler.vala +++ b/compiler/valacompiler.vala @@ -397,17 +397,6 @@ class Vala.Compiler { vapi_filename = "%s.vapi".printf (library); } - if (vapi_filename != null) { - var interface_writer = new CodeWriter (); - - // put .vapi file in current directory unless -d has been explicitly specified - if (directory != null && !Path.is_absolute (vapi_filename)) { - vapi_filename = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, vapi_filename); - } - - interface_writer.write_file (context, vapi_filename); - } - if (library != null) { if (gir != null) { if (context.profile == Profile.GOBJECT) { @@ -442,6 +431,19 @@ class Vala.Compiler { library = null; } + + // The GIRWriter places the gir_namespace and gir_version into the top namespace, so write the vapi after that stage + if (vapi_filename != null) { + var interface_writer = new CodeWriter (); + + // put .vapi file in current directory unless -d has been explicitly specified + if (directory != null && !Path.is_absolute (vapi_filename)) { + vapi_filename = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, vapi_filename); + } + + interface_writer.write_file (context, vapi_filename); + } + if (internal_vapi_filename != null) { if (internal_header_filename == null || header_filename == null) { diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala index 89fcab079..eeb01edd0 100644 --- a/vala/valacodewriter.vala +++ b/vala/valacodewriter.vala @@ -95,7 +95,18 @@ public class Vala.CodeWriter : CodeVisitor { } write_indent (); - write_string ("[CCode (cprefix = \"%s\", lower_case_cprefix = \"%s\")]".printf (ns.get_cprefix (), ns.get_lower_case_cprefix ())); + write_string ("[CCode (cprefix = \"%s\", lower_case_cprefix = \"%s\"".printf (ns.get_cprefix (), ns.get_lower_case_cprefix ())); + + if (ns.source_reference.file.gir_namespace != null) { + write_string (", "); + write_string ("gir_namespace = \"%s\"".printf (ns.source_reference.file.gir_namespace)); + } + if (ns.source_reference.file.gir_version != null) { + write_string(", "); + write_string ("gir_version = \"%s\"".printf (ns.source_reference.file.gir_version)); + } + + write_string (")]"); write_newline (); write_attributes (ns); diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala index a044888c6..8ddeb9dff 100644 --- a/vala/valanamespace.vala +++ b/vala/valanamespace.vala @@ -562,8 +562,14 @@ public class Vala.Namespace : Symbol { cheader_filenames.add (filename); } } + if (a.has_argument ("gir_namespace")) { + source_reference.file.gir_namespace = a.get_string ("gir_namespace"); + } + if (a.has_argument ("gir_version")) { + source_reference.file.gir_version = a.get_string ("gir_version"); + } } - + /** * Process all associated attributes. */ diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala index 6650512e2..df8436694 100644 --- a/vala/valasourcefile.vala +++ b/vala/valasourcefile.vala @@ -37,6 +37,18 @@ public class Vala.SourceFile { */ public bool external_package { get; set; } + /** + * GIR Namespace for this source file, if it's a VAPI package + */ + + public string gir_namespace { get; set; } + + /** + * GIR Namespace version for this source file, if it's a VAPI package + */ + + public string gir_version { get; set; } + /** * The context this source file belongs to. */ diff --git a/vapi/atk.vapi b/vapi/atk.vapi index de576c93e..ea6e91d21 100644 --- a/vapi/atk.vapi +++ b/vapi/atk.vapi @@ -1,6 +1,6 @@ /* atk.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Atk", lower_case_cprefix = "atk_")] +[CCode (cprefix = "Atk", lower_case_cprefix = "atk_", gir_namespace = "Atk", gir_version = "1.0")] namespace Atk { [Compact] [CCode (cheader_filename = "atk/atk.h")] diff --git a/vapi/cairo.vapi b/vapi/cairo.vapi index 2a070e751..d6c2f4607 100644 --- a/vapi/cairo.vapi +++ b/vapi/cairo.vapi @@ -20,7 +20,7 @@ * Jürg Billeter */ -[CCode (cheader_filename = "cairo.h")] +[CCode (cheader_filename = "cairo.h", gir_namespace = "cairo", gir_version = "1.0")] namespace Cairo { [Compact] [CCode (ref_function = "cairo_reference", unref_function = "cairo_destroy", cname = "cairo_t", cprefix = "cairo_", cheader_filename = "cairo.h")] diff --git a/vapi/clutter-1.0.vapi b/vapi/clutter-1.0.vapi index dae0d214a..001159e6f 100644 --- a/vapi/clutter-1.0.vapi +++ b/vapi/clutter-1.0.vapi @@ -1,6 +1,6 @@ /* clutter-1.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Clutter", lower_case_cprefix = "clutter_")] +[CCode (cprefix = "Clutter", lower_case_cprefix = "clutter_", gir_namespace = "Clutter", gir_version = "1.0")] namespace Clutter { [CCode (cprefix = "ClutterFrameSource", lower_case_cprefix = "clutter_frame_source_")] namespace FrameSource { diff --git a/vapi/clutter-json-1.0.vapi b/vapi/clutter-json-1.0.vapi index c1e87951a..200ae4f57 100644 --- a/vapi/clutter-json-1.0.vapi +++ b/vapi/clutter-json-1.0.vapi @@ -1,6 +1,6 @@ /* clutter-json-1.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "ClutterJson", lower_case_cprefix = "clutter_json_")] +[CCode (cprefix = "ClutterJson", lower_case_cprefix = "clutter_json_", gir_namespace = "ClutterJson", gir_version = "1.0")] namespace ClutterJson { [CCode (cname = "JsonGenerator", cheader_filename = "clutter/json/json-glib.h")] public class JsonGenerator : GLib.Object { diff --git a/vapi/cogl-1.0.vapi b/vapi/cogl-1.0.vapi index 3f84f9b3a..06ffe0485 100644 --- a/vapi/cogl-1.0.vapi +++ b/vapi/cogl-1.0.vapi @@ -1,6 +1,6 @@ /* cogl-1.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Cogl", lower_case_cprefix = "cogl_")] +[CCode (cprefix = "Cogl", lower_case_cprefix = "cogl_", gir_namespace = "Cogl", gir_version = "1.0")] namespace Cogl { [Compact] [CCode (cname = "CoglHandle", cheader_filename = "cogl/cogl.h")] diff --git a/vapi/gdk-2.0.vapi b/vapi/gdk-2.0.vapi index e143cbeea..efe8e7e81 100644 --- a/vapi/gdk-2.0.vapi +++ b/vapi/gdk-2.0.vapi @@ -1,6 +1,6 @@ /* gdk-2.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Gdk", lower_case_cprefix = "gdk_")] +[CCode (cprefix = "Gdk", lower_case_cprefix = "gdk_", gir_namespace = "Gdk", gir_version = "2.0")] namespace Gdk { [CCode (cheader_filename = "gdk/gdk.h")] public class AppLaunchContext : GLib.AppLaunchContext { diff --git a/vapi/gdk-pixbuf-2.0.vapi b/vapi/gdk-pixbuf-2.0.vapi index cf3572a70..62bd209a4 100644 --- a/vapi/gdk-pixbuf-2.0.vapi +++ b/vapi/gdk-pixbuf-2.0.vapi @@ -1,6 +1,6 @@ /* gdk-pixbuf-2.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Gdk", lower_case_cprefix = "gdk_")] +[CCode (cprefix = "Gdk", lower_case_cprefix = "gdk_", gir_namespace = "GdkPixbuf", gir_version = "2.0")] namespace Gdk { [CCode (cheader_filename = "gdk-pixbuf/gdk-pixdata.h")] public class Pixbuf : GLib.Object { diff --git a/vapi/gio-2.0.vapi b/vapi/gio-2.0.vapi index 3ff059969..b7f7c9570 100644 --- a/vapi/gio-2.0.vapi +++ b/vapi/gio-2.0.vapi @@ -1,6 +1,6 @@ /* gio-2.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "G", lower_case_cprefix = "g_")] +[CCode (cprefix = "G", lower_case_cprefix = "g_", gir_namespace = "Gio", gir_version = "2.0")] namespace GLib { [CCode (cheader_filename = "gio/gio.h")] public class AppLaunchContext : GLib.Object { diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index 4cf97255d..e883c44fa 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -1047,7 +1047,7 @@ public class string { } } -[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h")] +[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h", gir_namespace = "GLib", gir_version = "2.0")] namespace GLib { [CCode (lower_case_cprefix = "", cheader_filename = "math.h")] namespace Math { diff --git a/vapi/gobject-2.0.vapi b/vapi/gobject-2.0.vapi index 1c5411d19..e77d84f76 100644 --- a/vapi/gobject-2.0.vapi +++ b/vapi/gobject-2.0.vapi @@ -24,7 +24,7 @@ * Mathias Hasselmann */ -[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h")] +[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h", gir_namespace = "GObject", gir_version = "2.0")] namespace GLib { [CCode (type_id = "G_TYPE_GTYPE", marshaller_type_name = "GTYPE", get_value_function = "g_value_get_gtype", set_value_function = "g_value_set_gtype")] public struct Type : ulong { diff --git a/vapi/gtk+-2.0.vapi b/vapi/gtk+-2.0.vapi index 4b0f53d99..c4a0e7274 100644 --- a/vapi/gtk+-2.0.vapi +++ b/vapi/gtk+-2.0.vapi @@ -1,6 +1,6 @@ /* gtk+-2.0.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Gtk", lower_case_cprefix = "gtk_")] +[CCode (cprefix = "Gtk", lower_case_cprefix = "gtk_", gir_namespace = "Gtk", gir_version = "2.0")] namespace Gtk { [CCode (cheader_filename = "gtk/gtk.h")] public class AboutDialog : Gtk.Dialog, Atk.Implementor, Gtk.Buildable { diff --git a/vapi/packages/atk/atk.metadata b/vapi/packages/atk/atk.metadata index 19fa8679f..b0c2f9576 100644 --- a/vapi/packages/atk/atk.metadata +++ b/vapi/packages/atk/atk.metadata @@ -1,3 +1,3 @@ -Atk cheader_filename="atk/atk.h" +Atk cheader_filename="atk/atk.h" gir_namespace="Atk" gir_version="1.0" AtkRectangle is_value_type="1" diff --git a/vapi/packages/clutter-1.0/clutter-1.0.metadata b/vapi/packages/clutter-1.0/clutter-1.0.metadata index 13a3d20bc..fc989742f 100644 --- a/vapi/packages/clutter-1.0/clutter-1.0.metadata +++ b/vapi/packages/clutter-1.0/clutter-1.0.metadata @@ -1,4 +1,4 @@ -Clutter cheader_filename="clutter/clutter.h" +Clutter cheader_filename="clutter/clutter.h" gir_namespace="Clutter" gir_version="1.0" ClutterActor:clip accessor_method="0" ClutterActor:scale_gravity accessor_method="1" diff --git a/vapi/packages/cogl-1.0/cogl-1.0.metadata b/vapi/packages/cogl-1.0/cogl-1.0.metadata index f2a762d18..ce9062a21 100644 --- a/vapi/packages/cogl-1.0/cogl-1.0.metadata +++ b/vapi/packages/cogl-1.0/cogl-1.0.metadata @@ -1,4 +1,4 @@ -Cogl cheader_filename="cogl/cogl.h" +Cogl cheader_filename="cogl/cogl.h" gir_namespace="Cogl" gir_version="1.0" COGLint name="long" GLint name="long" diff --git a/vapi/packages/gdk-2.0/gdk-2.0.metadata b/vapi/packages/gdk-2.0/gdk-2.0.metadata index 6e29aadd5..261ea0e14 100644 --- a/vapi/packages/gdk-2.0/gdk-2.0.metadata +++ b/vapi/packages/gdk-2.0/gdk-2.0.metadata @@ -1,4 +1,4 @@ -Gdk cheader_filename="gdk/gdk.h" +Gdk cheader_filename="gdk/gdk.h" gir_namespace="Gdk" gir_version="2.0" gdk_add_client_message_filter.data hidden="1" GdkAppLaunchContextClass hidden="1" GdkAtom is_value_type="1" simple_type="1" diff --git a/vapi/packages/gdk-pixbuf-2.0/gdk-pixbuf-2.0.metadata b/vapi/packages/gdk-pixbuf-2.0/gdk-pixbuf-2.0.metadata index 36440a4c5..22700900e 100644 --- a/vapi/packages/gdk-pixbuf-2.0/gdk-pixbuf-2.0.metadata +++ b/vapi/packages/gdk-pixbuf-2.0/gdk-pixbuf-2.0.metadata @@ -1,4 +1,4 @@ -Gdk cheader_filename="gdk-pixbuf/gdk-pixdata.h" +Gdk cheader_filename="gdk-pixbuf/gdk-pixdata.h" gir_namespace="GdkPixbuf" gir_version="2.0" gdk_pixbuf_copy transfer_ownership="1" gdk_pixbuf_get_file_info.width is_out="1" gdk_pixbuf_get_file_info.height is_out="1" diff --git a/vapi/packages/gio-2.0/gio-2.0.metadata b/vapi/packages/gio-2.0/gio-2.0.metadata index ab4e17ac4..34c219e5f 100644 --- a/vapi/packages/gio-2.0/gio-2.0.metadata +++ b/vapi/packages/gio-2.0/gio-2.0.metadata @@ -1,4 +1,4 @@ -GLib cprefix="G" lower_case_cprefix="g_" cheader_filename="gio/gio.h" +GLib cprefix="G" lower_case_cprefix="g_" cheader_filename="gio/gio.h" gir_namespace="Gio" gir_version="2.0" g_app_info_launch.envp is_array="1" g_app_info_launch.launch_context nullable="1" g_app_info_launch_default_for_uri.launch_context nullable="1" diff --git a/vapi/packages/gtk+-2.0/gtk+-2.0.metadata b/vapi/packages/gtk+-2.0/gtk+-2.0.metadata index 681217d11..7c4920ed5 100644 --- a/vapi/packages/gtk+-2.0/gtk+-2.0.metadata +++ b/vapi/packages/gtk+-2.0/gtk+-2.0.metadata @@ -1,4 +1,4 @@ -Gtk cheader_filename="gtk/gtk.h" +Gtk cheader_filename="gtk/gtk.h" gir_namespace="Gtk" gir_version="2.0" gtk_about_dialog_set_artists.artists is_array="1" no_array_length="1" gtk_about_dialog_set_authors.authors is_array="1" no_array_length="1" gtk_about_dialog_set_documenters.documenters is_array="1" no_array_length="1" diff --git a/vapi/packages/pango/pango.metadata b/vapi/packages/pango/pango.metadata index 74023392e..e56a3f2e3 100644 --- a/vapi/packages/pango/pango.metadata +++ b/vapi/packages/pango/pango.metadata @@ -1,4 +1,4 @@ -Pango cheader_filename="pango/pango.h" +Pango cheader_filename="pango/pango.h" gir_namespace="Pango" gir_version="1.0" pango_attribute_copy transfer_ownership="1" PangoAttrColor base_class="PangoAttribute" free_function="pango_attribute_destroy" PangoAttrColor.attr hidden="1" diff --git a/vapi/packages/pangocairo/pangocairo.metadata b/vapi/packages/pangocairo/pangocairo.metadata index e0817a81d..a28c6ea82 100644 --- a/vapi/packages/pangocairo/pangocairo.metadata +++ b/vapi/packages/pangocairo/pangocairo.metadata @@ -1,4 +1,4 @@ -Pango cheader_filename="pango/pangocairo.h" +Pango cheader_filename="pango/pangocairo.h" gir_namespace="PangoCairo" gir_version="1.0" pango_cairo_create_context transfer_ownership="1" pango_cairo_create_layout transfer_ownership="1" diff --git a/vapi/pango.vapi b/vapi/pango.vapi index ede08180e..58f1e4ad6 100644 --- a/vapi/pango.vapi +++ b/vapi/pango.vapi @@ -1,6 +1,6 @@ /* pango.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Pango", lower_case_cprefix = "pango_")] +[CCode (cprefix = "Pango", lower_case_cprefix = "pango_", gir_namespace = "Pango", gir_version = "1.0")] namespace Pango { [CCode (cprefix = "PangoScale", lower_case_cprefix = "pango_scale_")] namespace Scale { diff --git a/vapi/pangocairo.vapi b/vapi/pangocairo.vapi index 186354c22..4e90a058d 100644 --- a/vapi/pangocairo.vapi +++ b/vapi/pangocairo.vapi @@ -1,6 +1,6 @@ /* pangocairo.vapi generated by vapigen, do not modify. */ -[CCode (cprefix = "Pango", lower_case_cprefix = "pango_")] +[CCode (cprefix = "Pango", lower_case_cprefix = "pango_", gir_namespace = "PangoCairo", gir_version = "1.0")] namespace Pango { [CCode (cheader_filename = "pango/pangocairo.h")] public interface CairoFont : Pango.Font { diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala index 246dd18f5..5664b416d 100644 --- a/vapigen/valagidlparser.vala +++ b/vapigen/valagidlparser.vala @@ -219,6 +219,10 @@ public class Vala.GIdlParser : CodeVisitor { } } else if (nv[0] == "lower_case_cprefix") { ns.set_lower_case_cprefix (eval (nv[1])); + } else if (nv[0] == "gir_namespace") { + ns.source_reference.file.gir_namespace = eval (nv[1]); + } else if (nv[0] == "gir_version") { + ns.source_reference.file.gir_version = eval (nv[1]); } } }