/** * Generic declarations and their applications: instantiating a template's * field table, remembering every application a module reaches, and the bound * and recursion checks an application has to pass. * * D114 R1d: `noteGenericApplications`, the two resolvers and the four * validation passes were private methods of `Analyzer`; they are one thing — * what `Box` means and whether it is legal — and live here now. */ import { type ClassDeclaration, type Program, type TypeReference, type TypeSyntax } from "../../ast.ts"; import { type ClassInfo } from "../../contracts.ts"; import { type Diagnostic, type DiagnosticFix } from "../../diagnostic.ts"; import { type Span } from "../../source.ts"; import { type GenericApplication, type GenericTypeInfo, type TypeParameterBound, type ValueType } from "../../types.ts"; /** * Everything this half of the declaration cluster asks of the analyzer that * hosts it. The five halves share one host object, so the interface is the * same shape for each and the union of them is what the analyzer builds. */ export interface GenericDeclarationsHost { readonly canonicalGenericApplications: Map; readonly classes: Map; readonly diagnostics: Diagnostic[]; fieldsOf(identity: string): ReadonlyMap | null; readonly genericApplications: Map; readonly genericTypes: Map; readonly genericTypesByIdentity: Map; readonly namedTypeReadonlyFields: Map>; readonly namedTypes: Map>; noteClassApplication(identity: string, application: GenericApplication): void; readonlyDataViewOf(type: ValueType): ValueType; resolveAnnotation(reference: TypeReference | null): ValueType; resolveNamedClasses(type: ValueType): ValueType; satisfiesBound(type: ValueType, bound: TypeParameterBound): boolean; typeError(message: string, errorSpan: Span, fix?: DiagnosticFix): void; validateTypeReference(reference: TypeReference, resolve?: (reference: TypeReference) => ValueType): boolean; } export declare class GenericDeclarations { private readonly host; constructor(host: GenericDeclarationsHost); /** * D55 rule 121: an instantiation's field table is the declaration's fields * with the arguments substituted, registered under the instantiation's own * identity. Computing it on demand rather than at the point the application * was written is what makes `type Tree: kids: List>` terminate: * the application is *noted* while the declaration is still being read, and * substituted only once someone asks, by which time the template is whole. * Substitution rebuilds nested applications through the same constructor, so * each one is noted in turn and the walk is finite in the number of distinct * instantiations — homogeneous recursion reaches its fixed point, and rule * 125's declaration-site rule is what stops a polymorphic one from existing. */ instantiateGenericFields(identity: string): ReadonlyMap | null; /** * Records every generic application inside a type so its field table can be * built on demand. Called wherever an application can first become visible — * a resolved annotation, an imported binding, a substituted field — because a * missed site is an instantiation whose fields silently read as "not a * record" (the batch M failure shape, one layer out). */ noteGenericApplications(type: ValueType, seen?: Set): void; /** * D55 rule 121: the one place an application written in this module becomes * canonical — declaration identity, display text, instantiation identity, and * the note that lets its field table be built. Every path that can be the * first to see an application calls this, so none of them can produce a * half-resolved one. */ resolveGenericApplication(type: Extract, resolveArgument?: (argument: ValueType) => ValueType): ValueType | null; /** * D55 rule 120 layer two: an application whose name is a generic class. The * declaration key is the class's identity where it has one and its local name * otherwise, which is the same key `this.host.classes` is filed under, so the * instantiation and its template are always found together. */ resolveGenericClassApplication(type: Extract): ValueType | null; /** * D55 rules 124 and 126: everything an instantiation has to answer for at the * place it is written — arity, the declared bounds, and the one argument * shape a runtime-validated record can never hold. */ validateGenericApplication(info: GenericTypeInfo, syntax: Extract): boolean; /** * D55 rule 120 layer two: `extends Stack` — the base must apply a * generic class fully, and a base that is not generic takes no arguments at * all. The refusals are the type position's, because `extends` is a type * position: the same missing-arity teaching, the same bound check. */ checkGenericClassBase(statement: ClassDeclaration, base: NonNullable): void; /** * D55 rule 125 reaching layer two: a generic class's reference to itself — * in a field, a parameter, a result, or its own base — must pass its own * parameters straight through. `class Node: let next: Node?` is * homogeneous and reaches a fixed point; `Node>` would demand * `Node>>` at every depth, without end. Reported on the line * that writes it, exactly as the record rule is. */ rejectPolymorphicClassRecursion(program: Program): void; /** * D55 rules 124 and 126 on the class side: arity and the declared bounds, * decided by the same grant table and reported in the same shape. A class is * never runtime-validated field by field, so the `Type` argument refusal * a record carries has nothing to say here. */ validateGenericClassApplication(name: string, info: ClassInfo, syntax: Extract): boolean; /** * D55 rule 125: a generic record's reference to a declaration in its own * recursive group must pass that group's parameters straight through. * `type Tree: kids: List>` is homogeneous — `Tree` needs * only `Tree`, and monomorphization reaches its fixed point. The * refused shape, `type Bad: next: Bad>?`, demands * `Bad>`, `Bad>>`, without end. The rule is * checked here, on the line that declares it, because an instantiation-depth * limit could only say "too deep" at some later call — the undirected * diagnostic family D42 spent its length removing. */ rejectPolymorphicRecursion(program: Program): void; } //# sourceMappingURL=generics.d.ts.map