summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2008-04-22 00:53:40 +0000
committerJohan Dahlin <johan@src.gnome.org>2008-04-22 00:53:40 +0000
commit49e22e9a37b4ef7e37152fe3e0367e9ab2ff7383 (patch)
treea9d4682be54b6f2b0a4d3bbd35e32c75c688faca /giscanner
parent307f0f7f14e3ff189d3895ec5a350c1090aa2a46 (diff)
downloadgobject-introspection-49e22e9a37b4ef7e37152fe3e0367e9ab2ff7383.tar.gz
Add a --include argument to include types from other idls. Add a
2008-04-21 Johan Dahlin <johan@gnome.org> * giscanner/gidlparser.py: * giscanner/gidlwriter.py: * giscanner/gobjecttreebuilder.py: * tools/g-ir-scanner: Add a --include argument to include types from other idls. Add a minimalistic GIDL parser (just objects for now) Implement resolving of external type references and use it to resolve parent types, argument types and return types. svn path=/trunk/; revision=206
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/gidlparser.py35
-rw-r--r--giscanner/gidlwriter.py14
-rw-r--r--giscanner/gobjecttreebuilder.py66
3 files changed, 99 insertions, 16 deletions
diff --git a/giscanner/gidlparser.py b/giscanner/gidlparser.py
new file mode 100644
index 00000000..77a2f299
--- /dev/null
+++ b/giscanner/gidlparser.py
@@ -0,0 +1,35 @@
+from xml.etree.ElementTree import parse
+
+from .gobjecttreebuilder import GLibObject
+
+
+class GIDLParser(object):
+ def __init__(self, filename):
+ self._nodes = []
+ self._namespace_name = None
+
+ tree = parse(filename)
+ self._parse_api(tree.getroot())
+
+ def _parse_api(self, root):
+ assert root.tag == 'api'
+ ns = root.find('namespace')
+ self._namespace_name = ns.attrib['name']
+ for child in ns.getchildren():
+ if child.tag == 'object':
+ self._parse_object(child)
+ else:
+ print 'PARSER: Unhandled %s' % (child.tag,)
+
+ def _parse_object(self, node):
+ gobj = GLibObject(node.attrib['name'],
+ node.attrib.get('parent'),
+ node.attrib['type-name'],
+ node.attrib['get-type'])
+ self._nodes.append(gobj)
+
+ def get_namespace_name(self):
+ return self._namespace_name
+
+ def get_nodes(self):
+ return self._nodes
diff --git a/giscanner/gidlwriter.py b/giscanner/gidlwriter.py
index 3ef34978..8d637d9c 100644
--- a/giscanner/gidlwriter.py
+++ b/giscanner/gidlwriter.py
@@ -65,7 +65,8 @@ class GIDLWriter(XMLWriter):
attrs = [('name', enum.name)]
tag_name = 'enum'
if isinstance(enum, GLibEnum):
- attrs.append(('get-type', enum.get_type))
+ attrs.extend([('type-name', enum.type_name),
+ ('get-type', enum.get_type)])
if isinstance(enum, GLibFlags):
tag_name = 'flags'
@@ -84,10 +85,12 @@ class GIDLWriter(XMLWriter):
attrs = [('name', node.name)]
if isinstance(node, Class):
tag_name = 'object'
- attrs.append(('parent', node.parent))
+ if node.parent is not None:
+ attrs.append(('parent', node.parent))
else:
tag_name = 'interface'
if isinstance(node, (GLibObject, GLibInterface)):
+ attrs.append(('type-name', node.type_name))
attrs.append(('get-type', node.get_type))
with self.tagcontext(tag_name, attrs):
if isinstance(node, Class):
@@ -99,9 +102,10 @@ class GIDLWriter(XMLWriter):
self._write_property(prop)
def _write_boxed(self, boxed):
- attrs = [('name', boxed.name)]
- if isinstance(boxed, GLibBoxed):
- attrs.append(('get-type', boxed.get_type))
+ attrs = [('name', boxed.name),
+ ('type-name', boxed.type_name),
+ ('get-type', boxed.get_type)]
+
with self.tagcontext('boxed', attrs):
for method in boxed.constructors:
self._write_constructor(method)
diff --git a/giscanner/gobjecttreebuilder.py b/giscanner/gobjecttreebuilder.py
index 188f1607..7b8004a2 100644
--- a/giscanner/gobjecttreebuilder.py
+++ b/giscanner/gobjecttreebuilder.py
@@ -3,10 +3,9 @@ import re
import os
from . import cgobject
+from .odict import odict
from .treebuilder import (Class, Enum, Function, Interface, Member, Property,
Struct)
-from .odict import odict
-
# Copied from h2defs.py
_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
@@ -33,8 +32,9 @@ def resolve_libtool(libname):
class GLibEnum(Enum):
- def __init__(self, name, members, get_type):
+ def __init__(self, name, members, type_name, get_type):
Enum.__init__(self, name, members)
+ self.type_name = type_name
self.get_type = get_type
def __repr__(self):
@@ -56,22 +56,25 @@ class GLibEnumMember(Member):
class GLibObject(Class):
- def __init__(self, name, parent, get_type):
+ def __init__(self, name, parent, type_name, get_type):
Class.__init__(self, name, parent)
+ self.type_name = type_name
self.get_type = get_type
class GLibBoxed(Struct):
- def __init__(self, name, get_type):
+ def __init__(self, name, type_name, get_type):
Struct.__init__(self, name)
self.constructors = []
self.methods = []
+ self.type_name = type_name
self.get_type = get_type
class GLibInterface(Interface):
- def __init__(self, name, get_type):
+ def __init__(self, name, type_name, get_type):
Interface.__init__(self, name)
+ self.type_name = type_name
self.get_type = get_type
@@ -84,6 +87,7 @@ class GObjectTreeBuilder(object):
self._namespace_name = namespace_name
self._output_ns = odict()
self._library = None
+ self._type_names = {}
# Public API
@@ -99,6 +103,13 @@ class GObjectTreeBuilder(object):
for node in nodes:
self._parse_node(node)
+ def register_include(self, filename):
+ from .gidlparser import GIDLParser
+ parser = GIDLParser(filename)
+ nsname = parser.get_namespace_name()
+ for node in parser.get_nodes():
+ self._type_names[node.type_name] = (nsname, node)
+
# Private
def _add_attribute(self, node, replace=False):
@@ -113,6 +124,9 @@ class GObjectTreeBuilder(object):
def _get_attribute(self, name):
return self._output_ns.get(name)
+ def _register_internal_type(self, type_name, node):
+ self._type_names[type_name] = (None, node)
+
def _strip_namespace(self, node):
prefix = self._namespace_name.lower()
if isinstance(node, Function):
@@ -131,6 +145,22 @@ class GObjectTreeBuilder(object):
old = node.name
node.name = node.name[len(prefix):]
+ 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)
+ return type_name
+
+ def _resolve_param_type(self, ptype):
+ type_name = ptype.replace('*', '')
+ resolved_type_name = self._resolve_type_name(type_name)
+ if type_name != resolved_type_name:
+ return ptype.replace(type_name, resolved_type_name)
+ return ptype
+
def _parse_node(self, node):
if isinstance(node, Enum):
self._parse_enum(node)
@@ -153,9 +183,16 @@ class GObjectTreeBuilder(object):
elif self._parse_method(func):
return
+ self._parse_parameters(func.parameters)
+ func.retval.type = self._resolve_param_type(func.retval.type)
+
self._strip_namespace(func)
self._add_attribute(func)
+ def _parse_parameters(self, parameters):
+ for parameter in parameters:
+ parameter.type = self._resolve_param_type(parameter.type)
+
def _parse_get_type_function(self, func):
# GType *_get_type(void)
symbol = func.name
@@ -217,6 +254,8 @@ class GObjectTreeBuilder(object):
class_.methods.append(func)
else:
class_.constructors.append(func)
+ self._parse_parameters(func.parameters)
+ func.retval.type = self._resolve_param_type(func.retval.type)
return True
def _parse_struct(self, struct):
@@ -253,33 +292,38 @@ class GObjectTreeBuilder(object):
klass = (GLibFlags if ftype_id == cgobject.TYPE_FLAGS else GLibEnum)
type_name = cgobject.type_name(type_id)
- cenum = klass(type_name, members, symbol)
+ cenum = klass(type_name, members, type_name, symbol)
self._strip_namespace(cenum)
self._add_attribute(cenum, replace=True)
+ self._register_internal_type(type_name, cenum)
def _introspect_object(self, type_id, symbol):
type_name = cgobject.type_name(type_id)
- parent_name = cgobject.type_name(cgobject.type_parent(type_id))
- node = GLibObject(type_name, parent_name, symbol)
+ parent_type_name = cgobject.type_name(cgobject.type_parent(type_id))
+ parent_name = self._resolve_type_name(parent_type_name)
+ node = GLibObject(type_name, parent_name, type_name, symbol)
self._introspect_properties(node, type_id)
self._strip_namespace(node)
self._add_attribute(node)
self._remove_attribute(type_name)
+ self._register_internal_type(type_name, node)
def _introspect_interface(self, type_id, symbol):
type_name = cgobject.type_name(type_id)
- node = GLibInterface(type_name, symbol)
+ node = GLibInterface(type_name, type_name, symbol)
self._strip_namespace(node)
self._introspect_properties(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):
type_name = cgobject.type_name(type_id)
- node = GLibBoxed(type_name, symbol)
+ node = GLibBoxed(type_name, type_name, symbol)
self._strip_namespace(node)
self._add_attribute(node)
self._remove_attribute(type_name)
+ self._register_internal_type(type_name, node)
def _introspect_properties(self, node, type_id):
fundamental_type_id = cgobject.type_fundamental(type_id)