/** * The sentences a refusal ends with: what the author should write instead, or * why the thing they wrote cannot be what they meant. * * D115 §三: these were eleven private methods of `Analyzer`, called from * assignability, from `is`, from an index, from a condition and from a member * read. None of them decides anything — every one takes types and spans and * answers a string or null — so they are one file, and the file that holds * them is the one place a wording is changed. */ import { type Expression } from "../../ast.ts"; import { type ClassInfo } from "../../contracts.ts"; import { type Span } from "../../source.ts"; import { type ValueType } from "../../types.ts"; import { type Binding, type MutableCellTarget } from "../scopes.ts"; /** What the guidance family asks of the analyzer that hosts it, and nothing more. */ export interface ExpressionGuidanceHost { readonly classFieldInitializerDepth: number; readonly classes: Map; readonly currentClass: string | null; expandAliases(type: ValueType, seen?: ReadonlySet): ValueType; fieldsOf(identity: string): ReadonlyMap | null; findGetter(className: string, name: string): { readonly owner: string; readonly type: ValueType; readonly abstract: boolean; } | null; findMethod(className: string, name: string): { readonly owner: string; readonly type: ValueType; readonly abstract: boolean; } | null; isAssignableHere(actual: ValueType, expected: ValueType): boolean; lookup(name: string): Binding | null; readonlyDataViewOf(type: ValueType): ValueType; readonly sourceText: string; readonly superMemberContext: "instance" | "static" | null; } export declare class ExpressionGuidance { private readonly host; constructor(host: ExpressionGuidanceHost); /** * CLS-I1: the positions where `self` does not exist, and why. A field * initializer runs while the instance is still being assembled, so there is * no complete `self` to read; a static member belongs to the class and has * no instance at all. Outside a class the word is simply an unknown name and * keeps the ordinary message. */ unavailableSelfGuidance(): string | null; /** * D90 R17: the author's own spelling of a boundary value, for the * diagnostics that teach `Type.parse`. Identifier and member paths render * exactly, a simple call renders as `name(...)`, and anything else answers * null so the caller falls back to the word `value`. */ boundaryReceiverText(expression: Expression): string | null; /** A type name suggested from the receiver's last name segment, or 'X' when none reads naturally. */ private boundaryTypeNameSuggestion; /** * D90 R17: an undeclared foreign value arrives as unknown, and the way into * the typed world is `Type.parse` at the edge. Every refusal on an unknown * teaches that ritual with the author's own expression spelled into it. */ boundaryValidationGuidance(expression: Expression | null, property: string | null): string; conditionSubjectText(condition: Expression): string | null; /** * A mutable cell declared without an annotation takes the exact member its * initializer named, so the second member ever stored into it is refused * against the first — `Cannot assign Locale to Locale.zhCN`, reported at the * assignment while the line that has to change is the declaration. The * refusal is right; naming the annotation is what turns it into one edit. */ enumSingletonCellGuidance(actual: ValueType, expected: ValueType, target: MutableCellTarget | null): string | null; /** * D114 S7: the one idiom that carries a class's behavior into a structural * contract. A record type whose fields are function types is what a caller * states when it wants behavior rather than a nominal type; a class instance * does not satisfy it (section 12), and a class name is not a value * (section 10). What passes is a record of *bound methods* — * `{close: terminal.close}` — where each method value binds its receiver * once at the reference site (section 18). * * The guidance is built from the names actually in front of the compiler: * the target's own function-typed fields that the class answers with a * method or a getter, in the target's declaration order, at most three * before the ellipsis. Nothing here changes assignability; the refusal is * the same refusal, and the message is the whole change. */ boundMethodRecordGuidance(actual: ValueType, expected: ValueType, valueSpan: Span): string | null; /** The written value when it is one ordinary binding name, for a message that reads it back. */ private simpleBindingSpelling; /** * A readonly view cannot flow into a contract that can replace its protected * slots. When that qualifier is the only difference, name the parameter view * that accepts the value. D117 keeps element permissions on their own types; * copying a readonly container creates writable slots with the same elements. */ readonlyProjectionGuidance(actual: ValueType, expected: ValueType, expandedExpected: ValueType, _expectedCore: ValueType): string | null; /** * D64 rule 163: the async result annotation is spelled two ways in two * positions, and both are right. A *declaration* annotates the resolved * value — `async def load(id: string) -> string` — because the `async` is * standing right there; VEL4018 refuses `-> Promise` for that reason. A * function *type* has no `async` on it and describes the value the call * hands back, which is a Promise, so `-> Promise` is the spelling there. * * An author who has just been taught VEL4018 therefore writes `-> string` in * the type position and is refused for obeying it. Naming only the mismatch * leaves that author with two diagnostics that contradict each other, so the * refusal names the spelling the type position wants. The check is exact: * the mismatch has to disappear when the result is wrapped, which is what * makes the named spelling a fact rather than a guess. */ asyncResultSpellingGuidance(actual: ValueType, expectedCore: ValueType): string | null; collectionBridgeGuidance(actual: ValueType, expectedCore: ValueType): string | null; } //# sourceMappingURL=guidance.d.ts.map