diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2021-08-16 20:20:35 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2021-08-16 20:56:00 +0100 |
commit | 3b17bb37ebad8931eac3e050252f02a9b9414f97 (patch) | |
tree | 63305cf3d908aa6ab615223503d30cc7e2a3e4a2 /giscanner | |
parent | 64ae0bfdcb922bdb7bd0edf1db5967253a74a424 (diff) | |
download | gobject-introspection-3b17bb37ebad8931eac3e050252f02a9b9414f97.tar.gz |
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
Diffstat (limited to 'giscanner')
-rw-r--r-- | giscanner/maintransformer.py | 13 |
1 files changed, 12 insertions, 1 deletions
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 |