@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
77 lines • 4.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeValue = void 0;
const resolve_helper_1 = require("../../environments/resolve-helper");
const general_1 = require("../values/general");
const string_constants_1 = require("../values/string/string-constants");
function infoOf(data, overrides) {
return {
environment: data.environment,
idMap: data.completeAst.idMap,
resolve: data.ctx.config.solver.variables,
ctx: data.ctx,
...overrides
};
}
function graphInfoOf(graph, ctx, overrides) {
return { graph, resolve: ctx.config.solver.variables, ctx, ...overrides };
}
/**
* The value(s) a node may hold, resolved against the state the current processor sees.
* Use {@link NodeValue.inGraph} to resolve against a finished {@link DataflowGraph} instead.
* Every entry point accepts overrides for the cases that deviate (e.g. another environment).
*
* This is constant propagation over the dataflow graph, not abstract interpretation: it follows definitions to
* constants and gives up wherever a value is not statically pinned down, with no fixpoint and no widening.
* Anything needing an abstract state lives in `src/abstract-interpretation/`.
* @example
* ```ts
* NodeValue.of(id, data); // during processing
* NodeValue.inGraph(id, graph, ctx); // on a finished graph
* NodeValue.sole(NodeValue.setOf(id, data)); // the single value, if there is exactly one
* ```
*/
exports.NodeValue = {
name: 'NodeValue',
/** The resolve info the processor's state stands for, for repeated resolutions. */
infoOf,
/** The value(s) the node may hold. */
of(id, data, overrides) {
return resolve_helper_1.Resolve.toValue(id, infoOf(data, overrides));
},
/** The value set the node may hold, `undefined` if it resolves to top or bottom. */
setOf(id, data, overrides) {
return (0, general_1.valueSetGuard)(resolve_helper_1.Resolve.toValue(id, infoOf(data, overrides)));
},
/** The strings the node may hold, `undefined` if it does not resolve to strings. */
stringsOf(id, data, overrides) {
const resolved = (0, general_1.valueSetGuard)(resolve_helper_1.Resolve.toValue(id, infoOf(data, overrides)));
return resolved ? (0, string_constants_1.collectStrings)(resolved.elements) : undefined;
},
/** The single string the node resolves to, `undefined` if it is not exactly one. */
singleStringOf(id, data, overrides) {
return resolve_helper_1.Resolve.toSingleString(id, infoOf(data, overrides));
},
/** The one value a set holds, `undefined` unless it holds exactly one, optionally of the given kind. */
sole: general_1.soleValue,
/** The one value the node resolves to, `undefined` unless it is exactly one, optionally of the given kind. */
soleOf(id, data, type, overrides) {
return (0, general_1.soleValue)((0, general_1.valueSetGuard)(resolve_helper_1.Resolve.toValue(id, infoOf(data, overrides))), type);
},
/** The same questions, asked of a finished dataflow graph instead of a running processor. */
inGraph: {
/** The value set the node may hold, `undefined` if it resolves to top or bottom. */
setOf(id, graph, ctx, overrides) {
return (0, general_1.valueSetGuard)(resolve_helper_1.Resolve.toValue(id, graphInfoOf(graph, ctx, overrides)));
},
/** The single string the node resolves to, `undefined` if it is not exactly one. */
singleStringOf(id, graph, ctx, overrides) {
return resolve_helper_1.Resolve.toSingleString(id, graphInfoOf(graph, ctx, overrides));
},
/** The one value the node resolves to, `undefined` unless it is exactly one, optionally of the given kind. */
soleOf(id, graph, ctx, type, overrides) {
return (0, general_1.soleValue)((0, general_1.valueSetGuard)(resolve_helper_1.Resolve.toValue(id, graphInfoOf(graph, ctx, overrides))), type);
}
}
};
//# sourceMappingURL=node-value.js.map