summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2008-08-21 17:47:00 +0000
committerColin Walters <walters@src.gnome.org>2008-08-21 17:47:00 +0000
commitc56ea941193491e5eb33c3510b4cc7ebce5129b3 (patch)
treec97ac553d97ec358192b31cc9e01348e51ad182d /giscanner
parent384723fe482a65c7b7f6da8e8bc73f4ad06aa2e0 (diff)
downloadgobject-introspection-c56ea941193491e5eb33c3510b4cc7ebce5129b3.tar.gz
Look up all permutations of class names when scanning methods/ctors based
2008-08-21 Colin Walters <walters@verbum.org> * giscanner/glibtransformer.py: Look up all permutations of class names when scanning methods/ctors based on the prefix instead of using the return value. This associates gtk_window_new with the right class. svn path=/trunk/; revision=442
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/glibtransformer.py42
-rw-r--r--giscanner/utils.py18
2 files changed, 50 insertions, 10 deletions
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 007b0054..1b999240 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -28,7 +28,7 @@ from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
from .transformer import Names
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibSignal, type_names)
-from .utils import extract_libtool, to_underscores
+from .utils import extract_libtool, to_underscores, to_pascal_combinations
class Unresolved(object):
@@ -243,28 +243,50 @@ class GLibTransformer(object):
target_arg = func.parameters[0]
target_arg.type = self._resolve_param_type(target_arg.type)
- klass = self._get_attribute(target_arg.type.name)
- if klass is None or not isinstance(klass, (GLibObject, GLibBoxed,
- GLibInterface)):
- return None
+ # We look at all possible permutations of the symbol prefixes
+ # in Pascal case permutations. For example, let's say we
+ # see gtk_frob_bar_new. We look for classes named:
+ # Frob, FROB, FrobBar, FROBBar, FrobBAR, FROBBAR,
+ # FrobBarNew, FrobBarNEW, FrobBARNew, ...
+ symbol_components = func.symbol.split('_')
+ for i in range(len(symbol_components)):
+ subset = symbol_components[:i]
+ subsymbol = '_'.join(subset)
+ klass = None
+ possible_classnames = to_pascal_combinations(subsymbol)
+ for possible_classname in possible_classnames:
+ strip = self._transformer.strip_namespace_object
+ possible_classname = strip(possible_classname)
+ klass = self._get_attribute(possible_classname)
+ if (klass is not None and
+ isinstance(klass, (GLibObject, GLibBoxed,
+ GLibInterface))):
+ break
+ if klass is not None:
+ break
+
+ if klass is None:
+ return
- orig_type = target_arg.type.ctype.replace('*', '')
- prefix = to_underscores(orig_type).lower() + '_'
if not is_method:
- # Interfaces can't have constructors, punt to global scope
# Constructors must have _new
new_idx = func.symbol.find('_new')
- if (isinstance(klass, GLibInterface) or
- new_idx < 0):
+ if new_idx < 0:
+ return None
+ # Interfaces can't have constructors, punt to global scope
+ if isinstance(klass, GLibInterface):
return None
# Just strip everything before _new
prefix = func.symbol[:new_idx+1]
# TODO - check that the return type is a subclass of the
# class from the prefix
else:
+ # Methods require their first arg to be a known class
# Look at the original C type (before namespace stripping), without
# pointers: GtkButton -> gtk_button_, so we can figure out the
# method name
+ orig_type = target_arg.type.ctype.replace('*', '')
+ prefix = to_underscores(orig_type).lower() + '_'
if not func.symbol.startswith(prefix):
return None
diff --git a/giscanner/utils.py b/giscanner/utils.py
index a41d3d64..2a8ce3b8 100644
--- a/giscanner/utils.py
+++ b/giscanner/utils.py
@@ -36,6 +36,24 @@ def to_underscores(name):
name = _upperstr_pat3.sub(r'\1_\2', name, count=1)
return name
+
+def _gen_pascal_combinations(nameset):
+ firstname = [nameset[0].title(), nameset[0].upper()]
+ if len(nameset) == 1:
+ return firstname
+ else:
+ subset = _gen_pascal_combinations(nameset[1:])
+ results = []
+ for x in subset:
+ results.append(firstname[0] + x)
+ results.append(firstname[1] + x)
+ return results
+
+
+def to_pascal_combinations(name):
+ return _gen_pascal_combinations(name.split('_'))
+
+
_libtool_pat = re.compile("dlname='([A-z0-9\.\-\+]+)'\n")