gobject-introspection r404 - in trunk: . giscanner tests/scanner



Author: johan
Date: Tue Aug 19 21:55:26 2008
New Revision: 404
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=404&view=rev

Log:
2008-08-19  Johan Dahlin  <johan gnome org>

    * giscanner/ast.py:
    * giscanner/girwriter.py:
    * giscanner/glibtransformer.py:
    * giscanner/transformer.py:
    * tests/scanner/Foo-expected.gir:
    Add basic support for union, base the code much
    on Struct. Add a testcase.



Modified:
   trunk/ChangeLog
   trunk/giscanner/ast.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/glibtransformer.py
   trunk/giscanner/transformer.py
   trunk/tests/scanner/Foo-expected.gir

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Tue Aug 19 21:55:26 2008
@@ -306,3 +306,14 @@
 
     def __repr__(self):
         return 'Sequence(%r of %r)' % (self.name, self.element_type, )
+
+
+class Union(Node):
+
+    def __init__(self, name, symbol):
+        Node.__init__(self, name)
+        self.fields = []
+        self.symbol = symbol
+
+    def __repr__(self):
+        return 'Union(%r, %r)' % (self.name, self.fields, )

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Tue Aug 19 21:55:26 2008
@@ -21,7 +21,7 @@
 from __future__ import with_statement
 
 from .ast import (Callback, Class, Enum, Function, Interface, Member,
-                  Sequence, Struct, Alias)
+                  Sequence, Struct, Alias, Union)
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
                       GLibFlags, GLibObject, GLibInterface)
 from .xmlwriter import XMLWriter
@@ -62,6 +62,8 @@
             self._write_callback(node)
         elif isinstance(node, Struct):
             self._write_record(node)
+        elif isinstance(node, Union):
+            self._write_union(node)
         elif isinstance(node, Member):
             # FIXME: atk_misc_instance singleton
             pass
@@ -227,6 +229,16 @@
         else:
             self.write_tag('record', attrs)
 
+    def _write_union(self, union):
+        attrs = [('name', union.name),
+                 ('c:type', union.symbol)]
+        if union.fields:
+            with self.tagcontext('union', attrs):
+                for field in union.fields:
+                    self._write_field(field)
+        else:
+            self.write_tag('union', attrs)
+
     def _write_field(self, field):
         # FIXME: Just function
         if isinstance(field, (Callback, Function)):

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Tue Aug 19 21:55:26 2008
@@ -23,7 +23,7 @@
 from . import cgobject
 from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
                   Sequence, Property, Return, Struct, Type, Alias,
-                  type_name_from_ctype)
+                  Union, type_name_from_ctype)
 from .transformer import Names
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
                       GLibInterface, GLibObject, GLibSignal, type_names)
@@ -160,8 +160,10 @@
         elif isinstance(node, Member):
             # FIXME: atk_misc_instance singletons
             pass
+        elif isinstance(node, Union):
+            self._parse_union(node)
         else:
-            print 'GOBJECT BUILDER: Unhandled node:', node
+            print 'GLIB Transformer: Unhandled node:', node
 
     def _parse_alias(self, alias):
         self._names.aliases[alias.name] = (None, alias)
@@ -277,6 +279,14 @@
         (ns, node) = node
         node.fields = struct.fields[:]
 
+    def _parse_union(self, union):
+        node = self._names.names.get(union.name)
+        if node is None:
+            self._add_attribute(union, replace=True)
+            return
+        (ns, node) = node
+        node.fields = union.fields[:]
+
     def _parse_callback(self, callback):
         self._add_attribute(callback)
 
@@ -489,6 +499,8 @@
             self._resolve_glib_boxed(node)
         elif isinstance(node, Struct):
             self._resolve_struct(node)
+        elif isinstance(node, Union):
+            self._resolve_union(node)
         elif isinstance(node, Alias):
             self._resolve_alias(node)
 
@@ -496,6 +508,10 @@
         for field in node.fields:
             self._resolve_field(field)
 
+    def _resolve_union(self, node):
+        for field in node.fields:
+            self._resolve_field(field)
+
     def _resolve_parent(self, node):
         if not isinstance(node, (GLibInterface, GLibObject)):
             raise AssertionError

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Tue Aug 19 21:55:26 2008
@@ -20,7 +20,7 @@
 
 from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
                            Parameter, Return, Sequence, Struct, Field,
-                           Type, Alias, Interface, Class, Node,
+                           Type, Alias, Interface, Class, Node, Union,
                            type_name_from_ctype, type_names)
 from .glibast import GLibBoxed
 from giscanner.sourcescanner import (
@@ -149,8 +149,7 @@
         elif stype == CSYMBOL_TYPE_MEMBER:
             return self._create_member(symbol)
         elif stype == CSYMBOL_TYPE_UNION:
-            # Unions are not supported
-            pass
+            return self._create_union(symbol)
         else:
             raise NotImplementedError(
                 'Transformer: unhandled symbol: %r' % (symbol, ))
@@ -227,12 +226,13 @@
             node = self._create_callback(symbol)
         elif ctype == CTYPE_STRUCT:
             node = self._create_typedef_struct(symbol)
+        elif ctype == CTYPE_UNION:
+            node = self._create_typedef_union(symbol)
         elif ctype == CTYPE_ENUM:
             return self._create_enum(symbol)
         elif ctype in (CTYPE_TYPEDEF,
                        CTYPE_POINTER,
                        CTYPE_BASIC_TYPE,
-                       CTYPE_UNION,
                        CTYPE_VOID):
             if symbol.base_type.name:
                 name = self.strip_namespace_object(symbol.ident)
@@ -308,6 +308,13 @@
         self._typedefs_ns[symbol.ident] = struct
         return struct
 
+    def _create_typedef_union(self, symbol):
+        name = self._remove_prefix(symbol.ident)
+        name = self.strip_namespace_object(name)
+        union = Union(name, symbol.ident)
+        self._typedefs_ns[symbol.ident] = union
+        return union
+
     def _create_struct(self, symbol):
         struct = self._typedefs_ns.get(symbol.ident, None)
         if struct is None:
@@ -330,6 +337,28 @@
 
         return struct
 
+    def _create_union(self, symbol):
+        union = self._typedefs_ns.get(symbol.ident, None)
+        if union is None:
+            # This is a bit of a hack; really we should try
+            # to resolve through the typedefs to find the real
+            # name
+            if symbol.ident.startswith('_'):
+                name = symbol.ident[1:]
+            else:
+                name = symbol.ident
+            name = self._remove_prefix(name)
+            name = self.strip_namespace_object(name)
+            name = self.resolve_type_name(name)
+            union = Union(name, symbol.ident)
+
+        for child in symbol.base_type.child_list:
+            field = self._traverse_one(child)
+            if field:
+                union.fields.append(field)
+
+        return union
+
     def _create_callback(self, symbol):
         parameters = self._create_parameters(symbol.base_type.base_type)
         retval = self._create_return(symbol.base_type.base_type.base_type)

Modified: trunk/tests/scanner/Foo-expected.gir
==============================================================================
--- trunk/tests/scanner/Foo-expected.gir	(original)
+++ trunk/tests/scanner/Foo-expected.gir	Tue Aug 19 21:55:26 2008
@@ -4,7 +4,6 @@
             xmlns:glib="http://www.gtk.org/introspection/glib/1.0";>
   <namespace name="Foo">
     <alias name="List" target="GSList" c:type="FooList"/>
-    <alias name="Event" target="Event" c:type="FooEvent"/>
     <interface name="Interface"
                c:type="FooInterface"
                glib:type-name="FooInterface"
@@ -420,5 +419,16 @@
         <type name="int" c:type="gint"/>
       </field>
     </record>
+    <union name="Event" c:type="FooEvent">
+      <field name="type">
+        <type name="int" c:type="int"/>
+      </field>
+      <field name="any">
+        <type name="EventAny" c:type="FooEventAny"/>
+      </field>
+      <field name="expose">
+        <type name="EventExpose" c:type="FooEventExpose"/>
+      </field>
+    </union>
   </namespace>
 </repository>



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