[gobject-introspection] Add (method) overrides



commit 09bca85dd42deb4d6901ac9926a23f89264b63b6
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date:   Fri Jan 21 18:07:45 2011 +0100

    Add (method) overrides
    
    So methods such as gtk_drag_dest_set() can be put inside Gtk.Widget
    
    https://bugzilla.gnome.org/show_bug.cgi?id=639945

 giscanner/annotationparser.py          |    6 +++-
 giscanner/maintransformer.py           |   46 +++++++++++++++++++++++---------
 tests/scanner/Regress-1.0-expected.gir |    5 +++
 tests/scanner/regress.c                |   10 +++++++
 tests/scanner/regress.h                |    1 +
 5 files changed, 54 insertions(+), 14 deletions(-)
---
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index f267d84..2a22ece 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -55,6 +55,7 @@ OPT_TRANSFER = 'transfer'
 OPT_TYPE = 'type'
 OPT_SKIP = 'skip'
 OPT_CONSTRUCTOR = 'constructor'
+OPT_METHOD = 'method'
 
 ALL_OPTIONS = [
     OPT_ALLOW_NONE,
@@ -72,7 +73,8 @@ ALL_OPTIONS = [
     OPT_TRANSFER,
     OPT_TYPE,
     OPT_SKIP,
-    OPT_CONSTRUCTOR]
+    OPT_CONSTRUCTOR,
+    OPT_METHOD]
 
 # Array options - array specific annotations
 OPT_ARRAY_FIXED_SIZE = 'fixed-size'
@@ -333,6 +335,8 @@ class DocTag(object):
                                       n_params=1)
             elif option == OPT_CONSTRUCTOR:
                 self._validate_option('constructor', value, n_params=0)
+            elif option == OPT_METHOD:
+                self._validate_option('method', value, n_params=0)
             else:
                 message.warn('invalid annotation option: %s' % (option, ),
                              self.position)
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 1fcf5e8..ea1b170 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -32,7 +32,7 @@ from .annotationparser import (OPT_ALLOW_NONE, OPT_ARRAY, OPT_ATTRIBUTE,
                                OPT_TYPE, OPT_CLOSURE, OPT_DESTROY, OPT_TRANSFER, OPT_SKIP,
                                OPT_FOREIGN, OPT_ARRAY_FIXED_SIZE,
                                OPT_ARRAY_LENGTH, OPT_ARRAY_ZERO_TERMINATED,
-                               OPT_CONSTRUCTOR)
+                               OPT_CONSTRUCTOR, OPT_METHOD)
 from .annotationparser import AnnotationParser
 from .transformer import TransformerException
 from .utils import to_underscores, to_underscores_noprefix
@@ -583,6 +583,9 @@ usage is void (*_gtk_reserved1)(void);"""
         if OPT_CONSTRUCTOR in block.options and isinstance(node, ast.Function):
             node.is_constructor = True
 
+        if OPT_METHOD in block.options:
+            node.is_method = True
+
     def _apply_annotations_alias(self, node, chain):
         block = self._get_block(node)
         self._apply_annotations_annotated(node, block)
@@ -897,7 +900,8 @@ method or constructor of some type."""
         if func.is_constructor or self._is_constructor(func, subsymbol):
             self._set_up_constructor(func, subsymbol)
             return
-        elif self._pair_method(func, subsymbol):
+        elif func.is_method or self._is_method(func, subsymbol):
+            self._setup_method(func, subsymbol)
             return
         elif self._pair_static_method(func, subsymbol):
             return
@@ -907,7 +911,7 @@ method or constructor of some type."""
         name = typeval.get_giname()
         return to_underscores_noprefix(name).lower()
 
-    def _pair_method(self, func, subsymbol):
+    def _is_method(self, func, subsymbol):
         if not func.parameters:
             return False
         first = func.parameters[0]
@@ -924,6 +928,27 @@ method or constructor of some type."""
         if first.type.ctype is not None and first.type.ctype.count('*') != 1:
             return False
 
+        uscored_prefix = self._get_uscored_prefix(func, subsymbol)
+        if not subsymbol.startswith(uscored_prefix):
+            return False
+
+        return True
+
+    def _setup_method(self, func, subsymbol):
+        uscored_prefix = self._get_uscored_prefix(func, subsymbol)
+        target = self._transformer.lookup_typenode(func.parameters[0].type)
+
+        func.instance_parameter = func.parameters.pop(0)
+        self._namespace.float(func)
+
+        if not func.is_method:
+            subsym_idx = func.symbol.find(subsymbol)
+            func.name = func.symbol[(subsym_idx + len(uscored_prefix) + 1):]
+            func.is_method = True
+
+        target.methods.append(func)
+
+    def _get_uscored_prefix(self, func, subsymbol):
         # Here we check both the c_symbol_prefix and (if that fails),
         # attempt to do a default uscoring of the type.  The reason we
         # look at a default underscore transformation is for
@@ -932,21 +957,16 @@ method or constructor of some type."""
         # "gdk_window".  Possibly need an annotation to override this.
         prefix_matches = False
         uscored_prefix = None
+        first_arg = func.parameters[0]
+        target = self._transformer.lookup_typenode(first_arg.type)
         if hasattr(target, 'c_symbol_prefix') and target.c_symbol_prefix is not None:
             prefix_matches = subsymbol.startswith(target.c_symbol_prefix)
             if prefix_matches:
                 uscored_prefix = target.c_symbol_prefix
         if not prefix_matches:
-            uscored_prefix = self._uscored_identifier_for_type(first.type)
-            if not subsymbol.startswith(uscored_prefix):
-                return False
-        func.instance_parameter = func.parameters.pop(0)
-        subsym_idx = func.symbol.find(subsymbol)
-        self._namespace.float(func)
-        func.name = func.symbol[(subsym_idx + len(uscored_prefix) + 1):]
-        target.methods.append(func)
-        func.is_method = True
-        return True
+            uscored_prefix = self._uscored_identifier_for_type(first_arg.type)
+
+        return uscored_prefix
 
     def _pair_static_method(self, func, subsymbol):
         split = self._split_uscored_by_type(subsymbol)
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index 45f62c0..10429ac 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -485,6 +485,11 @@ case.</doc>
           </parameter>
         </parameters>
       </method>
+      <method name="forced_method" c:identifier="regress_forced_method">
+        <return-value transfer-ownership="none">
+          <type name="none" c:type="void"/>
+        </return-value>
+      </method>
       <method name="instance_method"
               c:identifier="regress_test_obj_instance_method">
         <return-value transfer-ownership="none">
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index ad5cd25..8b71bc8 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -1955,6 +1955,16 @@ regress_test_obj_static_method (int x)
 }
 
 /**
+ * regress_forced_method: (method)
+ * @obj: A #RegressTestObj
+ *
+ */
+void
+regress_forced_method (RegressTestObj *obj)
+{
+}
+
+/**
  * regress_test_obj_torture_signature_0:
  * @obj: A #RegressTestObj
  * @x:
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 91b0084..14daf12 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -302,6 +302,7 @@ RegressTestObj*   regress_test_obj_new_from_file (const char *x, GError **error)
 void       regress_test_obj_set_bare (RegressTestObj *obj, GObject *bare);
 int        regress_test_obj_instance_method (RegressTestObj *obj);
 double     regress_test_obj_static_method (int x);
+void       regress_forced_method (RegressTestObj *obj);
 
 void regress_test_obj_torture_signature_0 (RegressTestObj    *obj,
                                    int        x,



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