@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
104 lines • 6.01 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbsintQueryDefinition = exports.AbsintQueryInferences = void 0;
const joi_1 = __importDefault(require("joi"));
const shape_inference_1 = require("../../../abstract-interpretation/data-frame/shape-inference");
const abstract_domain_1 = require("../../../abstract-interpretation/domains/abstract-domain");
const lattice_1 = require("../../../abstract-interpretation/domains/lattice");
const slice_query_parser_1 = require("../../../cli/repl/parser/slice-query-parser");
const retriever_1 = require("../../../r-bridge/retriever");
const parse_1 = require("../../../slicing/criterion/parse");
const record_1 = require("../../../util/record");
const ansi_1 = require("../../../util/text/ansi");
const time_1 = require("../../../util/text/time");
const absint_query_executor_1 = require("./absint-query-executor");
exports.AbsintQueryInferences = {
'df-shape': config => new shape_inference_1.DataFrameShapeInferenceVisitor(config)
};
function absintQueryCompleter(line, startingNewArg, _config) {
if (line.length === 0 || (line.length === 1 && !startingNewArg)) {
return { completions: record_1.Record.keys(exports.AbsintQueryInferences).map(type => `${type} `) };
}
else if ((line.length === 1 && startingNewArg) || (line.length === 2 && line[1].length === 0)) {
return { completions: ['(', '""', retriever_1.fileProtocol] };
}
else if (line.length === 2 && !startingNewArg && line[1].startsWith('(') && !line[1].endsWith(')') && !line[1].endsWith(';')) {
const criteria = (0, slice_query_parser_1.sliceCriteriaParser)(line[1] + ')');
if (criteria !== undefined && criteria.length > 0 && criteria.every(parse_1.SlicingCriterion.isValid)) {
return { completions: [';', ') '], argumentPart: '' };
}
}
else if ((line.length === 2 && startingNewArg) || (line.length === 3 && line[2].length === 0)) {
return { completions: ['""', retriever_1.fileProtocol] };
}
else if ((line.length === 2 && retriever_1.fileProtocol.startsWith(line[1])) || (line.length === 3 && retriever_1.fileProtocol.startsWith(line[2]))) {
return { completions: [retriever_1.fileProtocol] };
}
return { completions: [] };
}
function absintQueryLineParser(output, line, _config) {
const type = line[0].toLowerCase();
if (!Object.hasOwn(exports.AbsintQueryInferences, type)) {
output.stderr(output.formatter.format(`Invalid inference type "${type}", must be one of ${record_1.Record.keys(exports.AbsintQueryInferences).map(type => `"${type}"`).join(', ')}`, { color: 1 /* Colors.Red */, effect: ansi_1.ColorEffect.Foreground, style: 1 /* FontStyles.Bold */ }));
return { query: [] };
}
const criteria = (0, slice_query_parser_1.sliceCriteriaParser)(line[1]);
if (criteria !== undefined && !criteria.every(parse_1.SlicingCriterion.isValid)) {
output.stderr(output.formatter.format(`Invalid slicing criteria "${line[1]}"`, { color: 1 /* Colors.Red */, effect: ansi_1.ColorEffect.Foreground, style: 1 /* FontStyles.Bold */ }));
return { query: [] };
}
const code = (0, slice_query_parser_1.queryLineCode)(line, criteria ? 2 : 1);
return {
query: {
type: 'absint',
inference: type,
criteria: criteria
},
rCode: code
};
}
exports.AbsintQueryDefinition = {
title: 'Abstract Interpretation Query',
executor: absint_query_executor_1.executeAbsintQuery,
asciiSummarizer: (formatter, _analyzer, queryResults, result) => {
const out = queryResults;
const domains = out.result instanceof abstract_domain_1.AbstractDomain ? out.result.value : out.result;
result.push(`Query: ${(0, ansi_1.bold)('absint', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
if (domains === lattice_1.Bottom) {
result.push(` ╰ state: ${lattice_1.BottomSymbol}`);
return true;
}
else if (out.result instanceof abstract_domain_1.AbstractDomain && out.result.isTop()) {
result.push(` ╰ state: ${lattice_1.TopSymbol}`);
return true;
}
result.push(...domains.entries().take(20).map(([key, domain]) => {
const criterion = parse_1.SlicingCriterion.isValid(key) ? key : parse_1.SlicingCriterion.fromId(key);
return ` ╰ ${criterion}: ${domain?.toString()}`;
}));
if (domains.size > 20) {
result.push(' ╰ ... (see JSON)');
}
return true;
},
jsonFormatter: (queryResults) => {
const { result: domains, ...out } = queryResults;
const state = domains instanceof abstract_domain_1.AbstractDomain ? domains.value : domains;
const json = state === lattice_1.Bottom ? state.description : Object.fromEntries(state.entries().map(([key, domain]) => [key, domain?.toJSON() ?? null]));
const result = { domains: json, ...out };
return result;
},
completer: absintQueryCompleter,
fromLine: absintQueryLineParser,
syntax: '@absint <inference-type> [(<criteria>)] <code | file://path>',
schema: joi_1.default.object({
type: joi_1.default.string().valid('absint').required().description('The type of the query.'),
inference: joi_1.default.string().valid(...record_1.Record.keys(exports.AbsintQueryInferences)).required().description('The type of abstract interpretation inference.'),
criteria: joi_1.default.array().items(joi_1.default.string()).optional().description('The slicing criteria of the nodes to get the inferred abstract values for.')
}).description('The abstract interpretation query retrieves inferred abstract values'),
flattenInvolvedNodes: () => []
};
//# sourceMappingURL=absint-query-format.js.map