John Snow <jsnow@redhat.com> writes:
> Here's the weird bit. QAPIDoc generally expects -- virtually everywhere
> -- that it will always have a current section. The sole exception to
> this is in the case that end_comment() is called, which leaves us with
> *no* section. However, in this case, we also don't expect to actually
> ever mutate the comment contents ever again.
>
> NullSection is just a Null-object that allows us to maintain the
> invariant that we *always* have a current section, enforced by static
> typing -- allowing us to type that field as QAPIDoc.Section instead of
> the more ambiguous Optional[QAPIDoc.Section].
>
> end_section is renamed to switch_section and now accepts as an argument
> the new section to activate, clarifying that no callers ever just
> unilaterally end a section; they only do so when starting a new section.
>
> Signed-off-by: John Snow <jsnow@redhat.com>
>
> ---
>
> For my money: Optional types can be a nuisance because an unfamiliar
> reader may wonder in what circumstances the field may be unset. This
> makes the condition quite a bit more explicit and statically provable.
>
> Doing it in this way (and not by creating a dummy section) will also
("And not by creating a [mutable] dummy section" ... but this wasn't destined for the git log anyway.)
> continue to reject (rather noisily) any erroneous attempts to append
> additional lines after end_comment() has been called.
>
> Also, this section isn't indexed into .sections[] and isn't really
> visible in any way to external users of the class, so it seems like a
> harmless and low-cost way to formalize the "life cycle" of a QAPIDoc
> parser.
>
> Clean and clear as I can make it, in as few lines as I could muster.
>
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
> scripts/qapi/parser.py | 27 ++++++++++++++++-----------
> 1 file changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
> index 1fdc5bc7056..123fc2f099c 100644
> --- a/scripts/qapi/parser.py
> +++ b/scripts/qapi/parser.py
> @@ -478,6 +478,13 @@ def __init__(self, parser, name, indent=0):
> def connect(self, member):
> self.member = member
>
> + class NullSection(Section):
> + """
> + Empty section that signifies the end of a doc block.
What about "Dummy section for use at the end of a doc block"?
Sure. "Immutable dummy section for use at the end of a doc block."
> + """
> + def append(self, line):
> + assert False, "BUG: Text appended after end_comment() called."
How can a failing assertion *not* be a bug?
Haha. I'll drop the prefix. (I'll update my branch with these tiny edits and you can decide what you'd like to do with that.)