import { type PreservedSource } from './source.js'; /** * The two facts about each statement that are derived from the token stream, computed together. * * `ends` is where a statement's text ends FOR THE WRITER, which is not always its terminator. A * comment after the semicolon with nothing but horizontal whitespace between them is the last * field's comment. Leaving it in the gap is invisible while the statement is copied, because the * gap is copied too, and wrong the moment it is reformatted: the writer emits its own field comment * and the author's then arrives from the gap on the line below, so the output carries a line nobody * wrote. It is not even a duplicate, because the ordinary writer drops the unit the original * usually carries, so it reads as a stray fragment. * * That is not the writer guessing which comment belongs to which object. "On the same line as the * terminator" is a positional fact, and it is the one case where the owner is not in question. * * Three consequences, decided rather than discovered: * * - A file written unchanged is byte-identical still. The extent grows and the gap shrinks by * exactly the same characters, so the concatenation does not move. * - Removing an object takes that comment with it, where it used to be left on a line of its own * describing a field that no longer exists. * - Reformatting replaces it, which is the defect this closes. * * `firstToken` is where each statement's tokens begin. `annotations` used to start its cursor at * zero and seek forward, which is a full prefix scan of the token stream per statement: quadratic * in the file, and invisible to the benchmarks because they time an UNCHANGED write, where no * statement is reformatted and `annotations` is never reached. On a ten thousand statement model * that is the difference between milliseconds and seconds. * * Both come from one pass with monotone cursors, because the statements and the tokens are both in * source order. Memoised per retained source, which never changes after the read, so the walk and * the two document accessors share one answer rather than each deriving it. */ interface Derived { /** Where each statement's text ends for the writer. */ readonly ends: readonly number[]; /** The first token at or after each statement's type name, as a cursor for `annotations`. */ readonly firstToken: readonly number[]; } /** * The derived facts for one retained source, computed once. * * Exported so `IdfDocument.regionOf` answers with the SAME extent this walk replaces. Handing a * consumer `statement.region` instead would stop short of the terminator-line comment, and an edit * built on it would leave that comment behind, which is the defect the extent exists to close. */ export declare function derivedOf(source: PreservedSource): Derived; export {}; //# sourceMappingURL=write.d.ts.map