diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | giscanner/ast.py | 21 | ||||
-rw-r--r-- | giscanner/gdumpparser.py | 16 | ||||
-rw-r--r-- | giscanner/maintransformer.py | 7 | ||||
-rw-r--r-- | tests/scanner/GetType-1.0-expected.gir | 69 | ||||
-rw-r--r-- | tests/scanner/Makefile.am | 28 | ||||
-rw-r--r-- | tests/scanner/gettype.c | 62 | ||||
-rw-r--r-- | tests/scanner/gettype.h | 29 |
8 files changed, 211 insertions, 22 deletions
@@ -70,6 +70,7 @@ tests/repository/gitypelibtest tests/scanner/Annotation-1.0.gir tests/scanner/Bar-1.0.gir tests/scanner/Foo-1.0.gir +tests/scanner/GetType-1.0.gir tests/scanner/GtkFrob-1.0.gir tests/scanner/Headeronly-1.0.gir tests/scanner/Regress-1.0.gir diff --git a/giscanner/ast.py b/giscanner/ast.py index 6df356dd..9e9d7c37 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -21,6 +21,8 @@ import copy +from . import message + from .message import Position from .odict import odict from .utils import to_underscores @@ -589,6 +591,25 @@ class Function(Callable): clone.parameters = self.parameters[:] return clone + def is_type_meta_function(self): + # Named correctly + if not (self.name.endswith('_get_type') or + self.name.endswith('_get_gtype')): + return False + + # Doesn't have any parameters + if self.parameters: + return False + + # Returns GType + rettype = self.retval.type + if (not rettype.is_equiv(TYPE_GTYPE) and + rettype.target_giname != 'Gtk.Type'): + message.warn("function '%s' returns '%r', not a GType" % + (self.name, rettype)) + return False + + return True class ErrorQuarkFunction(Function): diff --git a/giscanner/gdumpparser.py b/giscanner/gdumpparser.py index c0c4ef61..c0b13f4a 100644 --- a/giscanner/gdumpparser.py +++ b/giscanner/gdumpparser.py @@ -188,18 +188,12 @@ blob containing data gleaned from GObject's primitive introspection.""" if func.symbol == 'g_variant_get_gtype': # We handle variants internally, see _initparse_gobject_record return True - if func.parameters: - return False - # GType *_get_type(void) - rettype = func.retval.type - if not (rettype.is_equiv(ast.TYPE_GTYPE) - or rettype.target_giname == 'Gtk.Type'): - message.warn("function returns '%r', not a GType" % ( - func.retval.type, )) - return False - self._get_type_functions.append(func.symbol) - return True + if func.is_type_meta_function(): + self._get_type_functions.append(func.symbol) + return True + + return False def _initparse_error_quark_function(self, func): if (func.retval.type.ctype != 'GQuark'): diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py index 3a35b0e7..7d274b34 100644 --- a/giscanner/maintransformer.py +++ b/giscanner/maintransformer.py @@ -955,10 +955,11 @@ _split_uscored_by_type(text_buffer_try_new) -> (ast.Class(TextBuffer), 'try_new' def _pair_function(self, func): """Check to see whether a toplevel function should be a method or constructor of some type.""" - if (func.symbol.endswith('_get_type') - or func.symbol.endswith('_get_gtype') - or func.symbol.startswith('_')): + + # Ignore internal symbols and type metadata functions + if func.symbol.startswith('_') or func.is_type_meta_function(): return + (ns, subsymbol) = self._transformer.split_csymbol(func.symbol) assert ns == self._namespace if self._is_constructor(func, subsymbol): diff --git a/tests/scanner/GetType-1.0-expected.gir b/tests/scanner/GetType-1.0-expected.gir new file mode 100644 index 00000000..3b1dd193 --- /dev/null +++ b/tests/scanner/GetType-1.0-expected.gir @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<!-- This file was automatically generated from C sources - DO NOT EDIT! +To affect the contents of this file, edit the original C definitions, +and/or use gtk-doc annotations. --> +<repository version="1.2" + xmlns="http://www.gtk.org/introspection/core/1.0" + xmlns:c="http://www.gtk.org/introspection/c/1.0" + xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> + <include name="GLib" version="2.0"/> + <include name="GObject" version="2.0"/> + <package name="gobject-2.0"/> + <c:include name="gettype.h"/> + <namespace name="GetType" + version="1.0" + shared-library="libgettype.so" + c:identifier-prefixes="GetType" + c:symbol-prefixes="gettype"> + <class name="Object" + c:symbol-prefix="object" + c:type="GetTypeObject" + parent="GObject.Object" + glib:type-name="GetTypeObject" + glib:get-type="gettype_object_get_type" + glib:type-struct="ObjectClass"> + <constructor name="new" c:identifier="gettype_object_new"> + <return-value transfer-ownership="full"> + <type name="Object" c:type="GetTypeObject*"/> + </return-value> + </constructor> + <function name="nonmeta2_get_type" + c:identifier="gettype_object_nonmeta2_get_type"> + <doc xml:whitespace="preserve">This shouldn't be scanned as a *_get_type function because it doesn't return +a GType. It will generate a warning.</doc> + <return-value transfer-ownership="none"> + <doc xml:whitespace="preserve">true</doc> + <type name="gboolean" c:type="gboolean"/> + </return-value> + </function> + <function name="nonmeta_get_gtype" + c:identifier="gettype_object_nonmeta_get_gtype"> + <doc xml:whitespace="preserve">This shouldn't be scanned as a *_get_type function because it doesn't return +a GType. It will generate a warning.</doc> + <return-value transfer-ownership="none"> + <doc xml:whitespace="preserve">true</doc> + <type name="gboolean" c:type="gboolean"/> + </return-value> + </function> + <method name="nonmeta1_get_type" + c:identifier="gettype_object_nonmeta1_get_type"> + <doc xml:whitespace="preserve">This shouldn't be scanned as a *_get_type function because it takes +arguments.</doc> + <return-value transfer-ownership="none"> + <doc xml:whitespace="preserve">0</doc> + <type name="GType" c:type="GType"/> + </return-value> + </method> + <field name="parent_instance"> + <type name="GObject.Object" c:type="GObject"/> + </field> + </class> + <record name="ObjectClass" + c:type="GetTypeObjectClass" + glib:is-gtype-struct-for="Object"> + <field name="parent_class"> + <type name="GObject.ObjectClass" c:type="GObjectClass"/> + </field> + </record> + </namespace> +</repository> diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am index d2bed5ac..0e5ddb53 100644 --- a/tests/scanner/Makefile.am +++ b/tests/scanner/Makefile.am @@ -1,14 +1,15 @@ include $(top_srcdir)/common.mk include $(top_srcdir)/Makefile.introspection -INTROSPECTION_SCANNER_ARGS += --warn-all --warn-error -I. +INTROSPECTION_SCANNER_ARGS += --warn-all check_LTLIBRARIES = \ libannotation.la \ libtestinherit.la \ libfoo.la \ libutility.la \ - libgtkfrob.la + libgtkfrob.la \ + libgettype.la if HAVE_CAIRO check_LTLIBRARIES += libregress.la endif @@ -28,6 +29,7 @@ libutility_la_SOURCES = $(srcdir)/utility.c $(srcdir)/utility.h libgtkfrob_la_SOURCES = $(srcdir)/gtkfrob.c $(srcdir)/gtkfrob.h libregress_la_SOURCES = $(srcdir)/regress.c $(srcdir)/regress.h libregress_la_LIBADD = $(GIO_LIBS) $(CAIRO_LIBS) +libgettype_la_SOURCES = $(srcdir)/gettype.c $(srcdir)/gettype.h testsdir = $(datadir)/gobject-introspection-1.0/tests tests_DATA = $(libregress_la_SOURCES) @@ -53,7 +55,7 @@ Regress-1.0.gir: $(top_builddir)/Gio-2.0.gir libregress.la Regress_1_0_gir_LIBS = libregress.la Regress_1_0_gir_INCLUDES = cairo-1.0 Gio-2.0 Regress_1_0_gir_FILES = $(libregress_la_SOURCES) -Regress_1_0_gir_SCANNERFLAGS = --c-include="regress.h" +Regress_1_0_gir_SCANNERFLAGS = --c-include="regress.h" --warn-error if HAVE_CAIRO GIRS += Regress-1.0.gir endif @@ -63,7 +65,7 @@ Annotation_1_0_gir_PACKAGES = gobject-2.0 Annotation_1_0_gir_LIBS = libannotation.la Annotation_1_0_gir_INCLUDES = GObject-2.0 Utility-1.0 Annotation_1_0_gir_FILES = $(libannotation_la_SOURCES) -Annotation_1_0_gir_SCANNERFLAGS = --c-include="annotation.h" +Annotation_1_0_gir_SCANNERFLAGS = --c-include="annotation.h" --warn-error GIRS += Annotation-1.0.gir TestInherit-1.0.gir: Utility-1.0.gir libtestinherit.la @@ -71,7 +73,7 @@ TestInherit_1_0_gir_PACKAGES = gobject-2.0 TestInherit_1_0_gir_LIBS = libtestinherit.la TestInherit_1_0_gir_INCLUDES = GObject-2.0 Utility-1.0 TestInherit_1_0_gir_FILES = $(libtestinherit_la_SOURCES) -TestInherit_1_0_gir_SCANNERFLAGS = --c-include="drawable.h" +TestInherit_1_0_gir_SCANNERFLAGS = --c-include="drawable.h" --warn-error GIRS += TestInherit-1.0.gir Foo-1.0.gir: Utility-1.0.gir libfoo.la @@ -79,7 +81,7 @@ Foo_1_0_gir_PACKAGES = gobject-2.0 Foo_1_0_gir_LIBS = libfoo.la Foo_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 Utility-1.0 Foo_1_0_gir_FILES = $(srcdir)/foo.h $(srcdir)/foo.c -Foo_1_0_gir_SCANNERFLAGS = --c-include="foo.h" +Foo_1_0_gir_SCANNERFLAGS = --c-include="foo.h" --warn-error GIRS += Foo-1.0.gir Utility-1.0.gir: libutility.la @@ -87,7 +89,7 @@ Utility_1_0_gir_PACKAGES = gobject-2.0 Utility_1_0_gir_LIBS = libutility.la Utility_1_0_gir_INCLUDES = GObject-2.0 Utility_1_0_gir_FILES = $(libutility_la_SOURCES) -Utility_1_0_gir_SCANNERFLAGS = --c-include="utility.h" +Utility_1_0_gir_SCANNERFLAGS = --c-include="utility.h" --warn-error GIRS += Utility-1.0.gir # This one tests different --namespace and --strip-prefix @@ -96,9 +98,19 @@ GtkFrob_1_0_gir_PACKAGES = gobject-2.0 GtkFrob_1_0_gir_LIBS = libgtkfrob.la GtkFrob_1_0_gir_INCLUDES = GObject-2.0 GtkFrob_1_0_gir_FILES = $(libgtkfrob_la_SOURCES) -GtkFrob_1_0_gir_SCANNERFLAGS = --identifier-prefix=Gtk --symbol-prefix=gtk_frob +GtkFrob_1_0_gir_SCANNERFLAGS = --identifier-prefix=Gtk --symbol-prefix=gtk_frob --warn-error GIRS += GtkFrob-1.0.gir +# This tests that functions called _get_type are only matched if they have no +# arguments and return GType +GetType-1.0.gir: libgettype.la +GetType_1_0_gir_PACKAGES = gobject-2.0 +GetType_1_0_gir_LIBS = libgettype.la +GetType_1_0_gir_INCLUDES = GObject-2.0 +GetType_1_0_gir_FILES = $(libgettype_la_SOURCES) +GetType_1_0_gir_SCANNERFLAGS = --c-include="gettype.h" --identifier-prefix=GetType --symbol-prefix=gettype +GIRS += GetType-1.0.gir + if !OS_WIN32 check_PROGRAMS = barapp diff --git a/tests/scanner/gettype.c b/tests/scanner/gettype.c new file mode 100644 index 00000000..cd816735 --- /dev/null +++ b/tests/scanner/gettype.c @@ -0,0 +1,62 @@ +#include "gettype.h" + +G_DEFINE_TYPE(GetTypeObject, gettype_object, G_TYPE_OBJECT); + +static void +gettype_object_class_init (GetTypeObjectClass *klass) +{ +} + +static void +gettype_object_init (GetTypeObject *object) +{ +} + +GetTypeObject * +gettype_object_new (void) +{ + return g_object_new (GETTYPE_TYPE_OBJECT, NULL); +} + +/** + * gettype_object_nonmeta1_get_type: + * @obj: self + * + * This shouldn't be scanned as a *_get_type function because it takes + * arguments. + * + * Returns: 0 + */ +GType +gettype_object_nonmeta1_get_type (GetTypeObject *obj) +{ + return 0; +} + +/** + * gettype_object_nonmeta2_get_type: + * + * This shouldn't be scanned as a *_get_type function because it doesn't return + * a GType. It will generate a warning. + * + * Returns: true + */ +gboolean +gettype_object_nonmeta2_get_type (void) +{ + return TRUE; +} + +/** + * gettype_object_nonmeta_get_gtype: + * + * This shouldn't be scanned as a *_get_type function because it doesn't return + * a GType. It will generate a warning. + * + * Returns: true + */ +gboolean +gettype_object_nonmeta_get_gtype (void) +{ + return TRUE; +} diff --git a/tests/scanner/gettype.h b/tests/scanner/gettype.h new file mode 100644 index 00000000..755f091c --- /dev/null +++ b/tests/scanner/gettype.h @@ -0,0 +1,29 @@ +#ifndef __GETTYPE_OBJECT_H__ +#define __GETTYPE_OBJECT_H__ + +#include <glib-object.h> + +#define GETTYPE_TYPE_OBJECT (gettype_object_get_type ()) +#define GETTYPE_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GETTYPE_TYPE_OBJECT, GetTypeObject)) +#define GETTYPE_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GETTYPE_TYPE_OBJECT)) + +typedef struct _GetTypeObject GetTypeObject; +typedef struct _GetTypeObjectClass GetTypeObjectClass; +struct _GetTypeObject +{ + GObject parent_instance; +}; + +struct _GetTypeObjectClass +{ + GObjectClass parent_class; +}; + +GType gettype_object_get_type (void) G_GNUC_CONST; +GetTypeObject* gettype_object_new (void); + +GType gettype_object_nonmeta1_get_type (GetTypeObject *obj); +gboolean gettype_object_nonmeta2_get_type (void); +gboolean gettype_object_nonmeta_get_gtype (void); + +#endif /* __GETTYPE_OBJECT_H__ */ |