@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
149 lines (148 loc) • 9.34 kB
TypeScript
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;
}