From f17539c80da3c0ebabbe75a04f5451995367ec91 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 4 Aug 2021 12:30:57 +0400 Subject: qapi: wrap Sequence[str] in an object Mechanical change, except for a new assertion in QAPISchemaEntity.ifcond(). Signed-off-by: Marc-André Lureau Message-Id: <20210804083105.97531-3-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster [Rebased with obvious conflicts, commit message adjusted] Signed-off-by: Markus Armbruster --- docs/sphinx/qapidoc.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/sphinx/qapidoc.py') diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 87c67ab23f..0eac3308b2 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -116,7 +116,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): the conditions are in literal-text and the commas are not. If with_if is False, we don't return the "(If: " and ")". """ - condlist = intersperse([nodes.literal('', c) for c in ifcond], + condlist = intersperse([nodes.literal('', c) for c in ifcond.ifcond], nodes.Text(', ')) if not with_if: return condlist @@ -139,7 +139,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): term.append(nodes.literal('', member.type.doc_type())) if member.optional: term.append(nodes.Text(' (optional)')) - if member.ifcond: + if member.ifcond.ifcond: term.extend(self._nodes_for_ifcond(member.ifcond)) return term @@ -154,7 +154,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): nodes.literal('', variants.tag_member.name), nodes.Text(' is '), nodes.literal('', '"%s"' % variant.name)] - if variant.ifcond: + if variant.ifcond.ifcond: term.extend(self._nodes_for_ifcond(variant.ifcond)) return term @@ -209,7 +209,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): dlnode = nodes.definition_list() for section in doc.args.values(): termtext = [nodes.literal('', section.member.name)] - if section.member.ifcond: + if section.member.ifcond.ifcond: termtext.extend(self._nodes_for_ifcond(section.member.ifcond)) # TODO drop fallbacks when undocumented members are outlawed if section.text: @@ -277,7 +277,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): def _nodes_for_if_section(self, ifcond): """Return list of doctree nodes for the "If" section""" nodelist = [] - if ifcond: + if ifcond.ifcond: snode = self._make_section('If') snode += nodes.paragraph( '', '', *self._nodes_for_ifcond(ifcond, with_if=False) -- cgit v1.2.3-55-g7522 From 33aa3267bacc5a7af363c0ffa5f1bdabba54b989 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 4 Aug 2021 12:30:58 +0400 Subject: qapi: add QAPISchemaIfCond.is_present() Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20210804083105.97531-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- docs/sphinx/qapidoc.py | 8 ++++---- scripts/qapi/introspect.py | 4 ++-- scripts/qapi/schema.py | 7 +++++-- tests/qapi-schema/test-qapi.py | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'docs/sphinx/qapidoc.py') diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 0eac3308b2..511520f33f 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -139,7 +139,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): term.append(nodes.literal('', member.type.doc_type())) if member.optional: term.append(nodes.Text(' (optional)')) - if member.ifcond.ifcond: + if member.ifcond.is_present(): term.extend(self._nodes_for_ifcond(member.ifcond)) return term @@ -154,7 +154,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): nodes.literal('', variants.tag_member.name), nodes.Text(' is '), nodes.literal('', '"%s"' % variant.name)] - if variant.ifcond.ifcond: + if variant.ifcond.is_present(): term.extend(self._nodes_for_ifcond(variant.ifcond)) return term @@ -209,7 +209,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): dlnode = nodes.definition_list() for section in doc.args.values(): termtext = [nodes.literal('', section.member.name)] - if section.member.ifcond.ifcond: + if section.member.ifcond.is_present(): termtext.extend(self._nodes_for_ifcond(section.member.ifcond)) # TODO drop fallbacks when undocumented members are outlawed if section.text: @@ -277,7 +277,7 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): def _nodes_for_if_section(self, ifcond): """Return list of doctree nodes for the "If" section""" nodelist = [] - if ifcond.ifcond: + if ifcond.is_present(): snode = self._make_section('If') snode += nodes.paragraph( '', '', *self._nodes_for_ifcond(ifcond, with_if=False) diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index db1ebbf53a..e23725e2f9 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -123,10 +123,10 @@ def _tree_to_qlit(obj: JSONValue, ret = '' if obj.comment: ret += indent(level) + f"/* {obj.comment} */\n" - if obj.ifcond.ifcond: + if obj.ifcond.is_present(): ret += gen_if(obj.ifcond.ifcond) ret += _tree_to_qlit(obj.value, level) - if obj.ifcond.ifcond: + if obj.ifcond.is_present(): ret += '\n' + gen_endif(obj.ifcond.ifcond) return ret diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index e3beb24500..86fcd6cbd5 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -29,6 +29,9 @@ class QAPISchemaIfCond: def __init__(self, ifcond=None): self.ifcond = ifcond or [] + def is_present(self): + return bool(self.ifcond) + class QAPISchemaEntity: meta: Optional[str] = None @@ -598,7 +601,7 @@ class QAPISchemaVariants: self.info, "discriminator member '%s' of %s must not be optional" % (self._tag_name, base)) - if self.tag_member.ifcond.ifcond: + if self.tag_member.ifcond.is_present(): raise QAPISemError( self.info, "discriminator member '%s' of %s must not be conditional" @@ -606,7 +609,7 @@ class QAPISchemaVariants: else: # simple union assert isinstance(self.tag_member.type, QAPISchemaEnumType) assert not self.tag_member.optional - assert self.tag_member.ifcond.ifcond == [] + assert not self.tag_member.ifcond.is_present() if self._tag_name: # flat union # branches that are not explicitly covered get an empty type cases = {v.name for v in self.variants} diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 7907b4ac3a..c92be2d086 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -94,7 +94,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): @staticmethod def _print_if(ifcond, indent=4): - if ifcond.ifcond: + if ifcond.is_present(): print('%sif %s' % (' ' * indent, ifcond.ifcond)) @classmethod -- cgit v1.2.3-55-g7522 From d806f89f87152def5f422e946c84948831615236 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 4 Aug 2021 12:31:00 +0400 Subject: qapidoc: introduce QAPISchemaIfCond.docgen() Instead of building the condition documentation from a list of string, use the result generated from QAPISchemaIfCond.docgen(). This changes the generated documentation from: - COND1, COND2... (where COND1, COND2 are Literal nodes, and ',' is Text) to: - COND1 and COND2 (the whole string as a Literal node) This will allow us to generate more complex conditions in the following patches, such as "(COND1 and COND2) or COND3". Adding back the differentiated formatting is left to the wish list. Signed-off-by: Marc-André Lureau Message-Id: <20210804083105.97531-6-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster [TODO comment added] Signed-off-by: Markus Armbruster --- docs/sphinx/qapidoc.py | 14 ++++++++------ scripts/qapi/common.py | 7 +++++++ scripts/qapi/schema.py | 10 +++++++++- 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'docs/sphinx/qapidoc.py') diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 511520f33f..d791b59492 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -112,17 +112,19 @@ class QAPISchemaGenRSTVisitor(QAPISchemaVisitor): def _nodes_for_ifcond(self, ifcond, with_if=True): """Return list of Text, literal nodes for the ifcond - Return a list which gives text like ' (If: cond1, cond2, cond3)', where - the conditions are in literal-text and the commas are not. + Return a list which gives text like ' (If: condition)'. If with_if is False, we don't return the "(If: " and ")". """ - condlist = intersperse([nodes.literal('', c) for c in ifcond.ifcond], - nodes.Text(', ')) + + doc = ifcond.docgen() + if not doc: + return [] + doc = nodes.literal('', doc) if not with_if: - return condlist + return [doc] nodelist = [nodes.Text(' ('), nodes.strong('', 'If: ')] - nodelist.extend(condlist) + nodelist.append(doc) nodelist.append(nodes.Text(')')) return nodelist diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index ba9fe14e4b..ddc54e4368 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -205,6 +205,13 @@ def cgen_ifcond(ifcond: Union[str, List[str]]) -> str: return '(' + ') && ('.join(ifcond) + ')' +def docgen_ifcond(ifcond: Union[str, List[str]]) -> str: + # TODO Doc generated for conditions needs polish + if not ifcond: + return '' + return ' and '.join(ifcond) + + def gen_if(cond: str) -> str: if not cond: return '' diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 4ea7e88846..a9345af7b7 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -19,7 +19,12 @@ import os import re from typing import Optional -from .common import POINTER_SUFFIX, c_name, cgen_ifcond +from .common import ( + POINTER_SUFFIX, + c_name, + cgen_ifcond, + docgen_ifcond, +) from .error import QAPIError, QAPISemError, QAPISourceError from .expr import check_exprs from .parser import QAPISchemaParser @@ -32,6 +37,9 @@ class QAPISchemaIfCond: def cgen(self): return cgen_ifcond(self.ifcond) + def docgen(self): + return docgen_ifcond(self.ifcond) + def is_present(self): return bool(self.ifcond) -- cgit v1.2.3-55-g7522