From 792c394d3b0350652291f2f93f9d769c3a03024e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 25 Nov 2008 22:29:20 +0000 Subject: =?UTF-8?q?Bug=20559705=20=E2=80=93=20Missing=20association=20betw?= =?UTF-8?q?een=20static=20methods=20and=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-11-25 Colin Walters 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 --- ChangeLog | 20 ++++++++++++++++ docs/typelib-format.txt | 10 ++++++-- girepository/ginfo.c | 2 +- girepository/girmodule.c | 2 +- girepository/girnode.c | 3 ++- girepository/girparser.c | 4 +++- girepository/gtypelib.c | 6 ++--- girepository/gtypelib.h | 7 ++++++ giscanner/ast.py | 1 + giscanner/girwriter.py | 5 ++++ giscanner/glibtransformer.py | 48 ++++++++++++++++++++++--------------- tests/scanner/foo-1.0-expected.gir | 5 ++++ tests/scanner/foo-1.0-expected.tgir | 5 ++++ tests/scanner/foo.h | 2 ++ 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 + + 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 * 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 @@ + + + + + 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 @@ + + + + + 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; -- cgit v1.2.1