summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--giscanner/ast.py12
-rw-r--r--giscanner/girwriter.py24
-rw-r--r--giscanner/maintransformer.py34
-rw-r--r--tests/scanner/Regress-1.0-C-expected/Regress.AnnotationFields.page25
-rw-r--r--tests/scanner/Regress-1.0-expected.gir14
-rw-r--r--tests/scanner/annotation.h15
6 files changed, 106 insertions, 18 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py
index a30a6a72..bd536c63 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -888,6 +888,18 @@ class Compound(Node, Registered):
if field.anonymous_node is not None:
field.anonymous_node.walk(callback, chain)
+ def get_field(self, name):
+ for field in self.fields:
+ if field.name == name:
+ return field
+ raise ValueError("Unknown field %s" % (name, ))
+
+ def get_field_index(self, name):
+ for i, field in enumerate(self.fields):
+ if field.name == name:
+ return i
+ raise ValueError("Unknown field %s" % (name, ))
+
class Field(Annotated):
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 78ad7e43..304cf322 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -217,7 +217,7 @@ class GIRWriter(XMLWriter):
attrs.append(('skip', '1'))
with self.tagcontext('return-value', attrs):
self._write_generic(return_)
- self._write_type(return_.type, function=parent)
+ self._write_type(return_.type, parent=parent)
def _write_parameters(self, callable):
if not callable.parameters and callable.instance_parameter is None:
@@ -253,7 +253,7 @@ class GIRWriter(XMLWriter):
attrs.append(('skip', '1'))
with self.tagcontext(nodename, attrs):
self._write_generic(parameter)
- self._write_type(parameter.type, function=parent)
+ self._write_type(parameter.type, parent=parent)
def _type_to_name(self, typeval):
if not typeval.resolved:
@@ -286,7 +286,7 @@ class GIRWriter(XMLWriter):
self.write_tag('type', attrs)
- def _write_type(self, ntype, relation=None, function=None):
+ def _write_type(self, ntype, relation=None, parent=None):
assert isinstance(ntype, ast.Type), ntype
attrs = []
if ntype.complete_ctype:
@@ -309,8 +309,12 @@ class GIRWriter(XMLWriter):
if ntype.size is not None:
attrs.append(('fixed-size', '%d' % (ntype.size, )))
if ntype.length_param_name is not None:
- assert function
- length = function.get_parameter_index(ntype.length_param_name)
+ if isinstance(parent, ast.Callable):
+ length = parent.get_parameter_index(ntype.length_param_name)
+ elif isinstance(parent, ast.Compound):
+ length = parent.get_field_index(ntype.length_param_name)
+ else:
+ assert False, "parent not a callable or compound: %r" % parent
attrs.insert(0, ('length', '%d' % (length, )))
with self.tagcontext('array', attrs):
@@ -445,7 +449,7 @@ class GIRWriter(XMLWriter):
for prop in sorted(node.properties):
self._write_property(prop)
for field in node.fields:
- self._write_field(field)
+ self._write_field(field, node)
for signal in sorted(node.signals):
self._write_signal(signal)
@@ -518,7 +522,7 @@ class GIRWriter(XMLWriter):
self._write_generic(record)
if record.fields:
for field in record.fields:
- self._write_field(field, is_gtype_struct)
+ self._write_field(field, record, is_gtype_struct)
for method in sorted(record.constructors):
self._write_constructor(method)
for method in sorted(record.methods):
@@ -541,7 +545,7 @@ class GIRWriter(XMLWriter):
self._write_generic(union)
if union.fields:
for field in union.fields:
- self._write_field(field)
+ self._write_field(field, union)
for method in sorted(union.constructors):
self._write_constructor(method)
for method in sorted(union.methods):
@@ -549,7 +553,7 @@ class GIRWriter(XMLWriter):
for method in sorted(union.static_methods):
self._write_static_method(method)
- def _write_field(self, field, is_gtype_struct=False):
+ def _write_field(self, field, parent, is_gtype_struct=False):
if field.anonymous_node:
if isinstance(field.anonymous_node, ast.Callback):
attrs = [('name', field.name)]
@@ -577,7 +581,7 @@ class GIRWriter(XMLWriter):
attrs.append(('private', '1'))
with self.tagcontext('field', attrs):
self._write_generic(field)
- self._write_type(field.type)
+ self._write_type(field.type, parent=parent)
def _write_signal(self, signal):
attrs = [('name', signal.name)]
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index d0eae900..08783131 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -130,6 +130,20 @@ class MainTransformer(object):
return param.argname
+ def _get_validate_field_name(self, parent, field_name, origin):
+ try:
+ field = parent.get_field(field_name)
+ except ValueError:
+ field = None
+ if field is None:
+ origin_name = 'field %s' % (origin.name, )
+ message.log_node(
+ message.FATAL, parent,
+ "can't find field %s referenced by %s of %r"
+ % (field_name, origin_name, parent.name))
+
+ return field.name
+
def _apply_annotation_rename_to(self, node, chain, block):
if not block:
return
@@ -375,13 +389,17 @@ class MainTransformer(object):
length = array_options.get(OPT_ARRAY_LENGTH)
if length:
- paramname = self._get_validate_parameter_name(parent, length, node)
+ if isinstance(parent, ast.Compound):
+ paramname = self._get_validate_field_name(parent, length, node)
+ else:
+ paramname = self._get_validate_parameter_name(parent, length, node)
+ if paramname:
+ param = parent.get_parameter(paramname)
+ param.direction = node.direction
+ if param.direction == ast.PARAM_DIRECTION_OUT:
+ param.transfer = ast.PARAM_TRANSFER_FULL
if paramname:
- param = parent.get_parameter(paramname)
- param.direction = node.direction
- if param.direction == ast.PARAM_DIRECTION_OUT:
- param.transfer = ast.PARAM_TRANSFER_FULL
- container_type.length_param_name = param.argname
+ container_type.length_param_name = paramname
fixed = array_options.get(OPT_ARRAY_FIXED_SIZE)
if fixed:
try:
@@ -728,8 +746,8 @@ class MainTransformer(object):
try:
self._adjust_container_type(parent, field, tag.annotations)
- except AttributeError:
- pass
+ except AttributeError, ex:
+ print ex
def _apply_annotations_property(self, parent, prop):
prefix = self._get_annotation_name(parent)
diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.AnnotationFields.page b/tests/scanner/Regress-1.0-C-expected/Regress.AnnotationFields.page
new file mode 100644
index 00000000..74c6eab8
--- /dev/null
+++ b/tests/scanner/Regress-1.0-C-expected/Regress.AnnotationFields.page
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<page id="Regress.AnnotationFields"
+ type="topic"
+ style="record"
+ xmlns="http://projectmallard.org/1.0/"
+ xmlns:api="http://projectmallard.org/experimental/api/"
+ xmlns:ui="http://projectmallard.org/1.0/ui/">
+ <info>
+
+ <link xref="index" group="record" type="guide"/>
+
+ </info>
+ <title>Regress.AnnotationFields</title>
+
+
+
+ <p>This is a struct for testing field documentation and annotations</p>
+
+
+
+
+
+
+
+</page>
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index bb83e225..925fe538 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -87,6 +87,20 @@ and/or use gtk-doc annotations. -->
</parameter>
</parameters>
</callback>
+ <record name="AnnotationFields" c:type="RegressAnnotationFields">
+ <doc xml:space="preserve">This is a struct for testing field documentation and annotations</doc>
+ <field name="field1" writable="1">
+ <type name="gint" c:type="int"/>
+ </field>
+ <field name="arr" writable="1">
+ <array length="2" zero-terminated="0" c:type="guchar*">
+ <type name="guint8" c:type="guchar"/>
+ </array>
+ </field>
+ <field name="len" writable="1">
+ <type name="gulong" c:type="gulong"/>
+ </field>
+ </record>
<callback name="AnnotationForeachFunc"
c:type="RegressAnnotationForeachFunc">
<return-value transfer-ownership="none">
diff --git a/tests/scanner/annotation.h b/tests/scanner/annotation.h
index 2084da29..b0cbe42d 100644
--- a/tests/scanner/annotation.h
+++ b/tests/scanner/annotation.h
@@ -159,6 +159,21 @@ struct RegressAnnotationStruct
RegressAnnotationObject *objects[10];
};
+/**
+ * RegressAnnotationFields:
+ * @field1: Some documentation
+ * @arr: (array length=len): an array of length @len
+ * @len: the length of array
+ *
+ * This is a struct for testing field documentation and annotations
+ */
+struct RegressAnnotationFields
+{
+ int field1;
+ guchar *arr;
+ gulong len;
+};
+
void regress_annotation_ptr_array (GPtrArray *array);
GObject * regress_annotation_test_parsing_bug630862 (void);