| 43 | |
| 44 | |
| 45 | class SourceInfo: |
| 46 | |
| 47 | _ready = False |
| 48 | |
| 49 | def __init__(self, filename, _current=None): |
| 50 | # immutable: |
| 51 | self.filename = filename |
| 52 | # mutable: |
| 53 | if isinstance(_current, str): |
| 54 | _current = TextInfo(_current) |
| 55 | self._current = _current |
| 56 | start = -1 |
| 57 | self._start = _current.start if _current else -1 |
| 58 | self._nested = [] |
| 59 | self._set_ready() |
| 60 | |
| 61 | def __repr__(self): |
| 62 | args = (f'{a}={getattr(self, a)!r}' |
| 63 | for a in ['filename', '_current']) |
| 64 | return f'{type(self).__name__}({", ".join(args)})' |
| 65 | |
| 66 | @property |
| 67 | def start(self): |
| 68 | if self._current is None: |
| 69 | return self._start |
| 70 | return self._current.start |
| 71 | |
| 72 | @property |
| 73 | def end(self): |
| 74 | if self._current is None: |
| 75 | return self._start |
| 76 | return self._current.end |
| 77 | |
| 78 | @property |
| 79 | def text(self): |
| 80 | if self._current is None: |
| 81 | return '' |
| 82 | return self._current.text |
| 83 | |
| 84 | def nest(self, text, before, start=None): |
| 85 | if self._current is None: |
| 86 | raise Exception('nesting requires active source text') |
| 87 | current = self._current |
| 88 | current.text = before |
| 89 | self._nested.append(current) |
| 90 | self._replace(text, start) |
| 91 | |
| 92 | def resume(self, remainder=None): |
| 93 | if not self._nested: |
| 94 | raise Exception('no nested text to resume') |
| 95 | if self._current is None: |
| 96 | raise Exception('un-nesting requires active source text') |
| 97 | if remainder is None: |
| 98 | remainder = self._current.text |
| 99 | self._clear() |
| 100 | self._current = self._nested.pop() |
| 101 | self._current.text += ' ' + remainder |
| 102 | self._set_ready() |
no outgoing calls
no test coverage detected
searching dependent graphs…