import { TSESTree } from '@typescript-eslint/types'; import { ParserServices } from '@typescript-eslint/utils'; import * as ts from 'typescript'; export type ClassLike = TSESTree.ClassDeclaration | TSESTree.ClassExpression; export type SignalClassification = 'signal' | 'not-signal' | 'unknown'; type ConnectCallExpression = TSESTree.CallExpression & { callee: TSESTree.MemberExpression; }; export type WalkAction = 'skip-children' | 'stop' | undefined; /** * Iterative AST walk from `root`, visiting every node. The visitor may return * 'skip-children' to avoid descending into a node, or 'stop' to abort the * whole walk. */ export declare function walkFrom(root: TSESTree.Node, visit: (node: TSESTree.Node) => WalkAction): void; /** * Checks if a node represents `.connect(...)`. */ export declare function isConnectCall(node: TSESTree.CallExpression): node is ConnectCallExpression; /** * Checks if a node represents `.disconnect(...)` or a call to one of * the additional cleanup method names. */ export declare function isDisconnectCall(node: TSESTree.CallExpression, extraMethodNames?: readonly string[]): boolean; /** * Checks if a node represents `.disposed.connect(...)` — disposal * cleanup wired through a `disposed`-style signal. */ export declare function isDisposedSignalWiring(node: TSESTree.CallExpression): boolean; /** * Collects the names under which the Lumino `Signal` namespace is reachable in * this file. Always includes 'Signal' (ambient/global usage), plus local * aliases from `import { Signal as X } from '@lumino/signaling'` and the * qualified `ns.Signal` form of `import * as ns from '@lumino/signaling'`. */ export declare function collectSignalNamespaceLocalNames(program: TSESTree.Program): Set; /** * Checks if a node represents `Signal.clearData(...)` or one of the other * static disconnect helpers on the `Signal` namespace (under any local name). */ export declare function isSignalNamespaceCleanupCall(node: TSESTree.CallExpression, signalLocalNames: ReadonlySet): boolean; /** * Returns the innermost class enclosing `node`, or null if the node is not * inside a class body. */ export declare function getEnclosingClass(node: TSESTree.Node): ClassLike | null; export type ThisBinding = 'instance' | 'constructor' | 'none'; /** * What does `this` denote at `node`? * * - `'instance'`: an instance of the enclosing class. * - `'constructor'`: the class object itself — `static` members and static * blocks. * - `'none'`: neither, because `this` is rebound on the way up: a nested * regular function, an object-literal method, or module scope. Whatever * `this` is there, it is not decided by the enclosing class. * * Arrow functions are transparent. Regular functions are not, unless they are * the value of a class member — that is the method itself, not a nested one. */ export declare function getThisBinding(node: TSESTree.Node): ThisBinding; /** * Finds the class member named `name` in the class body, matching privacy * (`this.#name` vs `this.name`) and staticness. Names are compared without * the `#` prefix. */ export declare function resolveClassMember(classNode: ClassLike, name: string, opts: { isPrivate: boolean; isStatic: boolean; }): TSESTree.MethodDefinition | TSESTree.PropertyDefinition | null; export interface UnboundThisMethodConnect { /** The `this.X` callback argument node. */ arg: TSESTree.MemberExpression; /** Member name, without the `#` prefix. */ name: string; isPrivate: boolean; } /** * Detects the "unbound method" connect shape: a single-argument * `signal.connect(this.X)` where `X` resolves in the enclosing class to a * regular method (or function-expression property) whose body actually uses * `this` — the case where the callback breaks at runtime without a thisArg. * Returns null for every other callback shape (arrow properties, methods not * using `this`, unresolved members, inline callbacks, free variables, ...). * * Shared by `require-signal-this-arg` (reports exactly this case) and * `prefer-signal-this-arg` (reports everything but this case), so the two * rules always partition cleanly. */ export declare function resolveUnboundThisMethodConnect(node: TSESTree.CallExpression): UnboundThisMethodConnect | null; /** * Scans an entire class body for any evidence that signal connections are * cleaned up somewhere: `Signal.clearData(...)`-style static cleanup calls or * `.disconnect(...)` calls (or configured additional cleanup methods). Nested * classes are opaque — their cleanup does not count for the outer class. */ export declare function classHasCleanupEvidence(classNode: ClassLike, signalLocalNames: ReadonlySet, extraMethodNames?: readonly string[]): boolean; /** * Scans a class body for cleanup calls that match connections **by * receiver**: `Signal.clearData(this)` / `Signal.disconnectReceiver(this)` / * `Signal.disconnectAll(this)` / `Signal.disconnectBetween(sender, this)` * (under any local `Signal` alias), or a two-argument * `.disconnect(callback, this)` call. A class using these relies on its * connections having been registered with `this` as the thisArg. Nested * classes are opaque. */ export declare function classUsesReceiverBasedCleanup(classNode: ClassLike, signalLocalNames: ReadonlySet): boolean; /** * Type-aware check: does this class (transitively) extend Lumino's `Widget` * (any class declared in `@lumino/widgets`)? Those base classes call * `Signal.clearData(this)` from `dispose()`, so subclasses rely on * receiver-based cleanup. Returns false when type information is * unavailable or resolution fails. */ export declare function classExtendsLuminoWidget(classNode: ClassLike, checker: ts.TypeChecker | null, services: ParserServices | null): boolean; /** * Type-aware check: does `type` (transitively) extend a class declared in * `@lumino/widgets`? Used both for "does the receiver class inherit * `Widget.dispose()`'s `Signal.clearData(this)`" and for rejecting widget-typed * hops when walking a sender expression (a widget reached through a long-lived * service is not itself long-lived). */ export declare function typeExtendsLuminoWidget(type: ts.Type, checker: ts.TypeChecker): boolean; /** * Checks whether a function body references `this` in its own binding. * Descends into arrow functions (lexically transparent) but not into nested * regular functions, static blocks, or nested classes (own `this` binding). */ export declare function methodUsesThis(fn: TSESTree.FunctionExpression): boolean; /** * Syntactic hint that an expression is likely a Lumino signal, based on * conventional signal naming (`stateChanged`, `disposed`, `somethingSignal`). */ export declare function looksLikeSignalByName(objectNode: TSESTree.Expression): boolean; /** * Classifies the static type of a `.connect()` receiver expression: * - 'signal': resolves to Lumino `ISignal`/`Signal` (by symbol name or a * declaration living in `@lumino/signaling`) * - 'not-signal': resolves to some other concrete type * - 'unknown': no type information, `any`/`unknown`, or resolution failure */ export declare function classifySignalReceiver(objectNode: TSESTree.Expression, checker: ts.TypeChecker | null, services: ParserServices | null): SignalClassification; export {};