[gobject-introspection/wip/transformer] A few bugfixes
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection/wip/transformer] A few bugfixes
- Date: Wed, 28 Jul 2010 21:41:20 +0000 (UTC)
commit a379bc54117dd637cfe762400e350dbe1345a715
Author: Colin Walters <walters verbum org>
Date: Wed Jul 28 16:51:39 2010 -0400
A few bugfixes
* Walk through multiple matching namespaces when trying type
resolution; we need to handle GLib, GObject, Gio which all
have a G prefix.
* Handle traversing to None for parent
* Handle unresolved types better when traversing introspectability
giscanner/finaltransformer.py | 22 ++++++++++++++++------
giscanner/primarytransformer.py | 8 ++++++--
giscanner/transformer.py | 16 +++++++++++-----
3 files changed, 33 insertions(+), 13 deletions(-)
---
diff --git a/giscanner/finaltransformer.py b/giscanner/finaltransformer.py
index cf19b55..07db3ba 100644
--- a/giscanner/finaltransformer.py
+++ b/giscanner/finaltransformer.py
@@ -82,6 +82,14 @@ class FinalTransformer(object):
self._parameter_warning(parent, node, "Missing (transfer) annotation")
parent.introspectable = False
+ def _type_is_introspectable(self, typeval, warn=False):
+ if not typeval.resolved:
+ return False
+ target = self._transformer.lookup_typenode(typeval)
+ if not target:
+ return False
+ return target.introspectable
+
def _analyze_node(self, obj, stack):
if obj.skip:
return False
@@ -92,6 +100,11 @@ class FinalTransformer(object):
for param in obj.parameters:
self._introspectable_param_analysis(obj, param)
self._introspectable_param_analysis(obj, obj.retval)
+ if isinstance(obj, (Class, Interface, Record, Union)):
+ for field in obj.fields:
+ if field.type:
+ if not self._type_is_introspectable(field.type):
+ field.introspectable = False
return True
def _introspectable_callable_analysis(self, obj, stack):
@@ -100,12 +113,10 @@ class FinalTransformer(object):
# Propagate introspectability of parameters to entire functions
if isinstance(obj, Callable):
for param in obj.parameters:
- target = self._transformer.lookup_typenode(param.type)
- if target and not target.introspectable:
+ if not self._type_is_introspectable(param.type):
obj.introspectable = False
return True
- target = self._transformer.lookup_typenode(obj.retval.type)
- if target and not target.introspectable:
+ if not self._type_is_introspectable(obj.retval.type):
obj.introspectable = False
return True
@@ -119,7 +130,6 @@ class FinalTransformer(object):
if not field.anonymous_node.introspectable:
field.introspectable = False
else:
- target = self._transformer.lookup_typenode(field.type)
- if target and not target.introspectable:
+ if not self._type_is_introspectable(field.type):
field.introspectable = False
return True
diff --git a/giscanner/primarytransformer.py b/giscanner/primarytransformer.py
index 71799b9..86d0d44 100644
--- a/giscanner/primarytransformer.py
+++ b/giscanner/primarytransformer.py
@@ -566,7 +566,8 @@ class PrimaryTransformer(object):
short = node.symbol[:-len('_quark')]
if short == "g_io_error":
# Special case; GIOError was already taken forcing GIOErrorEnum
- enum = self._names.type_names["GIOErrorEnum"][1]
+ assert self._namespace.name == 'Gio'
+ enum = self._namespace.get('IOErrorEnum')
else:
enum = self._uscore_type_names.get(short)
if enum is None:
@@ -667,7 +668,10 @@ method or constructor of some type."""
while parent:
if parent == target:
break
- parent = self._transformer.lookup_typenode(parent.parent)
+ if parent.parent:
+ parent = self._transformer.lookup_typenode(parent.parent)
+ else:
+ parent = None
if parent is None:
self._transformer.log_node_warning(func,
"Return value is not superclass for constructor; symbol=%r constructed=%r return=%r" % (func.symbol, str(origin_node.create_type()), str(func.retval.type)))
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index a79ed3a..4322bda 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -236,16 +236,17 @@ currently-scanned namespace is first."""
for ns in self._includes.itervalues():
yield ns
- def split_ctype(self, ident):
+ def split_ctype_namespaces(self, ident):
"""Given a StudlyCaps string identifier like FooBar, return a
-pair of (namespace, stripped_identifier) or raise ValueError."""
+list of (namespace, stripped_identifier) sorted by namespace length,
+or raise ValueError."""
matches = []
for ns in self._iter_namespaces():
if ns.contains_ident(ident):
matches.append((ns, ident[len(ns.c_prefix):]))
if matches:
matches.sort(lambda x,y : cmp(len(x[0].c_prefix), len(y[0].c_prefix)))
- return matches[0]
+ return matches
raise ValueError("Unknown namespace for identifier %r" % (ident, ))
def split_csymbol(self, symbol):
@@ -663,10 +664,15 @@ pair of (namespace, stripped_identifier) or raise ValueError."""
elif not typeval.resolved and typeval.ctype:
pointer_stripped = typeval.ctype.replace('*', '')
try:
- (ns, name) = self.split_ctype(pointer_stripped)
+ matches = self.split_ctype_namespaces(pointer_stripped)
except ValueError, e:
raise TypeResolutionException(e)
- typeval.target_giname = '%s.%s' % (ns.name, name)
+ target_giname=None
+ for namespace,name in matches:
+ target = namespace.get(name)
+ if target:
+ typeval.target_giname='%s.%s' % (namespace.name, target.name)
+ return
def _typepair_to_str(self, item):
nsname, item = item
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]