@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
74 lines • 2.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeLocationMapQuery = executeLocationMapQuery;
const location_map_query_format_1 = require("./location-map-query-format");
const model_1 = require("../../../r-bridge/lang-4.x/ast/model/model");
const assert_1 = require("../../../util/assert");
const parse_1 = require("../../../slicing/criterion/parse");
const fileIdRegex = /^(?<file>.*(\.[rR]))-/;
function fuzzyFindFile(node, idMap) {
if (node?.info.file) {
return node.info.file;
}
else if (node?.info.id) {
const file = fileIdRegex.exec(String(node.info.id));
if (file && file.groups?.file.trim()) {
return file.groups?.file.trim();
}
}
else if (node?.info.parent) {
const parent = idMap.get(node.info.parent);
if (parent) {
return fuzzyFindFile(parent, idMap);
}
}
return '@inline';
}
/** The range reported for a node under the requested {@link LocationMapSpan}, falling back to its own location. */
function rangeOf(node, idMap, span) {
if (span === location_map_query_format_1.LocationMapSpan.Token) {
return node.location;
}
const of = span === location_map_query_format_1.LocationMapSpan.Statement ? model_1.RNode.topLevelStatement(node, idMap) : node;
return model_1.RNode.span(of) ?? node.location;
}
/**
* Executes a location map query
* @see {@link LocationMapQuery}
*/
async function executeLocationMapQuery({ analyzer }, queries) {
const ast = await analyzer.normalize();
const start = Date.now();
const requested = queries.flatMap(q => q.ids ?? []);
const criteriaOfInterest = new Set(requested.map(c => parse_1.SlicingCriterion.tryParse(c, ast.idMap)).filter(assert_1.isNotUndefined));
const locationMap = {
files: {},
ids: {}
};
let count = 0;
const inverseMap = new Map();
await analyzer.dataflow(); // ensure all files are considered
for (const file of analyzer.inspectContext().files.consideredFilesList()) {
locationMap.files[count] = file;
inverseMap.set(file, count);
count++;
}
const span = queries.find(q => q.span !== undefined)?.span ?? location_map_query_format_1.LocationMapSpan.Token;
for (const [id, node] of ast.idMap.entries()) {
/* asking for ids none of which resolve yields nothing, not everything */
if (node.location && (requested.length === 0 || criteriaOfInterest.has(id))) {
const file = fuzzyFindFile(node, ast.idMap);
locationMap.ids[id] = [
inverseMap.get(file) ?? -1,
rangeOf(node, ast.idMap, span)
];
}
}
return {
'.meta': {
timing: Date.now() - start
},
map: locationMap
};
}
//# sourceMappingURL=location-map-query-executor.js.map