UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

104 lines 6.01 kB
"use strict"; 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