UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

120 lines 5.87 kB
"use strict"; 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