UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

135 lines (113 loc) 5.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RegisteredQueries = void 0; exports.showQuery = showQuery; exports.registerQueryDocumentation = registerQueryDocumentation; exports.linkToQueryOfName = linkToQueryOfName; exports.tocForQueryType = tocForQueryType; exports.explainQueries = explainQueries; const query_1 = require("../../queries/query"); const pipeline_executor_1 = require("../../core/pipeline-executor"); const default_pipelines_1 = require("../../core/steps/pipeline/default-pipelines"); const retriever_1 = require("../../r-bridge/retriever"); const json_1 = require("../../util/json"); const ansi_1 = require("../../util/text/ansi"); const doc_files_1 = require("./doc-files"); const doc_dfg_1 = require("./doc-dfg"); const doc_code_1 = require("./doc-code"); const time_1 = require("../../util/text/time"); const query_print_1 = require("../../queries/query-print"); const doc_cli_option_1 = require("./doc-cli-option"); const config_1 = require("../../config"); async function showQuery(shell, code, queries, { showCode, collapseResult, collapseQuery, addOutput = () => '' } = {}) { const now = performance.now(); const analysis = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, { parser: shell, request: (0, retriever_1.requestFromInput)(code) }, config_1.defaultConfigOptions).allRemainingSteps(); const results = await Promise.resolve((0, query_1.executeQueries)({ dataflow: analysis.dataflow, ast: analysis.normalize, config: (0, config_1.cloneConfig)(config_1.defaultConfigOptions) }, queries)); const duration = performance.now() - now; const metaInfo = ` The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment. `.trim(); const str = JSON.stringify(queries, json_1.jsonReplacer, collapseQuery ? ' ' : 2); return ` ${(0, doc_code_1.codeBlock)('json', collapseQuery ? str.split('\n').join(' ').replace(/([{[])\s{2,}/g, '$1 ').replace(/\s{2,}([\]}])/g, ' $1') : str)} ${(function () { if (queries.length === 1 && Object.keys(queries[0]).length === 1) { return `(This query can be shortened to \`@${queries[0].type}\` when used within the REPL command ${(0, doc_cli_option_1.getReplCommand)('query')}).`; } else { return ''; } })()} ${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''} _Results (prettified and summarized):_ ${(0, query_print_1.asciiSummaryOfQueryResult)(ansi_1.markdownFormatter, duration, results, analysis, queries)} <details> <summary style="color:gray">Show Detailed Results as Json</summary> ${metaInfo} In general, the JSON contains the Ids of the nodes in question as they are present in the normalized AST or the dataflow graph of flowR. Please consult the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more information on how to get those. ${(0, doc_code_1.jsonWithLimit)(results)} </details> ${showCode ? ` <details> <summary style="color:gray">Original Code</summary> ${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { switchCodeAndGraph: true })} </details> ` : ''} ${collapseResult ? '</details>' : ''} ${addOutput(results, analysis)} `; } exports.RegisteredQueries = { 'active': new Map(), 'virtual': new Map() }; function registerQueryDocumentation(query, doc) { const map = exports.RegisteredQueries[doc.type]; if (map.has(query)) { throw new Error(`Query ${query} already registered`); } map.set(query, doc); } function linkify(name) { return name.toLowerCase().replace(/ /g, '-'); } function linkToQueryOfName(id) { const query = exports.RegisteredQueries.active.get(id) ?? exports.RegisteredQueries.virtual.get(id); if (!query) { throw new Error(`Query ${id} not found`); } return `[${query.name}](#${linkify(query.name)})`; } function tocForQueryType(type) { const queries = [...exports.RegisteredQueries[type].entries()].sort(([, { name: a }], [, { name: b }]) => a.localeCompare(b)); const result = []; for (const [id, { name, shortDescription }] of queries) { result.push(`1. [${name}](#${linkify(name)}) (\`${id}\`):\\\n ${shortDescription}`); } return result.join('\n'); } async function explainQuery(shell, { name, functionName, functionFile, buildExplanation }) { return ` ### ${name} ${await buildExplanation(shell)} <details> <summary style="color:gray">Implementation Details</summary> Responsible for the execution of the ${name} query is \`${functionName}\` in ${(0, doc_files_1.getFilePathMd)(functionFile)}. </details> `; } async function explainQueries(shell, type) { const queries = [...exports.RegisteredQueries[type].entries()].sort(([, { name: a }], [, { name: b }]) => a.localeCompare(b)); const result = []; for (const [, doc] of queries) { result.push(await explainQuery(shell, doc)); } return result.join(`\n${'-'.repeat(5)}\n\n`); } //# sourceMappingURL=doc-query.js.map