diff options
author | C. Scott Ananian <cscott@litl.com> | 2009-05-19 20:17:08 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2009-05-20 12:13:15 -0400 |
commit | aa94335b84d17512281ab3ed4cd20fb1fad9dcd8 (patch) | |
tree | 026c1f2e46d42743e211b4374ddfe12d529e400d | |
parent | 50dd263dbe16ecf8e81c3f674d23cb086f79ca7e (diff) | |
download | gobject-introspection-aa94335b84d17512281ab3ed4cd20fb1fad9dcd8.tar.gz |
Better handle classes with non-standard to_underscore names.
Previously we tried to guess what the "underscore version" of a class name
would be, but for classes like NMSetting8021x we'd guess "nm_setting8021x"
instead of "nm_setting_802_1x". All such guesses are subject to error:
instead let's try to use the prefix of the _get_type() method instead, and
only guess if that doesn't work.
We do this for both class names and when detecting methods. An additional
type with a "non-standard" underscored version (TestWi8021x) added to the
everything.[ch] test suite to test proper conversion.
GdkWindow and GObject have unusual get_type methods; add special quirks
to handle these (at least until the methods are renamed upstream).
(Slightly modified for PEP8 compliance by Colin Walters)
Signed-off-by: Colin Walters <walters@verbum.org>
-rw-r--r-- | giscanner/glibtransformer.py | 29 | ||||
-rw-r--r-- | tests/everything/everything.c | 106 | ||||
-rw-r--r-- | tests/everything/everything.h | 24 |
3 files changed, 157 insertions, 2 deletions
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py index 0f5b0c92..6a0dee06 100644 --- a/giscanner/glibtransformer.py +++ b/giscanner/glibtransformer.py @@ -60,6 +60,18 @@ SYMBOL_BLACKLIST = [ SYMBOL_BLACKLIST_RE = [re.compile(x) for x in \ [r'\w+_marshal_[A-Z]+__', ]] +GET_TYPE_OVERRIDES = { + # this is a special case, from glibtransforer.py:create_gobject + 'intern': 'g_object_get_type', + # this is presumably a typo, should be fixed upstream + 'g_gstring_get_type': 'g_string_get_type', + # this is historical cruft: there's a deprecated + # #define gdk_window_get_type gdk_window_get_window_type + # upstream; this method can be renamed properly upstream once + # that deprecated alias is removed (in some future release) + 'gdk_window_object_get_type': 'gdk_window_get_type', +} + class IntrospectionBinary(object): @@ -213,6 +225,10 @@ class GLibTransformer(object): def _register_internal_type(self, type_name, node): self._names.type_names[type_name] = (None, node) uscored = to_underscores(type_name).lower() + # prefer the prefix of the get_type method, if there is one + if hasattr(node, 'get_type'): + uscored = GET_TYPE_OVERRIDES.get(node.get_type, node.get_type) + uscored = uscored[:-len('_get_type')] self._uscore_type_names[uscored] = node # Besides the straight underscore conversion, we also try # removing the underscores from the namespace as a possible C @@ -220,7 +236,9 @@ class GLibTransformer(object): suffix = self._transformer.remove_prefix(type_name) prefix = type_name[:-len(suffix)] no_uscore_prefixed = (prefix + '_' + to_underscores(suffix)).lower() - self._uscore_type_names[no_uscore_prefixed] = node + # since this is a guess, don't overwrite any 'real' prefix + if no_uscore_prefixed not in self._uscore_type_names: + self._uscore_type_names[no_uscore_prefixed] = node def _resolve_quarks(self): for node in self._error_quark_functions: @@ -401,7 +419,7 @@ class GLibTransformer(object): target_klass = None prefix_components = None methname = None - for i in xrange(1, len(components)-1): + for i in xrange(1, len(components)): prefix_components = '_'.join(components[0:-i]) methname = '_'.join(components[-i:]) target_klass = self._uscore_type_names.get(prefix_components) @@ -446,6 +464,13 @@ class GLibTransformer(object): argtype = target_arg.type.ctype.replace('*', '') name = self._transformer.remove_prefix(argtype) name_uscore = to_underscores_noprefix(name).lower() + # prefer the prefix of the _get_type method, if there is one + if argtype in self._names.type_names: + node = self._names.type_names[argtype][1] + if hasattr(node, 'get_type'): + name_uscore = GET_TYPE_OVERRIDES.get(node.get_type, + node.get_type) + name_uscore = name_uscore[:-len('_get_type')] name_offset = func.symbol.find(name_uscore) if name_offset < 0: return None diff --git a/tests/everything/everything.c b/tests/everything/everything.c index 7c9e4e5d..52dec4ba 100644 --- a/tests/everything/everything.c +++ b/tests/everything/everything.c @@ -1345,3 +1345,109 @@ test_interface_get_type(void) return type; } +/* gobject with non-standard prefix */ +G_DEFINE_TYPE(TestWi8021x, test_wi_802_1x, G_TYPE_OBJECT); + +enum +{ + PROP_TEST_WI_802_1X_TESTBOOL = 1 +}; + +static void +test_wi_802_1x_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + TestWi8021x *self = TEST_WI_802_1X (object); + + switch (property_id) + { + case PROP_TEST_WI_802_1X_TESTBOOL: + test_wi_802_1x_set_testbool (self, g_value_get_boolean (value)); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +test_wi_802_1x_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + TestWi8021x *self = TEST_WI_802_1X (object); + + switch (property_id) + { + case PROP_TEST_WI_802_1X_TESTBOOL: + g_value_set_boolean (value, test_wi_802_1x_get_testbool (self)); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +test_wi_802_1x_dispose (GObject *gobject) +{ + /* Chain up to the parent class */ + G_OBJECT_CLASS (test_wi_802_1x_parent_class)->dispose (gobject); +} + +static void +test_wi_802_1x_class_init (TestWi8021xClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + gobject_class->set_property = test_wi_802_1x_set_property; + gobject_class->get_property = test_wi_802_1x_get_property; + gobject_class->dispose = test_wi_802_1x_dispose; + + pspec = g_param_spec_boolean ("testbool", + "Nick for testbool", + "Blurb for testbool", + TRUE, + G_PARAM_READWRITE); + g_object_class_install_property (gobject_class, + PROP_TEST_WI_802_1X_TESTBOOL, + pspec); +} + +static void +test_wi_802_1x_init (TestWi8021x *obj) +{ + obj->testbool = TRUE; +} + +TestWi8021x * +test_wi_802_1x_new (void) +{ + return g_object_new (TEST_TYPE_WI_802_1X, NULL); +} + +void +test_wi_802_1x_set_testbool (TestWi8021x *obj, gboolean val) +{ + obj->testbool = val; +} + +gboolean +test_wi_802_1x_get_testbool (TestWi8021x *obj) +{ + return obj->testbool; +} + +int +test_wi_802_1x_static_method (int x) +{ + return 2*x; +} diff --git a/tests/everything/everything.h b/tests/everything/everything.h index 9f4c7d7a..2a7e3cdd 100644 --- a/tests/everything/everything.h +++ b/tests/everything/everything.h @@ -258,4 +258,28 @@ struct _TestInterfaceIface { GType test_interface_get_type (void) G_GNUC_CONST; +/* gobject with non-standard prefix */ +#define TEST_TYPE_WI_802_1X (test_wi_802_1x_get_type ()) +#define TEST_WI_802_1X(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_WI_802_1X, TestWi8021x)) +#define TEST_IS_WI_802_1X(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_WI_802_1X)) +#define TEST_WI_802_1X_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_WI_802_1X, TestWi8021xClass)) + +typedef struct +{ + GObject parent_instance; + + gboolean testbool; +} TestWi8021x; + +typedef struct +{ + GObjectClass parent_class; +} TestWi8021xClass; + +GType test_wi_802_1x_get_type (void); +TestWi8021x* test_wi_802_1x_new (void); +gboolean test_wi_802_1x_get_testbool (TestWi8021x *obj); +void test_wi_802_1x_set_testbool (TestWi8021x *obj, gboolean v); +int test_wi_802_1x_static_method (int x); + #endif /* __GITESTTYPES_H__ */ |