gobject-introspection r442 - in trunk: . giscanner



Author: walters
Date: Thu Aug 21 17:47:00 2008
New Revision: 442
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=442&view=rev

Log:
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.


Modified:
   trunk/ChangeLog
   trunk/giscanner/glibtransformer.py
   trunk/giscanner/utils.py

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Thu Aug 21 17:47:00 2008
@@ -28,7 +28,7 @@
 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 @@
             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
 

Modified: trunk/giscanner/utils.py
==============================================================================
--- trunk/giscanner/utils.py	(original)
+++ trunk/giscanner/utils.py	Thu Aug 21 17:47:00 2008
@@ -36,6 +36,24 @@
     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")
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]