/** * What every advisory proof shares: the shapes it reads, the narrow face it * asks the analyzer for, and the two small rosters and proofs more than one * family needs. * * D115 §三 / D114 R1f: `advisories.ts` split into one file per advisory family * when A8 arrived and pushed it past the 800-line budget. This module is the * floor of that directory and imports nothing from its siblings. */ import { type BindingPattern, type Expression } from "../../ast.ts"; import { type CollectionOperation, type RecordFromHint } from "../../contracts.ts"; import { type DiagnosticFix } from "../../diagnostic.ts"; import { type Span } from "../../source.ts"; import { type ValueType } from "../../types.ts"; /** The part of a resolved binding the proofs read. */ export interface AdvisoryBinding { readonly type: ValueType; readonly storageType: ValueType; readonly span: Span; } /** The record shape `Target.from` / `Target.mapFrom` projections are proved against. */ export interface AdvisoryRecordShape { readonly fields: ReadonlyMap; readonly optionalFields: ReadonlySet; readonly readonlyFields: ReadonlySet; readonly readonlyView: boolean; } /** * The one analysis-extension hook the roster calls (A13). Declared structurally * rather than imported: `CompilerAnalysisExtension` lives in `extension.ts`, * which imports the analyzer, and naming it here would put this module back * inside the five-module import ring `contracts.ts` was extracted to shrink. * `CompilerAnalysisExtension` satisfies this shape. */ export interface CanonicalCollectionProjectionExtension { readonly canonicalCollectionProjection?: (expression: Expression, pure: (expression: Expression) => boolean) => boolean | undefined; } /** The lowering facts a proof consults before claiming a call is compiler-owned. */ export interface AdvisoryLoweringFacts { readonly collectionCalls: ReadonlyMap; readonly recordFromCalls: ReadonlyMap; expressionUsesRuntimeNarrowing(expression: Expression): boolean; } /** * Everything the roster asks of the analyzer that hosts it, and nothing more. */ export interface AdvisoryHost { /** The module source: quoted in a message, and read to withhold a comment-erasing fix. */ readonly sourceText: string; /** Asked whether a target extension owns an expression form the pipeline proof met (A13). */ readonly analysisExtensions: readonly CanonicalCollectionProjectionExtension[]; /** Searched for the name a projected record type is written as (A9/A10). */ readonly typeAliases: ReadonlyMap; /** What the emitter will lower a call to, when a proof needs the call to be compiler-owned. */ readonly lowering: AdvisoryLoweringFacts; advise(code: string, message: string, adviceSpan: Span, fix?: DiagnosticFix): void; expandAliases(type: ValueType): ValueType; /** The declared fields of a named type, for the member reads a proof rebuilds. */ fieldsOf(identity: string): ReadonlyMap | null; /** How deep in `finally` blocks the walk is, so A8 can refuse to leave one. */ readonly finallyLoopDepths: number[]; /** How many function bodies the walk is inside, and how many constructors. */ readonly functionDepth: number; readonly constructorDepth: number; inferredExpressionType(expression: Expression): ValueType; lookup(name: string): AdvisoryBinding | null; collectPatternNames(pattern: BindingPattern, add: (name: string) => void): void; commentPreservingMechanicalFix(rewriteSpan: Span, replacement: string, title: string): DiagnosticFix | undefined; recordProjectionShape(type: ValueType): AdvisoryRecordShape | null; stableDataMember(objectExpression: Expression, property: string): boolean; } export declare const loopIndexSlotNames: Set; export declare const loopValueSlotNames: Set; /** * The singular of the iterated collection's own name, so `for i, user in * users` reads as the same swap as `for i, v in users`. Only a plain name is * read; an arbitrary expression has no name to make singular. */ export declare function singularIterableName(iterable: Expression): string | null; /** * Whether a member read a proof is about to rebuild is a plain data read that * cannot execute anything: a declared field, a record or enum entry, or the * `size` of a collection. A class getter or a method would run code, so no * proof may put it in a replacement it offers. * * D114 R1f: this was a private method of `analyzer.ts` reached only through * `AdvisoryHost`. Both readers — A8's predicate spelling and A13's pipeline * spelling — are in this directory, so it moved in with them and the host * member it needed is gone. */ export declare function canonicalCollectionMemberReadIsStable(host: Pick, expression: Extract): boolean; /** * The A roster: every advisory id the language publishes, with the one line * that says what it is about. * * D114 MD-I4 made this a table rather than a set of `advise("A7", …)` call * sites scattered across this directory and two extensions. Two things needed * one place to read: `velar-allow` has to be able to say that `A18` is a real * id and `VEL6010` is not, and D114 item 11 puts the roster in the Core surface * digest so an id cannot be added, retitled or dropped without the `core` * counter moving. The titles are one line each on purpose — the rule each * advisory guards is written where that rule lives, never restated here. * * Ids an extension raises (`A4`, `A11`, `A12`, `A14`, `A16`) are listed here * too: the roster is the language's, and the number space is one space. What * belongs to the extension is the proof, not the id. */ export declare const ADVISORY_ROSTER: ReadonlyMap; /** * D114 MD-I4: the advisories the *project driver* raises over the module graph * rather than `compile()` over one module. A module compile can neither produce * one nor prove that one did not fire, so a `velar-allow` naming one leaves the * compile unresolved instead of being reported stale, and the driver that owns * the graph applies it. This is the whole of what makes `A18` different from * every other id in the roster above. */ export declare const PROJECT_GRAPH_ADVISORY_CODES: ReadonlySet; //# sourceMappingURL=roster.d.ts.map