@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
137 lines (136 loc) • 8.36 kB
TypeScript
import { AbstractFlowrAnalyzerContext } from './abstract-flowr-analyzer-context';
import { FlowrAnalyzerPackageVersionsPlugin, type SigDbLoadedInfo } from '../plugins/package-version-plugins/flowr-analyzer-package-versions-plugin';
import { Package } from '../plugins/package-version-plugins/package';
import type { PackageSignatureSource } from '../sigdb/reader';
import { Identifier } from '../../dataflow/environments/identifier';
import type { DecodedFunction } from '../sigdb/decode';
import type { Range } from 'semver';
import type { FlowrAnalyzerFunctionsContext, ReadOnlyFlowrAnalyzerFunctionsContext } from './flowr-analyzer-functions-context';
import type { InvalidationEvent, InvalidationEventReceiver } from '../cache/flowr-cache';
/**
* Read-only interface to the {@link FlowrAnalyzerDependenciesContext} for inspecting dependencies without modifying them.
*/
export interface ReadOnlyFlowrAnalyzerDependenciesContext {
/**
* The name of this context.
*/
readonly name: string;
/**
* The functions context associated with this dependencies-context.
*/
readonly functionsContext: ReadOnlyFlowrAnalyzerFunctionsContext;
/**
* Get the dependency with the given name, if it exists.
*
* If the static dependencies have not yet been loaded, this may trigger a resolution step.
* Pass `version` to pin the resolution to a constraint (an exact version string, or a {@link Range}; uncached;
* `versionOverrides` config still wins, base-R stays tied to the assumed R version); otherwise the version
* comes from the declared constraints.
* @param name - The name of the dependency to get.
* @param version - Optional version constraint to pin the resolution to (exact version string or a {@link Range}).
* @returns The dependency with the given name, or undefined if it does not exist.
*/
getDependency(name: string, version?: string | Range): Readonly<Package> | undefined;
/**
* The versions a dependency can possibly have: its {@link Package.derivedRange|derived range}, but only once
* some version can satisfy it. `undefined` if the dependency is unknown, if nothing constrains it, or if the
* sources contradict each other, since then no version is possible at all.
*
* For *why* it is what it is (the individual constraints, or the version the database resolved to), take the
* {@link Package} from {@link getDependency}.
* @param name - The name of the dependency.
*/
inferredRange(name: string): Range | undefined;
/**
* Get all dependencies known to this context.
*/
getDependencies(): readonly Readonly<Package>[];
/**
* Every package name the project *declares* (`Depends`/`Imports`/`Suggests`/`LinkingTo`/`Enhances`), whether or
* not it became a loadable dependency here. `Suggests` do not, yet they still name packages the project may install.
*/
declaredPackageNames(): readonly string[];
/**
* Metadata of the signature databases the version plugins currently have loaded.
*/
loadedSignatureDatabases(): SigDbLoadedInfo[];
/**
* The identifying names (scopes, e.g. `base`/`current`/`history`) of the signature databases currently
* available, deduplicated. A simple view over {@link loadedSignatureDatabases} for checking what a project
* can resolve against; empty when the signature database is disabled or none is loaded.
*/
availableSignatureDatabases(): readonly string[];
/**
* Whether at least one signature database is available (i.e., {@link availableSignatureDatabases} is non-empty).
* Cheaper than materializing the list when only the presence matters.
*/
hasSignatureDatabase(): boolean;
/**
* The names of known packages that export `name` (from the version plugins' signature databases). Used to
* hint which `library()`/`::` might be missing for an otherwise-undefined symbol. Empty if no database is
* available or the signature database is disabled.
*/
packagesExporting(name: string): readonly string[];
/** The signature sources the version plugins currently have loaded (backs the signature query). */
signatureSources(): readonly PackageSignatureSource[];
/**
* The signature-database entry for the qualified call `id` (a `pkg::fn` {@link Identifier}) from the first
* {@link signatureSources|source} that has it, resolving the package version from the project's dependency info
* unless `version` overrides it. This is the easy way to obtain a function's parameters from a context: pass
* `fn.signature` (or {@link signatureParameterNames}) to {@link RFunctionCall.matchArgsToParams}. `undefined`
* if `id` is unqualified or no loaded source defines it.
*/
signatureOf(id: Identifier, version?: string): DecodedFunction | undefined;
}
/**
* Manages the project's dependencies, their versions, and their interplay with {@link FlowrAnalyzerPackageVersionsPlugin}s.
*/
export declare class FlowrAnalyzerDependenciesContext extends AbstractFlowrAnalyzerContext<undefined, void, FlowrAnalyzerPackageVersionsPlugin> implements ReadOnlyFlowrAnalyzerDependenciesContext, InvalidationEventReceiver {
readonly name = "flowr-analyzer-dependencies-context";
readonly functionsContext: FlowrAnalyzerFunctionsContext;
private dependencies;
/** what {@link getDependency} resolved for a package the project does not depend on, so a lookup never makes it one */
private resolvedOnly;
private staticsLoaded;
/** resolvers consulted lazily to fill in exports; `existing` carries version info from other plugins */
private lazyResolvers;
private resolvedMisses;
reset(): void;
/** Register a resolver consulted by {@link getDependency} to fill in a package's exports lazily. */
addLazyResolver(resolver: (name: string, existing?: Package) => Package | undefined): void;
loadedSignatureDatabases(): SigDbLoadedInfo[];
availableSignatureDatabases(): readonly string[];
hasSignatureDatabase(): boolean;
packagesExporting(name: string): readonly string[];
signatureSources(): readonly PackageSignatureSource[];
signatureOf(id: Identifier, version?: string): DecodedFunction | undefined;
/** Whether any version plugin can resolve the base-R packages (a versioned signature source is available). */
hasBaseRSource(): boolean;
/** Cheap fingerprint of only the base-R-providing databases, so base-R-derived caches survive unrelated database changes. */
baseRSourceFingerprint(): string;
/** Mount an additional signature database/source by path (a plain `.sigs.ndjson`, a `.br`, or a manifest). */
addDatabaseSource(source: string): Promise<void>;
/** Eagerly mount every version plugin's signature database up front (see `solver.sigdb.eagerlyLoad`). */
eagerlyLoadSignatureDatabases(): void;
receive(event: InvalidationEvent): void;
constructor(functionsContext: FlowrAnalyzerFunctionsContext, plugins?: readonly FlowrAnalyzerPackageVersionsPlugin[]);
resolveStaticDependencies(): void;
/** Runs the static plugins once. They fill this context and the project metadata, so both gate their reads on it. */
ensureStaticsLoaded(): void;
/**
* Register a dependency declared by a project metadata file (`DESCRIPTION`, `renv.lock`, `rv.lock`, `uvr.lock`). Gated by
* `solver.sigdb.loadProjectDependencies`: when project-dependency loading is disabled this is a no-op, so the
* declared deps never enter the context (unlike {@link addDependency}, used for on-demand signature-database
* resolution).
*/
addDeclaredDependency(pkg: Package): this;
addDependency(pkg: Package): this;
getDependency(name: string, version?: string | Range): Package | undefined;
/** Like {@link getDependency}, but for a package the code pulls in (`library(p)`): the result joins the project's {@link getDependencies|dependencies}. */
loadDependency(name: string): Package | undefined;
/** Resolve `name` constrained to `range` via the plugins (uncached); falls back to the cached dependency. */
private resolvePinnedDependency;
inferredRange(name: string): Range | undefined;
getDependencies(): Package[];
declaredPackageNames(): string[];
}