UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

93 lines 4.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const assert_1 = require("../util/assert"); const log_1 = require("../util/log"); const process_1 = require("../benchmark/summarizer/first-phase/process"); const slice_diff_ansi_1 = require("../core/print/slice-diff-ansi"); const json_1 = require("../util/json"); const script_1 = require("./common/script"); const slicer_1 = require("../benchmark/slicer"); const print_1 = require("../benchmark/stats/print"); const magic_comments_1 = require("../reconstruct/auto-select/magic-comments"); const auto_select_defaults_1 = require("../reconstruct/auto-select/auto-select-defaults"); const config_1 = require("../config"); const options = (0, script_1.processCommandLineArgs)('slicer', ['input', 'criterion'], { subtitle: 'Slice R code based on a given slicing criterion', examples: [ '{bold -c} {italic "12@product"} {italic test/testfiles/example.R}', // why double escaped :C '{bold -c} {italic "3@a"} {bold -r} {italic "a <- 3\\\\nb <- 4\\\\nprint(a)"} {bold --diff}', '{bold -i} {italic example.R} {bold --stats} {bold --criterion} {italic "8:3;3:1;12@product"}', '{bold --help}' ] }); async function getSlice() { const slicer = new slicer_1.BenchmarkSlicer('r-shell'); (0, assert_1.guard)(options.input !== undefined, 'input must be given'); (0, assert_1.guard)(options.criterion !== undefined, 'a slicing criterion must be given'); const config = config_1.FlowrConfig.fromFile(); await slicer.init(options['input-is-text'] ? { request: 'text', content: options.input.replaceAll('\\n', '\n') } : { request: 'file', content: options.input }, config, options['no-magic-comments'] ? auto_select_defaults_1.doNotAutoSelect : (0, magic_comments_1.makeMagicCommentHandler)(auto_select_defaults_1.doNotAutoSelect)); let mappedSlices = []; let reconstruct = undefined; const doSlicing = options.criterion.trim() !== ''; let slice = undefined; if (doSlicing) { const slices = options.criterion.split(';').map(c => c.trim()); try { const { stats: { reconstructedCode, slicingCriteria }, slice: sliced } = await slicer.slice(...slices); slice = sliced; mappedSlices = slicingCriteria; reconstruct = reconstructedCode; if (options.output) { console.log('Written reconstructed code to', options.output); console.log(`Automatically selected ${reconstructedCode.linesWithAutoSelected} lines`); fs_1.default.writeFileSync(options.output, reconstructedCode.code); } else if (!options.api && !options.diff) { console.log(reconstructedCode.code); } } catch (e) { log_1.log.error(`[Skipped] Error while processing ${options.input}: ${e.message} (${e.stack ?? ''})`); } } const { stats, normalize, parse, tokenMap, dataflow } = slicer.finish(); const mappedCriteria = mappedSlices.map(c => ` ${c.criterion} => ${c.id} (${JSON.stringify(normalize.idMap.get(c.id)?.location)})`).join('\n'); log_1.log.info(`Mapped criteria:\n${mappedCriteria}`); const sliceStatsAsString = (0, print_1.stats2string)(await (0, process_1.summarizeSlicerStats)(stats, undefined, config_1.FlowrConfig.getForEngine(config, 'r-shell'))); if (options.api) { const output = { tokenMap, parse, normalize, dataflow, ...(options.stats ? { stats } : {}), ...(doSlicing ? { slice: mappedSlices, reconstruct } : {}) }; console.log(JSON.stringify(output, json_1.jsonReplacer)); } else { if (doSlicing && options.diff) { let originalCode = options.input; if (!options['input-is-text']) { const request = { request: 'file', content: options.input }; originalCode = request.request === 'text' ? request.content : fs_1.default.readFileSync(request.content).toString(); } console.log((0, slice_diff_ansi_1.sliceDiffAnsi)(slice.result, normalize, new Set(mappedSlices.map(({ id }) => id)), originalCode)); } if (options.stats) { console.log(sliceStatsAsString); const filename = `${options.input}.stats`; console.log(`Writing stats for ${options.input} to "${filename}"`); fs_1.default.writeFileSync(filename, sliceStatsAsString); } } } void getSlice(); //# sourceMappingURL=slicer-app.js.map