mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -06:00
docs/qapi-domain: Add QAPIDescription abstract class
This class is a generic, top-level directive for documenting some kind of QAPI thingamajig that we expect to go into the Index. This class doesn't do much by itself, and it isn't yet associated with any particular directive. handle_signature(), _object_hierarchy_parts() and _toc_entry_name() are defined in the base class. get_index_text() and add_target_and_index() are new methods defined here; they are based heavily on the layout and format of the Python domain's general object class. Signed-off-by: John Snow <jsnow@redhat.com> Message-ID: <20250311034303.75779-11-jsnow@redhat.com> Acked-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
6d64a27cd3
commit
1ea664862a
1 changed files with 99 additions and 2 deletions
|
@ -14,11 +14,13 @@ from typing import (
|
|||
NamedTuple,
|
||||
Optional,
|
||||
Tuple,
|
||||
cast,
|
||||
)
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.addnodes import pending_xref
|
||||
from sphinx.addnodes import desc_signature, pending_xref
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.domains import (
|
||||
Domain,
|
||||
Index,
|
||||
|
@ -28,7 +30,7 @@ from sphinx.domains import (
|
|||
from sphinx.locale import _, __
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.nodes import make_refnode
|
||||
from sphinx.util.nodes import make_id, make_refnode
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -96,6 +98,101 @@ class QAPIXRefRole(XRefRole):
|
|||
return title, target
|
||||
|
||||
|
||||
Signature = str
|
||||
|
||||
|
||||
class QAPIDescription(ObjectDescription[Signature]):
|
||||
"""
|
||||
Generic QAPI description.
|
||||
|
||||
This is meant to be an abstract class, not instantiated
|
||||
directly. This class handles the abstract details of indexing, the
|
||||
TOC, and reference targets for QAPI descriptions.
|
||||
"""
|
||||
|
||||
def handle_signature(self, sig: str, signode: desc_signature) -> Signature:
|
||||
# Do nothing. The return value here is the "name" of the entity
|
||||
# being documented; for QAPI, this is the same as the
|
||||
# "signature", which is just a name.
|
||||
|
||||
# Normally this method must also populate signode with nodes to
|
||||
# render the signature; here we do nothing instead - the
|
||||
# subclasses will handle this.
|
||||
return sig
|
||||
|
||||
def get_index_text(self, name: Signature) -> Tuple[str, str]:
|
||||
"""Return the text for the index entry of the object."""
|
||||
|
||||
# NB: this is used for the global index, not the QAPI index.
|
||||
return ("single", f"{name} (QMP {self.objtype})")
|
||||
|
||||
def add_target_and_index(
|
||||
self, name: Signature, sig: str, signode: desc_signature
|
||||
) -> None:
|
||||
# name is the return value of handle_signature.
|
||||
# sig is the original, raw text argument to handle_signature.
|
||||
# For QAPI, these are identical, currently.
|
||||
|
||||
assert self.objtype
|
||||
|
||||
# If we're documenting a module, don't include the module as
|
||||
# part of the FQN.
|
||||
modname = ""
|
||||
if self.objtype != "module":
|
||||
modname = self.options.get(
|
||||
"module", self.env.ref_context.get("qapi:module")
|
||||
)
|
||||
fullname = (modname + "." if modname else "") + name
|
||||
|
||||
node_id = make_id(
|
||||
self.env, self.state.document, self.objtype, fullname
|
||||
)
|
||||
signode["ids"].append(node_id)
|
||||
|
||||
self.state.document.note_explicit_target(signode)
|
||||
domain = cast(QAPIDomain, self.env.get_domain("qapi"))
|
||||
domain.note_object(fullname, self.objtype, node_id, location=signode)
|
||||
|
||||
if "no-index-entry" not in self.options:
|
||||
arity, indextext = self.get_index_text(name)
|
||||
assert self.indexnode is not None
|
||||
if indextext:
|
||||
self.indexnode["entries"].append(
|
||||
(arity, indextext, node_id, "", None)
|
||||
)
|
||||
|
||||
def _object_hierarchy_parts(
|
||||
self, sig_node: desc_signature
|
||||
) -> Tuple[str, ...]:
|
||||
if "fullname" not in sig_node:
|
||||
return ()
|
||||
modname = sig_node.get("module")
|
||||
fullname = sig_node["fullname"]
|
||||
|
||||
if modname:
|
||||
return (modname, *fullname.split("."))
|
||||
|
||||
return tuple(fullname.split("."))
|
||||
|
||||
def _toc_entry_name(self, sig_node: desc_signature) -> str:
|
||||
# This controls the name in the TOC and on the sidebar.
|
||||
|
||||
# This is the return type of _object_hierarchy_parts().
|
||||
toc_parts = cast(Tuple[str, ...], sig_node.get("_toc_parts", ()))
|
||||
if not toc_parts:
|
||||
return ""
|
||||
|
||||
config = self.env.app.config
|
||||
*parents, name = toc_parts
|
||||
if config.toc_object_entries_show_parents == "domain":
|
||||
return sig_node.get("fullname", name)
|
||||
if config.toc_object_entries_show_parents == "hide":
|
||||
return name
|
||||
if config.toc_object_entries_show_parents == "all":
|
||||
return ".".join(parents + [name])
|
||||
return ""
|
||||
|
||||
|
||||
class QAPIIndex(Index):
|
||||
"""
|
||||
Index subclass to provide the QAPI definition index.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue