import type { Scope } from "./scope.js";
import { AgencyConfig } from "../config.js";
import { AgencyNode, FunctionDefinition, GraphNodeDefinition, TypeAliasEntry, VariableType } from "../types.js";
import { SourceLocation } from "../types/base.js";
import type { ImportedFunctionSignature, ScopedTypeAliases } from "../compilationUnit.js";
import type { InterruptKind } from "../symbolTable.js";
export type TypeCheckError = {
    message: string;
    severity?: "error" | "warning";
    variableName?: string;
    expectedType?: string;
    actualType?: string;
    loc?: SourceLocation;
};
export type TypeCheckResult = {
    errors: TypeCheckError[];
    scopes: ScopeInfo[];
    interruptKindsByFunction: Record<string, InterruptKind[]>;
};
export type ScopeInfo = {
    scope: Scope;
    body: AgencyNode[];
    name: string;
    scopeKey: string;
    returnType?: VariableType | null;
};
export type BuiltinSignature = {
    params: (VariableType | "any")[];
    returnType: VariableType | "any";
    minParams?: number;
    restParam?: VariableType | "any";
    /** One-line markdown description shown in LSP hover. */
    description?: string;
    /** If true, the typechecker allows a block argument on calls to this
     *  builtin. Used by language-construct builtins like `fork` / `race`. */
    acceptsBlock?: boolean;
};
export type TypeCheckerContext = {
    programNodes: AgencyNode[];
    scopedTypeAliases: ScopedTypeAliases;
    currentScopeKey: string;
    functionDefs: Record<string, FunctionDefinition>;
    nodeDefs: Record<string, GraphNodeDefinition>;
    importedFunctions: Record<string, ImportedFunctionSignature>;
    /** Names brought in by non-Agency JS imports — see CompilationUnit. */
    jsImportedNames: Record<string, true>;
    interruptKindsByFunction: Record<string, InterruptKind[]>;
    errors: TypeCheckError[];
    inferredReturnTypes: Record<string, VariableType | "any">;
    inferringReturnType: Set<string>;
    config: AgencyConfig;
    getTypeAliases(): Record<string, TypeAliasEntry>;
    withScope<T>(key: string, fn: () => T): T;
    inferReturnTypeFor(name: string, def: FunctionDefinition | GraphNodeDefinition): VariableType | "any";
};
