summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2008-04-27 23:27:17 +0000
committerJohan Dahlin <johan@src.gnome.org>2008-04-27 23:27:17 +0000
commitbc995eb2d5af650e33ec6dc5c8722ae27aa124b7 (patch)
tree35b80bb86d7ce8fa5ada279862fb979344958f4f
parent65c706f0d9c2dd8ac34bcf9fe7b399eccea25fdc (diff)
downloadgobject-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--ChangeLog13
-rw-r--r--giscanner/ast.py32
-rw-r--r--giscanner/gidlwriter.py6
-rw-r--r--giscanner/girwriter.py29
-rw-r--r--giscanner/glibtransformer.py23
-rw-r--r--giscanner/scannerlexer.l29
-rw-r--r--giscanner/transformer.py23
7 files changed, 108 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index e681e6b6..9ba9ac08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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