[Vala] [PATCH] Various enhancements for boxed types and static classes



---
 trunk/vala/ChangeLog                             |    6 ++
 trunk/vala/vala/valainterfacewriter.vala         |   40 ++++++++++-
 trunk/vala/vala/valastruct.vala                  |   82 +++++++++++++++++++--
 trunk/vapigen/ChangeLog                          |    9 +++
 trunk/vapigen/gobject-introspection/gidl.vala    |    2 +
 trunk/vapigen/gobject-introspection/gidlnode.c   |    1 +
 trunk/vapigen/gobject-introspection/gidlnode.h   |    2 +
 trunk/vapigen/gobject-introspection/gidlparser.c |    6 ++
 trunk/vapigen/packages/pango/pango.metadata      |    8 ++-
 trunk/vapigen/vapigen/valagidlparser.vala        |   54 +++++++++++++-
 10 files changed, 192 insertions(+), 18 deletions(-)

diff --git a/trunk/vala/ChangeLog b/trunk/vala/ChangeLog
index b94605e..8c42062 100644
--- a/trunk/vala/ChangeLog
+++ b/trunk/vala/ChangeLog
@@ -1,3 +1,9 @@
+2007-03-26  Mathias Hasselmann  <mathias hasselmann gmx de>
+
+       * vala/valainterfacewriter.vala, vala/valastruct.vala: improve support
+         for boxed types
+       * vala/valainterfacewriter.vala: support static classes like PangoCairo
+
 2007-03-22  Raffaele Sandrini  <rasa gmx ch>
        * vala/valaflags.vala, vala/valaenum.vala, vala/valadatatype.vala,
          vala/valastruct.vala: add support for default values of types
