UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

130 lines 5.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Package = void 0; const semver_1 = require("semver"); const assert_1 = require("../../../util/assert"); const flowr_namespace_file_1 = require("../file-plugins/files/flowr-namespace-file"); const flowr_file_1 = require("../../context/flowr-file"); const r_version_1 = require("../../../util/r-version"); const node_id_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/node-id"); /** * A package as the sources describe it, accumulated with {@link addInfo}/{@link mergeInPlace}: only those may * change it, everything else reads. Its three version views run from the rawest to the most concrete: * - {@link versionConstraints}: what each source declared, unmerged. * - {@link derivedRange}: their intersection, whether or not a version can satisfy it (see * {@link hasSatisfiableVersion}, and `inferredRange` on the dependencies context for the range that is only * handed out once it is). * - {@link resolvedVersion}: the one concrete version the exports were read from. */ class Package { name; _type; _dependencies; _namespaceInfo; _resolvedVersion; _versionConstraints = []; /** the intersection of {@link versionConstraints}, computed on demand and dropped whenever one is added */ _derivedRange; get type() { return this._type; } get dependencies() { return this._dependencies; } get namespaceInfo() { return this._namespaceInfo; } get resolvedVersion() { return this._resolvedVersion; } get versionConstraints() { return this._versionConstraints; } get derivedRange() { this._derivedRange ??= this.deriveRange(); return this._derivedRange; } /** {@link derivedRange} if a source declared one, else the {@link resolvedVersion} the exports were read from. */ get effectiveRange() { return this.derivedRange ?? (this._resolvedVersion !== undefined ? r_version_1.RRange.parse('=' + this._resolvedVersion) : undefined); } constructor(info) { this.name = info.name; this.addInfo(info); } /** Builds a package from a raw `NAMESPACE` body and its list of callable exports. */ static fromConstants(name, namespace, callable) { return new Package({ name, namespaceInfo: (0, flowr_namespace_file_1.setCallable)(flowr_namespace_file_1.FlowrNamespaceFile.from(new flowr_file_1.FlowrInlineTextFile('NAMESPACE', namespace)).content().current, callable) }); } has(name, className) { if (!this.namespaceInfo) { return false; } // an explicit `generic`/`className` pair -> S3 method lookup if (className) { const classes = this.namespaceInfo.exportS3Generics.get(name); return classes ? classes.includes(className) : false; } // a directly exported symbol/function - this also covers dotted plain exports such as // `solve.QP`, `as.Date` or `read.csv` that are not S3 methods if (this.namespaceInfo.exportedFunctions.includes(name) || this.namespaceInfo.exportedSymbols.includes(name)) { return true; } // otherwise it may be an S3 method `generic.class` whose exported generic reconstructs it if (name.includes('.')) { const dot = name.indexOf('.'); const classes = this.namespaceInfo.exportS3Generics.get(name.slice(0, dot)); return classes ? classes.includes(name.slice(dot + 1)) : false; } return false; } s3For(generic) { return this.namespaceInfo?.exportS3Generics.get(generic) ?? []; } mergeInPlace(other) { (0, assert_1.guard)(this.name === other.name, 'Can only merge packages with the same name'); this.addInfo({ type: other.type, dependencies: other._dependencies, namespaceInfo: other.namespaceInfo, versionConstraints: other._versionConstraints, resolvedVersion: other.resolvedVersion }); } addInfo({ type, dependencies, namespaceInfo, versionConstraints, resolvedVersion }) { this._resolvedVersion = resolvedVersion ?? this._resolvedVersion; this._type = type ?? this._type; this._dependencies = dependencies ?? this._dependencies; this._namespaceInfo = namespaceInfo ?? this._namespaceInfo; if (versionConstraints !== undefined && versionConstraints.length > 0) { this._versionConstraints.push(...versionConstraints); this._derivedRange = undefined; // re-derived on the next read, once every source has had its say } } /** The combined (intersected) range of all recorded constraints, or `undefined` if none were given. */ deriveRange() { // sources may disagree, which `hasSatisfiableVersion` reports rather than this failing return r_version_1.RRange.intersect(this._versionConstraints); } /** Whether some concrete version can satisfy every recorded constraint at once. */ hasSatisfiableVersion() { const range = this.derivedRange; return range !== undefined && (0, semver_1.minVersion)(range) !== null; } static parsePkgVersionRange(constraint, version) { if (version) { return constraint ? r_version_1.RRange.parse(constraint + version) : r_version_1.RRange.parse(version); } else { return undefined; } } static functionIdentifier(dependency, func) { return node_id_1.NodeId.pkgFnName(dependency, func); } } exports.Package = Package; //# sourceMappingURL=package.js.map