@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
184 lines • 9.93 kB
JavaScript
"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