Parse struct fields properly, improve debugging.
authorJohan Dahlin <johan@gnome.org>
Sat, 3 May 2008 14:36:47 +0000 (14:36 +0000)
committerJohan Dahlin <johan@src.gnome.org>
Sat, 3 May 2008 14:36:47 +0000 (14:36 +0000)
2008-05-03  Johan Dahlin  <johan@gnome.org>

        * giscanner/__init__.py:
        * giscanner/ast.py:
        * giscanner/girwriter.py:
        * giscanner/glibtransformer.py:
        * giscanner/transformer.py:
        Parse struct fields properly, improve debugging.

svn path=/trunk/; revision=261

ChangeLog
giscanner/__init__.py
giscanner/ast.py
giscanner/girwriter.py
giscanner/glibtransformer.py
giscanner/transformer.py
tests/parser/Foo-expected.gir

index ff93dea..8788018 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-05-03  Johan Dahlin  <johan@gnome.org>
+
+       * giscanner/__init__.py:
+       * giscanner/ast.py:
+       * giscanner/girwriter.py:
+       * giscanner/glibtransformer.py:
+       * giscanner/transformer.py:
+       Parse struct fields properly, improve debugging.
+
 2008-04-29  Johan Dahlin  <johan@gnome.org>
 
        * giscanner/ast.py:
index 74a7f4a..532d779 100644 (file)
@@ -14,7 +14,8 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
 #
 
 (CSYMBOL_TYPE_INVALID,
@@ -58,3 +59,16 @@ FUNCTION_INLINE = 1 << 1
  UNARY_MINUS,
  UNARY_BITWISE_COMPLEMENT,
  UNARY_LOGICAL_NEGATION) = range(6)
+
+def symbol_type_name(symbol_type):
+    return {
+        CSYMBOL_TYPE_INVALID: 'invalid',
+        CSYMBOL_TYPE_CONST: 'const',
+        CSYMBOL_TYPE_OBJECT: 'object',
+        CSYMBOL_TYPE_FUNCTION: 'function',
+        CSYMBOL_TYPE_STRUCT: 'struct',
+        CSYMBOL_TYPE_UNION: 'union',
+        CSYMBOL_TYPE_ENUM: 'enum',
+        CSYMBOL_TYPE_TYPEDEF: 'typedef'
+        }.get(symbol_type)
+
index 86f9aaf..9780548 100644 (file)
@@ -51,9 +51,9 @@ class Type(Node):
 
 
 class Parameter(Node):
-    def __init__(self, name, type_name):
+    def __init__(self, name, typenode):
         Node.__init__(self, name)
-        self.type = Type(type_name)
+        self.type = typenode
         self.direction = 'in'
         self.transfer = False
 
index c93dd62..911b76f 100644 (file)
@@ -210,7 +210,7 @@ class GIRWriter(XMLWriter):
             return
 
         attrs = [('name', field.name),
-                 ('type', str(field.type))]
+                 ('value', str(field.value))]
         self.write_tag('field', attrs)
 
     def _write_signal(self, signal):
index 3b24db6..cd3ac9b 100644 (file)
@@ -25,7 +25,7 @@ import os
 from . import cgobject
 from .odict import odict
 from .ast import (Callback, Enum, Function, Parameter, Property, Return,
-                  Sequence, Struct)
+                  Sequence, Struct, Type)
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
                       GLibInterface, GLibObject, GLibSignal)
 
@@ -54,8 +54,6 @@ def resolve_libtool(libname):
     return libname
 
 
-
-
 class GLibTransformer(object):
     def __init__(self, namespace_name):
         self._namespace_name = namespace_name
@@ -77,8 +75,9 @@ class GLibTransformer(object):
         for node in nodes:
             self._parse_node(node)
 
-        # Second round, associate GtkButtonClass with GtkButton
+        # Second round
         for node in self._output_ns.values():
+            # associate GtkButtonClass with GtkButton
             if isinstance(node, Struct):
                 self._pair_class_struct(node)
 
@@ -242,7 +241,12 @@ class GLibTransformer(object):
         return True
 
     def _parse_struct(self, struct):
-        self._add_attribute(struct)
+        type_name = self._resolve_type_name(struct.name)
+        node = self._output_ns.get(type_name)
+        if node is None:
+            self._add_attribute(struct, replace=True)
+            return
+        node.fields = struct.fields[:]
 
     def _parse_callback(self, callback):
         self._add_attribute(callback)
