summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Merry <dev@randomguy3.me.uk>2010-12-13 18:35:15 +0000
committerAlex Merry <dev@randomguy3.me.uk>2010-12-13 18:35:15 +0000
commit82a80f89e04c4ba208bdd8bf24e01b0286dd124d (patch)
tree2e643c1a1cf5c591d66eeac855695a527b1d5f3a
parent8e556c3fe22eb1ee7f07dc4801bbe7d6aaa41144 (diff)
Make a note of annotations when parsing the spec.
-rw-r--r--doc/templates/interface.html2
-rw-r--r--doc/templates/style.css9
-rw-r--r--tools/specparser.py81
3 files changed, 90 insertions, 2 deletions
diff --git a/doc/templates/interface.html b/doc/templates/interface.html
index 279bed01..2d19eff7 100644
--- a/doc/templates/interface.html
+++ b/doc/templates/interface.html
@@ -237,6 +237,7 @@
$method.get_added()
$method.get_changed()
$method.get_deprecated()
+ $method.get_no_reply()
#if $method.in_args
<div class="indent">
@@ -412,6 +413,7 @@
$property.get_added()
$property.get_changed()
$property.get_deprecated()
+ $property.get_emits_changed()
#if $property.is_connection_parameter:
<div class="annotation connection-parameter">
diff --git a/doc/templates/style.css b/doc/templates/style.css
index bca3d8da..85cd6f14 100644
--- a/doc/templates/style.css
+++ b/doc/templates/style.css
@@ -223,6 +223,7 @@ div.havoc {
}
div.deprecated span.version,
+div.deprecated.no-version,
span.warning {
color: #a40000;
}
@@ -235,10 +236,18 @@ div.connection-parameter .note {
color: #0000a4;
}
+div.emits-changed {
+ border-left-color: #17BBC3;
+}
+
div.immutable {
border-left-color: #02598f;
}
+div.no-reply {
+ border-left-color: #9C11A1;
+}
+
div.requestable {
border-left-color: #598f02;
}
diff --git a/tools/specparser.py b/tools/specparser.py
index 0baf3f1b..37ded16d 100644
--- a/tools/specparser.py
+++ b/tools/specparser.py
@@ -75,6 +75,13 @@ def getChildrenByName(dom, namespace, name):
n.localName == name,
dom.childNodes)
+def getChildrenByNameAndAttribute(dom, namespace, name, attribute, value):
+ return filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
+ n.namespaceURI == namespace and \
+ n.localName == name and \
+ n.getAttribute(attribute) == value,
+ dom.childNodes)
+
def getOnlyChildByName(dom, namespace, name):
kids = getChildrenByName(dom, namespace, name)
@@ -88,6 +95,19 @@ def getOnlyChildByName(dom, namespace, name):
return kids[0]
+def getAnnotationByName(dom, name):
+ kids = getChildrenByNameAndAttribute(dom, None, 'annotation', 'name', name)
+
+ if len(kids) == 0:
+ return None
+
+ if len(kids) > 1:
+ raise WrongNumberOfChildren(
+ '<%s> node should have at most one %s annotation' %
+ (dom.tagName, name))
+
+ return kids[0].getAttribute('value')
+
def getNamespace(n):
if n.namespaceURI is not None:
return n.namespaceURI
@@ -142,6 +162,9 @@ class Base(object):
self.docstring = getOnlyChildByName(dom, XMLNS_TP, 'docstring')
self.added = getOnlyChildByName(dom, XMLNS_TP, 'added')
self.deprecated = getOnlyChildByName(dom, XMLNS_TP, 'deprecated')
+ self.is_deprecated = True
+ if self.deprecated == None:
+ self.is_deprecated = getAnnotationByName(dom, 'org.freedesktop.DBus.Deprecated') == 'true'
self.changed = getChildrenByName(dom, XMLNS_TP, 'changed')
@@ -211,8 +234,14 @@ class Base(object):
"Added in %s.")
def get_deprecated(self):
- return self._get_generic_with_ver(self.deprecated, 'deprecated',
- "Deprecated since %s.")
+ if self.deprecated is None:
+ if self.is_deprecated:
+ return '<div class="annotation deprecated no-version">Deprecated.</div>'
+ else:
+ return ''
+ else:
+ return self._get_generic_with_ver(self.deprecated, 'deprecated',
+ "Deprecated since %s.")
def get_changed(self):
return '\n'.join(map(lambda n:
@@ -480,6 +509,8 @@ class Method(DBusConstruct):
self.possible_errors = build_list(self, PossibleError, None,
dom.getElementsByTagNameNS(XMLNS_TP, 'error'))
+ self.no_reply = getAnnotationByName(dom, 'org.freedesktop.DBus.Method.NoReply') == 'true'
+
def get_in_args(self):
return ', '.join(map(lambda a: a.spec_name(), self.in_args))
@@ -489,6 +520,13 @@ class Method(DBusConstruct):
else:
return 'nothing'
+ def get_no_reply(self):
+ if self.no_reply:
+ return '<div class="annotation no-reply">' \
+ 'The caller should not expect a reply when calling this method.</div>'
+ else:
+ return ''
+
def check_consistency(self):
for x in self.in_args:
x.check_consistency()
@@ -557,6 +595,11 @@ class Property(DBusConstruct, Typed):
ACCESS_READWRITE = ACCESS_READ | ACCESS_WRITE
+ EMITS_CHANGED_UNKNOWN = 0
+ EMITS_CHANGED_NONE = 1
+ EMITS_CHANGED_UPDATES = 2
+ EMITS_CHANGED_INVALIDATES = 3
+
def __init__(self, parent, namespace, dom):
super(Property, self).__init__(parent, namespace, dom)
@@ -581,6 +624,21 @@ class Property(DBusConstruct, Typed):
self.requestable = requestable != ''
self.sometimes_requestable = requestable == 'sometimes'
+ # According to the D-Bus specification, EmitsChangedSignal defaults
+ # to true, but - realistically - this cannot be assumed for old specs.
+ # As a result, we treat the absence of the annotation as "unknown".
+ emits_changed = getAnnotationByName(dom, 'org.freedesktop.DBus.Property.EmitsChangedSignal')
+ if emits_changed is None:
+ emits_changed = getAnnotationByName(dom.parentNode, 'org.freedesktop.DBus.Property.EmitsChangedSignal')
+ if emits_changed == 'true':
+ self.emits_changed = self.EMITS_CHANGED_UPDATES;
+ elif emits_changed == 'invalidates':
+ self.emits_changed = self.EMITS_CHANGED_INVALIDATES;
+ elif emits_changed == 'false':
+ self.emits_changed = self.EMITS_CHANGED_NONE;
+ else:
+ self.emits_changed = self.EMITS_CHANGED_UNKNOWN;
+
def get_access(self):
if self.access & self.ACCESS_READ and self.access & self.ACCESS_WRITE:
return 'Read/Write'
@@ -604,6 +662,25 @@ class Property(DBusConstruct, Typed):
return ', '.join(descriptions)
+ def get_emits_changed(self):
+ if self.emits_changed == self.EMITS_CHANGED_UPDATES:
+ return '<div class="annotation emits-changed emits-changed-updates">' \
+ 'When this property changes, the ' \
+ '<literal>org.freedesktop.DBus.Properties.PropertiesChanged</literal> ' \
+ 'signal is emitted with the new value.</div>';
+ elif self.emits_changed == self.EMITS_CHANGED_INVALIDATES:
+ return '<div class="annotation emits-changed emits-changed-invalidates">' \
+ 'When this property changes, the ' \
+ '<literal>org.freedesktop.DBus.Properties.PropertiesChanged</literal> ' \
+ 'signal is emitted, but the new value is not sent.</div>';
+ elif self.emits_changed == self.EMITS_CHANGED_NONE:
+ return '<div class="annotation emits-changed emits-changed-none">' \
+ 'The ' \
+ '<literal>org.freedesktop.DBus.Properties.PropertiesChanged</literal> ' \
+ 'signal is <strong>not</strong> emitted when this property changes.</div>';
+ else:
+ return '';
+
class AwkwardTelepathyProperty(Typed):
def get_type_name(self):
return 'Telepathy Property'