UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

184 lines 9.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompoundQuerySchema = exports.SupportedQueries = void 0; exports.executeQueriesOfSameType = executeQueriesOfSameType; exports.executeQueries = executeQueries; exports.SupportedQueriesSchema = SupportedQueriesSchema; exports.VirtualQuerySchema = VirtualQuerySchema; exports.AnyQuerySchema = AnyQuerySchema; exports.QueriesSchema = QueriesSchema; exports.genericWrapReplFailIfNoRequest = genericWrapReplFailIfNoRequest; const call_context_query_format_1 = require("./catalog/call-context-query/call-context-query-format"); const assert_1 = require("../util/assert"); const virtual_queries_1 = require("./virtual-query/virtual-queries"); const dataflow_query_format_1 = require("./catalog/dataflow-query/dataflow-query-format"); const id_map_query_format_1 = require("./catalog/id-map-query/id-map-query-format"); const normalized_ast_query_format_1 = require("./catalog/normalized-ast-query/normalized-ast-query-format"); const static_slice_query_format_1 = require("./catalog/static-slice-query/static-slice-query-format"); const cluster_query_format_1 = require("./catalog/cluster-query/cluster-query-format"); const dependencies_query_format_1 = require("./catalog/dependencies-query/dependencies-query-format"); const ansi_1 = require("../util/text/ansi"); const joi_1 = __importDefault(require("joi")); const location_map_query_format_1 = require("./catalog/location-map-query/location-map-query-format"); const config_query_format_1 = require("./catalog/config-query/config-query-format"); const search_query_format_1 = require("./catalog/search-query/search-query-format"); const happens_before_query_format_1 = require("./catalog/happens-before-query/happens-before-query-format"); const resolve_value_query_format_1 = require("./catalog/resolve-value-query/resolve-value-query-format"); const dataflow_lens_query_format_1 = require("./catalog/dataflow-lens-query/dataflow-lens-query-format"); const project_query_format_1 = require("./catalog/project-query/project-query-format"); const origin_query_format_1 = require("./catalog/origin-query/origin-query-format"); const linter_query_format_1 = require("./catalog/linter-query/linter-query-format"); const control_flow_query_format_1 = require("./catalog/control-flow-query/control-flow-query-format"); const df_shape_query_format_1 = require("./catalog/df-shape-query/df-shape-query-format"); const inspect_higher_order_query_format_1 = require("./catalog/inspect-higher-order-query/inspect-higher-order-query-format"); const log_1 = require("../util/log"); const files_query_format_1 = require("./catalog/files-query/files-query-format"); const call_graph_query_format_1 = require("./catalog/call-graph-query/call-graph-query-format"); const inspect_recursion_query_format_1 = require("./catalog/inspect-recursion-query/inspect-recursion-query-format"); const does_call_query_format_1 = require("./catalog/does-call-query/does-call-query-format"); const inspect_exception_query_format_1 = require("./catalog/inspect-exceptions-query/inspect-exception-query-format"); const input_sources_query_format_1 = require("./catalog/input-sources-query/input-sources-query-format"); const provenance_query_format_1 = require("./catalog/provenance-query/provenance-query-format"); exports.SupportedQueries = { 'call-context': call_context_query_format_1.CallContextQueryDefinition, 'config': config_query_format_1.ConfigQueryDefinition, 'control-flow': control_flow_query_format_1.ControlFlowQueryDefinition, 'call-graph': call_graph_query_format_1.CallGraphQueryDefinition, 'dataflow': dataflow_query_format_1.DataflowQueryDefinition, 'does-call': does_call_query_format_1.DoesCallQueryDefinition, 'dataflow-lens': dataflow_lens_query_format_1.DataflowLensQueryDefinition, 'df-shape': df_shape_query_format_1.DfShapeQueryDefinition, 'files': files_query_format_1.FilesQueryDefinition, 'id-map': id_map_query_format_1.IdMapQueryDefinition, 'normalized-ast': normalized_ast_query_format_1.NormalizedAstQueryDefinition, 'dataflow-cluster': cluster_query_format_1.ClusterQueryDefinition, 'static-slice': static_slice_query_format_1.StaticSliceQueryDefinition, 'provenance': provenance_query_format_1.ProvenanceQueryDefinition, 'input-sources': input_sources_query_format_1.InputSourcesDefinition, 'dependencies': dependencies_query_format_1.DependenciesQueryDefinition, 'location-map': location_map_query_format_1.LocationMapQueryDefinition, 'search': search_query_format_1.SearchQueryDefinition, 'happens-before': happens_before_query_format_1.HappensBeforeQueryDefinition, 'inspect-exception': inspect_exception_query_format_1.InspectExceptionQueryDefinition, 'inspect-higher-order': inspect_higher_order_query_format_1.InspectHigherOrderQueryDefinition, 'inspect-recursion': inspect_recursion_query_format_1.InspectRecursionQueryDefinition, 'resolve-value': resolve_value_query_format_1.ResolveValueQueryDefinition, 'project': project_query_format_1.ProjectQueryDefinition, 'origin': origin_query_format_1.OriginQueryDefinition, 'linter': linter_query_format_1.LinterQueryDefinition }; /** * Executes a set of queries that are all of the same type. * Only use this function if you are sure all queries are of the same type. * Otherwise, use {@link executeQueries}. */ async function executeQueriesOfSameType(data, queries) { (0, assert_1.guard)(queries.length > 0, 'At least one query must be provided'); const qzt = queries[0].type; /* every query must have the same type */ (0, assert_1.guard)(queries.every(q => q.type === qzt), 'All queries must have the same type'); const query = exports.SupportedQueries[qzt]; (0, assert_1.guard)(query !== undefined, `Unsupported query type: ${qzt}`); return query.executor(data, queries); } function isVirtualQuery(query) { return virtual_queries_1.SupportedVirtualQueries[query.type] !== undefined; } function groupQueriesByType(queries) { const grouped = {}; function addQuery(query) { grouped[query.type] ??= []; grouped[query.type].push(query); } for (const query of queries) { if (isVirtualQuery(query)) { const executor = virtual_queries_1.SupportedVirtualQueries[query.type]; const subQueries = executor(query); for (const subQuery of subQueries) { addQuery(subQuery); } } else { addQuery(query); } } return grouped; } /** * This is the main query execution function that takes a set of queries and executes them on the given data. * @see {@link executeQueriesOfSameType} */ async function executeQueries(data, queries) { const now = Date.now(); const grouped = groupQueriesByType(queries); const entries = Object.entries(grouped); const results = []; for (const [type, group] of entries) { try { const result = await executeQueriesOfSameType(data, group); results.push([type, result]); } catch (e) { log_1.log.warn(e); results.push([type, undefined]); } } const r = Object.fromEntries(results); r['.meta'] = { timing: Date.now() - now }; return r; } /** * Produces a Joi schema representing all supported queries. */ function SupportedQueriesSchema() { return joi_1.default.alternatives(Object.values(exports.SupportedQueries).map(q => q.schema)).description('Supported queries'); } exports.CompoundQuerySchema = joi_1.default.object({ type: joi_1.default.string().valid('compound').required().description('The type of the query.'), query: joi_1.default.string().required().description('The query to run on the file analysis information.'), commonArguments: joi_1.default.object().required().description('Common arguments for all queries.'), arguments: joi_1.default.array().items(joi_1.default.object()).required().description('Arguments for each query.') }).description('Compound query used to combine queries of the same type'); /** * Produces a Joi schema representing all virtual queries. */ function VirtualQuerySchema() { return joi_1.default.alternatives(exports.CompoundQuerySchema).description('Virtual queries (used for structure)'); } /** * Produces a Joi schema representing any supported query (including virtual queries). */ function AnyQuerySchema() { return joi_1.default.alternatives(SupportedQueriesSchema(), VirtualQuerySchema()).description('A virtual or an active query!'); } /** * Produces a Joi schema representing an array of supported queries. */ function QueriesSchema() { return joi_1.default.array().items(AnyQuerySchema()).description('Queries to run on the file analysis information (in the form of an array)'); } /** * Wraps a function that executes a REPL query and, if it fails, checks whether there were any requests to analyze. */ async function genericWrapReplFailIfNoRequest(fn, output, analyzer) { try { return await fn(); } catch (e) { if (analyzer.inspectContext().files.loadingOrder.getUnorderedRequests().length === 0) { output.stderr(output.formatter.format('No requests to analyze were found.', { color: 1 /* Colors.Red */, style: 1 /* FontStyles.Bold */, effect: ansi_1.ColorEffect.Foreground }) + '\nIf you consider this an error, please report a bug: ' + (0, assert_1.getGuardIssueUrl)('analyzer found no requests to analyze')); output.stderr('Full error message: ' + ((e instanceof Error) ? e.message : String(e))); } else { throw e; } } } //# sourceMappingURL=query.js.map