diff options
-rw-r--r-- | giscanner/ast.py | 12 | ||||
-rw-r--r-- | giscanner/girwriter.py | 24 | ||||
-rw-r--r-- | giscanner/maintransformer.py | 34 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-C-expected/Regress.AnnotationFields.page | 25 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-expected.gir | 14 | ||||
-rw-r--r-- | tests/scanner/annotation.h | 15 |
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); |