diff options
author | Colin Walters <walters@verbum.org> | 2008-08-21 17:47:00 +0000 |
---|---|---|
committer | Colin Walters <walters@src.gnome.org> | 2008-08-21 17:47:00 +0000 |
commit | c56ea941193491e5eb33c3510b4cc7ebce5129b3 (patch) | |
tree | c97ac553d97ec358192b31cc9e01348e51ad182d /giscanner | |
parent | 384723fe482a65c7b7f6da8e8bc73f4ad06aa2e0 (diff) | |
download | gobject-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.py | 42 | ||||
-rw-r--r-- | giscanner/utils.py | 18 |
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") |