UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

133 lines 5.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemorySignatureSource = void 0; exports.memorySourceOfPackages = memorySourceOfPackages; const r_version_1 = require("../../util/r-version"); const reader_1 = require("./reader"); const r_base_packages_1 = require("../../util/r-base-packages"); /** what {@link LibraryExports.version} says when the source was given no version to claim */ const UnknownVersion = ''; /** * A signature source held entirely in memory, for the places that cannot open a database file: a browser * (the playground bundles its packages rather than reading them) and a test that wants to state a package's * exports outright. It answers what a package brings into scope; the per-function view a real database * decodes from its blobs is not part of what it can say, so those answers stay empty. * @see {@link SigDatabase} - the file-backed source */ class MemorySignatureSource { packages; /** reverse index `class -> owning package`, built on first use (see {@link classOwner}) */ classIndex; constructor(packages) { this.packages = packages instanceof Map ? packages : new Map(Object.entries(packages)); } has(pkg) { return this.packages.has(pkg); } hasVersion(pkg, version) { const known = this.versionOf(pkg); return known !== UnknownVersion && known === version; } isCranVersion(pkg, version) { return this.hasVersion(pkg, version); } lookup(pkg, version) { const found = this.packages.get(pkg); /* a source given no version has one answer and gives it whatever is asked for: it cannot say no */ if (found === undefined || !this.answersFor(pkg, version)) { return undefined; } return { version: this.versionOf(pkg), exported: found.exported, internal: [], deprecated: found.deprecated ?? [], s3Classes: found.s3Classes ?? [], s4Classes: found.s4Classes ?? [], cran: true }; } packagesExporting(name) { return [...this.packages] .filter(([, p]) => p.exported.includes(name)) .sort(([an, a], [bn, b]) => (b.downloads ?? 0) - (a.downloads ?? 0) || an.localeCompare(bn)) .map(([pkg]) => pkg); } classOwner(className, version) { if (version !== undefined) { return this.packageNames().find(pkg => { const lib = this.lookup(pkg, version); return (lib?.s3Classes.includes(className) ?? false) || (lib?.s4Classes.includes(className) ?? false); }); } this.classIndex ??= (0, reader_1.classOwnerIndexFor)(this, this.packageNames()); return this.classIndex.get(className); } /** no blobs to decode, so the rich per-function view has nothing to give */ functions() { return undefined; } functionByName() { return undefined; } transitiveCallees() { return undefined; } dependencies(pkg, version) { const found = this.packages.get(pkg); if (found === undefined || !this.answersFor(pkg, version)) { return undefined; } return [...found.deps ?? []]; } packageNames() { return [...this.packages.keys()]; } isBaseR(pkg) { return (0, r_base_packages_1.baseRPackages)().includes(pkg); } downloads(pkg) { return this.packages.get(pkg)?.downloads ?? 0; } /** the R releases a base package shipped with are a property of the database, which this source has none of */ coreVersions() { return undefined; } releaseDate(pkg) { return this.packages.get(pkg)?.released; } releaseDates(pkg) { const version = this.latestVersion(pkg); const date = this.releaseDate(pkg); return version === undefined || date === undefined ? [] : [{ version, date }]; } latestVersion(pkg) { const known = this.versionOf(pkg); return known === UnknownVersion ? undefined : r_version_1.RVersion.parse(known); } /** nothing is held open */ close() { /* nothing to release */ } /** whether the package answers a lookup for `version`, which an unversioned one always does */ answersFor(pkg, version) { return version === undefined || this.versionOf(pkg) === UnknownVersion || this.versionOf(pkg) === version; } versionOf(pkg) { return this.packages.get(pkg)?.version ?? UnknownVersion; } } exports.MemorySignatureSource = MemorySignatureSource; /** * A {@link MemorySignatureSource} from what a page can carry: `package -> [version, release date, ...exports]`. * The version is what the exports were read from, so recording it is what keeps a consumer from being told * the package is unknown when only its history is. */ function memorySourceOfPackages(packages) { return new MemorySignatureSource(Object.fromEntries(Object.entries(packages).map(([pkg, [version = '', released = '', ...exported]]) => [pkg, { exported, version: version.length > 0 ? version : undefined, released: released.length > 0 ? new Date(released) : undefined }]))); } //# sourceMappingURL=memory-source.js.map