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



Author: walters
Date: Wed Aug 13 20:36:15 2008
New Revision: 357
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=357&view=rev

Log:
2008-08-13  Colin Walters  <walters verbum org>

	* giscanner/girparser.py: Parse more than just <class.
	* giscanner/glibtransformer.py: Put aliases in a separate
	data structure since their name is not canonicall.
	* giscanner/transformer.py: Handle resolving type names
	from includes.




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

Modified: trunk/giscanner/girparser.py
==============================================================================
--- trunk/giscanner/girparser.py	(original)
+++ trunk/giscanner/girparser.py	Wed Aug 13 20:36:15 2008
@@ -18,12 +18,20 @@
 # 02110-1301, USA.
 #
 
+import os
+import sys
+
 from xml.etree.cElementTree import parse
 
-from .glibast import GLibObject
+from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
+                  Property, Return, Sequence, Struct, Field, Type, Alias,
+                  type_name_from_ctype)
+from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
+                      GLibInterface, GLibObject, GLibSignal)
 
 CORE_NS = "http://www.gtk.org/introspection/core/1.0";
 GLIB_NS = "http://www.gtk.org/introspection/glib/1.0";
+C_NS = "http://www.gtk.org/introspection/c/1.0";
 
 
 def _corens(tag):
@@ -33,6 +41,8 @@
 def _glibns(tag):
     return '{%s}%s' % (GLIB_NS, tag)
 
+def _cns(tag):
+    return '{%s}%s' % (C_NS, tag)
 
 class GIRParser(object):
 
@@ -43,35 +53,75 @@
         tree = parse(filename)
         self._parse_api(tree.getroot())
 
+
+    def _add_node(self, node):
+        self._nodes.append(node)
+
+
     def _parse_api(self, root):
         assert root.tag == _corens('repository')
         ns = root.find(_corens('namespace'))
         assert ns is not None
         self._namespace_name = ns.attrib['name']
         for child in ns.getchildren():
+            if child.tag in (_corens('callback'), ):
+                self._add_node(self._parse_function(child, Callback))
+            if child.tag in (_corens('function'), ):
+                self._add_node(self._parse_function(child, Function))
             if child.tag == _corens('class'):
-                self._parse_object(child)
-            elif child.tag in [_corens('callback'),
-                               _corens('function'),
-                               _corens('record'),
-                               _corens('enumeration'),
-                               _corens('bitfield'),
-                               _corens('interface'),
-                               _glibns('boxed'),
-                               ]:
-                continue
-            else:
-                print 'PARSER: Unhandled %s' % (child.tag, )
-
-    def _parse_object(self, node):
-        gobj = GLibObject(node.attrib['name'],
-                          node.attrib.get('parent'),
-                          node.attrib[_glibns('type-name')],
-                          node.attrib[_glibns('get-type')])
-        self._nodes.append(gobj)
+                c = GLibObject(child.attrib['name'],
+                               child.attrib.get('parent'),
+                               child.attrib[_glibns('type-name')],
+                               child.attrib[_glibns('get-type')])
+                self._parse_functions_props(child, c)
+                self._add_node(c)
+            if child.tag == _corens('interface'):
+                c = GLibInterface(child.attrib['name'], child.attrib[_glibns('type-name')], child.attrib[_glibns('get-type')])
+                self._parse_functions_props(child, c)
+                self._add_node(c)
+            if child.tag in [_corens('record'), _corens('interface'),
+                             _glibns('boxed'),
+                             _corens('enumeration'),
+                             _corens('bitfield'),
+                             ]:
+                pass
+
+    def _parse_functions_props(self, child, obj):
+        for meth in child.findall(_corens('method')):
+            obj.methods.append(_parse_function(meth, Function))
+        for ctor in child.findall(_corens('constructor')):
+            obj.constructors.append(_parse_function(meth, Function))
+        for cb in child.findall(_corens('callback')):
+            obj.fields.append(_parse_function(meth, Callback))
+
+
+    def _parse_function(self, child, klass):
+        retval = Return(self._parse_type(child.find(_corens('return-value'))))
+        params = []
+        for paramnode in child.findall('parameter'):
+            paramtype = self._parse_type(paramnode)
+            params.append(Parameter(paramnode.attrib['name'], paramtype))
+        try:
+            ident = child.attrib[_cns('identifier')]
+        except KeyError, e:
+            ident = None
+        args = [child.attrib['name'], retval, params]
+        if ident:
+            args.append(ident)
+        return klass(*args)
+
+
+    def _parse_type(self, node):
+        typenode = node.find(_corens('type'))
+        if node is None:
+            raise ValueError("failed to find type")
+        return Type(typenode.attrib['name'], typenode.attrib[_cns('type')])
+
 
     def get_namespace_name(self):
         return self._namespace_name
 
