diff options
author | Johan Dahlin <johan@gnome.org> | 2008-04-22 00:53:40 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-04-22 00:53:40 +0000 |
commit | 49e22e9a37b4ef7e37152fe3e0367e9ab2ff7383 (patch) | |
tree | a9d4682be54b6f2b0a4d3bbd35e32c75c688faca /giscanner | |
parent | 307f0f7f14e3ff189d3895ec5a350c1090aa2a46 (diff) | |
download | gobject-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.py | 35 | ||||
-rw-r--r-- | giscanner/gidlwriter.py | 14 | ||||
-rw-r--r-- | giscanner/gobjecttreebuilder.py | 66 |
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) |