4"""A tiny indentation-aware writer for emitting source text.
6Lets the type/module emitters avoid threading an `indent` string or
7hand-writing trailing newlines and doubled `{{` / `}}` braces. Text is
8streamed straight to the underlying output sink as it is produced --
12from contextlib
import contextmanager
13from typing
import Iterator, TextIO
17 """Stream indented source text to an output sink.
19 Wraps a `TextIO`-like `out` and tracks indentation as a stack of two-space
20 levels, so emit code never has to thread an `indent` string or hand-write
21 trailing newlines and doubled `{{` / `}}` braces. Every call writes through
22 to `out` immediately. The primitives are:
24 * `line(text)` -- write one line at the current indent (blank if empty).
25 * `block(header)` -- a context manager that writes `header {`, indents its
26 body, then closes with `}` (plus an optional `tail`, e.g. `;`).
27 * `access(label)` -- write an access specifier (`public:` / `private:`)
28 one level out from the members it introduces.
30 `write(text)` streams `text` verbatim (no indentation); it mirrors
31 `TextIO.write` so an `IndentedWriter` can itself stand in for a sink.
32 `indented()` opens a bare indent (e.g. a single-statement loop body)
36 def __init__(self, out: TextIO, level: int = 0) ->
None:
40 def line(self, text: str =
"") ->
None:
41 self.
_out.
write(f
"{' ' * self._level}{text}\n" if text
else "\n")
43 def lines(self, *texts: str) ->
None:
47 def write(self, text: str) ->
None:
48 """Write `text` verbatim (no indentation). Mirrors `TextIO.write` so the
49 writer can be passed to emitters that build pre-indented strings."""
52 def access(self, label: str) ->
None:
55 outer = max(self.
_level - 1, 0)
56 self.
_out.
write(f
"{' ' * outer}{label}\n")
67 def block(self, header: str, *, tail: str =
"") -> Iterator[
None]:
68 self.
line(f
"{header} {{")
74 self.
line(f
"}}{tail}")
Iterator[None] indented(self)
None line(self, str text="")
None write(self, str text)
None __init__(self, TextIO out, int level=0)
None access(self, str label)
Iterator[None] block(self, str header, *str tail="")
None lines(self, *str texts)