@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
93 lines • 4.81 kB
JavaScript
;
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