diff options
author | Johan Dahlin <johan@gnome.org> | 2008-04-27 23:27:17 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-04-27 23:27:17 +0000 |
commit | bc995eb2d5af650e33ec6dc5c8722ae27aa124b7 (patch) | |
tree | 35b80bb86d7ce8fa5ada279862fb979344958f4f | |
parent | 65c706f0d9c2dd8ac34bcf9fe7b399eccea25fdc (diff) | |
download | gobject-introspection-bc995eb2d5af650e33ec6dc5c8722ae27aa124b7.tar.gz |
Allow parenthesis in annotations
2008-04-27 Johan Dahlin <johan@gnome.org>
* giscanner/scannerlexer.l:
Allow parenthesis in annotations
* giscanner/ast.py:
* giscanner/gidlwriter.py:
* giscanner/girwriter.py:
* giscanner/glibtransformer.py:
* giscanner/transformer.py:
Add initial sequence support, including annotation.
Refactor type handling a bit.
svn path=/trunk/; revision=233
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | giscanner/ast.py | 32 | ||||
-rw-r--r-- | giscanner/gidlwriter.py | 6 | ||||
-rw-r--r-- | giscanner/girwriter.py | 29 | ||||
-rw-r--r-- | giscanner/glibtransformer.py | 23 | ||||
-rw-r--r-- | giscanner/scannerlexer.l | 29 | ||||
-rw-r--r-- | giscanner/transformer.py | 23 |
7 files changed, 108 insertions, 47 deletions
@@ -1,5 +1,18 @@ 2008-04-27 Johan Dahlin <johan@gnome.org> + * giscanner/scannerlexer.l: + Allow parenthesis in annotations + + * giscanner/ast.py: + * giscanner/gidlwriter.py: + * giscanner/girwriter.py: + * giscanner/glibtransformer.py: + * giscanner/transformer.py: + Add initial sequence support, including annotation. + Refactor type handling a bit. + +2008-04-27 Johan Dahlin <johan@gnome.org> + * tests/parser/Foo-expected.gidl: * tests/parser/foo-object.h: * tests/parser/foo.c (foo_object_class_init), diff --git a/giscanner/ast.py b/giscanner/ast.py index 7fe4d5ff..4f7ad546 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -40,10 +40,18 @@ class VFunction(Function): pass +class Type(Node): + def __init__(self, name): + Node.__init__(self, name) + + def __repr__(self): + return 'Type(%r)' % (self.name,) + + class Parameter(Node): - def __init__(self, name, type): + def __init__(self, name, type_name): Node.__init__(self, name) - self.type = type + self.type = Type(type_name) self.direction = 'in' self.transfer = 'none' @@ -79,10 +87,11 @@ class Struct(Node): class Return(Node): - def __init__(self, type): + def __init__(self, type_name): Node.__init__(self) - self.type = type + self.type = Type(type_name) self.transfer = 'none' + self.ctype = self.type def __repr__(self): return 'Return(%r)' % (self.type,) @@ -117,9 +126,9 @@ class Interface(Node): class Constant(Node): - def __init__(self, name, type, value): + def __init__(self, name, type_name, value): Node.__init__(self, name) - self.type = type + self.type = Type(type_name) self.value = value def __repr__(self): @@ -128,9 +137,9 @@ class Constant(Node): class Property(Node): - def __init__(self, name, type): + def __init__(self, name, type_name): Node.__init__(self, name) - self.type = type + self.type = Type(type_name) def __repr__(self): return '%s(%r, %r, %r)' % ( @@ -147,3 +156,10 @@ class Callback(Node): def __repr__(self): return 'Callback(%r, %r, %r)' % ( self.name, self.retval, self.parameters) + + +class Sequence(Type): + # Subclass, because a Sequence is a kind of Type + def __init__(self, name, element_type): + Type.__init__(self, name) + self.element_type = element_type diff --git a/giscanner/gidlwriter.py b/giscanner/gidlwriter.py index db1aa79f..8b28289c 100644 --- a/giscanner/gidlwriter.py +++ b/giscanner/gidlwriter.py @@ -69,7 +69,7 @@ class GIDLWriter(XMLWriter): def _write_return_type(self, return_): if not return_: return - attrs = [('type', return_.type)] + attrs = [('type', return_.ctype.name)] if return_.transfer != 'none': attrs.append(('transfer', return_.transfer)) self.write_tag('return-type', attrs) @@ -83,7 +83,7 @@ class GIDLWriter(XMLWriter): def _write_parameter(self, parameter): attrs = [('name', parameter.name), - ('type', parameter.type)] + ('type', parameter.type.name)] if parameter.direction != 'in': attrs.append(('direction', parameter.direction)) if parameter.transfer != 'none': @@ -147,7 +147,7 @@ class GIDLWriter(XMLWriter): def _write_property(self, prop): attrs = [('name', prop.name), - ('prop', prop.type)] + ('prop', prop.type.name)] self.write_tag('property', attrs) def _write_signal(self, signal): diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index bb3b033c..4c0df8fa 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -19,7 +19,7 @@ from __future__ import with_statement -from .ast import Callback, Class, Enum, Function, Interface +from .ast import (Callback, Class, Enum, Function, Interface, Sequence) from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags, GLibObject, GLibInterface) from .xmlwriter import XMLWriter @@ -75,12 +75,12 @@ class GIRWriter(XMLWriter): def _write_return_type(self, return_): if not return_: return - with self.tagcontext('return-values'): - with self.tagcontext('return-value'): - attrs = [('name', return_.type)] - if return_.transfer != 'none': - attrs.append(('transfer', return_.transfer)) - self.write_tag('type', attrs) + attrs = [('c:identifer', return_.type.name)] + with self.tagcontext('return-value', attrs): + if isinstance(return_.type, Sequence): + self._write_sequence(return_.type) + else: + self._write_type(return_.type) def _write_parameters(self, parameters): if not parameters: @@ -95,8 +95,17 @@ class GIRWriter(XMLWriter): attrs.append(('direction', parameter.direction)) if parameter.transfer != 'none': attrs.append(('transfer', parameter.transfer)) - with self.tagcontext('parameters', attrs): - self.write_tag('type', [('name', parameter.type)]) + with self.tagcontext('parameter', attrs): + self._write_type(parameter.type) + + def _write_type(self, type): + self.write_tag('type', [('name', type.name)]) + + def _write_sequence(self, sequence): + attrs = [('c:owner', sequence.cowner)] + with self.tagcontext('sequence', attrs): + attrs = [('c:identifier', sequence.element_type)] + self.write_tag('element-type', attrs) def _write_enum(self, enum): attrs = [('name', enum.name)] @@ -151,7 +160,7 @@ class GIRWriter(XMLWriter): def _write_property(self, prop): attrs = [('name', prop.name), - ('prop', prop.type)] + ('prop', prop.type.name)] self.write_tag('property', attrs) def _write_callback(self, callback): diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py index 54ff49d7..3812939a 100644 --- a/giscanner/glibtransformer.py +++ b/giscanner/glibtransformer.py @@ -23,10 +23,10 @@ import os from . import cgobject from .odict import odict -from .ast import (Callback, Enum, Function, - Parameter, Property, Return, Struct) -from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags, GLibInterface, - GLibObject, GLibSignal) +from .ast import (Callback, Enum, Function, Parameter, Property, Return, + Sequence, Struct) +from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags, + GLibInterface, GLibObject, GLibSignal) # Copied from h2defs.py @@ -131,10 +131,9 @@ class GLibTransformer(object): return type_name def _resolve_param_type(self, ptype): - type_name = ptype.replace('*', '') - resolved_type_name = self._resolve_type_name(type_name) - if type_name != resolved_type_name: - return ptype.replace(type_name, resolved_type_name) + type_name = ptype.name.replace('*', '') + ptype.name = ptype.name.replace(type_name, + self._resolve_type_name(type_name)) return ptype def _parse_node(self, node): @@ -176,7 +175,7 @@ class GLibTransformer(object): symbol = func.name if not symbol.endswith('_get_type'): return False - if func.retval.type != 'GType': + if func.retval.type.name != 'GType': return False if func.parameters: return False @@ -195,7 +194,7 @@ class GLibTransformer(object): # FIXME: This is hackish, we should preserve the pointer structures # here, so we can find pointers to objects and not just # pointers to anything - first_arg = func.parameters[0].type + first_arg = func.parameters[0].type.name if first_arg.count('*') != 1: return False @@ -207,10 +206,10 @@ class GLibTransformer(object): # here, so we can find pointers to objects and not just # pointers to anything rtype = func.retval.type - if rtype.count('*') != 1: + if rtype.name.count('*') != 1: return False - object_name = rtype.replace('*', '') + object_name = rtype.name.replace('*', '') return self._parse_method_common(func, object_name, is_method=False) def _parse_method_common(self, func, object_name, is_method): diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l index 9870efd7..51355c2a 100644 --- a/giscanner/scannerlexer.l +++ b/giscanner/scannerlexer.l @@ -227,23 +227,32 @@ parse_gtkdoc (GISourceScanner *scanner, { char *ptr = parts[1]; GString *current = NULL; - gboolean open = (*ptr == '('); + gint8 pstack = 0; current = g_string_new (""); value = parts[2]; - while (*ptr++) + do { if (*ptr == '(') - open = TRUE; - else if (*ptr != ')' && open) - g_string_append_c (current, *ptr); - else if (*ptr == ')') { - options = g_slist_prepend (options, g_strdup (current->str)); - open = FALSE; - } + { + pstack++; + if (pstack == 1) + continue; + } + else if (*ptr == ')') + pstack--; + + if (pstack == 0) + { + options = g_slist_prepend (options, current->str); + break; + } + g_string_append_c (current, *ptr); } - g_string_free (current, TRUE); + while (*ptr++); + + g_string_free (current, FALSE); } else value = parts[1]; diff --git a/giscanner/transformer.py b/giscanner/transformer.py index 6a7a6bb6..1bdc36b5 100644 --- a/giscanner/transformer.py +++ b/giscanner/transformer.py @@ -19,7 +19,7 @@ import giscanner from giscanner.ast import (Callback, Enum, Function, Member, Parameter, - Return, Struct) + Return, Sequence, Struct) class Transformer(object): @@ -120,11 +120,20 @@ class Transformer(object): option,) return param - def _create_return(self, symbol, options): - return_ = Return(self._create_source_type(symbol)) + def _create_return(self, source_type, options=None): + if not options: + options = [] + return_type = self._create_source_type(source_type) + return_ = Return(return_type) for option in options: if option == 'caller-owns': return_.transfer = 'full' + elif option.startswith('seq '): + value, element_options = option[3:].split(None, 2) + element_type = self._parse_type_annotation(value) + seq = Sequence(return_type, element_type) + seq.cowner = 'caller' + return_.type = seq else: print 'Unhandled parameter annotation option: %s' % ( option,) @@ -143,5 +152,11 @@ class Transformer(object): def _create_callback(self, symbol): parameters = self._create_parameters(symbol.base_type.base_type) - retval = Return(self._create_source_type(symbol.base_type.base_type.base_type)) + retval = self._create_return(symbol.base_type.base_type.base_type) return Callback(symbol.ident, retval, list(parameters)) + + def _parse_type_annotation(self, annotation): + if (annotation[0] == "[" and + annotation[-1] == "]"): + return Sequence(self._parse_type_annotation(annotation[1:-1])) + return annotation |