@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
132 lines • 5.03 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowrAnalyzerIncrementalAnalysisContext = void 0;
const assert_1 = require("../../util/assert");
const fs_1 = __importDefault(require("fs"));
/**
* Information to carry over for future incremental builds
*/
class FlowrAnalyzerIncrementalAnalysisContext {
name = 'flowr-analyzer-incremental-analysis-context';
context;
/**
* The files that have been changed since the last analysis mapping to their old content.
*/
changedFilesWithOldContent = new Map();
oldParseResults = new Map();
lastKnownMtime = new Map();
constructor(context) {
this.context = context;
}
reset() {
this.changedFilesWithOldContent = new Map();
this.oldParseResults = new Map();
}
handleFileInvalidate(filePath, oldContent) {
if (this.changedFilesWithOldContent.has(filePath)) {
// If a file is changed multiple times since the last analysis, we only want to store the original old content as the old analysis results were computed with that.
return;
}
this.changedFilesWithOldContent.set(filePath, oldContent);
}
handleShouldReparse(filePath, ctx) {
if (ctx.config.incremental.alwaysIncremental) {
return true;
}
if (!ctx.config.incremental.parsing.activated) {
return false;
}
const heuristics = ctx.config.incremental.parsing.heuristics;
if (!heuristics.activated || heuristics.alwaysWithEdits) {
return true;
}
const checks = [];
if (heuristics.mtime) {
checks.push((filePath, ctx) => {
let currentMtime;
try {
currentMtime = fs_1.default.statSync(filePath).mtimeMs;
}
catch {
return true;
}
const lastMtime = ctx.inc.getLastKnownMtime(filePath);
const mtimeChanged = !(lastMtime !== undefined && lastMtime === currentMtime);
if (mtimeChanged) {
ctx.inc.setLastKnownMtime(filePath, currentMtime);
}
return mtimeChanged;
});
}
if (heuristics.linesFrom !== undefined) {
checks.push((filePath, ctx) => {
const content = ctx.files.getFileByPath(filePath)?.content();
if (typeof content !== 'string') {
return false;
}
const lineCount = content.split('\n').length;
return lineCount >= heuristics.linesFrom;
});
}
if (heuristics.bytesFrom) {
checks.push((filePath) => {
try {
return fs_1.default.statSync(filePath).size >= heuristics.bytesFrom;
}
catch {
return true;
}
});
}
if (heuristics.minFiles !== undefined) {
checks.push((_filePath, ctx) => {
return ctx.files.getFileCount() >= heuristics.minFiles;
});
}
return checks.length === 0
? true
: checks.every(check => check(filePath, ctx));
}
receive(event) {
const type = event.type;
switch (type) {
case "full" /* InvalidationEventType.Full */:
this.reset();
break;
case "single-file-invalidate" /* InvalidationEventType.SingleFileInvalidate */:
this.handleFileInvalidate(event.filePath, event.oldContent?.toString());
break;
default:
(0, assert_1.assertUnreachable)(type);
}
}
storeOldParseResults(parseStepOutput) {
for (const parsedStepSingleOutput of parseStepOutput.files) {
if (parsedStepSingleOutput.filePath === undefined) {
// there could be multiple files without a file path, making a distinction impossible
continue;
}
this.oldParseResults.set(parsedStepSingleOutput.filePath, parsedStepSingleOutput.parsed);
}
}
getOldParseResultOf(filePath) {
return this.oldParseResults.get(filePath);
}
getOldContentOf(filePath) {
return this.changedFilesWithOldContent.get(filePath);
}
deleteOldContentOf(filePath) {
this.changedFilesWithOldContent.delete(filePath);
}
getLastKnownMtime(filePath) {
return this.lastKnownMtime.get(filePath);
}
setLastKnownMtime(filePath, mtimeMs) {
this.lastKnownMtime.set(filePath, mtimeMs);
}
}
exports.FlowrAnalyzerIncrementalAnalysisContext = FlowrAnalyzerIncrementalAnalysisContext;
//# sourceMappingURL=flowr-analyzer-incremental-analysis-context.js.map