summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--giscanner/annotationparser.py26
-rw-r--r--giscanner/ast.py20
-rw-r--r--tests/scanner/annotation-1.0-expected.gir21
-rw-r--r--tests/scanner/annotation-1.0-expected.tgir16
-rw-r--r--tests/scanner/annotation.c35
-rw-r--r--tests/scanner/annotation.h7
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 &quot;Rename To&quot; 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);