@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
107 lines • 4.26 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EmptyBuiltInEnvironment = exports.BuiltInEnvironment = exports.Environment = void 0;
exports.makeReferenceMaybe = makeReferenceMaybe;
exports.makeAllMaybe = makeAllMaybe;
exports.initializeCleanEnvironments = initializeCleanEnvironments;
exports.builtInEnvJsonReplacer = builtInEnvJsonReplacer;
const identifier_1 = require("./identifier");
const built_in_1 = require("./built-in");
const resolve_by_name_1 = require("./resolve-by-name");
const json_1 = require("../../util/json");
/**
* Marks the reference as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
*/
function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = undefined) {
const node = graph.get(ref.nodeId, true);
if (includeDefs) {
const definitions = ref.name ? (0, resolve_by_name_1.resolveByName)(ref.name, environments, ref.type) : undefined;
for (const definition of definitions ?? []) {
if (definition.type !== identifier_1.ReferenceType.BuiltInFunction && definition.type !== identifier_1.ReferenceType.BuiltInConstant) {
if (definition.controlDependencies && defaultCd && !definition.controlDependencies.find(c => c.id === defaultCd.id)) {
definition.controlDependencies.push(defaultCd);
}
else {
definition.controlDependencies = defaultCd ? [defaultCd] : [];
}
}
}
}
if (node) {
const [fst] = node;
if (fst.cds && defaultCd && !fst.cds.includes(defaultCd)) {
fst.cds.push(defaultCd);
}
else {
fst.cds = defaultCd ? [defaultCd] : [];
}
}
return { ...ref, controlDependencies: [...ref.controlDependencies ?? [], ...(defaultCd ? [defaultCd] : [])] };
}
function makeAllMaybe(references, graph, environments, includeDefs, defaultCd = undefined) {
if (references === undefined) {
return [];
}
return references.map(ref => makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd));
}
let environmentIdCounter = 0;
/** @see REnvironmentInformation */
class Environment {
id = environmentIdCounter++;
parent;
memory;
constructor(parent) {
this.parent = parent;
this.memory = new Map();
}
}
exports.Environment = Environment;
/**
* The built-in {@link REnvironmentInformation|environment} is the root of all environments.
*
* For its default content (when not overwritten by a flowR config),
* see the {@link DefaultBuiltinConfig}.
*/
exports.BuiltInEnvironment = new Environment(undefined);
exports.BuiltInEnvironment.memory = undefined;
/**
* The twin of the {@link BuiltInEnvironment} but with less built ins defined for
* cases in which we want some commonly overwritten variables to remain open.
* If you do not know if you need the empty environment, you do not need the empty environment (right now).
*
* @see {@link BuiltInEnvironment}
*/
exports.EmptyBuiltInEnvironment = {
id: exports.BuiltInEnvironment.id,
memory: undefined,
parent: undefined
};
/**
* Initialize a new {@link REnvironmentInformation|environment} with the built-ins.
* See {@link EmptyBuiltInEnvironment} for the case `fullBuiltIns = false`.
*/
function initializeCleanEnvironments(fullBuiltIns = true) {
if (exports.BuiltInEnvironment.memory === undefined) {
exports.BuiltInEnvironment.memory = built_in_1.BuiltInMemory;
exports.EmptyBuiltInEnvironment.memory = built_in_1.EmptyBuiltInMemory;
}
return {
current: new Environment(fullBuiltIns ? exports.BuiltInEnvironment : exports.EmptyBuiltInEnvironment),
level: 0
};
}
/**
* Helps to serialize an environment, but replaces the built-in environment with a placeholder.
*/
function builtInEnvJsonReplacer(k, v) {
if (v === exports.BuiltInEnvironment) {
return '<BuiltInEnvironment>';
}
else if (v === exports.EmptyBuiltInEnvironment) {
return '<EmptyBuiltInEnvironment>';
}
else {
return (0, json_1.jsonReplacer)(k, v);
}
}
//# sourceMappingURL=environment.js.map