+
     def get_nodes(self):
         return self._nodes
+

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Wed Aug 13 20:36:15 2008
@@ -37,6 +37,7 @@
     def __init__(self, transformer):
         self._transformer = transformer
         self._namespace_name = None
+        self._aliases = []
         self._output_ns = odict()
         self._libraries = []
         self._type_names = {}
@@ -64,7 +65,7 @@
             self._resolve_node(node)
 
         namespace = Namespace(namespace.name)
-        namespace.nodes = self._output_ns.values()
+        namespace.nodes = self._aliases + self._output_ns.values()
         return namespace
 
     # Private
@@ -145,7 +146,7 @@
                     self._resolve_function(field)
 
     def _parse_alias(self, alias):
-        self._add_attribute(alias)
+        self._aliases.append(alias)
 
     def _parse_enum(self, enum):
         self._add_attribute(enum)

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Wed Aug 13 20:36:15 2008
@@ -24,6 +24,8 @@
 from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
                            Parameter, Return, Sequence, Struct, Field,
                            Type, Alias, type_name_from_ctype)
+from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
+                      GLibInterface, GLibObject, GLibSignal)
 from giscanner.sourcescanner import (
     SourceSymbol, ctype_name, symbol_type_name, CTYPE_POINTER,
     CTYPE_BASIC_TYPE, CTYPE_UNION, CTYPE_ARRAY,
@@ -41,6 +43,7 @@
         self._namespace = Namespace(namespace_name)
         self._output_ns = {}
         self._type_names = {}
+        self._ctype_names = {}
         self._typedefs_ns = {}
         self._strip_prefix = ''
         self._typedefs = {}
@@ -77,7 +80,13 @@
             raise NotImplementedError(filename)
         nsname = parser.get_namespace_name()
         for node in parser.get_nodes():
-            self._type_names[node.type_name] = (nsname, node)
+            if hasattr(node, 'ctype'):
+                self._ctype_names[node.ctype] = (nsname, node)
+            if isinstance(node, GLibBoxed) or isinstance(node, GLibInterface) \
+                    or isinstance(node, GLibObject):
+                self._type_names[node.type_name] = (nsname, node)
+            else:
+                self._type_names[node.name] = (nsname, node)
 
     def strip_namespace_object(self, name):
         orig_name = name
@@ -207,7 +216,9 @@
                        CTYPE_BASIC_TYPE,
                        CTYPE_UNION,
                        CTYPE_VOID):
-            return Alias(symbol.ident, symbol.base_type.name)
+            if symbol.base_type.name:
+                return Alias(symbol.ident, symbol.base_type.name)
+            return None
         else:
             raise NotImplementedError(
                 "symbol %r of type %s" % (symbol.ident, ctype_name(ctype)))
@@ -291,16 +302,27 @@
             return Sequence(self._parse_type_annotation(annotation[1:-1]))
         return annotation
 
+    def _typepair_to_str(self, item):
+        nsname, item = item
+        if nsname is None:
+            return item.name
+        return '%s.%s' % (nsname, item.name)
+
     def _resolve_type_name(self, type_name):
-        item = self._type_names.get(type_name)
-        if item is not None:
-            nsname, item = item
-            if nsname is None:
-                return item.name
-            return '%s.%s' % (nsname, item.name)
+        resolved = self._type_names.get(type_name)
+        if resolved:
+            return self._typepair_to_str(resolved)
         return type_name
 
     def _resolve_param_type(self, ptype):
         type_name = ptype.name
-        ptype.name = self._resolve_type_name(type_name)
+        resolved = self._type_names.get(type_name)
+        if resolved:
+            ptype.name = self._typepair_to_str(resolved)
+            return ptype
+        if hasattr(ptype, 'ctype'):
+            ctype = ptype.ctype
+            resolved = self._ctype_names.get(ctype)
+            if resolved:
+                ptype.name = self._typepair_to_str(resolved)
         return ptype

Modified: trunk/tests/scanner/Foo-expected.gir
==============================================================================
--- trunk/tests/scanner/Foo-expected.gir	(original)
+++ trunk/tests/scanner/Foo-expected.gir	Wed Aug 13 20:36:15 2008
@@ -3,6 +3,7 @@
             xmlns:c="http://www.gtk.org/introspection/c/1.0";
             xmlns:glib="http://www.gtk.org/introspection/glib/1.0";>
   <namespace name="Foo">
+    <alias name="FooList" target="GSList"/>
     <interface name="Interface"
                c:type="FooInterface"
                glib:type-name="FooInterface"
@@ -243,7 +244,6 @@
         </parameters>
       </glib:signal>
     </class>
-    <alias name="FooList" target="GSList"/>
     <class name="Subobject"
            c:type="FooSubobject"
            parent="Object"



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