summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-09-08 12:18:51 -0400
committerColin Walters <walters@verbum.org>2010-09-08 12:18:51 -0400
commit5140ec172415192af4f406b1fd5ff4615caf1386 (patch)
treefeb543dea2f0465624f90794f17fb81246aaddf5
parent6172c268a98c7a2e478b78068ccdb3c23e80ce66 (diff)
downloadgobject-introspection-5140ec172415192af4f406b1fd5ff4615caf1386.tar.gz
scanner: Don't mark as constructors things that are more obviously methods
If the first parameter matches the origin, don't scan as a constructor. Happened in practice with meta_screen_append_new_workspace from mutter.
-rw-r--r--giscanner/maintransformer.py13
-rw-r--r--tests/scanner/Foo-1.0-expected.gir25
-rw-r--r--tests/scanner/foo.c37
-rw-r--r--tests/scanner/foo.h10
4 files changed, 82 insertions, 3 deletions
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index ae051958..a9f43a3f 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -819,9 +819,7 @@ method or constructor of some type."""
target = self._transformer.lookup_typenode(func.retval.type)
if not isinstance(target, (ast.Class, glibast.GLibBoxed)):
return False
- new_idx = func.symbol.rfind('_new')
- assert (new_idx >= 0)
- prefix = func.symbol[:new_idx]
+
split = self._split_uscored_by_type(subsymbol)
if split is None:
# TODO - need a e.g. (method) annotation
@@ -829,10 +827,19 @@ method or constructor of some type."""
"Can't find matching type for constructor; symbol=%r" % (func.symbol, ))
return False
(origin_node, funcname) = split
+
+ # Some sanity checks; only objects and boxeds can have ctors
if not isinstance(origin_node, (ast.Class, glibast.GLibBoxed)):
return False
+ # Verify the namespace - don't want to append to foreign namespaces!
if origin_node.namespace != self._namespace:
return False
+ # If it takes the object as a first arg, it's not a constructor
+ if len(func.parameters) > 0:
+ first_arg = self._transformer.lookup_typenode(func.parameters[0].type)
+ if (first_arg is not None) and first_arg.gi_name == origin_node.gi_name:
+ return False
+
if isinstance(target, ast.Class):
parent = origin_node
while parent and (not parent.gi_name == 'GObject.Object'):
diff --git a/tests/scanner/Foo-1.0-expected.gir b/tests/scanner/Foo-1.0-expected.gir
index 0c4c2b63..36bec038 100644
--- a/tests/scanner/Foo-1.0-expected.gir
+++ b/tests/scanner/Foo-1.0-expected.gir
@@ -368,6 +368,18 @@ uses a C sugar return type.</doc>
</parameter>
</parameters>
</virtual-method>
+ <method name="append_new_stack_layer"
+ c:identifier="foo_object_append_new_stack_layer">
+ <doc xml:whitespace="preserve">This shouldn't be scanned as a constructor.</doc>
+ <return-value transfer-ownership="none">
+ <type name="OtherObject" c:type="FooOtherObject*"/>
+ </return-value>
+ <parameters>
+ <parameter name="x" transfer-ownership="none">
+ <type name="gint" c:type="int"/>
+ </parameter>
+ </parameters>
+ </method>
<method name="dup_name" c:identifier="foo_object_dup_name">
<return-value transfer-ownership="full">
<type name="utf8" c:type="char*"/>
@@ -560,6 +572,19 @@ uses a C sugar return type.</doc>
</array>
</field>
</record>
+ <class name="OtherObject"
+ c:symbol-prefix="other_object"
+ c:type="FooOtherObject"
+ parent="GObject.Object"
+ glib:type-name="FooOtherObject"
+ glib:get-type="foo_other_object_get_type"
+ glib:type-struct="OtherObjectClass">
+ </class>
+ <record name="OtherObjectClass"
+ c:type="FooOtherObjectClass"
+ disguised="1"
+ glib:is-gtype-struct-for="OtherObject">
+ </record>
<constant name="PIE_IS_TASTY" value="3.141590">
<type name="gdouble" c:type="gdouble"/>
</constant>
diff --git a/tests/scanner/foo.c b/tests/scanner/foo.c
index d84c58a5..9e3a38d6 100644
--- a/tests/scanner/foo.c
+++ b/tests/scanner/foo.c
@@ -667,6 +667,31 @@ foo_buffer_some_method (FooBuffer *buffer)
{
}
+struct _FooOtherObject
+{
+ GObject parent_instance;
+};
+
+struct _FooOtherObjectClass
+{
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE(FooOtherObject, foo_other_object, G_TYPE_OBJECT);
+
+static void
+foo_other_object_class_init (FooOtherObjectClass *klass)
+{
+
+}
+
+static void
+foo_other_object_init (FooOtherObject *object)
+{
+
+}
+
+
#define FOO_DEFINE_SHOULD_NOT_BE_EXPOSED "should not be exposed"
/**
@@ -714,3 +739,15 @@ foo_test_varargs_callback3 (FooVarargsCallback callback,
{
}
+/**
+ * foo_object_append_new_stack_layer:
+ *
+ * This shouldn't be scanned as a constructor.
+ *
+ * Returns: (transfer none):
+ */
+FooOtherObject *
+foo_object_append_new_stack_layer (FooObject *obj, int x)
+{
+ return NULL;
+}
diff --git a/tests/scanner/foo.h b/tests/scanner/foo.h
index 5a67e654..110c3139 100644
--- a/tests/scanner/foo.h
+++ b/tests/scanner/foo.h
@@ -34,6 +34,10 @@
#define FOO_BUFFER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), FOO_TYPE_BUFFER, FooBuffer))
#define FOO_IS_BUFFER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), FOO_TYPE_BUFFER))
+#define FOO_TYPE_OTHER_OBJECT (foo_other_object_get_type ())
+#define FOO_OTHER_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), FOO_TYPE_OTHER_OBJECT, FooOtherObject))
+#define FOO_IS_OTHER_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), FOO_TYPE_OTHER_OBJECT))
+
typedef struct _FooInterface FooInterface;
typedef struct _FooInterfaceIface FooInterfaceIface;
typedef struct _FooSubInterface FooSubInterface;
@@ -44,6 +48,8 @@ typedef struct _FooSubobject FooSubobject;
typedef struct _FooSubobjectClass FooSubobjectClass;
typedef struct _FooBuffer FooBuffer;
typedef struct _FooBufferClass FooBufferClass;
+typedef struct _FooOtherObject FooOtherObject;
+typedef struct _FooOtherObjectClass FooOtherObjectClass;
struct _FooInterfaceIface
{
@@ -151,6 +157,8 @@ GType foo_buffer_get_type (void);
void foo_buffer_some_method (FooBuffer *buffer);
+GType foo_other_object_get_type (void) G_GNUC_CONST;
+
typedef enum
{
FOO_ENUM_ALPHA,
@@ -420,4 +428,6 @@ struct _FooForeignStruct
*/
void foo_object_a_global_method (UtilityObject *obj);
+FooOtherObject * foo_object_append_new_stack_layer (FooObject *obj, int x);
+
#endif /* __FOO_OBJECT_H__ */