/** * What a check proves, and what a write takes away: the rules that turn a * condition into facts about named locations, install those facts on the scope * that entered them, and retract the ones an assignment or a mutating call * falsified. * * D114 R1d: this is the narrowing half of the flow cluster — `conditionNarrowing` * and its eight sub-rules, the assignment-established facts of D44 rule 71, the * member-path bookkeeping (`stableMemberAccessPath` and the seven invalidators), * and the "not a stable location" rules that keep a getter or an index out of * the fact store. All of it was private methods of `Analyzer` interleaved with * everything else; here it is one collaborator the analyzer owns as * `this.narrowing`, and `NarrowingHost` is the exact record of what it needs * back from the analyzer. * * The two protected seams that expose it — `narrowingFor` and * `applyNarrowings` — stay declared on `Analyzer` and forward here, because * the Web and Node analyzers subclass that class and not this one. */ import { type BindingPattern, type Expression, type MatchPattern, type TypeReference } from "../../ast.ts"; import { type Span } from "../../source.ts"; import { type EnumInfo, type ValueType } from "../../types.ts"; import { type Binding, type MemberNarrowing } from "../scopes.ts"; import { type MemberLocations } from "./locations.ts"; /** * Everything the narrowing half asks of the analyzer that hosts it, and * nothing more. The scope stack, the member-fact stack and the flow frame * depth all move under it while a condition is being analyzed, so they arrive * as live getters rather than as values captured at construction. */ export interface NarrowingHost { builtin(name: string): Binding | null; containsInferredResultPlaceholder(type: ValueType): boolean; enterScope(): void; readonly enums: Map; erasedClassCheckType(source: ValueType, checked: ValueType): ValueType; exitScope(): void; expandAliases(type: ValueType, seen?: ReadonlySet): ValueType; fieldsOf(identity: string): ReadonlyMap | null; readonly flowFrameDepth: number; inferExpression(expression: Expression, contextualType?: ValueType): ValueType; readonly inferredExpressionTypes: Map; isAssignableHere(actual: ValueType, expected: ValueType): boolean; iterationContract(type: ValueType): ValueType | null; lookup(name: string): Binding | null; matchTypesOverlap(left: ValueType, right: ValueType): boolean; readonly memberNarrowings: Map[]; readonly narrowedNames: Set[]; readonlyDataViewOf(type: ValueType): ValueType; readonlyFieldsOf(identity: string): ReadonlySet | null; recordFlowFactOrigin(binding: Binding): void; recordScopedName(name: string): void; requireCondition(type: ValueType, condition: Expression): void; resolveAnnotation(reference: TypeReference | null): ValueType; runtimeTypeCheckMayExecute(input: ValueType, checkedInput: ValueType): boolean; runtimeTypeObjectValue(type: Extract): ValueType; readonly scopes: Map[]; readonly locations: MemberLocations; survivingNarrowings(narrowed: ReadonlyMap): ReadonlyMap; trackNarrowingShadow(shadow: Binding): void; } export declare class Narrowing { private readonly host; /** The truthy/falsy facts a logical operator already decided, keyed by its span. */ readonly logicalConditionNarrowings: Map; readonly falsy: ReadonlyMap; }>; constructor(host: NarrowingHost); conditionNarrowing(expression: Expression, truthy: boolean, knownType?: ValueType): ReadonlyMap; /** * FLW-N4: a membership test asks the `==` question one element at a time * (section 4), so a true answer means one element matched — and every * element is of the container's element or key type. The false answer * proves nothing: any element could be the one that failed to match. */ private membershipNarrowing; /** What `==` and `!=` prove: presence, an enum singleton, and the two members of bool. */ private equalityNarrowing; /** What one element of a membership probe's container is, matching the `in` operand rules. */ private membershipElementType; /** The concrete checked value behind `Kind.is(value)`, when Kind is a runtime validator. */ private validatorTargetOf; private bareConditionNarrowing; private excludeCheckedType; addLocationNarrowing(target: Map, expression: Expression, type: ValueType): void; private narrowableLocation; private narrowEnumMember; /** * FLW-N7: the fact a boolean-literal comparison proves about its owner. * A location already typed `bool` learns nothing, so no fact is recorded * for it — a needless fact would only buy a runtime recheck on every later * read. */ private narrowToBoolean; private narrowDiscriminatedOwner; inferNarrowedExpression(expression: Expression, narrowed: ReadonlyMap, contextualType: ValueType): ValueType; withTemporaryNarrowings(narrowed: ReadonlyMap, narrowingSpan: Span, analyze: () => T): T; optionalExecutionNarrowings(expression: Expression): ReadonlyMap; inferConditionWithNarrowings(expression: Expression, narrowed: ReadonlyMap): { readonly type: ValueType; readonly truthy: ReadonlyMap; readonly falsy: ReadonlyMap; readonly surviving: ReadonlyMap; }; combineNarrowings(first: ReadonlyMap, second: ReadonlyMap): ReadonlyMap; applyNarrowings(narrowed: ReadonlyMap, narrowingSpan: Span): void; persistNarrowings(narrowed: ReadonlyMap): void; private assignedFactType; establishAssignedFact(name: string, assigned: ValueType): void; /** Rule 71 for member targets: establish after invalidation so the new fact survives its own write. */ establishAssignedMemberFact(target: Extract, assigned: ValueType, declaredMemberType: ValueType): void; /** Rule 71 for destructuring declarations: each binding learns its own initializer piece. */ establishAssignedPatternFacts(pattern: BindingPattern, assigned: ValueType): void; runtimeCheckedType(input: ValueType, rawChecked: ValueType): ValueType; matchPatternReflectionMayExecute(pattern: MatchPattern, input: ValueType): boolean; } //# sourceMappingURL=narrowing.d.ts.map