gobject-introspection r226 - in trunk: . giscanner tests/parser



Author: johan
Date: Fri Apr 25 23:50:02 2008
New Revision: 226
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=226&view=rev

Log:
2008-04-25  Johan Dahlin  <jdahlin async com br>

    * TODO:
    * giscanner/gidlwriter.py:
    * giscanner/giscannermodule.c (pygi_source_directive_new),
    (directive_get_options), (pygi_source_symbol_new),
    (symbol_get_base_type), (pygi_source_type_new),
    (type_get_base_type), (type_get_child_list),
    (pygi_source_scanner_get_symbols),
    (pygi_source_scanner_get_directives):
    * giscanner/gobjecttreebuilder.py:
    * giscanner/sourcescanner.py:
    * giscanner/treebuilder.py:
    * tests/parser/foo-object.h:
    Add support for virtual methods.
    Pair struct FooClass with struct Foo.
    Clean up the SourceScanner bindings a bit.
    Add a testcase for virtual methods.



Modified:
   trunk/ChangeLog
   trunk/TODO
   trunk/giscanner/gidlwriter.py
   trunk/giscanner/giscannermodule.c
   trunk/giscanner/gobjecttreebuilder.py
   trunk/giscanner/sourcescanner.py
   trunk/giscanner/treebuilder.py
   trunk/tests/parser/Foo-expected.gidl
   trunk/tests/parser/foo-object.h

Modified: trunk/TODO
==============================================================================
--- trunk/TODO	(original)
+++ trunk/TODO	Fri Apr 25 23:50:02 2008
@@ -32,8 +32,6 @@
 
 Scanner
 ------
-- Virtual functions
-- Signals
 - Property.readable/writable, GLibProperty.blurb/nick
 - Constants
 - Annotations in external files

Modified: trunk/giscanner/gidlwriter.py
==============================================================================
--- trunk/giscanner/gidlwriter.py	(original)
+++ trunk/giscanner/gidlwriter.py	Fri Apr 25 23:50:02 2008
@@ -110,6 +110,8 @@
                 self._write_method(method)
             for prop in node.properties:
                 self._write_property(prop)
+            for field in node.fields:
+                self._write_field(field)
             for signal in node.signals:
                 self._write_signal(signal)
 
@@ -140,3 +142,12 @@
         with self.tagcontext('callback', attrs):
             self._write_return_type(func.retval)
             self._write_parameters(func.parameters)
+
+    def _write_field(self, field):
+        if isinstance(field, Callback):
+            self._write_callback(field)
+            return
+
+        attrs = [('name', field.name),
+                 ('type', str(field.type))]
+        self.write_tag('field', attrs)

Modified: trunk/giscanner/giscannermodule.c
==============================================================================
--- trunk/giscanner/giscannermodule.c	(original)
+++ trunk/giscanner/giscannermodule.c	Fri Apr 25 23:50:02 2008
@@ -62,6 +62,8 @@
   GISourceType *type;
 } PyGISourceType;
 
