@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
118 lines • 5.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getArgumentStringValue = getArgumentStringValue;
const graph_1 = require("../../graph/graph");
const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
const assert_1 = require("../../../util/assert");
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
const dependencies_query_format_1 = require("../../../queries/catalog/dependencies-query/dependencies-query-format");
const general_1 = require("../values/general");
const alias_tracking_1 = require("./alias-tracking");
const r_value_1 = require("../values/r-value");
const convert_values_1 = require("../../../r-bridge/lang-4.x/convert-values");
const string_constants_1 = require("../values/string/string-constants");
/**
* Get the values of all arguments matching the criteria.
*/
function getArgumentStringValue(variableResolve, graph, vertex, argumentIndex, argumentName, resolveValue, ctx) {
if (argumentName) {
const arg = vertex?.args.findIndex(arg => arg !== r_function_call_1.EmptyArgument && arg.name === argumentName);
if (arg >= 0) {
argumentIndex = arg;
}
}
if (!vertex || argumentIndex === undefined) {
return undefined;
}
if (argumentIndex === 'unnamed') {
// return all unnamed arguments
const references = vertex.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.FunctionArgument.getReference).filter(assert_1.isNotUndefined);
const map = new Map();
for (const ref of references) {
let valueNode = graph.idMap?.get(ref);
if (valueNode?.type === type_1.RType.Argument) {
valueNode = valueNode.value;
}
if (valueNode) {
// this should be evaluated in the callee-context
const values = resolveBasedOnConfig(variableResolve, graph, vertex, valueNode, vertex.environment, graph.idMap, resolveValue, ctx) ?? [dependencies_query_format_1.Unknown];
map.set(ref, new Set(values));
}
}
return map;
}
if (argumentIndex < vertex.args.length) {
const arg = graph_1.FunctionArgument.getReference(vertex.args[argumentIndex]);
if (!arg) {
return undefined;
}
let valueNode = graph.idMap?.get(arg);
if (valueNode?.type === type_1.RType.Argument) {
valueNode = valueNode.value;
}
if (valueNode) {
const values = resolveBasedOnConfig(variableResolve, graph, vertex, valueNode, vertex.environment, graph.idMap, resolveValue, ctx) ?? [dependencies_query_format_1.Unknown];
return new Map([[arg, new Set(values)]]);
}
}
return undefined;
}
function hasCharacterOnly(variableResolve, graph, vertex, idMap, ctx) {
if (!vertex.args || vertex.args.length === 0 || !idMap) {
return false;
}
const treatAsChar = getArgumentStringValue(variableResolve, graph, vertex, 5, 'character.only', true, ctx);
if (!treatAsChar) {
return false;
}
const hasTrue = treatAsChar.values().some(set => set?.has('TRUE'));
const hasFalse = hasTrue ? treatAsChar.values().some(set => set === undefined || set.has('FALSE')) : false;
if (hasTrue && hasFalse) {
return 'maybe';
}
else {
return hasTrue;
}
}
function resolveBasedOnConfig(variableResolve, graph, vertex, argument, environment, idMap, resolveValue, ctx) {
let full = true;
if (!resolveValue) {
full = false;
}
if (resolveValue === 'library') {
const hasChar = hasCharacterOnly(variableResolve, graph, vertex, idMap, ctx);
if (hasChar === false) {
if (argument.type === type_1.RType.Symbol) {
return [argument.lexeme];
}
full = false;
}
}
const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(argument, { environment, graph, full, resolve: variableResolve, ctx }));
if (resolved) {
const values = [];
for (const value of resolved.elements) {
if (!(0, r_value_1.isValue)(value)) {
return undefined;
}
else if (value.type === 'string' && (0, r_value_1.isValue)(value.value)) {
values.push(value.value.str);
}
else if (value.type === 'logical' && (0, r_value_1.isValue)(value.value)) {
values.push(value.value.valueOf() ? convert_values_1.RTrue : convert_values_1.RFalse);
}
else if (value.type === 'vector' && (0, r_value_1.isValue)(value.elements)) {
const elements = (0, string_constants_1.collectStrings)(value.elements, !full);
if (elements === undefined) {
return undefined;
}
values.push(...elements);
}
else {
return undefined;
}
}
return values;
}
}
//# sourceMappingURL=resolve-argument.js.map