diff --git a/trunk/vala/vala/valainterfacewriter.vala b/trunk/vala/vala/valainterfacewriter.vala
index 72b68cc..689fe9e 100644
--- a/trunk/vala/vala/valainterfacewriter.vala
+++ b/trunk/vala/vala/valainterfacewriter.vala
@@ -110,6 +110,9 @@ public class Vala.InterfaceWriter : CodeVisitor {
                
                write_indent ();
                write_string ("public ");
+               if (cl.is_static) {
+                       write_string ("static ");
+               }
                if (cl.is_abstract) {
                        write_string ("abstract ");
                }
@@ -118,15 +121,19 @@ public class Vala.InterfaceWriter : CodeVisitor {
                
                var base_types = cl.get_base_types ();
                if (base_types != null) {
-                       write_string (" : ");
-               
                        bool first = true;
                        foreach (TypeReference base_type in base_types) {
+                               if (cl.is_static && "GLib.Object" == 
+                                   base_type.data_type.symbol.get_full_name ())
+                                       continue;
+
                                if (!first) {
                                        write_string (", ");
                                } else {
+                                       write_string (" : ");
                                        first = false;
                                }
+
                                write_string (base_type.data_type.symbol.get_full_name ());
                        }
                }
@@ -149,9 +156,36 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        return;
                }
                
+               var attrs = new String ("(");
+               string attrs_str;
+
+               if (st.is_boxed_type ()) {
+                       if (attrs.len > 1) {
+                               attrs.append (", ");
+                       }
+                       attrs.append ("boxed = true");
+               }
+
+               if (st.has_type_id ()) {
+                       if (attrs.len > 1) {
+                               attrs.append (", ");
+                       }
+
+                       attrs.append ("type_id = \"");
+                       attrs.append (st.get_type_id ());
+                       attrs.append ("\"");
+               }
+
+               if (attrs.len > 1) {
+                       attrs.append (")");
+                       attrs_str = attrs.str;
+               } else {
+                       attrs_str = "";
+               }
+
                if (st.is_reference_type ()) {
                        write_indent ();
-                       write_string ("[ReferenceType]");
+                       write_string ("[ReferenceType%s]".printf (attrs_str));
                }
                
                write_indent ();
diff --git a/trunk/vala/vala/valastruct.vala b/trunk/vala/vala/valastruct.vala
index 3e57c6b..08e5dd5 100644
--- a/trunk/vala/vala/valastruct.vala
+++ b/trunk/vala/vala/valastruct.vala
@@ -37,9 +37,12 @@ public class Vala.Struct : DataType {
        private string const_cname;
        private string dup_function;
        private string free_function;
+       private Method ref_function;
+       private Method unref_function;
        private string type_id;
        private string lower_case_cprefix;
        private string lower_case_csuffix;
+       private bool boxed_type;
        private bool reference_type;
        private bool integer_type;
        private bool floating_type;
@@ -112,6 +115,20 @@ public class Vala.Struct : DataType {
                return_if_fail (m != null);
                
                methods.append (m);
+
+               var name = m.name;
+
+               if (null != name) {
+                       if ("ref" == name) {
+stderr.printf(
+       "struct %s, method %s, symbol: %s\n",
+       this.name, m.name, null != m.symbol ? m.symbol.name : "(none)");
+assert(null != m.symbol);      
+                               ref_function = m;
+                       } else if ("unref" == name) {
+                               unref_function = m;
+                       }
+               }
        }
        
        /**
@@ -197,6 +214,10 @@ public class Vala.Struct : DataType {
                return reference_type;
        }
        
+       public bool is_boxed_type () {
+               return boxed_type;
+       }
+       
        /**
         * Returns whether this is an integer type.
         *
@@ -233,6 +254,16 @@ public class Vala.Struct : DataType {
                reference_type = ref_type;
        }
        
+       /**
+        * Sets whether this data type is boxed.
+        *
+        * @param ref_type true if this data type is boxed
+        */
+       public void set_is_boxed_type (bool boxed) {
+               set_is_reference_type (true);
+               boxed_type = boxed;
+       }
+       
        private void process_ccode_attribute (Attribute! a) {
                if (a.has_argument ("cname")) {
                        set_cname (a.get_string ("cname"));
@@ -268,6 +299,12 @@ public class Vala.Struct : DataType {
        
        private void process_ref_type_attribute (Attribute! a) {
                reference_type = true;
+               if (a.has_argument ("boxed")) {
+                       set_is_boxed_type (a.get_bool ("boxed"));
+               }
+               if (a.has_argument ("type_id")) {
+                       set_type_id (a.get_string ("type_id"));
+               }
                if (a.has_argument ("dup_function")) {
                        set_dup_function (a.get_string ("dup_function"));
                }
@@ -308,14 +345,18 @@ public class Vala.Struct : DataType {
        }
 
        public override bool is_reference_counting () {
-               return false;
+               return (reference_type && null != ref_function && null != unref_function);
        }
        
        public override string get_dup_function () {
-               if (dup_function == null) {
-                       Report.error (source_reference, "The type `%s` doesn't contain a copy 
function".printf (symbol.get_full_name ()));
+               if (dup_function != null) {
+                       return dup_function;
                }
-               return dup_function;
+               if (is_boxed_type ()) {
+                       return "g_boxed_copy";
+               }
+
+               Report.error (source_reference, "The type `%s` doesn't contain a copy function".printf 
(symbol.get_full_name ()));
        }
        
        public void set_dup_function (string! name) {
@@ -323,19 +364,44 @@ public class Vala.Struct : DataType {
        }
        
        public override string get_free_function () {
-               if (free_function == null) {
-                       Report.error (source_reference, "The type `%s` doesn't contain a free 
function".printf (symbol.get_full_name ()));
+               if (free_function != null) {
+                       return free_function;
                }
-               return free_function;
+               if (is_boxed_type ()) {
+                       return "g_boxed_free";
+               }
+
+               Report.error (source_reference, "The type `%s` doesn't contain a free function".printf 
(symbol.get_full_name ()));
        }
        
        private void set_free_function (string! name) {
                this.free_function = name;
        }
        
+
+       public override string get_ref_function () {
+               if (null != ref_function)
+                       return ref_function.get_cname();
+
+               return null;
+       }
+
+       public override string get_unref_function () {
+               if (null != unref_function)
+                       return unref_function.get_cname();
+
+               return null;
+       }
+
+       public bool has_type_id () {
+               return (null != type_id);
+       }
+
        public override string get_type_id () {
                if (type_id == null) {
-                       if (is_reference_type ()) {
+                       if (is_boxed_type ()) {
+                               type_id = get_upper_case_cname ("TYPE_");
+                       } else if (is_reference_type ()) {
                                type_id = "G_TYPE_POINTER";
                        } else {
                                Report.error (source_reference, "The type `%s` doesn't declare a type 
id".printf (symbol.get_full_name ()));
diff --git a/trunk/vapigen/ChangeLog b/trunk/vapigen/ChangeLog
index 0e352e8..e6cfe66 100644
--- a/trunk/vapigen/ChangeLog
+++ b/trunk/vapigen/ChangeLog
@@ -1,3 +1,12 @@
+2007-03-26  Mathias Hasselmann  <mathias hasselmann gmx de>
+
+       * gobject-introspection/gidl.vala, gobject-introspection/gidlnode.c,
+         gobject-introspection/gidlnode.h, gobject-introspection/gidlparser.c:
+         do not drop the type-name attribute for struct nodes
+       * vapigen/valagidlparser.vala: support static classes, improve support
+         of boxed types, consider type_id parameter of ReferenceType attribute
+       * packages/pango/pango.metadata: use correct value_type annotations
+
 2007-03-24  Mathias Hasselmann  <mathias hasselmann gmx de>
 
        * gidlgen/gidlgen: Properly detect pkglibdir, remove Bash-isms
diff --git a/trunk/vapigen/gobject-introspection/gidl.vala b/trunk/vapigen/gobject-introspection/gidl.vala
index 2572b32..8b8018d 100644
--- a/trunk/vapigen/gobject-introspection/gidl.vala
+++ b/trunk/vapigen/gobject-introspection/gidl.vala
@@ -197,6 +197,8 @@ namespace GLib {
        [ReferenceType (free_function = "g_idl_node_free")]
        public struct IdlNodeStruct {
                public bool deprecated;
+
+               public string gtype_name;
                
                public List<IdlNode> members;
        }
diff --git a/trunk/vapigen/gobject-introspection/gidlnode.c b/trunk/vapigen/gobject-introspection/gidlnode.c
index bbde2a0..b5aab55 100644
--- a/trunk/vapigen/gobject-introspection/gidlnode.c
+++ b/trunk/vapigen/gobject-introspection/gidlnode.c
@@ -291,6 +291,7 @@ g_idl_node_free (GIdlNode *node)
        GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
 
        g_free (node->name);
+       g_free (struct_->gtype_name);
        for (l = struct_->members; l; l = l->next)
          g_idl_node_free ((GIdlNode *)l->data);
        g_list_free (struct_->members);
diff --git a/trunk/vapigen/gobject-introspection/gidlnode.h b/trunk/vapigen/gobject-introspection/gidlnode.h
index 7b6f156..8e5433b 100644
--- a/trunk/vapigen/gobject-introspection/gidlnode.h
+++ b/trunk/vapigen/gobject-introspection/gidlnode.h
@@ -273,6 +273,8 @@ struct _GIdlNodeStruct
 
   gboolean deprecated;
   
+  gchar *gtype_name;
+
   GList *members;
 };
 
diff --git a/trunk/vapigen/gobject-introspection/gidlparser.c 
b/trunk/vapigen/gobject-introspection/gidlparser.c
index b774bb9..c9f5a3f 100644
--- a/trunk/vapigen/gobject-introspection/gidlparser.c
+++ b/trunk/vapigen/gobject-introspection/gidlparser.c
@@ -1450,9 +1450,11 @@ start_struct (GMarkupParseContext *context,
     {
       const gchar *name;
       const gchar *deprecated;
+      const gchar *typename;
       
       name = find_attribute ("name", attribute_names, attribute_values);
       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
+      typename = find_attribute ("type-name", attribute_names, attribute_values);
       
       if (name == NULL)
        MISSING_ATTRIBUTE (error, element_name, "name");
@@ -1463,6 +1465,10 @@ start_struct (GMarkupParseContext *context,
          struct_ = (GIdlNodeStruct *) g_idl_node_new (G_IDL_NODE_STRUCT);
          
          ((GIdlNode *)struct_)->name = g_strdup (name);
+
+         if (typename)
+           struct_->gtype_name = g_strdup (typename);
+
          if (deprecated && strcmp (deprecated, "1") == 0)
            struct_->deprecated = TRUE;
          else
diff --git a/trunk/vapigen/packages/pango/pango.metadata b/trunk/vapigen/packages/pango/pango.metadata
index 9554466..974e1b4 100644
--- a/trunk/vapigen/packages/pango/pango.metadata
+++ b/trunk/vapigen/packages/pango/pango.metadata
@@ -1,6 +1,8 @@
 Pango cheader_filename="pango/pango.h"
 pango_attr_size_new_absolute hidden="1"
-PangoColor is_value_type="1"
-PangoMatrix is_value_type="1"
+PangoAnalysis is_value_type="1"
+PangoGlyphGeometry is_value_type="1"
+PangoGlyphInfo is_value_type="1"
+PangoGlyphVisAttr is_value_type="1"
+PangoLogAttr is_value_type="1"
 PangoRectangle is_value_type="1"
-
diff --git a/trunk/vapigen/vapigen/valagidlparser.vala b/trunk/vapigen/vapigen/valagidlparser.vala
index d4e7fbe..88961e3 100644
--- a/trunk/vapigen/vapigen/valagidlparser.vala
+++ b/trunk/vapigen/vapigen/valagidlparser.vala
@@ -114,14 +114,18 @@ public class Vala.GIdlParser : CodeVisitor {
                                if (st.name.has_prefix (module.name)) {
                                        st.name = st.name.offset (module.name.len ());
                                }
-                               ns.add_struct (st);
+
+                               if (st is Struct) {
+                                       ns.add_struct ((Struct)st);
+                               } else {
+                                       ns.add_class ((Class)st);
+                               }
                        } else if (node.type == IdlNodeTypeId.BOXED) {
                                var st = parse_boxed ((IdlNodeBoxed) node);
                                if (st.name.has_prefix (module.name)) {
                                        st.name = st.name.offset (module.name.len ());
                                }
                                ns.add_struct (st);
-                               st.set_type_id (st.get_upper_case_cname ("TYPE_"));
                        } else if (node.type == IdlNodeTypeId.ENUM) {
                                var en = parse_enum ((IdlNodeEnum) node);
                                if (en.name.has_prefix (module.name)) {
@@ -186,12 +190,49 @@ public class Vala.GIdlParser : CodeVisitor {
                return cb;
        }
        
-       private ref Struct parse_struct (IdlNodeStruct! st_node) {
+       private ref Class parse_static_struct (IdlNodeStruct! st_node) {
                weak IdlNode node = (IdlNode) st_node;
                
                if (st_node.deprecated) {
                        return null;
                }
+
+               var cl = new Class (node.name, current_source_reference);
+               cl.access = MemberAccessibility.PUBLIC;
+
+               cl.is_static = true;
+               
+               current_data_type = cl;
+               
+               foreach (IdlNode member in st_node.members) {
+                       if (member.type == IdlNodeTypeId.FUNCTION) {
+                               var m = parse_function ((IdlNodeFunction) member);
+                               if (m != null) {
+                                       cl.add_method (m);
+                               }
+                       } else if (member.type == IdlNodeTypeId.FIELD) {
+                               var f = parse_field ((IdlNodeField) member);
+                               if (f != null) {
+                                       cl.add_field (f);
+                               }
+                       }
+               }
+
+               current_data_type = null;
+               
+               return cl;
+       }
+       
+       private ref DataType parse_struct (IdlNodeStruct! st_node) {
+               weak IdlNode node = (IdlNode) st_node;
+               
+               if (st_node.deprecated) {
+                       return null;
+               }
+
+               if (null == st_node.gtype_name) {
+                       return parse_static_struct (st_node);
+               }
        
                var st = new Struct (node.name, current_source_reference);
                st.access = MemberAccessibility.PUBLIC;
@@ -204,6 +245,8 @@ public class Vala.GIdlParser : CodeVisitor {
                                var nv = attr.split ("=", 2);
                                if (nv[0] == "is_value_type" && eval (nv[1]) == "1") {
                                        st.set_is_reference_type (false);
+                               } else if (nv[0] == "type_id") {
+                                       st.set_type_id (eval (nv[1]));
                                }
                        }
                }
@@ -235,7 +278,7 @@ public class Vala.GIdlParser : CodeVisitor {
                var st = new Struct (node.name, current_source_reference);
                st.access = MemberAccessibility.PUBLIC;
 
-               st.set_is_reference_type (true);
+               st.set_is_boxed_type (true);
 
                var st_attributes = get_attributes (node.name);
                if (st_attributes != null) {
@@ -243,7 +286,10 @@ public class Vala.GIdlParser : CodeVisitor {
                                var nv = attr.split ("=", 2);
                                if (nv[0] == "is_value_type" && eval (nv[1]) == "1") {
                                        st.set_is_reference_type (false);
+                               } else if (nv[0] == "type_id") {
+                                       st.set_type_id (eval (nv[1]));
                                }
+
                        }
                }
                
-- 
1.4.4.2




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