]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
qapi: Clean up doc comment checking for implicit union base
authorMarkus Armbruster <armbru@redhat.com>
Thu, 24 Oct 2019 11:02:28 +0000 (13:02 +0200)
committerMarkus Armbruster <armbru@redhat.com>
Tue, 29 Oct 2019 06:35:16 +0000 (07:35 +0100)
An object type's doc comment describes the type's members, less the
ones defined in a named base type.  Cases:

* Struct: the members are defined in 'data' and inherited from 'base'.
  Since the base type cannot be implicit, the doc comment describes
  just 'data'.

* Simple union: the only member is the implicit tag member @type, and
  the doc comment describes it.

* Flat union with implicit base type: the members are defined in
  'base', and the doc comment describes it.

* Flat union with named base type: the members are inherited from
  'base'.  The doc comment describes no members.

Before we can check a doc comment with .check_doc(), we need
.connect_doc() connect each of its "argument sections" to the member
it documents.

For structs and simple unions, this is straightforward: the members in
question are in .local_members, and .connect_doc() connects them.

For flat unions with a named base type, it's trivial: .local_members
is empty, and .connect_doc() does nothing.

For flat unions with an implicit base type, it's tricky.  We have
QAPISchema._make_implicit_object_type() forward the union's doc
comment to the implicit base type, so that the base type's
.connect_doc() connects the members.  The union's .connect_doc() does
nothing, as .local_members is empty.

Dirt effect: we check the doc comment twice, once for the union type,
and once for the implicit base type.

This is needlessly brittle and hard to understand.  Clean up as
follows.  Make the union's .connect_doc() connect an implicit base's
members itself.  Do not forward the union's doc comment to its
implicit base type.

Requires extending .connect_doc() so it can work with a doc comment
other than self.doc.  Add an optional argument for that.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20191024110237.30963-11-armbru@redhat.com>

scripts/qapi/schema.py

index 0381e3cb405db6a989bd20b98cabe42580883674..c16dce1fe0e6b39287f111c15116d0d72ac1a519 100644 (file)
@@ -51,7 +51,7 @@ class QAPISchemaEntity(object):
                                            os.path.dirname(schema.fname))
         self._checked = True
 
-    def connect_doc(self):
+    def connect_doc(self, doc=None):
         pass
 
     def check_doc(self):
@@ -224,10 +224,11 @@ class QAPISchemaEnumType(QAPISchemaType):
         for m in self.members:
             m.check_clash(self.info, seen)
 
-    def connect_doc(self):
-        if self.doc:
+    def connect_doc(self, doc=None):
+        doc = doc or self.doc
+        if doc:
             for m in self.members:
-                self.doc.connect_member(m)
+                doc.connect_member(m)
 
     def check_doc(self):
         if self.doc:
@@ -380,10 +381,13 @@ class QAPISchemaObjectType(QAPISchemaType):
         for m in self.members:
             m.check_clash(info, seen)
 
-    def connect_doc(self):
-        if self.doc:
+    def connect_doc(self, doc=None):
+        doc = doc or self.doc
+        if doc:
+            if self.base and self.base.is_implicit():
+                self.base.connect_doc(doc)
             for m in self.local_members:
-                self.doc.connect_member(m)
+                doc.connect_member(m)
 
     def check_doc(self):
         if self.doc:
@@ -657,10 +661,11 @@ class QAPISchemaAlternateType(QAPISchemaType):
                         % (v.describe(self.info), types_seen[qt]))
                 types_seen[qt] = v.name
 
-    def connect_doc(self):
-        if self.doc:
+    def connect_doc(self, doc=None):
+        doc = doc or self.doc
+        if doc:
             for v in self.variants.variants:
-                self.doc.connect_member(v)
+                doc.connect_member(v)
 
     def check_doc(self):
         if self.doc:
@@ -974,7 +979,7 @@ class QAPISchema(object):
         tag_member = None
         if isinstance(base, dict):
             base = self._make_implicit_object_type(
-                name, info, doc, ifcond,
+                name, info, None, ifcond,
                 'base', self._make_members(base, info))
         if tag_name:
             variants = [self._make_variant(key, value['type'],