@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
77 lines • 4.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AttachedBasePackageSet = exports.AttachedBasePackages = void 0;
exports.baseRPackages = baseRPackages;
exports.baseRExportOwner = baseRExportOwner;
exports.isBaseRPackage = isBaseRPackage;
const r_base_packages_generated_1 = require("../data/r-base-packages.generated");
const r_base_primitives_generated_1 = require("../data/r-base-primitives.generated");
const r_version_1 = require("./r-version");
/** the base packages R attaches to the search path on startup, so their exports are usable without a `library` call */
exports.AttachedBasePackages = ['base', 'stats', 'graphics', 'grDevices', 'utils', 'datasets', 'methods'];
/** {@link AttachedBasePackages} for membership tests, which happen far more often than iteration. */
exports.AttachedBasePackageSet = new Set(exports.AttachedBasePackages);
/** clamp `rVersion` to the newest R release the store knows about (so a future R version stays answerable) */
function effective(rVersion) {
return r_version_1.RVersion.compare(rVersion, r_base_packages_generated_1.RBasePackageStore.newestRVersion) > 0 ? r_base_packages_generated_1.RBasePackageStore.newestRVersion : rVersion;
}
/** memoized results per assumed R version, so the list is computed at most once per version (never per lookup) */
const cache = new Map();
/**
* The base packages available at the assumed R version (all of them if omitted). A package counts as
* available when that R release lies within the range it was part of core; e.g. `parallel` (added in R
* 2.14.0) is absent for an assumed R 2.10, and long-merged packages like `ctest` are absent for modern R.
*
* The newest release is served from the precomputed {@link RBasePackageStore.current} array.
* Every other version is computed once and memoized, so this never recomputes on repeated calls.
*/
function baseRPackages(rVersion) {
// fast path: no version, or the exact newest-release string, avoids the (regex-based) version compare entirely
if (rVersion === undefined || rVersion === r_base_packages_generated_1.RBasePackageStore.newestRVersion || r_version_1.RVersion.compare(rVersion, r_base_packages_generated_1.RBasePackageStore.newestRVersion) >= 0) {
return r_base_packages_generated_1.RBasePackageStore.current; // the current base set, precomputed at bundle time
}
const cached = cache.get(rVersion);
if (cached !== undefined) {
return cached;
}
const eff = effective(rVersion);
const result = Object.entries(r_base_packages_generated_1.RBasePackageStore.packages)
.filter(([, [first, last]]) => r_version_1.RVersion.compare(first, eff) <= 0 && r_version_1.RVersion.compare(last, eff) >= 0)
.map(([name]) => name);
cache.set(rVersion, result);
return result;
}
/** the base export to owning-package map, materialised once from the grouped store (never per lookup) */
let exportOwners;
/**
* The base-R package that exports `name` (e.g. `sd` yields `stats`, `plot` yields `base`), or `undefined`.
* Backed by the bundle-time store, so it needs no loaded database and no runtime resolution: the
* export-to-package index is inverted from {@link RBasePackageStore.exportsByPackage} once on first use.
* Base primitives/internals and base data constants (`is.na`, `.Machine`, ...) are not in the sigdb
* export list, so they are answered from {@link RBasePrimitives} and owned by `base`.
*/
function baseRExportOwner(name) {
if (exportOwners === undefined) {
exportOwners = new Map();
for (const [pkg, names] of Object.entries(r_base_packages_generated_1.RBasePackageStore.exportsByPackage)) {
for (const exported of names) {
exportOwners.set(exported, pkg);
}
}
}
return exportOwners.get(name) ?? (r_base_primitives_generated_1.RBasePrimitives.has(name) ? 'base' : undefined);
}
/** whether `name` is an R-core / base package at the assumed R version (see {@link baseRPackages}). */
function isBaseRPackage(name, rVersion) {
// the store is `as const`, so it carries no string index signature; read it as a record for the dynamic lookup
const range = r_base_packages_generated_1.RBasePackageStore.packages[name];
if (range === undefined) {
return false;
}
if (rVersion === undefined) {
return true;
}
const eff = effective(rVersion);
return r_version_1.RVersion.compare(range[0], eff) <= 0 && r_version_1.RVersion.compare(range[1], eff) >= 0;
}
//# sourceMappingURL=r-base-packages.js.map