import { type AdvisorySuppression } from "./advisory-suppression.ts"; import { type Advisory, type Diagnostic } from "./diagnostic.ts"; import type { CompilerLexicalExtension } from "./extension.ts"; import { type Token } from "./token.ts"; export interface LexResult { readonly tokens: readonly Token[]; readonly diagnostics: readonly Diagnostic[]; /** D89: the advisory channel, accumulated beside the diagnostics and never merged into them. */ readonly advisories: readonly Advisory[]; /** D89: the reasoned `velar-allow` suppressions this module's line comments carry. */ readonly suppressions: readonly AdvisorySuppression[]; } export declare class Lexer { private readonly text; private readonly extensionForbiddenIdentifiers; private readonly extensionScanners; private readonly numericSuffixes; private readonly tokens; private readonly diagnostics; private readonly advisories; private readonly suppressions; private readonly diagnosedBidirectionalOffsets; private readonly indentStack; private readonly classBodyStack; private readonly typeBodyStack; private readonly externBodyStack; private readonly openBrackets; private index; private atLineStart; private bracketLineStart; private nesting; private logicalLineIndent; private scannedLineStart; private scannedTo; private cachedLineEndFrom; private cachedLineEnd; private semicolonRunEnd; private readonly bracketFragment; private readonly scanSourceHygiene; /** * D115 §三 / D114 R1f: the nine halves of the scan. Each declares the narrow * face it needs, and all eight read this lexer through the single * `scannerHost()` object whose type is the union of those faces. The cursor * moves under them, so every piece of state on it is a live accessor. */ private readonly brackets; private readonly comments; private readonly continuation; private readonly embedded; private readonly hygiene; private readonly identifiers; private readonly numbers; private readonly punctuation; private readonly strings; constructor(text: string, extensions?: readonly CompilerLexicalExtension[], options?: { readonly bracketFragment?: boolean; readonly scanSourceHygiene?: boolean; }); /** * The one object the nine halves are handed. Every property is a live read * of this lexer: the cursor moves, the token array grows and the bracket * stack is rewritten while a half is running, so none of it can be a value * captured when the halves were built. */ private scannerHost; lex(): LexResult; /** * The scanners that read a token by its shape rather than by one character: * horizontal space, a newline, the two comment forms, an extension-owned * token, embedded JavaScript, the string forms, an identifier and a number. * They run in the order a reader meets them, and the answer is whether one of * them claimed the source at `start`. */ private readScannedToken; private readIndentation; /** * Whether the logical line that just ended opens a class body. Read by the * member-name exemption: `def with(...)` declares a member here and a binding * anywhere else, and only the enclosing block distinguishes them. */ private opensClassBody; /** * CO-I3: whether the logical line that just ended opens an `extern module` or * `extern js` contract. It nests, because the `class` whose name is being * refused sits one block below the `extern` line itself. */ private opensExternBody; /** Whether the logical line that just ended opens a record-type body. */ private opensTypeBody; private readNewline; private operator; private skipHorizontalWhitespace; /** * The deletion of a line-ending semicolon, including the blank space it would * leave behind. A semicolon followed by anything except further semicolons, * spaces, or a comment separates two statements: putting those on their own * lines is a change of layout rather than of spelling, so it carries no fix. */ private trailingSemicolonFix; private simple; /** * The start of the physical line `index` sits on. D90 (compiler-front-2): the * backward scan this used to be is O(column) per call, and its callers — A1, * the block-comment reader, the semicolon fix, and every opening bracket — * run once per token, so one long physical line cost O(n²). A line of 20000 * semicolons took 673 ms and a 4 MiB one would have taken hours, with nothing * to stop it: a ';' produces no token, so `MAX_TOKENS` never fires. * * The offsets those callers ask about only move forward, so the scan is * carried across the file once and each call pays for the characters since * the last one. An earlier offset still falls back to the backward scan, * which is correct and, being off the hot path, is not the cost. */ private lineStart; /** * The end of the physical line `index` sits on. Every offset between a line's * start and its end shares that end, so one line answers every call about it * once — which is what keeps a line of N semicolons from paying N forward * scans of its own tail. */ private lineEnd; private isAtEnd; private peek; private advance; private isIdentifierStart; private isIdentifierPart; private isDigit; } //# sourceMappingURL=lexer.d.ts.map