UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

149 lines (148 loc) 9.34 kB
import { FlowrAnalyzerPackageVersionsPlugin, type SigDbLoadedInfo } from './flowr-analyzer-package-versions-plugin'; import { SemVer } from 'semver'; import type { FlowrAnalyzerContext } from '../../context/flowr-analyzer-context'; import { type PackageSignatureSource } from '../../sigdb/reader'; import { type FlowrConfig } from '../../../config'; /** the plugin's instance name (pass to `unregisterPlugins` to disable the default sigdb resolver) */ export declare const SigDbPluginName = "flowr-analyzer-package-versions-sigdb-plugin"; export declare const sigDbLog: import("tslog").Logger<import("tslog").ILogObj>; /** an opened signature source, or a local file path (a plain `.sigs.ndjson`, or a `.br`/manifest via {@link FlowrAnalyzerPackageVersionsSigDbPlugin.preload}) */ export type SigDbSource = PackageSignatureSource | string; /** * The database flattens S3 methods into the export list, so we recover the `generic -> classes` map for * dispatch: an export `generic.class` is a method when the `generic` is itself exported (e.g. `print.foo`). */ export declare function reconstructS3Generics(exported: readonly string[]): Map<string, string[]>; /** * The packages exporting one name: the sole exporter bare, the rivals as an array. Roughly 95% of the names in a * bundle are exported by exactly one package, so giving those an array of their own would cost more than the * index itself. */ export type ExportIndexEntry = string | string[]; /** * The reverse `export name -> packages exporting it` view of a signature source, each entry ordered by download * count (descending, ties by name) so whoever has to pick one exporter starts with the package a script most * likely means. * * Building the view reads every package blob of a bundle, which is why {@link of} memoizes it on the source * object rather than on the caller: signature sources are opened once per process (see {@link getSharedSigSource}) * and are immutable, so every analyzer mounting the same bundle shares one index instead of re-scanning the * database per analysis. It is deliberately analyzer-independent -- self-package exclusion belongs to the caller * (see {@link FlowrAnalyzerPackageVersionsSigDbPlugin.packagesExporting}), not to the index. */ export declare const ExportIndex: { readonly name: "ExportIndex"; /** The index of `src`, built on first use and shared by every later caller; see {@link ExportIndex}. */ readonly of: (this: void, src: PackageSignatureSource) => ReadonlyMap<string, ExportIndexEntry>; /** The packages an {@link ExportIndexEntry} names, as a list; empty when no package exports the name. */ readonly owners: (this: void, entry: ExportIndexEntry | undefined) => readonly string[]; }; /** * Resolves `library(pkg)` / `use(pkg, fn)` from precomputed `flowr-sigdb` databases via the * {@link PackageSignatureSource} contract. For an R-core package it picks the version shipped with the assumed * R release (`solver.sigdb.assumedRVersion`), so `library(stats)` attaches that release's exports. Plain-file * sources load lazily; a `.br` or manifest source is mounted by {@link preload}. On by default. */ export declare class FlowrAnalyzerPackageVersionsSigDbPlugin extends FlowrAnalyzerPackageVersionsPlugin { readonly name = "flowr-analyzer-package-versions-sigdb-plugin"; readonly description = "Resolves library exports (and versioned base R) from precomputed flowr-sigdb databases."; readonly version: SemVer; private readonly extraSources; private sources; /** the `additionalPaths` the current {@link sources} were assembled with, so a later config resolves a rebuild */ private sourcesKey; private analyzerCtx; /** `packagesExporting` answers, merged across the source set and self-filtered; the scan itself is {@link ExportIndex} */ private exportsByName; /** `pkg@assumedR` keys already reported via {@link baseVersionFor}'s fallback, so the info is logged once */ private readonly baseFallbacksLogged; /** installed package versions for `versionSelection: 'system'`, read once from R (see {@link warmInstalledVersions}) */ private installedVersions; /** guards the one-time async warm-up of {@link installedVersions} */ private installedVersionsPromise; /** invalidate the assembled source list and derived caches (after a source or config change) */ private resetAssembled; constructor(...sources: SigDbSource[]); /** * Dynamically add signature sources after construction (opened instances, plain `.sigs.ndjson`, or `.br`/ * manifest paths). Added sources take precedence over the bundled default, so they can override or extend it. */ addSource(...sources: readonly SigDbSource[]): void; process(ctx: FlowrAnalyzerContext): void; private syncPromise; /** * Opt-in (`solver.sigdb.autoSync`) startup re-sync. * If the committed `sigdb.remote.json` link file lists shards whose cached copies are missing or hash-mismatched, * this will sync them. */ private startBackgroundSync; private warmPromise; /** * Warm the hot shards (base + most-downloaded packages) of any sharded source in a background task, so the * first `library()` lookup no longer blocks on decompression. Idempotent. */ private startBackgroundWarm; /** * Read the system's installed package versions once (for `versionSelection: 'system'`), off the hot path. Only * an R-backed parser exposes `installedPackageVersions`; a tree-sitter (no-R) parser skips this, so `system` * gracefully falls back to `newest` in {@link resolve}. Idempotent; failures leave the map empty (same fallback). */ private warmInstalledVersions; /** Mount the databases up front instead of on the first library load (see `solver.sigdb.eagerlyLoad`). */ preloadDatabasesSync(): void; /** whether any loaded source carries a versioned base-R package (so base namespaces can be attached eagerly) */ providesBaseRPackages(): boolean; signatureSources(config?: FlowrConfig): readonly PackageSignatureSource[]; loadedDatabases(): SigDbLoadedInfo[]; /** * Packages in the loaded sources (respecting `self`-package exclusion) that export `name`, **most downloaded * first**, so whoever has to pick one (or show only a few) starts with the package a script most likely means. * Backed by {@link ExportIndex}, a reverse index built once per *source* (and hence shared by every analyzer * mounting the same bundle), so repeated hint lookups (e.g. from the `undefined-symbol` linter) do not re-scan * every package. Self-package exclusion is applied here rather than baked into the index, which keeps the * index analyzer-independent. */ packagesExporting(name: string): readonly string[]; /** * The raw sources in priority order: explicit constructor sources, `$FLOWR_SIGDB`, then **every** bundled * database discovered in the data dirs (see {@link defaultSigDbPaths}), so an extra bundle dropped next to * the default (e.g. a downloaded full-history one) is mounted automatically. All bundled defaults are skipped * when `$FLOWR_DISABLE_DEFAULT_SIGDB` is set; explicit sources are always honored. */ private rawSources; /** synchronously openable sources (instances + plain `.sigs.ndjson`); `.br`/manifests are added by {@link preload}. */ private loadSources; private loadSync; /** * Open every source, including compressed bundles (`.br`/`.gz`) and manifests (`*.manifest.json`). * Call once at the analyzer boundary so resolution can fall through to them. */ preload(): Promise<void>; addDatabaseSource(source: string): Promise<void>; /** Whether the given name is the analyzed project itself (so we must not shadow its own definitions). */ private isSelfPackage; /** * For a base package, the newest core version `<=` the assumed R version (see * {@link FlowrAnalyzerContext.resolvedRVersion}). If the assumed version predates every recorded core * release, the closest supported one (the earliest) is used and the substitution is logged once as info. */ private baseVersionFor; private resolve; /** the concrete export view for a non-base package under the active {@link VersionSelection} policy, or `undefined` if none satisfies */ private selectVersion; /** * Newest version satisfying the constraint. Fast path: prefer the source's latest (no history decompression for * the common `>=` case) and accept it when it satisfies; only otherwise enumerate the stored versions and pick * the highest satisfying one (e.g. an upper-bound or exact-old pin). */ private newestSatisfying; /** Lowest stored version satisfying the constraint (using the store's actual R-form version strings). */ private oldestSatisfying; /** * The versions the source can answer for a package (dated releases, base-R core releases, and the latest), * ascending. Versions that differ in writing but not in order (`1.2` and `1.2.0`) are settled by release date. */ private availableVersions; /** build the resolved {@link Package} (namespace + version) from a source's export view */ private toResolvedPackage; }