UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

83 lines 6.34 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InputSourcesDefinition = exports.DefaultInputClassifierConfig = void 0; const ansi_1 = require("../../../util/text/ansi"); const time_1 = require("../../../util/text/time"); const joi_1 = __importDefault(require("joi")); const simple_input_classifier_1 = require("./simple-input-classifier"); const slice_query_parser_1 = require("../../../cli/repl/parser/slice-query-parser"); const input_sources_query_executor_1 = require("./input-sources-query-executor"); const range_1 = require("../../../util/range"); const flowr_search_builder_1 = require("../../../search/flowr-search-builder"); const read_functions_1 = require("../dependencies-query/function-info/read-functions"); const input_source_functions_1 = require("./input-source-functions"); exports.DefaultInputClassifierConfig = { [simple_input_classifier_1.InputTraceType.Pure]: input_source_functions_1.PureFunctions, [simple_input_classifier_1.InputType.File]: read_functions_1.ReadFunctions.map(readFunction => readFunction.name), [simple_input_classifier_1.InputType.Network]: flowr_search_builder_1.Q.fromQuery({ type: 'linter', rules: ['network-functions'] }), [simple_input_classifier_1.InputType.Random]: flowr_search_builder_1.Q.fromQuery({ type: 'linter', rules: ['seeded-randomness'] }), [simple_input_classifier_1.InputType.System]: input_source_functions_1.SystemFunctions, [simple_input_classifier_1.InputType.Ffi]: input_source_functions_1.FfiFunctions, [simple_input_classifier_1.InputType.Lang]: input_source_functions_1.LangFunctions, [simple_input_classifier_1.InputType.Options]: input_source_functions_1.OptionsFunctions, [simple_input_classifier_1.InputType.User]: input_source_functions_1.UserFunctions }; function inputSourcesQueryLineParser(output, line, _config) { const criterion = (0, slice_query_parser_1.sliceCriteriaParser)(line[0]); if (!criterion || criterion.length !== 1) { output.stderr(output.formatter.format('Invalid provenance query format, a single slicing criterion must be given in the form "(criterion1)"', { color: 1 /* Colors.Red */, effect: ansi_1.ColorEffect.Foreground, style: 1 /* FontStyles.Bold */ })); return { query: [] }; } return { query: [{ type: 'input-sources', criterion: criterion[0], }], rCode: line[1] }; } exports.InputSourcesDefinition = { executor: input_sources_query_executor_1.executeInputSourcesQuery, asciiSummarizer: async (formatter, analyzer, queryResults, result) => { const out = queryResults; result.push(`Query: ${(0, ansi_1.bold)('input-sources', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`); const nast = (await analyzer.normalize()).idMap; for (const [key, sources] of Object.entries(out.results)) { result.push(` ╰ Input Sources for ${key}`); for (const { id, trace, types, value } of sources) { const kNode = nast.get(id); const kLoc = kNode ? range_1.SourceLocation.format(range_1.SourceLocation.fromNode(kNode)) : 'unknown location'; const valueStr = value !== undefined ? `, value: ${JSON.stringify(value)}` : ''; result.push(` ╰ ${kLoc} (id: ${id}), type: ${JSON.stringify(types)}, trace: ${trace}${valueStr}`); } } return true; }, fromLine: inputSourcesQueryLineParser, schema: joi_1.default.object({ type: joi_1.default.string().valid('input-sources').required().description('The type of the query.'), criterion: joi_1.default.string().required().description('The slicing criterion to use.'), config: joi_1.default.object({ [simple_input_classifier_1.InputTraceType.Pure]: joi_1.default.array().items(joi_1.default.string()).optional().description('Deterministic/pure functions: functions that preserve constantness of their inputs (e.g., arithmetic, parse).'), [simple_input_classifier_1.InputType.File]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that read from the filesystem and produce data (e.g., read.csv, readRDS).'), [simple_input_classifier_1.InputType.Network]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that fetch data from the network (e.g., download.file, url connections).'), [simple_input_classifier_1.InputType.Random]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that produce randomness (e.g., runif, rnorm).'), [simple_input_classifier_1.InputType.System]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that execute system commands (e.g., system, system2, shell, pipe).'), [simple_input_classifier_1.InputType.Ffi]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that call native code via the R FFI (.C, .Call, .Fortran, .External, dyn.load).'), [simple_input_classifier_1.InputType.Lang]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that produce language objects (e.g., substitute, quote, bquote, expression).'), [simple_input_classifier_1.InputType.Options]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that access or set global options (e.g., options, getOption).'), [simple_input_classifier_1.InputType.User]: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that read interactive user input (e.g., file.choose, readline, menu, askYesNo).'), }).optional() }).description('Input Sources query definition'), flattenInvolvedNodes: (queryResults) => { const flattened = []; const out = queryResults; for (const obj of Object.values(out.results)) { for (const e of obj) { flattened.push(e.id); } } return flattened; } }; //# sourceMappingURL=input-sources-query-format.js.map