[gobject-introspection/gstring-ctor] scanner: Handle constructors with mismatched GTypes




commit 3b17bb37ebad8931eac3e050252f02a9b9414f97
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Aug 16 20:20:35 2021 +0100

    scanner: Handle constructors with mismatched GTypes
    
    For historical reasons, we have boxed types that do not follow the
    typical conversion from CamelCase to snake_case when it comes to their
    get_type function.
    
    The introspection scanner will correctly detect that a type is matched
    to that get_type function, but then it will default to tokenize the
    get_type function to set the c_symbol_prefix of the given type.
    
    The method pairing code in the main transformation path takes that
    mismatch into consideration, but the constructor pairing code does not.
    This leads to interesting cases, like GString.
    
    GString is correctly detected as GLib.String, and correctly matched to
    its `g_gstring_get_type()` type function, but its c_symbol_prefix is set
    to `gstring` after the tokenization. While methods like
    `g_string_append()` are correctly paired to the `GLib.String` node,
    constructors like `g_string_new()` do not, and end up being turned into
    function nodes, like `GLib.string_new`, even if they are annotated as
    constructors.
    
    I'm not entirely confident that changing the c_symbol_prefix
    tokenization this late in the game is going to be free of regressions;
    instead, we provide a way for pairing constructors if they are annotated
    as such.
    
    In other words: non-annotated constructors of types that have a
    different symbol prefix than the one of the get_type function will stay
    as they are today—a global function. To enforce the matching, we rely on
    an explicit `(constructor)` annotation; at least, this should ensure
    that we have explicit buy in from the maintainers of the API.
    
    Fixes: #399

 giscanner/maintransformer.py | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
---
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 3da86797..0f1ea9b6 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -1304,10 +1304,21 @@ method or constructor of some type."""
         return origin_node
 
     def _get_constructor_name(self, func, subsymbol):
-        name = None
+        prefix_matches = False
+        uscored_prefix = None
+        target = self._transformer.lookup_typenode(func.retval.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(func.retval.type)
         split = self._split_uscored_by_type(subsymbol)
         if split is None:
             if func.is_constructor:
+                if uscored_prefix in func.symbol:
+                    subsym_idx = func.symbol.find(subsymbol)
+                    func.name = func.symbol[(subsym_idx + len(uscored_prefix) + 1):]
                 name = func.name
         else:
             _, name = split


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