[PATCH 01/13] qapi: Memorize since & returns sections

Markus Armbruster posted 13 patches 9 months ago
Maintainers: Markus Armbruster <armbru@redhat.com>, Michael Roth <michael.roth@amd.com>, Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Eric Blake <eblake@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Yanan Wang <wangyanan55@huawei.com>, Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>, Jason Wang <jasowang@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Stefan Berger <stefanb@linux.vnet.ibm.com>, Gerd Hoffmann <kraxel@redhat.com>, Lukas Straub <lukasstraub2@web.de>, Konstantin Kostiuk <kkostiuk@redhat.com>
[PATCH 01/13] qapi: Memorize since & returns sections
Posted by Markus Armbruster 9 months ago
This is chiefly to make code that looks up these sections easier to
read.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 scripts/qapi/parser.py | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index 11707418fb..bfc47cf3cb 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -639,6 +639,10 @@ def __init__(self, info: QAPISourceInfo, symbol: Optional[str] = None):
         # dicts mapping parameter/feature names to their description
         self.args: Dict[str, QAPIDoc.ArgSection] = {}
         self.features: Dict[str, QAPIDoc.ArgSection] = {}
+        # a command's "Returns" section
+        self.returns: Optional[QAPIDoc.Section] = None
+        # "Since" section
+        self.since: Optional[QAPIDoc.Section] = None
         # sections other than .body, .args, .features
         self.sections: List[QAPIDoc.Section] = []
 
@@ -660,14 +664,17 @@ def ensure_untagged_section(self, info: QAPISourceInfo) -> None:
         self.all_sections.append(section)
 
     def new_tagged_section(self, info: QAPISourceInfo, tag: str) -> None:
-        if tag in ('Returns', 'Since'):
-            for section in self.all_sections:
-                if isinstance(section, self.ArgSection):
-                    continue
-                if section.tag == tag:
-                    raise QAPISemError(
-                        info, "duplicated '%s' section" % tag)
         section = self.Section(info, tag)
+        if tag == 'Returns':
+            if self.returns:
+                raise QAPISemError(
+                    info, "duplicated '%s' section" % tag)
+            self.returns = section
+        elif tag == 'Since':
+            if self.since:
+                raise QAPISemError(
+                    info, "duplicated '%s' section" % tag)
+            self.since = section
         self.sections.append(section)
         self.all_sections.append(section)
 
@@ -708,13 +715,9 @@ def connect_feature(self, feature: 'QAPISchemaFeature') -> None:
         self.features[feature.name].connect(feature)
 
     def check_expr(self, expr: QAPIExpression) -> None:
-        if 'command' not in expr:
-            sec = next((sec for sec in self.sections
-                        if sec.tag == 'Returns'),
-                       None)
-            if sec:
-                raise QAPISemError(sec.info,
-                                   "'Returns:' is only valid for commands")
+        if self.returns and 'command' not in expr:
+            raise QAPISemError(self.returns.info,
+                               "'Returns:' is only valid for commands")
 
     def check(self) -> None:
 
-- 
2.43.0