@@ -259,9 +263,15 @@ class GLibTransformer(object):
 
         node = self._output_ns.get(self._resolve_type_name(name))
         del self._output_ns[class_node.name]
+        if node is None:
+            return
         for field in class_node.fields[1:]:
             node.fields.append(field)
 
+    def _create_type(self, type_id):
+        type_name = cgobject.type_name(type_id)
+        return Type(type_name)
+
     def _introspect_type(self, type_id, symbol):
         fundamental_type_id = cgobject.type_fundamental(type_id)
         if (fundamental_type_id == cgobject.TYPE_ENUM or
@@ -348,6 +358,7 @@ class GLibTransformer(object):
                     name = 'object'
                 else:
                     name = 'p%s' % (i-1,)
-                signal.parameters.append(
-                    Parameter(name, cgobject.type_name(parameter)))
+                ptype = self._create_type(parameter)
+                param = Parameter(name, ptype)
+                signal.parameters.append(param)
             node.signals.append(signal)
index d3e7647..86e51c1 100644 (file)
 #
 
 import giscanner
+
 from giscanner.ast import (Callback, Enum, Function, Member, Parameter,
-                           Return, Sequence, Struct)
+                           Return, Sequence, Struct, Type)
+from giscanner.sourcescanner import SourceSymbol
 
 
 class Transformer(object):
@@ -60,6 +62,8 @@ class Transformer(object):
         return name
 
     def _traverse_one(self, symbol, stype=None):
+        assert isinstance(symbol, SourceSymbol), symbol
+
         if stype is None:
             stype = symbol.type
         if stype == giscanner.CSYMBOL_TYPE_FUNCTION:
@@ -81,11 +85,15 @@ class Transformer(object):
             return self._create_struct(symbol)
         elif stype == giscanner.CSYMBOL_TYPE_ENUM:
             return self._create_enum(symbol)
+        elif stype == giscanner.CSYMBOL_TYPE_OBJECT:
+            return self._create_object(symbol)
         elif stype == giscanner.CSYMBOL_TYPE_UNION:
             # Unions are not supported
             pass
         else:
-            print 'BUILDER: unhandled symbol', symbol.type
+            raise NotImplementedError(
+                'Transformer: unhandled symbol: %r of type %r'
+                % (symbol.ident, giscanner.symbol_type_name(stype)))
 
     def _create_enum(self, symbol):
         members = []
@@ -95,6 +103,9 @@ class Transformer(object):
 
         return Enum(symbol.ident, members)
 
+    def _create_object(self, symbol):
+        return Member(symbol.ident, symbol.base_type.name)
+
     def _create_function(self, symbol):
         directives = symbol.directives()
         parameters = list(self._create_parameters(symbol.base_type, directives))
@@ -126,9 +137,13 @@ class Transformer(object):
             yield self._create_parameter(
                 child, options.get(child.ident, []))
 
+    def _create_type(self, source_type):
+        type_name = self._create_source_type(source_type)
+        return Type(type_name)
+
     def _create_parameter(self, symbol, options):
-        param = Parameter(symbol.ident,
-                          self._create_source_type(symbol.base_type))
+        ptype = self._create_type(symbol.base_type)
+        param = Parameter(symbol.ident, ptype)
         for option in options:
             if option in ['in-out', 'inout']:
                 param.direction = 'inout'
@@ -176,7 +191,8 @@ class Transformer(object):
 
         for child in symbol.base_type.child_list:
             field = self._traverse_one(child, child.base_type.type)
-            struct.fields.append(field)
+            if field:
+                struct.fields.append(field)
         return struct
 
     def _create_callback(self, symbol):
index 6284a08..5bd7ad3 100644 (file)
       <property name="string">
         <type name="gchararray" c:type="gchararray"/>
       </property>
+      <callback name="virtual_method">
+        <return-value>
+          <type name="gboolean" c:type="gboolean"/>
+        </return-value>
+        <parameters>
+          <parameter name="object">
+            <type name="FooObject*" c:type="FooObject*"/>
+          </parameter>
+          <parameter name="first_param">
+            <type name="int" c:type="int"/>
+          </parameter>
+        </parameters>
+      </callback>
       <glib:signal name="signal">
         <return-value>
           <type name="gchararray" c:type="gchararray"/>
         </parameter>
       </parameters>
     </callback>
-    <record name="FooStruct" c:type="FooStruct"/>
+    <record name="FooStruct" c:type="FooStruct">
+      <field name="member" value="int"/>
+    </record>
     <record name="FooStructPrivate" c:type="FooStructPrivate"/>
   </namespace>
 </repository>