docs/qapi-domain: add QAPIObject class

This patch adds another abstract class that describes "a QAPI
thingie". The main difference here is that this class will be generating
visible documentation, unlike the QAPIDescription class.

Signed-off-by: John Snow <jsnow@redhat.com>
Message-ID: <20250311034303.75779-13-jsnow@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
John Snow 2025-03-10 23:42:10 -04:00 committed by Markus Armbruster
parent 7320feeb96
commit 8799c3641a

View file

@ -18,7 +18,9 @@ from typing import (
)
from docutils import nodes
from docutils.parsers.rst import directives
from compat import KeywordNode, SpaceNode
from sphinx import addnodes
from sphinx.addnodes import desc_signature, pending_xref
from sphinx.directives import ObjectDescription
@ -40,6 +42,7 @@ if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.builders import Builder
from sphinx.environment import BuildEnvironment
from sphinx.util.typing import OptionSpec
logger = logging.getLogger(__name__)
@ -99,6 +102,8 @@ class QAPIXRefRole(XRefRole):
return title, target
# Alias for the return of handle_signature(), which is used in several places.
# (In the Python domain, this is Tuple[str, str] instead.)
Signature = str
@ -194,6 +199,65 @@ class QAPIDescription(ObjectDescription[Signature]):
return ""
class QAPIObject(QAPIDescription):
"""
Description of a generic QAPI object.
It's not used directly, but is instead subclassed by specific directives.
"""
# Inherit some standard options from Sphinx's ObjectDescription
option_spec: OptionSpec = ( # type:ignore[misc]
ObjectDescription.option_spec.copy()
)
option_spec.update(
{
# Borrowed from the Python domain:
"module": directives.unchanged, # Override contextual module name
}
)
def get_signature_prefix(self) -> List[nodes.Node]:
"""Return a prefix to put before the object name in the signature."""
assert self.objtype
return [
KeywordNode("", self.objtype.title()),
SpaceNode(" "),
]
def get_signature_suffix(self) -> List[nodes.Node]:
"""Return a suffix to put after the object name in the signature."""
return []
def handle_signature(self, sig: str, signode: desc_signature) -> Signature:
"""
Transform a QAPI definition name into RST nodes.
This method was originally intended for handling function
signatures. In the QAPI domain, however, we only pass the
definition name as the directive argument and handle everything
else in the content body with field lists.
As such, the only argument here is "sig", which is just the QAPI
definition name.
"""
modname = self.options.get(
"module", self.env.ref_context.get("qapi:module")
)
signode["fullname"] = sig
signode["module"] = modname
sig_prefix = self.get_signature_prefix()
if sig_prefix:
signode += addnodes.desc_annotation(
str(sig_prefix), "", *sig_prefix
)
signode += addnodes.desc_name(sig, sig)
signode += self.get_signature_suffix()
return sig
class QAPIModule(QAPIDescription):
"""
Directive to mark description of a new module.