UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

137 lines (136 loc) 8.36 kB
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[]; }