summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2008-11-25 22:29:20 +0000
committerJohan Dahlin <johan@src.gnome.org>2008-11-25 22:29:20 +0000
commit792c394d3b0350652291f2f93f9d769c3a03024e (patch)
treeca01bd0a4ad24825e7470f8a5e187a5d82844f7b
parent620a59eec01141746f560a3b37357b838a47177a (diff)
downloadgobject-introspection-792c394d3b0350652291f2f93f9d769c3a03024e.tar.gz
Bug 559705 – Missing association between static methods and classes
2008-11-25 Colin Walters <walters@verbum.org> Bug 559705 – Missing association between static methods and classes * docs/typelib-format.txt: * girepository/ginfo.c (g_function_info_get_flags): * girepository/girmodule.c (g_ir_module_build_typelib): * girepository/girnode.c (g_ir_node_get_size), (g_ir_node_build_typelib): * girepository/girparser.c (start_function): * girepository/gtypelib.c (g_typelib_check_sanity), (validate_header), (validate_function_blob): * girepository/gtypelib.h: * giscanner/ast.py: * giscanner/girwriter.py: * giscanner/glibtransformer.py: * tests/scanner/foo-1.0-expected.gir: * tests/scanner/foo-1.0-expected.tgir: * tests/scanner/foo.h: svn path=/trunk/; revision=972
-rw-r--r--ChangeLog20
-rw-r--r--docs/typelib-format.txt10
-rw-r--r--girepository/ginfo.c2
-rw-r--r--girepository/girmodule.c2
-rw-r--r--girepository/girnode.c3
-rw-r--r--girepository/girparser.c4
-rw-r--r--girepository/gtypelib.c6
-rw-r--r--girepository/gtypelib.h7
-rw-r--r--giscanner/ast.py1
-rw-r--r--giscanner/girwriter.py5
-rw-r--r--giscanner/glibtransformer.py48
-rw-r--r--tests/scanner/foo-1.0-expected.gir5
-rw-r--r--tests/scanner/foo-1.0-expected.tgir5
-rw-r--r--tests/scanner/foo.h2
14 files changed, 92 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index e6f8b292..84539b30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2008-11-25 Colin Walters <walters@verbum.org>
+
+ Bug 559705 – Missing association between static methods and classes
+
+ * docs/typelib-format.txt:
+ * girepository/ginfo.c (g_function_info_get_flags):
+ * girepository/girmodule.c (g_ir_module_build_typelib):
+ * girepository/girnode.c (g_ir_node_get_size),
+ (g_ir_node_build_typelib):
+ * girepository/girparser.c (start_function):
+ * girepository/gtypelib.c (g_typelib_check_sanity),
+ (validate_header), (validate_function_blob):
+ * girepository/gtypelib.h:
+ * giscanner/ast.py:
+ * giscanner/girwriter.py:
+ * giscanner/glibtransformer.py:
+ * tests/scanner/foo-1.0-expected.gir:
+ * tests/scanner/foo-1.0-expected.tgir:
+ * tests/scanner/foo.h:
+
2008-11-25 Johan Dahlin <jdahlin@async.com.br>
* giscanner/ast.py: Define socklen_t as an alias for int32.
diff --git a/docs/typelib-format.txt b/docs/typelib-format.txt
index d7cfedae..895c1f0d 100644
--- a/docs/typelib-format.txt
+++ b/docs/typelib-format.txt
@@ -302,7 +302,7 @@ arguments:
An array of ArgBlob for the arguments of the function.
-FunctionBlob (16 bytes)
+FunctionBlob (20 bytes)
struct FunctionBlob
{
@@ -313,12 +313,14 @@ struct FunctionBlob
guint is_getter : 1;
guint is_constructor : 1;
guint wraps_vfunc : 1;
- guint reserved : 1;
+ guint throws : 1;
guint index :10;
guint32 name;
guint32 c_name;
guint32 signature;
+ guint is_static : 1;
+ guint reserved : 31;
}
c_name: The symbol which can be used to obtain the function pointer with
@@ -352,6 +354,10 @@ signature:
Offset of the SignatureBlob describing the parameter types and the
return value type.
+is_static
+ The function is a "static method"; in other words it's a pure
+ function whose name is conceptually scoped to the object.
+
CallbackBlob (12 bytes)
diff --git a/girepository/ginfo.c b/girepository/ginfo.c
index 0e39bcd0..5df1e3f8 100644
--- a/girepository/ginfo.c
+++ b/girepository/ginfo.c
@@ -494,7 +494,7 @@ g_function_info_get_flags (GIFunctionInfo *info)
flags = 0;
/* Make sure we don't flag Constructors as methods */
- if (base->container != NULL && !blob->constructor)
+ if (!blob->constructor && !blob->is_static)
flags = flags | GI_FUNCTION_IS_METHOD;
if (blob->constructor)
diff --git a/girepository/girmodule.c b/girepository/girmodule.c
index 1b26f3de..be41a1ed 100644
--- a/girepository/girmodule.c
+++ b/girepository/girmodule.c
@@ -209,7 +209,7 @@ g_ir_module_build_typelib (GIrModule *module,
: 0);
header->directory = ALIGN_VALUE (header_size, 4);
header->entry_blob_size = 12;
- header->function_blob_size = 16;
+ header->function_blob_size = sizeof (FunctionBlob);
header->callback_blob_size = 12;
header->signal_blob_size = 12;
header->vfunc_blob_size = 16;
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 75dd265c..61e4f0b6 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -415,7 +415,7 @@ g_ir_node_get_size (GIrNode *node)
break;
case G_IR_NODE_FUNCTION:
- size = 16;
+ size = sizeof (FunctionBlob);
break;
case G_IR_NODE_PARAM:
@@ -1581,6 +1581,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->blob_type = BLOB_TYPE_FUNCTION;
blob->deprecated = function->deprecated;
+ blob->is_static = !function->is_method;
blob->setter = function->is_setter;
blob->getter = function->is_getter;
blob->constructor = function->is_constructor;
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 48e31192..e6d59b4c 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -674,10 +674,12 @@ start_function (GMarkupParseContext *context,
strcmp (element_name, "callback") == 0);
break;
case STATE_CLASS:
+ found = strcmp (element_name, "function") == 0;
+ /* fallthrough */
case STATE_BOXED:
case STATE_STRUCT:
case STATE_UNION:
- found = strcmp (element_name, "constructor") == 0;
+ found = (found || strcmp (element_name, "constructor") == 0);
/* fallthrough */
case STATE_INTERFACE:
found = (found ||
diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c
index 5cda7057..51cbafcd 100644
--- a/girepository/gtypelib.c
+++ b/girepository/gtypelib.c
@@ -167,7 +167,7 @@ g_typelib_check_sanity (void)
CHECK_SIZE (ArgBlob, 12);
CHECK_SIZE (SignatureBlob, 8);
CHECK_SIZE (CommonBlob, 8);
- CHECK_SIZE (FunctionBlob, 16);
+ CHECK_SIZE (FunctionBlob, 20);
CHECK_SIZE (InterfaceTypeBlob, 4);
CHECK_SIZE (ArrayTypeBlob, 8);
CHECK_SIZE (ParamTypeBlob, 4);
@@ -315,7 +315,7 @@ validate_header (ValidateContext *ctx,
}
if (header->entry_blob_size != 12 ||
- header->function_blob_size != 16 ||
+ header->function_blob_size != 20 ||
header->callback_blob_size != 12 ||
header->signal_blob_size != 12 ||
header->vfunc_blob_size != 16 ||
@@ -731,7 +731,7 @@ validate_function_blob (ValidateContext *ctx,
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID_BLOB,
- "Wrong blob type");
+ "Wrong blob type %d, expected function", blob->blob_type);
return FALSE;
}
diff --git a/girepository/gtypelib.h b/girepository/gtypelib.h
index 7db15db3..343f9e1b 100644
--- a/girepository/gtypelib.h
+++ b/girepository/gtypelib.h
@@ -172,10 +172,17 @@ typedef struct
guint16 wraps_vfunc : 1;
guint16 throws : 1;
guint16 index :10;
+ /* Note the bits above need to match CommonBlob
+ * and are thus exhausted, extend things using
+ * the reserved block below. */
guint32 name;
guint32 symbol;
guint32 signature;
+
+ guint16 is_static : 1;
+ guint16 reserved : 15;
+ guint16 reserved2 : 16;
} FunctionBlob;
typedef struct
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 3b3673f7..8b78634d 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -368,6 +368,7 @@ class Class(Node):
self.parent = parent
self.is_abstract = is_abstract
self.methods = []
+ self.static_methods = []
self.interfaces = []
self.constructors = []
self.properties = []
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index a5c50d97..23d3a927 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -121,6 +121,9 @@ class GIRWriter(XMLWriter):
def _write_method(self, method):
self._write_function(method, tag_name='method')
+ def _write_static_method(self, method):
+ self._write_function(method, tag_name='function')
+
def _write_constructor(self, method):
self._write_function(method, tag_name='constructor')
@@ -260,6 +263,8 @@ class GIRWriter(XMLWriter):
if isinstance(node, Class):
for method in node.constructors:
self._write_constructor(method)
+ for method in node.static_methods:
+ self._write_static_method(method)
for method in node.methods:
self._write_method(method)
for prop in node.properties:
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 8aa34eb3..b6526ea0 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -329,6 +329,27 @@ class GLibTransformer(object):
except KeyError, e:
return False
+ def _parse_static_method(self, func):
+ components = func.symbol.split('_')
+ if len(components) < 2:
+ return None
+ target_klass = None
+ prefix_components = None
+ methname = None
+ for i in xrange(1, len(components)-1):
+ prefix_components = '_'.join(components[0:-i])
+ methname = '_'.join(components[-i:])
+ target_klass = self._uscore_type_names.get(prefix_components)
+ if target_klass and isinstance(target_klass, GLibObject):
+ break
+ target_klass = None
+ if not target_klass:
+ return None
+ self._remove_attribute(func.name)
+ func.name = methname
+ target_klass.static_methods.append(func)
+ return func
+
def _parse_method(self, func):
if not func.parameters:
return False
@@ -378,19 +399,6 @@ class GLibTransformer(object):
return None
prefix = func.symbol[:new_idx]
- klass = None
-
- def valid_matching_klass(tclass):
- if tclass is None:
- return False
- elif isinstance(klass, (GLibEnum, GLibFlags)):
- return False
- elif not isinstance(tclass, (GLibObject, GLibBoxed,
- GLibInterface)):
- return False
- else:
- return True
-
klass = self._uscore_type_names.get(prefix)
if klass is None:
#print "NOTE: No valid matching class for likely "+\
@@ -676,13 +684,14 @@ class GLibTransformer(object):
self._resolve_alias(node)
def _resolve_function_toplevel(self, func):
- newfunc = self._parse_constructor(func)
- if not newfunc:
- newfunc = self._parse_method(func)
- if not newfunc:
- self._resolve_function(func)
+ for parser in [self._parse_constructor,
+ self._parse_method,
+ self._parse_static_method]:
+ newfunc = parser(func)
+ if newfunc:
+ self._resolve_function(newfunc)
return
- self._resolve_function(newfunc)
+ self._resolve_function(func)
def _pair_boxed_type(self, boxed):
name = self._transformer.remove_prefix(boxed.type_name)
@@ -744,6 +753,7 @@ class GLibTransformer(object):
for x in node.interfaces])
self._resolve_constructors(node.constructors)
self._resolve_methods(node.methods)
+ self._resolve_methods(node.static_methods)
self._resolve_properties(node.properties, node)
self._resolve_signals(node.signals)
for field in node.fields:
diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir
index 21d70c5f..9db4c29a 100644
--- a/tests/scanner/foo-1.0-expected.gir
+++ b/tests/scanner/foo-1.0-expected.gir
@@ -87,6 +87,11 @@
<type name="Object" c:type="FooObject*"/>
</return-value>
</constructor>
+ <function name="static_meth" c:identifier="foo_object_static_meth">
+ <return-value transfer-ownership="none">
+ <type name="int" c:type="int"/>
+ </return-value>
+ </function>
<method name="external_type" c:identifier="foo_object_external_type">
<return-value transfer-ownership="full">
<type name="utility.Object" c:type="UtilityObject*"/>
diff --git a/tests/scanner/foo-1.0-expected.tgir b/tests/scanner/foo-1.0-expected.tgir
index 2591fdfa..d44f118c 100644
--- a/tests/scanner/foo-1.0-expected.tgir
+++ b/tests/scanner/foo-1.0-expected.tgir
@@ -36,6 +36,11 @@
<type name="Object"/>
</return-value>
</constructor>
+ <function name="static_meth" c:identifier="foo_object_static_meth">
+ <return-value transfer-ownership="none">
+ <type name="int"/>
+ </return-value>
+ </function>
<method name="external_type" c:identifier="foo_object_external_type">
<return-value transfer-ownership="full">
<type name="utility.Object"/>
diff --git a/tests/scanner/foo.h b/tests/scanner/foo.h
index c7da0a43..fd9d3590 100644
--- a/tests/scanner/foo.h
+++ b/tests/scanner/foo.h
@@ -91,6 +91,8 @@ char * foo_object_dup_name (FooObject *object);
void foo_object_handle_glyph (FooObject *object, UtilityGlyph glyph);
+int foo_object_static_meth ();
+
struct _FooSubobject
{
FooObject parent_instance;