@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
120 lines • 5.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.postProcess = postProcess;
exports.writeVariableInfoToCsv = writeVariableInfoToCsv;
const post_processing_1 = require("../../post-processing");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const summarizer_1 = require("../../../../util/summarizer");
const files_1 = require("../../../../util/files");
function collectUsedVariables(featureRoot, info, config, outputPath) {
const used = collectVariableInfoFor(path_1.default.join(featureRoot, 'usedVariables.txt'), info, config);
writeVariableInfoToCsv(outputPath, 'used-variables.csv', used);
// we manually clear these maps to save memory
used.clear();
}
function collectDefinedVariables(featureRoot, info, config, outputPath) {
const defined = collectVariableInfoFor(path_1.default.join(featureRoot, 'definedVariables.txt'), info, config);
writeVariableInfoToCsv(outputPath, 'defined-variables.csv', defined);
defined.clear();
}
function collectRedefinedVariables(featureRoot, info, config, outputPath) {
const redefined = collectVariableInfoFor(path_1.default.join(featureRoot, 'redefinedVariables.txt'), info, config);
writeVariableInfoToCsv(outputPath, 'redefined-variables.csv', redefined);
redefined.clear();
}
function writeVariableCountsToCsv(outputPath, collected) {
const variablesOutStream = fs_1.default.createWriteStream(path_1.default.join(outputPath, 'variable-counts.csv'));
variablesOutStream.write(`kind,unique-projects,unique-files,${(0, summarizer_1.summarizedMeasurement2CsvHeader)()}\n`);
for (const [key, val] of Object.entries(collected)) {
if (key === 'unknownVariables') {
// they are for function calls etc and in hindsight not a good idea
continue;
}
const data = val;
const sum = (0, summarizer_1.summarizeMeasurement)(data.count);
variablesOutStream.write(`${JSON.stringify(key)},${data.uniqueProjects.size},${data.uniqueFiles.size},${(0, summarizer_1.summarizedMeasurement2Csv)(sum)}\n`);
}
variablesOutStream.close();
}
function collectInformation(info, config) {
const collected = {};
for (const [filepath, data] of info.entries()) {
const value = data.variables;
for (const [key, val] of Object.entries(value)) {
let get = collected[key];
if (!get) {
get = (0, post_processing_1.emptySummarizedWithProject)();
collected[key] = get;
}
get.count.push(val);
if (val > 0) {
(0, post_processing_1.recordFilePath)(get, filepath, config);
}
}
}
return collected;
}
function postProcess(featureRoot, info, outputPath, config) {
const collected = collectInformation(info, config);
writeVariableCountsToCsv(outputPath, collected);
collectUsedVariables(featureRoot, info, config, outputPath);
collectDefinedVariables(featureRoot, info, config, outputPath);
collectRedefinedVariables(featureRoot, info, config, outputPath);
}
function writeVariableInfoToCsv(outputPath, filename, data) {
const out = fs_1.default.createWriteStream(path_1.default.join(outputPath, filename));
out.write(`variable,unique-projects,unique-files,${(0, summarizer_1.summarizedMeasurement2CsvHeader)('count')},${(0, summarizer_1.summarizedMeasurement2CsvHeader)('line-frac')}\n`);
for (const [key, val] of data.entries()) {
const { count, uniqueProjects, uniqueFiles, linePercentageInFile } = val;
const counts = (0, summarizer_1.summarizeMeasurement)(count);
const lineFrac = (0, summarizer_1.summarizeMeasurement)(linePercentageInFile.flat());
out.write(`${JSON.stringify(key)},${uniqueProjects.size},${uniqueFiles.size},${(0, summarizer_1.summarizedMeasurement2Csv)(counts)},${(0, summarizer_1.summarizedMeasurement2Csv)(lineFrac)}\n`);
}
out.close();
}
function collectVariableInfoFor(filepath, info, config) {
// variable name to summary
const collected = new Map();
(0, files_1.readLineByLineSync)(filepath, (line, lineNumber) => {
if (line.length === 0) {
return;
}
if (lineNumber % 2_500 === 0) {
console.log(` Processed ${lineNumber} lines of ${filepath}`);
}
const [vars, context] = JSON.parse(line.toString());
const numberOfLines = info.get(context ?? '')?.stats.lines[0].length;
// first we have to collect what this file gives us
const perFile = new Map();
for (const [name, [line]] of vars) {
let get = perFile.get(name);
if (!get) {
get = { ...(0, post_processing_1.emptySummarizedWithProject)(), linePercentageInFile: [] };
perFile.set(name, get);
}
get.count.push(1);
if (numberOfLines) {
get.linePercentageInFile.push(line / numberOfLines);
}
}
// now we merge it into the global map (oh gosh this is so horrible
for (const [name, data] of perFile.entries()) {
let get = collected.get(name);
if (!get) {
get = { ...(0, post_processing_1.emptySummarizedWithProject)(), linePercentageInFile: [] };
collected.set(name, get);
}
get.count.push(data.count.length);
get.linePercentageInFile.push(data.linePercentageInFile);
if (data.count.length > 0) {
(0, post_processing_1.recordFilePath)(get, context, config);
}
}
});
return collected;
}
//# sourceMappingURL=post-process.js.map