Expand description
Tree-edit primitives for incremental reparse (cy-zv0, spec §11).
§Scope
This module exposes a TextEdit value type plus an
incremental_reparse entry point shaped so downstream crates
(cyrs-db) can route document edits through a single API. The name
incremental_reparse is aspirational: the current implementation is a
whole-file reparse fallback that reconstructs the full source from
the old tree and calls crate::parse on the result. The API shape is
designed so a future “smart” path can slot underneath without breaking
callers.
§Why an API-first tranche
Rowan supports lossless green-tree splicing in principle
(SyntaxNode::replace_with, GreenNode::replace_child), but a
production-quality incremental reparse needs:
- A re-lex boundary sniff so edits inside trivia don’t trigger a parser re-entry.
- A minimal sub-tree identification that is safe across clause
boundaries (an edit that deletes
MATCHmust invalidate the enclosing statement, not just the token). - Error-recovery reconciliation so an edit that introduces or heals a syntax error produces a tree whose error set matches a full reparse.
Items 1–3 are a research-sized tranche. Landing the API + whole-file
fallback lets downstream crates migrate onto Database::edit_file
(see cyrs-db) today; the smart path can then land in a follow-up
bead without touching any caller.
§Future smart path
When the incremental feature (defaulted-on) is enabled, a future
implementation of incremental_reparse may short-circuit to a
sub-tree reparse. Consumers must not rely on either the slow or fast
path: the invariant is that the returned tree is byte-equal to
parse(new_text).syntax() for some canonical new_text derived from
old_tree + edit.
§Invariants
incremental_reparse(old_tree, edit)produces aParsewhosesyntax().to_string()equals the new source text.- The call is infallible: malformed UTF-8 cannot enter because
TextEdit::replacetakesimpl Into<String>andTextEdit::applyconcatenates bytes at char boundaries. edit.rangemust lie inside the old source; out-of-range offsets saturate to the source length (matchingString::replace_range’s documented behaviour).
Structs§
- Text
Edit - A single-range text edit.
Functions§
- incremental_
reparse - Reparse after applying
edittoold_tree’s source.