import type { Region } from './region.js'; /** * What a span of text is, grammatically. Nothing here needs a schema: the layer records what the * text says and never what it means, so a `value` is a value whether or not the field exists. */ export type TokenKind = 'typeName' | 'value' | 'separator' | 'terminator' | 'comment' | 'trivia'; /** * One token, materialised. * * A `Token` *is* a `Region` rather than carrying one, which keeps a classified stream to one * object per token instead of two. On a file of forty thousand lines that difference is the * difference between an editor that repaints and one that stutters, and a token still passes * anywhere a region is expected. * * A materialised token never crosses a line boundary; a stored `value` region may, because the * format lets a field be written across two lines, and the classification view splits it. */ export interface Token extends Region { readonly kind: TokenKind; } /** * Every token of one text, packed into three parallel arrays. * * Nine bytes per token, against upwards of forty for an object: a start, an end, and a kind code, * held in `Int32Array`, `Int32Array` and `Uint8Array`. On a reference model of ten thousand * statements that is roughly 3.6 MB rather than upwards of 16 MB. * * This is a contract rather than an implementation note. The intended use is an editor holding * several large files open at once, and a layer that allocated an object per token would pass * every correctness test while being unusable there. So `Token` objects are materialised only when * a caller asks for one, which for classification means only for the tokens actually drawn. * * The store knows nothing of the scanner that fills it or of the layer that holds it, and nothing * of the text either: it holds positions, and the text they index stays with the layer. */ export declare class TokenStore implements Iterable { #private; constructor(capacity?: number); /** How many tokens are stored. The arrays below are longer than this; they carry slack. */ get length(): number; /** * Start offsets, in source order. * * A view over the live buffer, trimmed to `length`, for a consumer that wants to walk the * positions without materialising anything. It is invalidated by the next {@link push}, which in * practice means it is safe for as long as the layer is: nothing appends to a built layer. */ get starts(): Int32Array; /** End offsets, exclusive, in source order. A live view, like {@link starts}. */ get ends(): Int32Array; /** Kind codes, indices into the `TokenKind` union. A live view, like {@link starts}. */ get kinds(): Uint8Array; /** Append one token and return its index. Grows geometrically, so a scan stays linear. */ push(start: number, end: number, kind: TokenKind): number; /** The start offset of one token. */ startAt(index: number): number; /** The end offset of one token, exclusive. */ endAt(index: number): number; /** The kind of one token. */ kindAt(index: number): TokenKind; /** The stored kind code of one token, for a consumer encoding kinds numerically. */ kindCodeAt(index: number): number; /** * Build a `Token` object for one stored token. * * The only place a token becomes an object. Called for the tokens a consumer actually reads, and * never on the way in. */ materialise(index: number): Token; /** * Every stored token, materialised one at a time. * * Convenient rather than cheap: it allocates per token, so a consumer colouring a viewport reads * the arrays or goes through `classify`, which yields only what it is asked for. Note that this * yields stored tokens alone, so the gaps between them are not covered; `trivia` is never stored * and is computed as the complement. */ [Symbol.iterator](): IterableIterator; } //# sourceMappingURL=tokens.d.ts.map