/** * What a bare name means where it is read: the binding it resolves to, the * report when it resolves to nothing, and the side tables a read writes — the * reactive references, the builtin values, the runtime narrowings, the * module-initialization reads, and the two retirement migrations. * * D115 §三: this was `inferIdentifier`, the longest single arm of the * expression dispatcher, and the one helper it reads. */ import { type Expression } from "../../ast.ts"; import { type RetiredNamespace } from "../../contracts.ts"; import { type Diagnostic, type DiagnosticFix } from "../../diagnostic.ts"; import { type Span } from "../../source.ts"; import { type GenericTypeInfo, type ValueType } from "../../types.ts"; import { LoweringRecorder } from "../lowering-recorder.ts"; import { type Binding } from "../scopes.ts"; /** What an identifier read asks of the analyzer that hosts it, and nothing more. */ export interface IdentifierExpressionsHost { readonly arrowCaptureFrames: { captured: { readonly handle: string; readonly depth: number; } | null; }[]; builtin(name: string): Binding | null; checkShadowedRead(name: string, span: Span): void; readonly diagnostics: Diagnostic[]; expandAliases(type: ValueType, seen?: ReadonlySet): ValueType; readonly genericTypes: Map; readonly hoistedClassDeclarations: Map; readonly importedBindingOrigins: Map; inModuleInitializationPosition(): boolean; lookup(name: string): Binding | null; readonly lowering: LoweringRecorder; readonly memberAccessProperties: Map; recordInitializationImportRead(binding: Binding, local: string, span: Span): void; reportUnresolvedName(name: string, span: Span): void; readonly retiredCollections: { readonly importOrigins: ReadonlyMap; readonly importReads: { readonly local: string; readonly imported: string; readonly span: Span; }[]; }; readonly retiredNamespaceImportOrigins: ReadonlyMap; readonly retiredNamespaceImportReads: { readonly local: string; readonly source: string; readonly imported: string; readonly span: Span; }[]; retiredNamespaceOwning(name: string): string | null; readonly retiredNamespaceUses: { readonly namespace: string; readonly member: string | null; readonly span: Span; readonly memberEnd: number; readonly bare: boolean; }[]; readonly retiredNamespaces: Map; runtimeTypeObjectValue(type: Extract): ValueType; typeError(message: string, errorSpan: Span, fix?: DiagnosticFix): void; unavailableSelfGuidance(): string | null; } export declare class IdentifierExpressions { private readonly host; constructor(host: IdentifierExpressionsHost); private recordRuntimeReference; inferIdentifier(expression: Extract, contextualType: ValueType): ValueType; /** * `const value = map.get(key); if value == null: ...` 之后,`value` 是一次读取 * 得到的稳定副本。它不能被重新赋值,存在性检查得到的类型又恰好是原 * optional 的非空分支,因此后续读取无需再运行一次完整的 Type 检查。 * * 这个证明只回答“这个局部副本还会不会变回 null”,与它指向的 * List、Map 或记录内容是否可变无关。别名可以修改对象内容,却无法把这个 * `const` 绑定本身改成 null;因此用整个记录的 Type 遍历去重复证明非空, * 会把普通 Map 更新意外变成二次复杂度。 * * 参数、`let`、类实例、响应式值和导入的实时绑定仍会生成运行时收窄 * 守卫;从 unknown/union 通过 `is` 得到的更具体类型也仍会深度复验。 * 这些形状证明的不只是存在性,不能借用这条快路。 */ private isStableOptionalValueCopy; } //# sourceMappingURL=identifiers.d.ts.map