/** * String literals: the inline and layout forms, the `f` prefix's interpolated * parts, the escapes a literal may spell, and the two advisories a JavaScript * template reflex earns (A5 and A6). * * D115 §三 / D114 R1f: the string half of `lexer.ts`. The scanning of one * literal's bytes stays in `interpolated-string.ts`, which the formatter and * the editor read as well; this module is what the lexer does with the result. */ import { type Advisory, type Diagnostic } from "../diagnostic.ts"; import { type StringLiteralScan } from "../interpolated-string.ts"; import { type Token } from "../token.ts"; /** Everything this half of the lexer asks of the scanner that hosts it, and nothing more. */ export interface StringScannerHost { readonly advisories: Advisory[]; atLineStart: boolean; readonly bracketFragment: boolean; readonly diagnostics: { push(...reports: readonly Diagnostic[]): void; }; index: number; isAtEnd(): boolean; isBidirectionalControl(codePoint: number): boolean; isForbiddenLiteralControl(codePoint: number): boolean; readonly text: string; readonly tokens: Token[]; } export declare class StringScanner { private readonly host; constructor(host: StringScannerHost); readString(scanned: StringLiteralScan): void; /** * D89 A5/A6: JavaScript's `${...}` never interpolates in VelarScript. The * charter keeps it literal on purpose — generating JavaScript source is a * real use of these literals — so the spelling cannot become an error, and a * string that carries it compiles in silence with a meaning the JavaScript * reflex behind it did not intend. That is D89's admission shape exactly, * on both sides of the `f` prefix: * * - A5, a plain double-quoted or backtick string: nothing interpolates, the * `${name}` stays text. The way out is the `f` prefix with `{name}`. * - A6, an `f` or `rf` string: the `$` ahead of `{` keeps that brace * literal, so the author who wrote the prefix *and* the JavaScript * spelling still gets text. The way out is dropping the `$`. * * The non-triggers, each deliberate: an empty `${}` or an unclosed `${` * carries no expression to interpolate; a raw `r"..."` string is the author * asking for literal text by name, so the deliberate-literal reading wins * there (`rf` still triggers A6 — its rawness is about backslashes, not * about interpolation); a single-quoted string is already VEL1005; an * unterminated string is already VEL1003; and an inline `extern js` / * `unsafe js` block never reaches this method at all — it is scanned by * `readEmbeddedJavaScript`, where `${...}` is documented literal * JavaScript. One advisory speaks per literal: the rewrite names the whole * string, so a second occurrence adds nothing the first did not say. * * The fix is registered only where D38 §48's no-judgment bar holds: every * `${...}` well-formed, every body a plain dotted name path (see * `interpolationPathBody`), no `$` immediately ahead of an occurrence's own * `$` — JavaScript's `$${x}` spells a literal `$` before an interpolation, * and deleting the occurrence's `$` leaves `${x}`, whose surviving `$` * holds the brace literal all over again, so the quoted rewrite would not * interpolate — and, for A5, no bare brace outside the occurrences, because * the `f` prefix would turn `{` into an interpolation opener and `{{` into * a single literal brace. Everything else keeps the message and loses the * one-click edit. * * A bracket fragment is exempt for A1's reason: its lexer holds the * fragment's text rather than the module's, so a span there would not land * on the physical line a `velar-allow` reads. */ adviseTemplateInterpolation(scanned: StringLiteralScan, start: number): void; /** The literal's source text with each occurrence's `$` removed, for the message that quotes the rewrite. */ private literalWithoutDollars; private diagnoseStringContents; private decodeStringText; legacyTripleQuotePrefix(): { readonly prefix: "" | "f" | "r" | "rf" | "fr"; readonly interpolated: boolean; readonly raw: boolean; } | null; readLegacyTripleQuote(options: { readonly prefix: "" | "f" | "r" | "rf" | "fr"; readonly interpolated: boolean; readonly raw: boolean; }): void; } //# sourceMappingURL=strings.d.ts.map