]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
GIR Namespace support
authorRob Taylor <rob.taylor@codethink.co.uk>
Sun, 31 Jan 2010 16:11:00 +0000 (16:11 +0000)
committerJürg Billeter <j@bitron.ch>
Mon, 1 Feb 2010 15:52:38 +0000 (16:52 +0100)
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.

28 files changed:
codegen/valagirwriter.vala
compiler/valacompiler.vala
vala/valacodewriter.vala
vala/valanamespace.vala
vala/valasourcefile.vala
vapi/atk.vapi
vapi/cairo.vapi
vapi/clutter-1.0.vapi
vapi/clutter-json-1.0.vapi
vapi/cogl-1.0.vapi
vapi/gdk-2.0.vapi
vapi/gdk-pixbuf-2.0.vapi
vapi/gio-2.0.vapi
vapi/glib-2.0.vapi
vapi/gobject-2.0.vapi
vapi/gtk+-2.0.vapi
vapi/packages/atk/atk.metadata
vapi/packages/clutter-1.0/clutter-1.0.metadata
vapi/packages/cogl-1.0/cogl-1.0.metadata
vapi/packages/gdk-2.0/gdk-2.0.metadata
vapi/packages/gdk-pixbuf-2.0/gdk-pixbuf-2.0.metadata
vapi/packages/gio-2.0/gio-2.0.metadata
vapi/packages/gtk+-2.0/gtk+-2.0.metadata
vapi/packages/pango/pango.metadata
vapi/packages/pangocairo/pangocairo.metadata
vapi/pango.vapi
vapi/pangocairo.vapi
vapigen/valagidlparser.vala

index 5d1ca71e93e9773038d8981fa17b165839a0ff9d..122bba154dd1aefe0fc7fe631cd74b727a92df75 100644 (file)
@@ -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<GIRNamespace?> externals = new ArrayList<GIRNamespace?> ((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 ("<include name=\"%s\" version=\"%s\"/>\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;
                }
        }
index 71e70589bbb013bce5062604c7364807d4674f76..78429d1e7816ef30fc9b1985d0c4b363dccf8818 100644 (file)
@@ -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) {
index 89fcab079bf62245830324f68531b3e847c0baae..eeb01edd086355f5bf964325a332a9f286d7d6ee 100644 (file)
@@ -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);
index a044888c6f1395ecdbe3c584d63abaf31ca87d58..8ddeb9dffd88af9e5e48d227149a629a982430b6 100644 (file)
@@ -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.
         */
index 6650512e2a68a428c025fec90a8258302dc66869..df8436694f28b4a229b3ca2cd1b20bddbb847df8 100644 (file)
@@ -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.
         */
index de576c93ef60da95c4b77815560519543983e2f6..ea6e91d215bbc9ac24f891ad0c22888c7c027351 100644 (file)
@@ -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")]
index 2a070e7513e8209cd206c229f9980a30b261aab6..d6c2f46071a6dab92c187f73ead8862ee91fcf64 100644 (file)
@@ -20,7 +20,7 @@
  *     Jürg Billeter <j@bitron.ch>
  */
 
-[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")]
index dae0d214aca0b3930d80b9c6d81a76896ffbbdc2..001159e6f863d685f306c85401db492e132a9abb 100644 (file)
@@ -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 {
index c1e87951ad3d3ce333ae3c33ea095fb216e52c49..200ae4f57ce1c9758f49bf6317ec2847121272c3 100644 (file)
@@ -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 {
index 3f84f9b3a3faee4d2c5ca7e169eb04662700ab54..06ffe0485ae7bb9206f5df3eb7b9ca99e5798542 100644 (file)
@@ -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")]
index e143cbeea2d169ed84645a6b47141efdf7d57685..efe8e7e811745ff8ca9971de20f435dad6873ca3 100644 (file)
@@ -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 {
index cf3572a703e63e2a8a86e822f02b1f79be244dd2..62bd209a452b6d4ee9d0e0385bd4e3774bd790c6 100644 (file)
@@ -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 {
index 3ff059969b3ddaf797765685f0d4faab90d60768..b7f7c9570e12ee458076b873cdb8d784ca6c2ea7 100644 (file)
@@ -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 {
index 4cf97255daaeac124cce657b2394366b07cffc2a..e883c44faab179f220bf33ce2e4fad7386778286 100644 (file)
@@ -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 {
index 1c5411d192edaec047ed5e7ed5d2e19189fd7778..e77d84f76e8c6881aff3d74c4ed9315cd9d2082c 100644 (file)
@@ -24,7 +24,7 @@
  *     Mathias Hasselmann <mathias.hasselmann@gmx.de>
  */
 
-[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 {
index 4b0f53d992c3abcb87c78b90e5f6075efbafd079..c4a0e72749365c24511fb64e86e21e10c1a475b0 100644 (file)
@@ -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 {
index 19fa8679fe09629e940a14c88ee8f828c977f3d7..b0c2f957642ba55e29912f657fd5dc9576b813aa 100644 (file)
@@ -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"
 
index 13a3d20bc50c1cd56f95e5ecdc375b5d2b070bad..fc989742f1395016f69a8ef744bae15dbb027b6f 100644 (file)
@@ -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"
index f2a762d18b6e8e4e45c62639cead6704a4b32176..ce9062a2175692a8cba14ba588b4dc84b19b9876 100644 (file)
@@ -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"
index 6e29aadd5546a9a341fe94fc9f62ebc6f617624e..261ea0e141aaab5636e8347d9eecfc246d19a410 100644 (file)
@@ -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"
index 36440a4c510188fea945c379ae38f779e6db388a..22700900e567eff52512f913bae4aa64008b1c2c 100644 (file)
@@ -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"
index ab4e17ac452fac581a74f66dd780c93d262101a5..34c219e5f6f7aed1b520b63970902866dd24a65f 100644 (file)
@@ -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"
index 681217d11c72987fa39c5080ce88cfb06c08ebfa..7c4920ed54abe1eba6417af95bdcb376058faa2c 100644 (file)
@@ -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"
index 74023392e10b4fb4a489a01c2d8840e7399c7c71..e56a3f2e30d00d2787d7e687c044ecfa1afd685d 100644 (file)
@@ -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"
index e0817a81d3673fe6536232708db2437af557880b..a28c6ea82e4ef4ff41fec9cee92266b5ac362fc7 100644 (file)
@@ -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"
index ede08180e47d78c63fac679cafbaa971ef5062d6..58f1e4ad695df77ee08e8054105dabc7dd54918b 100644 (file)
@@ -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 {
index 186354c22aa2b581c0d8946d14bf1361b3ffa12c..4e90a058d152048688b3e71ba08e341c44bf9dac 100644 (file)
@@ -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 {
index 246dd18f5062509d650f45969f29d1cf154ffce4..5664b416d47c39bcfda6527da05afeb666ef8ba8 100644 (file)
@@ -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]);
                                }
                        }
                }