+static PyObject * pygi_source_type_new (GISourceType *type);
+
 typedef struct {
   PyObject_HEAD
   GISourceSymbol *symbol;
@@ -82,6 +84,23 @@
 /* Directive */
 
 static PyObject *
+pygi_source_directive_new (GISourceDirective *directive)
+{
+  PyGISourceDirective *self;
+
+  if (directive == NULL)
+    {
+      Py_INCREF (Py_None);
+      return Py_None;
+    }
+    
+  self = (PyGISourceDirective *)PyObject_New (PyGISourceDirective,
+					      &PyGISourceDirective_Type);
+  self->directive = directive;
+  return (PyObject*)self;
+}
+
+static PyObject *
 directive_get_name (PyGISourceDirective *self,
 		    void                *context)
 {
@@ -110,8 +129,8 @@
   
   for (l = self->directive->options; l; l = l->next)
     {
-      PyObject *item = PyString_FromString(l->data);
-      PyList_SetItem (list, i++, (PyObject*)item);
+      PyObject *item = PyString_FromString (l->data);
+      PyList_SetItem (list, i++, item);
       Py_INCREF (item);
     }
 
@@ -129,6 +148,23 @@
 /* Symbol */
 
 static PyObject *
+pygi_source_symbol_new (GISourceSymbol *symbol)
+{
+  PyGISourceSymbol *self;
+  
+  if (symbol == NULL)
+    {
+      Py_INCREF (Py_None);
+      return Py_None;
+    }
+    
+  self = (PyGISourceSymbol *)PyObject_New (PyGISourceSymbol,
+					   &PyGISourceSymbol_Type);
+  self->symbol = symbol;
+  return (PyObject*)self;
+}
+
+static PyObject *
 symbol_get_type (PyGISourceSymbol *self,
 		 void             *context)
 {
@@ -146,11 +182,7 @@
 symbol_get_base_type (PyGISourceSymbol *self,
 		      void             *context)
 {
-  PyGISourceType *item;
-  item = (PyGISourceType *)PyObject_New (PyGISourceType,
-					 &PyGISourceType_Type);
-  item->type = self->symbol->base_type;
-  return (PyObject*)item;
+  return pygi_source_type_new (self->symbol->base_type);
 }
 
 static PyObject *
@@ -211,6 +243,23 @@
 /* Type */
 
 static PyObject *
+pygi_source_type_new (GISourceType *type)
+{
+  PyGISourceType *self;
+  
+  if (type == NULL)
+    {
+      Py_INCREF (Py_None);
+      return Py_None;
+    }
+  
+  self = (PyGISourceType *)PyObject_New (PyGISourceType,
+					 &PyGISourceType_Type);
+  self->type = type;
+  return (PyObject*)self;
+}
+
+static PyObject *
 type_get_type (PyGISourceType *self,
 	       void           *context)
 {
@@ -255,11 +304,7 @@
 type_get_base_type (PyGISourceType *self,
 		    void           *context)
 {
-  PyGISourceType *item;
-  item = (PyGISourceType *)PyObject_New (PyGISourceType,
-					 &PyGISourceType_Type);
-  item->type = self->type->base_type;
-  return (PyObject*)item;
+  return pygi_source_type_new (self->type->base_type);
 }
 
 static PyObject *
@@ -277,11 +322,8 @@
   
   for (l = self->type->child_list; l; l = l->next)
     {
-      PyGISourceSymbol *item;
-      item = (PyGISourceSymbol *)PyObject_New (PyGISourceSymbol,
-					       &PyGISourceSymbol_Type);
-      item->symbol = l->data;
-      PyList_SetItem (list, i++, (PyObject*)item);
+      PyObject *item = pygi_source_symbol_new (l->data);
+      PyList_SetItem (list, i++, item);
       Py_INCREF (item);
     }
 
@@ -398,11 +440,8 @@
   
   for (l = symbols; l; l = l->next)
     {
-      PyGISourceSymbol *item;
-      item = (PyGISourceSymbol *)PyObject_New (PyGISourceSymbol,
-					       &PyGISourceSymbol_Type);
-      item->symbol = l->data;
-      PyList_SetItem (list, i++, (PyObject*)item);
+      PyObject *item = pygi_source_symbol_new (l->data);
+      PyList_SetItem (list, i++, item);
       Py_INCREF (item);
     }
 
@@ -427,11 +466,8 @@
   
   for (l = directives; l; l = l->next)
     {
-      PyGISourceDirective *item;
-      item = (PyGISourceDirective *)PyObject_New (PyGISourceDirective,
-						  &PyGISourceDirective_Type);
-      item->directive = l->data;
-      PyList_SetItem (list, i++, (PyObject*)item);
+      PyObject *item = pygi_source_directive_new (l->data);
+      PyList_SetItem (list, i++, item);
       Py_INCREF (item);
     }
 

Modified: trunk/giscanner/gobjecttreebuilder.py
==============================================================================
--- trunk/giscanner/gobjecttreebuilder.py	(original)
+++ trunk/giscanner/gobjecttreebuilder.py	Fri Apr 25 23:50:02 2008
@@ -111,6 +111,11 @@
         for node in nodes:
             self._parse_node(node)
 
+        # Second round, associate GtkButtonClass with GtkButton
+        for node in self._output_ns.values():
+            if isinstance(node, Struct):
+                self._pair_class_struct(node)
+
     def register_include(self, filename):
         from .gidlparser import GIDLParser
         parser = GIDLParser(filename)
@@ -267,15 +272,26 @@
         return True
 
     def _parse_struct(self, struct):
-        if (struct.name.startswith('_') or
-            struct.name.endswith('Iface') or
-            struct.name.endswith('Class')):
-            return
         self._add_attribute(struct)
 
     def _parse_callback(self, callback):
         self._add_attribute(callback)
 
+    def _pair_class_struct(self, class_node):
+        name = class_node.name
+        if (name.endswith('Class') or
+            name.endswith('Iface')):
+            name = name[:-5]
+        elif name.endswith('Interface'):
+            name = name[:-9]
+        else:
+            return
+
+        node = self._output_ns.get(self._resolve_type_name(name))
+        del self._output_ns[class_node.name]
+        for field in class_node.fields[1:]:
+            node.fields.append(field)
+
     def _introspect_type(self, type_id, symbol):
         fundamental_type_id = cgobject.type_fundamental(type_id)
         if (fundamental_type_id == cgobject.TYPE_ENUM or
@@ -327,7 +343,6 @@
         self._introspect_properties(node, type_id)
         self._introspect_signals(node, type_id)
         self._add_attribute(node)
-        self._remove_attribute(type_name)
         self._register_internal_type(type_name, node)
 
     def _introspect_boxed(self, type_id, symbol):
@@ -335,7 +350,6 @@
         node = GLibBoxed(self._strip_namespace_object(type_name),
                          type_name, symbol)
         self._add_attribute(node)
-        self._remove_attribute(type_name)
         self._register_internal_type(type_name, node)
 
     def _introspect_properties(self, node, type_id):

Modified: trunk/giscanner/sourcescanner.py
==============================================================================
--- trunk/giscanner/sourcescanner.py	(original)
+++ trunk/giscanner/sourcescanner.py	Fri Apr 25 23:50:02 2008
@@ -4,18 +4,48 @@
 import giscanner
 
 
+class SourceType(object):
+    def __init__(self, scanner, stype):
+        self._scanner = scanner
+        self._stype = stype
+
+    @property
+    def type(self):
+        return self._stype.type
+
+    @property
+    def base_type(self):
+        if self._stype.base_type is not None:
+            return SourceType(self._scanner, self._stype.base_type)
+
+    @property
+    def name(self):
+        return self._stype.name
+
+    @property
+    def child_list(self):
+        for symbol in self._stype.child_list:
+            if symbol is None:
+                continue
+            yield SourceSymbol(self._scanner, symbol)
+
+
 class SourceSymbol(object):
-    def __init__(self, symbol, directives):
+    def __init__(self, scanner, symbol):
+        self._scanner = scanner
         self._symbol = symbol
-        self._directives = directives
 
     def directives(self):
         mapping = {}
-        for directive in self._directives:
+        for directive in self._scanner.get_directives(self._symbol.ident):
             mapping[directive.name] = directive.options
         return mapping
 
     @property
+    def const_int(self):
+        return self._symbol.const_int
+
+    @property
     def ident(self):
         return self._symbol.ident
 
@@ -25,7 +55,8 @@
 
     @property
     def base_type(self):
-        return self._symbol.base_type
+        if self._symbol.base_type is not None:
+            return SourceType(self._scanner, self._symbol.base_type)
 
 
 class SourceScanner(object):
@@ -66,8 +97,7 @@
 
     def get_symbols(self):
         for symbol in self._scanner.get_symbols():
-            yield SourceSymbol(
-                symbol, self._scanner.get_directives(symbol.ident))
+            yield SourceSymbol(self._scanner, symbol)
 
     def dump(self):
         print '-'*30

Modified: trunk/giscanner/treebuilder.py
==============================================================================
--- trunk/giscanner/treebuilder.py	(original)
+++ trunk/giscanner/treebuilder.py	Fri Apr 25 23:50:02 2008
@@ -14,8 +14,13 @@
         self.symbol = symbol
 
     def __repr__(self):
-        return 'Function(%r, %r, %r)' % (self.name, self.retval,
-                                         self.parameters)
+        return '%s(%r, %r, %r)' % (self.__class__.__name__,
+                                   self.name, self.retval,
+                                   self.parameters)
+
+
+class VFunction(Function):
+    pass
 
 
 class Parameter(Node):
@@ -48,6 +53,10 @@
 
 
 class Struct(Node):
+    def __init__(self, name):
+        Node.__init__(self, name)
+        self.fields = []
+
     def __repr__(self):
         return 'Struct(%r)' % (self.name,)
 
@@ -69,6 +78,7 @@
         self.methods = []
         self.constructors = []
         self.properties = []
+        self.fields = []
 
     def __repr__(self):
         return '%s(%r, %r, %r)' % (
@@ -81,6 +91,7 @@
         Node.__init__(self, name)
         self.methods = []
         self.properties = []
+        self.fields = []
 
     def __repr__(self):
         return '%s(%r, %r)' % (
@@ -125,7 +136,8 @@
     def __init__(self, generator):
         self.generator = generator
         self.nodes = []
-
+        self._output_ns = {}
+        self._typedefs_ns = {}
         self._traverse()
 
     def get_nodes(self):
@@ -135,13 +147,14 @@
     def _traverse(self):
         for symbol in self.generator.get_symbols():
             node = self._traverse_one(symbol)
-            if node is not None:
-                self.nodes.append(node)
+            if node is None:
+                continue
+            if node.name.startswith('_'):
+                continue
+            self.nodes.append(node)
+            self._output_ns[node.name] = node
 
     def _traverse_one(self, symbol, stype=None):
-        # Skip private symbols
-        if symbol.ident.startswith('_'):
-            return
         if stype is None:
             stype = symbol.type
         if stype == giscanner.CSYMBOL_TYPE_FUNCTION:
@@ -149,9 +162,12 @@
         elif stype == giscanner.CSYMBOL_TYPE_TYPEDEF:
             if (symbol.base_type.type == giscanner.CTYPE_POINTER and
                 symbol.base_type.base_type.type == giscanner.CTYPE_FUNCTION):
-                return self._create_callback(symbol)
+                node = self._create_callback(symbol)
+            elif symbol.base_type.type == giscanner.CTYPE_STRUCT:
+                node = self._create_typedef_struct(symbol)
             else:
-                return self._traverse_one(symbol, symbol.base_type.type)
+                node = self._traverse_one(symbol, symbol.base_type.type)
+            return node
         elif stype == giscanner.CSYMBOL_TYPE_STRUCT:
             return self._create_struct(symbol)
         elif stype == giscanner.CSYMBOL_TYPE_ENUM:
@@ -175,6 +191,8 @@
         return Function(symbol.ident, return_, parameters, symbol.ident)
 
     def _create_source_type(self, source_type):
+        if source_type is None:
+            return 'None'
         if source_type.type == giscanner.CTYPE_VOID:
             value = 'void'
         elif source_type.type == giscanner.CTYPE_BASIC_TYPE:
@@ -222,8 +240,16 @@
                     option,)
         return return_
 
+    def _create_typedef_struct(self, symbol):
+        self._typedefs_ns[symbol.base_type.name] = symbol.ident
+
     def _create_struct(self, symbol):
-        return Struct(symbol.ident)
+        name = self._typedefs_ns.get(symbol.ident, symbol.ident)
+        struct = Struct(name)
+        for child in symbol.base_type.child_list:
+            struct.fields.append(self._traverse_one(child,
+                                                    child.base_type.type))
+        return struct
 
     def _create_callback(self, symbol):
         parameters = self._create_parameters(symbol.base_type.base_type)

Modified: trunk/tests/parser/Foo-expected.gidl
==============================================================================
--- trunk/tests/parser/Foo-expected.gidl	(original)
+++ trunk/tests/parser/Foo-expected.gidl	Fri Apr 25 23:50:02 2008
@@ -125,6 +125,13 @@
 					<parameter name="p1" type="gpointer"/>
 				</parameters>
 			</signal>
+			<vfunc name="virtual_method">
+				<return-type type="gboolean"/>
+				<parameters>
+					<parameter name="object" type="FooObject*"/>
+					<parameter name="first_param" type="int"/>
+				</parameters>
+			</vfunc>
 		</object>
 		<object name="FooSubobject" parent="FooObject" type-name="FooSubobject" get-type="foo_subobject_get_type">
 			<constructor name="new" symbol="foo_subobject_new">

Modified: trunk/tests/parser/foo-object.h
==============================================================================
--- trunk/tests/parser/foo-object.h	(original)
+++ trunk/tests/parser/foo-object.h	Fri Apr 25 23:50:02 2008
@@ -38,6 +38,8 @@
 struct _FooObjectClass
 {
   GObjectClass parent_class;
+
+  gboolean (* virtual_method) (FooObject *object, int first_param);
 };
 
 gint                  foo_init                     (void);



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