docs: Clarify conventions about type naming and name mangling in GObject

These rules are not new, they’ve been around for a long time and are
needed to allow introspection machinery to be able to work reliably and
deterministically.

Unfortunately, they have not been documented canonically in one place
before.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This commit is contained in:
Philip Withnall 2024-07-22 19:23:08 +02:00
parent a8b1e818f3
commit 35d76da8c8
No known key found for this signature in database
GPG Key ID: DCDF5885B1F3ED73

View File

@ -344,6 +344,16 @@ new types which are to be exported in a header file:
- Use prefixing to avoid namespace conflicts with other projects. If your
library (or application) is named `Viewer`, prefix all your function names
with `viewer_`. For example: `viewer_object_method`.
- The prefix should be a single term, i.e. should not contain any capital
letters after the first letter. For example, `Exampleprefix` rather than
`ExamplePrefix`.
- This allows the lowercase-with-underscores versions of names
to be automatically and unambiguously generated from the camel-case
versions. See [Name mangling](#name-mangling).
- Multiple-term prefixes can be supported if additional arguments are passed
to type and introspection tooling, but its best to avoid the need for this.
- Object/Class names (such as `File` in the examples here) may contain multiple
terms. For example, `LocalFile`.
- Create a macro named `PREFIX_TYPE_OBJECT` which always returns the `GType`
for the associated object type. For an object of type `File` in the
`Viewer` namespace, use: `VIEWER_TYPE_FILE`. This macro is implemented
@ -408,6 +418,31 @@ GType viewer_file_get_type (void)
}
```
## Name mangling
GObject tooling, in particular introspection, relies on being able to
unambiguously convert between type names (in camel-case, such as
`GNetworkMonitor` or `MyViewerFile`) and function prefixes (in
lowercase-with-underscores, such as `g_network_monitor` or `my_viewer_file`).
The latter can then be used to prefix methods such as
`g_network_monitor_can_reach()` or `my_viewer_file_get_type()`.
The algorithm for converting from camel-case to lowercase-with-underscores is:
<!-- This algorithm is here:
https://gitlab.gnome.org/GNOME/gtk/-/blob/a118cbb3ff552d4258d433e67bdb94e8aef0f439/gtk/gtkbuilderscope.c#L195-229
Weve ignored the case of (split_first_cap == TRUE) to simplify things, and
because that functionality is discouraged. -->
1. The output is a lower-case version of the input, with zero or more splits.
2. Wherever the input is split, insert an underscore in the output.
3. Split the input on:
- Each character (after index zero) which is uppercase and the previous
character is not uppercase
- The second character (index one) if it is uppercase and the first character
(index zero) is uppercase
- Each character (after index two) which is uppercase and the previous two
characters are also uppercase
## Non-instantiatable non-classed fundamental types
A lot of types are not instantiatable by the type system and do not have a class. Most of these types are fundamental trivial types such as `gchar`, and are already registered by GLib.