diff options
-rw-r--r-- | giscanner/annotationparser.py | 26 | ||||
-rw-r--r-- | giscanner/ast.py | 20 | ||||
-rw-r--r-- | tests/scanner/annotation-1.0-expected.gir | 21 | ||||
-rw-r--r-- | tests/scanner/annotation-1.0-expected.tgir | 16 | ||||
-rw-r--r-- | tests/scanner/annotation.c | 35 | ||||
-rw-r--r-- | tests/scanner/annotation.h | 7 |
6 files changed, 124 insertions, 1 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py index e94afa34..fae839f0 100644 --- a/giscanner/annotationparser.py +++ b/giscanner/annotationparser.py @@ -47,6 +47,7 @@ TAG_DEPRECATED = 'deprecated' TAG_RETURNS = 'returns' TAG_RETURNS_ALT = 'return value' TAG_ATTRIBUTES = 'attributes' +TAG_RENAME_TO = 'rename to' # Options - annotations for parameters and return values OPT_ALLOW_NONE = 'allow-none' @@ -103,6 +104,8 @@ class DocTag(object): self.options = {} self.comment = None + def __repr__(self): + return '<DocTag %r %r>' % (self.name, self.options) class Option(object): @@ -270,8 +273,10 @@ class AnnotationApplier(object): return block.get(tag_name) def parse(self, namespace): - for node in namespace.nodes: + self._namespace = namespace + for node in namespace.nodes[:]: self._parse_node(node) + del self._namespace # Boring parsing boilerplate. @@ -409,6 +414,7 @@ class AnnotationApplier(object): def _parse_function(self, func): block = self._blocks.get(func.symbol) self._parse_callable(func, block) + self._parse_rename_to_func(func, block) def _parse_signal(self, parent, signal): block = self._blocks.get('%s::%s' % (parent.type_name, signal.name)) @@ -646,6 +652,24 @@ class AnnotationApplier(object): for key, value in annos_tag.options.iteritems(): node.attributes.append((key, value.one())) + def _parse_rename_to_func(self, node, block): + rename_to_tag = self._get_tag(block, TAG_RENAME_TO) + if rename_to_tag is None: + return + new_name = rename_to_tag.value + + shadowed = [] + + def shadowed_filter(n): + if isinstance(n, Function) and n.symbol == new_name: + shadowed.append(n) + return False + return True + + self._namespace.remove_matching(shadowed_filter) + assert len(shadowed) == 1 + node.name = shadowed[0].name + def _guess_direction(self, node): if node.direction: return node.direction diff --git a/giscanner/ast.py b/giscanner/ast.py index 0f0d1bb5..0d3f0bb8 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -158,6 +158,8 @@ class Node(object): def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.name) + def remove_matching_children(self, pred): + pass class Namespace(Node): @@ -170,6 +172,13 @@ class Namespace(Node): return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name, self.version, self.nodes) + def remove_matching(self, pred): + + def recursive_pred(node): + node.remove_matching_children(pred) + return pred(node) + + self.nodes = filter(recursive_pred, self.nodes) class Include(Node): @@ -384,6 +393,11 @@ class Record(Node): self.doc = None self.methods = [] + def remove_matching_children(self, pred): + self.fields = filter(pred, self.fields) + self.constructors = filter(pred, self.constructors) + self.methods = filter(pred, self.methods) + # BW compat, remove Struct = Record @@ -433,6 +447,12 @@ class Class(Node): self.fields = [] self.doc = None + def remove_matching_children(self, pred): + self.methods = filter(pred, self.methods) + self.constructors = filter(pred, self.constructors) + self.properties = filter(pred, self.properties) + self.fields = filter(pred, self.fields) + def __repr__(self): return '%s(%r, %r, %r)' % ( self.__class__.__name__, diff --git a/tests/scanner/annotation-1.0-expected.gir b/tests/scanner/annotation-1.0-expected.gir index 91fe5611..e82201e4 100644 --- a/tests/scanner/annotation-1.0-expected.gir +++ b/tests/scanner/annotation-1.0-expected.gir @@ -430,6 +430,27 @@ type."> <type name="GObject.Object" c:type="GObject*"/> </return-value> </method> + <method name="watch" + c:identifier="annotation_object_watch_full" + doc="Test overriding via the "Rename To" annotation."> + <return-value transfer-ownership="none"> + <type name="none" c:type="void"/> + </return-value> + <parameters> + <parameter name="func" + transfer-ownership="none" + closure="2" + destroy="3"> + <type name="ForeachFunc" c:type="AnnotationForeachFunc"/> + </parameter> + <parameter name="user_data" transfer-ownership="none"> + <type name="any" c:type="gpointer"/> + </parameter> + <parameter name="destroy" transfer-ownership="none"> + <type name="GLib.DestroyNotify" c:type="GDestroyNotify"/> + </parameter> + </parameters> + </method> <method name="extra_annos" c:identifier="annotation_object_extra_annos"> <attribute name="org.foobar" value="testvalue"/> <return-value transfer-ownership="none"> diff --git a/tests/scanner/annotation-1.0-expected.tgir b/tests/scanner/annotation-1.0-expected.tgir index 3629d5ff..0d88c47b 100644 --- a/tests/scanner/annotation-1.0-expected.tgir +++ b/tests/scanner/annotation-1.0-expected.tgir @@ -324,6 +324,22 @@ <type name="GObject.Object"/> </return-value> </method> + <method name="watch" c:identifier="annotation_object_watch_full"> + <return-value transfer-ownership="none"> + <type name="none"/> + </return-value> + <parameters> + <parameter name="func" transfer-ownership="none" closure="2" destroy="3"> + <type name="ForeachFunc"/> + </parameter> + <parameter name="user_data" transfer-ownership="none"> + <type name="any"/> + </parameter> + <parameter name="destroy" transfer-ownership="none"> + <type name="GLib.DestroyNotify"/> + </parameter> + </parameters> + </method> <method name="extra_annos" c:identifier="annotation_object_extra_annos"> <attribute name="org.foobar" value="testvalue"/> <return-value transfer-ownership="none"> diff --git a/tests/scanner/annotation.c b/tests/scanner/annotation.c index 3dcc6be7..7c25d9a2 100644 --- a/tests/scanner/annotation.c +++ b/tests/scanner/annotation.c @@ -513,6 +513,41 @@ annotation_object_do_not_use (AnnotationObject *object) } /** + * annotation_object_watch: + * @object: A #AnnotationObject + * @func: The callback + * @user_data: The callback data + * + * This is here just for the sake of being overriden by its + * annotation_object_watch_full(). + */ +void +annotation_object_watch (AnnotationObject *object, + AnnotationForeachFunc func, + gpointer user_data) +{ +} + +/** + * annotation_object_watch_full: + * @object: A #AnnotationObject + * @func: The callback + * @user_data: The callback data + * @destroy: Destroy notification + * + * Test overriding via the "Rename To" annotation. + * + * Rename to: annotation_object_watch + */ +void +annotation_object_watch_full (AnnotationObject *object, + AnnotationForeachFunc func, + gpointer user_data, + GDestroyNotify destroy) +{ +} + +/** * annotation_init: * @argc: (inout): The number of args. * @argv: (inout) (array length=argc): The arguments. diff --git a/tests/scanner/annotation.h b/tests/scanner/annotation.h index 102b571a..e43e7ba6 100644 --- a/tests/scanner/annotation.h +++ b/tests/scanner/annotation.h @@ -105,6 +105,13 @@ void annotation_object_set_data3 (AnnotationObject *object, gsize length); GObject* annotation_object_do_not_use (AnnotationObject *object); +void annotation_object_watch (AnnotationObject *object, + AnnotationForeachFunc func, + gpointer user_data); +void annotation_object_watch_full (AnnotationObject *object, + AnnotationForeachFunc func, + gpointer user_data, + GDestroyNotify destroy); void annotation_init (int *argc, char ***argv); |