/** * Parser for `leaks --referenceTree --groupByType --noContent`. * * `leaks --referenceTree` walks the heap reachability graph and prints * per-class instance counts plus total bytes. With `--groupByType`, instances * of the same class are aggregated into a single entry; with `--noContent`, * the inline ivar dumps are suppressed so the tree stays compact. * * Example input (excerpt from a real run on a notelet-like target): * * ```text * + ! : 342 (28.8K) AVPlayerItem * + ! : | 334 (28.7K) _playerItem --> AVPlayerItemInternal * + ! : 290 (19.1K) AVPlayerPlaybackCoordinator * + ! 1 (48 bytes) __strong _object --> NSKeyValueObservance * + ! 15 (720 bytes) __strong _object --> NSKeyValueObservance * + ! 8 (384 bytes) NSKeyValueObservance * + ! 9 (400 bytes) NSKeyValueObservationInfo * ``` * * Each data line has the shape: * * () [--> ] * * - When `--> ClassName` is present, the class name is the part AFTER the * arrow (the value's type). The text before the arrow is the property / * ivar name pointing at it. * - When no arrow is present, the trailing token IS the class name. * * memorydetective's abandoned-memory surface aggregates by class name across * the entire tree, summing counts and bytes, and returns the top N by * instance count. The use case is "show me classes that are alive in the * heap that the agent should suspect", which is orthogonal to leak count. */ export interface ReferenceTreeEntry { className: string; instanceCount: number; totalBytes: number; } /** * Pure: parse a size literal from leaks output like "832 bytes", "28.8K", "1.5M". * Returns the value in BYTES. Unrecognized formats return 0 (parser is * conservative; the aggregation that consumes this still produces a usable * count even if the size is missing). */ export declare function parseSizeBytes(raw: string): number; /** * Pure: extract the class name from a leaks reference-tree line value. * * - "AVPlayerItem" -> "AVPlayerItem" * - "_playerItem --> AVPlayerItemInternal" -> "AVPlayerItemInternal" * - "__strong _object --> NSKeyValueObservance" -> "NSKeyValueObservance" * - " [64]" -> "CFDictionary" * - " [32]" -> "NSMutableDictionary" * - "_object --> [16]" -> "NSObject" * - "" -> null (caller skips) * * The ` [size]` form is what `leaks --referenceTree` emits * for arrow-targeted instances (e.g. `_object --> `). * Without normalization, each address becomes its own aggregation key and * the same logical class shows up as N separate rows in the top-N list. * Normalizing to the base class name (the token inside the `<...>`) folds * those rows back together. This is the v1.10 fix for the gap where * AVPlayerItem-style classes appeared aggregated at the root level but * NSMutableDictionary-style classes appeared per-address in arrow targets. * * Excludes c-runtime allocations like `malloc in FigSimpleMutex...` AND the * bracketed form `` / `` / `` * that leaks emits alongside Obj-C/Swift classes; those are not actionable * for abandoned-memory triage and would inflate the top-N list with * low-signal entries. */ export declare function extractClassName(rawLabel: string): string | null; /** * Pure: returns true when the class name is framework-noise that crowds out * actionable classes in the abandoned-memory top-N list. Used by the * `analyzeMemgraph` and `analyzeAbandonedMemory` tools to populate a * `*Suspects[]` / `actionable*[]` field alongside the raw `*Top[]` field. * * The list catalogs: * - Foundation collection types (`NSMutableDictionary`, `CFString`, etc.) * that grow with normal app activity and are rarely the leak itself * - ObjC runtime / metadata classes (`Class.data`, `OBJC_METACLASS_$...`) * - Apple system frameworks' static data sections (`__DATA __bss`, * `__DATA __data`, `__DATA __common`) * - `<>` summary row * - "Stack of thread N" and similar meta-rows * - Non-object zone descriptors and memory-zone metadata * * Deliberately NOT noise: AV*, NSKeyValueObserv*, SwiftUI app-level types, * Combine, RxSwift, app-named classes, anonymous closures (``). * * The default behavior of `analyzeMemgraph` continues to return the raw * `abandonedMemoryTop[]` so callers who need framework-collection counts * (e.g. cache-bloat investigations) still see them. The actionable field * is parallel data, not a replacement. */ export declare function isFrameworkNoise(className: string): boolean; /** * Pure: parse `leaks --referenceTree --groupByType --noContent` stdout, * aggregate instance counts + bytes by class name, return the top N by * instance count. * * Returned entries are sorted by `instanceCount` desc, ties broken by * `totalBytes` desc, ties broken by alphabetic class name for stability. * * The caller passes `topN` so very large heaps do not produce massive * responses; the default in the tool is 20 but the parser does not impose * a default to keep the function pure. */ export declare function parseReferenceTreeText(text: string, topN: number): ReferenceTreeEntry[];