UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

118 lines 5.15 kB
"use strict"; 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