@eagleoutice/flowr 2.1.3 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/benchmark/slicer.js +1 -1
  2. package/cli/repl/commands/repl-parse.js +1 -1
  3. package/cli/repl/commands/repl-query.js +4 -5
  4. package/cli/repl/server/connection.js +6 -1
  5. package/cli/repl/server/messages/message-query.js +2 -2
  6. package/cli/repl/server/net.js +1 -1
  7. package/cli/repl/server/send.js +3 -6
  8. package/cli/repl/server/server.d.ts +2 -2
  9. package/cli/repl/server/server.js +1 -1
  10. package/config.js +1 -1
  11. package/core/pipeline-executor.js +2 -1
  12. package/core/steps/all/core/00-parse.d.ts +11 -4
  13. package/core/steps/all/core/00-parse.js +5 -5
  14. package/core/steps/all/core/10-normalize.d.ts +2 -1
  15. package/core/steps/all/core/20-dataflow.d.ts +2 -2
  16. package/core/steps/all/core/20-dataflow.js +2 -2
  17. package/core/steps/pipeline/default-pipelines.d.ts +41 -23
  18. package/core/steps/pipeline/pipeline.d.ts +15 -3
  19. package/core/steps/pipeline/pipeline.js +2 -2
  20. package/dataflow/environments/built-in.d.ts +8 -6
  21. package/dataflow/environments/built-in.js +6 -1
  22. package/dataflow/environments/default-builtin-config.js +21 -5
  23. package/dataflow/environments/environment.d.ts +1 -0
  24. package/dataflow/environments/environment.js +5 -5
  25. package/dataflow/extractor.js +23 -0
  26. package/dataflow/graph/dataflowgraph-builder.d.ts +2 -0
  27. package/dataflow/graph/dataflowgraph-builder.js +9 -0
  28. package/dataflow/graph/diff.js +1 -1
  29. package/dataflow/graph/graph.d.ts +7 -2
  30. package/dataflow/graph/graph.js +10 -2
  31. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
  32. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +2 -2
  33. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +2 -2
  34. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +1 -1
  35. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
  36. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
  37. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  38. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +13 -1
  39. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
  40. package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
  41. package/dataflow/processor.d.ts +3 -3
  42. package/documentation/data/server/doc-data-server-messages.js +8 -14
  43. package/documentation/doc-util/doc-cli-option.js +4 -4
  44. package/documentation/doc-util/doc-query.d.ts +4 -6
  45. package/documentation/doc-util/doc-query.js +16 -156
  46. package/documentation/doc-util/doc-repl.js +2 -2
  47. package/documentation/print-dataflow-graph-wiki.js +2 -1
  48. package/documentation/print-interface-wiki.js +8 -3
  49. package/documentation/print-query-wiki.js +107 -16
  50. package/package.json +1 -1
  51. package/queries/base-query-format.d.ts +6 -0
  52. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  53. package/queries/catalog/call-context-query/call-context-query-executor.js +26 -80
  54. package/queries/catalog/call-context-query/call-context-query-format.d.ts +14 -13
  55. package/queries/catalog/call-context-query/call-context-query-format.js +32 -14
  56. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +17 -0
  57. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +99 -0
  58. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
  59. package/queries/catalog/cluster-query/cluster-query-format.d.ts +59 -0
  60. package/queries/catalog/cluster-query/cluster-query-format.js +29 -0
  61. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
  62. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +59 -0
  63. package/queries/catalog/dataflow-query/dataflow-query-format.js +21 -0
  64. package/queries/catalog/dependencies-query/dependencies-query-executor.d.ts +3 -0
  65. package/queries/catalog/dependencies-query/dependencies-query-executor.js +144 -0
  66. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +102 -0
  67. package/queries/catalog/dependencies-query/dependencies-query-format.js +187 -0
  68. package/queries/catalog/id-map-query/id-map-query-executor.d.ts +1 -1
  69. package/queries/catalog/id-map-query/id-map-query-format.d.ts +59 -0
  70. package/queries/catalog/id-map-query/id-map-query-format.js +21 -0
  71. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
  72. package/queries/catalog/lineage-query/lineage-query-format.d.ts +59 -0
  73. package/queries/catalog/lineage-query/lineage-query-format.js +24 -0
  74. package/queries/catalog/location-map-query/location-map-query-executor.d.ts +3 -0
  75. package/queries/catalog/location-map-query/location-map-query-executor.js +21 -0
  76. package/queries/catalog/location-map-query/location-map-query-format.d.ts +17 -0
  77. package/queries/catalog/location-map-query/location-map-query-format.js +24 -0
  78. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +1 -1
  79. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +59 -0
  80. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +21 -0
  81. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  82. package/queries/catalog/static-slice-query/static-slice-query-executor.js +8 -3
  83. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +59 -0
  84. package/queries/catalog/static-slice-query/static-slice-query-format.js +40 -0
  85. package/queries/query-print.d.ts +8 -0
  86. package/queries/query-print.js +94 -0
  87. package/queries/query.d.ts +431 -26
  88. package/queries/query.js +36 -18
  89. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  90. package/r-bridge/lang-4.x/ast/parser/json/parser.js +2 -2
  91. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +2 -1
  92. package/r-bridge/retriever.js +1 -1
  93. package/r-bridge/shell-executor.js +1 -1
  94. package/r-bridge/shell.d.ts +1 -2
  95. package/r-bridge/shell.js +22 -18
  96. package/slicing/static/static-slicer.js +3 -1
  97. package/statistics/features/supported/used-functions/used-functions.js +1 -1
  98. package/{documentation/doc-util/doc-hover-over.js → util/html-hover-over.js} +1 -1
  99. package/util/json.d.ts +2 -1
  100. package/util/json.js +101 -3
  101. package/util/objects.d.ts +2 -1
  102. package/util/objects.js +3 -0
  103. package/util/version.js +1 -1
  104. package/queries/query-schema.d.ts +0 -13
  105. package/queries/query-schema.js +0 -54
  106. /package/{documentation/doc-util/doc-hover-over.d.ts → util/html-hover-over.d.ts} +0 -0
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RegisteredQueries = void 0;
4
- exports.asciiSummaryOfQueryResult = asciiSummaryOfQueryResult;
5
4
  exports.showQuery = showQuery;
6
5
  exports.registerQueryDocumentation = registerQueryDocumentation;
6
+ exports.linkToQueryOfName = linkToQueryOfName;
7
7
  exports.tocForQueryType = tocForQueryType;
8
8
  exports.explainQueries = explainQueries;
9
9
  const query_1 = require("../../queries/query");
@@ -16,154 +16,8 @@ const doc_files_1 = require("./doc-files");
16
16
  const doc_dfg_1 = require("./doc-dfg");
17
17
  const doc_code_1 = require("./doc-code");
18
18
  const time_1 = require("../../util/time");
19
- const built_in_1 = require("../../dataflow/environments/built-in");
20
- const dfg_1 = require("../../util/mermaid/dfg");
21
- const ast_1 = require("../../util/mermaid/ast");
22
- const doc_hover_over_1 = require("./doc-hover-over");
23
- function nodeString(id, formatter, processed) {
24
- if (id === built_in_1.BuiltIn) {
25
- return (0, ansi_1.italic)('built-in', formatter);
26
- }
27
- const node = processed.normalize.idMap.get(id);
28
- if (node === undefined) {
29
- return `UNKNOWN: ${id}`;
30
- }
31
- return `${(0, ansi_1.italic)('`' + (node.lexeme ?? node.info.fullLexeme ?? 'UNKNOWN') + '`', formatter)} (L.${node.location?.[0]})`;
32
- }
33
- function asciiCallContextSubHit(formatter, results, processed) {
34
- const result = [];
35
- for (const { id, calls = [], linkedIds = [], aliasRoots = [] } of results) {
36
- const node = processed.normalize.idMap.get(id);
37
- if (node === undefined) {
38
- result.push(` ${(0, ansi_1.bold)('UNKNOWN: ' + JSON.stringify({ calls, linkedIds }))}`);
39
- continue;
40
- }
41
- let line = nodeString(id, formatter, processed);
42
- if (calls.length > 0) {
43
- line += ` with ${calls.length} call${calls.length > 1 ? 's' : ''} (${calls.map(c => nodeString(c, formatter, processed)).join(', ')})`;
44
- }
45
- if (linkedIds.length > 0) {
46
- line += ` with ${linkedIds.length} link${linkedIds.length > 1 ? 's' : ''} (${linkedIds.map(c => nodeString(c, formatter, processed)).join(', ')})`;
47
- }
48
- if (aliasRoots.length > 0) {
49
- line += ` with ${aliasRoots.length} alias root${aliasRoots.length > 1 ? 's' : ''} (${aliasRoots.map(c => nodeString(c, formatter, processed)).join(', ')})`;
50
- }
51
- result.push(line);
52
- }
53
- return result.join(', ');
54
- }
55
- function asciiCallContext(formatter, results, processed) {
56
- /* traverse over 'kinds' and within them 'subkinds' */
57
- const result = [];
58
- for (const [kind, { subkinds }] of Object.entries(results['kinds'])) {
59
- result.push(` ╰ ${(0, ansi_1.bold)(kind, formatter)}`);
60
- for (const [subkind, values] of Object.entries(subkinds)) {
61
- result.push(` ╰ ${(0, ansi_1.bold)(subkind, formatter)}: ${asciiCallContextSubHit(formatter, values, processed)}`);
62
- }
63
- }
64
- return result.join('\n');
65
- }
66
- function summarizeIdsIfTooLong(ids) {
67
- const naive = ids.join(', ');
68
- if (naive.length <= 20) {
69
- return naive;
70
- }
71
- let acc = '';
72
- let i = 0;
73
- while (acc.length <= 20) {
74
- acc += ids[i++] + ', ';
75
- }
76
- if (i < ids.length) {
77
- acc += '... (see JSON below)';
78
- }
79
- return (0, doc_hover_over_1.textWithTooltip)(acc, JSON.stringify(ids));
80
- }
81
- function asciiSummaryOfQueryResult(formatter, totalInMs, results, processed) {
82
- const result = [];
83
- for (const [query, queryResults] of Object.entries(results)) {
84
- if (query === '.meta') {
85
- continue;
86
- }
87
- if (query === 'call-context') {
88
- const out = queryResults;
89
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
90
- result.push(asciiCallContext(formatter, out, processed));
91
- continue;
92
- }
93
- else if (query === 'dataflow') {
94
- const out = queryResults;
95
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
96
- result.push(` ╰ [Dataflow Graph](${(0, dfg_1.graphToMermaidUrl)(out.graph)})`);
97
- continue;
98
- }
99
- else if (query === 'id-map') {
100
- const out = queryResults;
101
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
102
- result.push(` ╰ Id List: {${summarizeIdsIfTooLong([...out.idMap.keys()])}}`);
103
- continue;
104
- }
105
- else if (query === 'normalized-ast') {
106
- const out = queryResults;
107
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
108
- result.push(` ╰ [Normalized AST](${(0, ast_1.normalizedAstToMermaidUrl)(out.normalized.ast)})`);
109
- continue;
110
- }
111
- else if (query === 'static-slice') {
112
- const out = queryResults;
113
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
114
- for (const [fingerprint, obj] of Object.entries(out.results)) {
115
- const { criteria, noMagicComments, noReconstruction } = JSON.parse(fingerprint);
116
- const addons = [];
117
- if (noReconstruction) {
118
- addons.push('no reconstruction');
119
- }
120
- if (noMagicComments) {
121
- addons.push('no magic comments');
122
- }
123
- result.push(` ╰ Slice for {${criteria.join(', ')}} ${addons.join(', ')}`);
124
- if ('reconstruct' in obj) {
125
- result.push(' ╰ Code (newline as <code>&#92;n</code>): <code>' + obj.reconstruct.code.split('\n').join('\\n') + '</code>');
126
- }
127
- else {
128
- result.push(` ╰ Id List: {${summarizeIdsIfTooLong([...obj.slice.result])}}`);
129
- }
130
- }
131
- continue;
132
- }
133
- else if (query === 'dataflow-cluster') {
134
- const out = queryResults;
135
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${out['.meta'].timing.toFixed(0)}ms)`);
136
- result.push(` ╰ Found ${out.clusters.length} cluster${out.clusters.length === 1 ? '' : 's'}`);
137
- for (const cluster of out.clusters) {
138
- const unknownSideEffects = cluster.hasUnknownSideEffects ? '(has unknown side effect)' : '';
139
- result.push(` ╰ ${unknownSideEffects} {${summarizeIdsIfTooLong(cluster.members)}} ([marked](${(0, dfg_1.graphToMermaidUrl)(processed.dataflow.graph, false, new Set(cluster.members))}))`);
140
- }
141
- continue;
142
- }
143
- else if (query === 'lineage') {
144
- const out = queryResults;
145
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
146
- for (const [criteria, lineage] of Object.entries(out.lineages)) {
147
- result.push(` ╰ ${criteria}: {${summarizeIdsIfTooLong([...lineage])}}`);
148
- }
149
- continue;
150
- }
151
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)}`);
152
- let timing = -1;
153
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
154
- for (const [key, value] of Object.entries(queryResults)) {
155
- if (key === '.meta') {
156
- timing = value.timing;
157
- continue;
158
- }
159
- result.push(` ╰ ${key}: ${JSON.stringify(value)}`);
160
- }
161
- result.push(` - Took ${(0, time_1.printAsMs)(timing, 0)}`);
162
- }
163
- result.push((0, ansi_1.italic)(`All queries together required ≈${(0, time_1.printAsMs)(results['.meta'].timing, 0)} (1ms accuracy, total ${(0, time_1.printAsMs)(totalInMs, 0)})`, formatter));
164
- return formatter.format(result.join('\n'));
165
- }
166
- async function showQuery(shell, code, queries, { showCode, collapseResult } = {}) {
19
+ const query_print_1 = require("../../queries/query-print");
20
+ async function showQuery(shell, code, queries, { showCode, collapseResult, collapseQuery } = {}) {
167
21
  const now = performance.now();
168
22
  const analysis = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
169
23
  shell,
@@ -174,17 +28,16 @@ async function showQuery(shell, code, queries, { showCode, collapseResult } = {}
174
28
  const metaInfo = `
175
29
  The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
176
30
  `.trim();
31
+ const str = JSON.stringify(queries, json_1.jsonReplacer, collapseQuery ? ' ' : 2);
177
32
  return `
178
33
 
179
- \`\`\`json
180
- ${JSON.stringify(queries, json_1.jsonReplacer, 2)}
181
- \`\`\`
34
+ ${(0, doc_code_1.codeBlock)('json', collapseQuery ? str.split('\n').join(' ').replace(/([{[])\s{2,}/g, '$1 ').replace(/\s{2,}([\]}])/g, ' $1') : str)}
182
35
 
183
36
  ${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
184
37
 
185
38
  _Results (prettified and summarized):_
186
39
 
187
- ${asciiSummaryOfQueryResult(ansi_1.markdownFormatter, duration, results, analysis)}
40
+ ${(0, query_print_1.asciiSummaryOfQueryResult)(ansi_1.markdownFormatter, duration, results, analysis)}
188
41
 
189
42
  <details> <summary style="color:gray">Show Detailed Results as Json</summary>
190
43
 
@@ -223,6 +76,13 @@ function registerQueryDocumentation(query, doc) {
223
76
  function linkify(name) {
224
77
  return name.toLowerCase().replace(/ /g, '-');
225
78
  }
79
+ function linkToQueryOfName(id) {
80
+ const query = exports.RegisteredQueries.active.get(id) ?? exports.RegisteredQueries.virtual.get(id);
81
+ if (!query) {
82
+ throw new Error(`Query ${id} not found`);
83
+ }
84
+ return `[${query.name}](#${linkify(query.name)})`;
85
+ }
226
86
  function tocForQueryType(type) {
227
87
  const queries = [...exports.RegisteredQueries[type].entries()].sort(([, { name: a }], [, { name: b }]) => a.localeCompare(b));
228
88
  const result = [];
@@ -248,11 +108,11 @@ Responsible for the execution of the ${name} query is \`${functionName}\` in ${(
248
108
  `;
249
109
  }
250
110
  async function explainQueries(shell, type) {
251
- const queries = exports.RegisteredQueries[type];
111
+ const queries = [...exports.RegisteredQueries[type].entries()].sort(([, { name: a }], [, { name: b }]) => a.localeCompare(b));
252
112
  const result = [];
253
- for (const doc of queries.values()) {
113
+ for (const [, doc] of queries) {
254
114
  result.push(await explainQuery(shell, doc));
255
115
  }
256
- return result.join('\n\n\n');
116
+ return result.join(`\n${'-'.repeat(5)}\n\n`);
257
117
  }
258
118
  //# sourceMappingURL=doc-query.js.map
@@ -4,7 +4,7 @@ exports.printReplHelpAsMarkdownTable = printReplHelpAsMarkdownTable;
4
4
  exports.documentReplSession = documentReplSession;
5
5
  const repl_commands_1 = require("../../cli/repl/commands/repl-commands");
6
6
  const doc_cli_option_1 = require("./doc-cli-option");
7
- const doc_hover_over_1 = require("./doc-hover-over");
7
+ const html_hover_over_1 = require("../../util/html-hover-over");
8
8
  const core_1 = require("../../cli/repl/core");
9
9
  const ansi_1 = require("../../util/ansi");
10
10
  const doc_docker_1 = require("./doc-docker");
@@ -19,7 +19,7 @@ function printHelpForScript(script, starredVersion) {
19
19
  return base;
20
20
  }
21
21
  const aliases = script[1].aliases;
22
- return `${base} (alias${aliases.length > 1 ? 'es' : ''}: ${aliases.map(a => '**:' + (0, doc_hover_over_1.textWithTooltip)(a, `Alias of ':${script[0]}'. ${script[1].description}`) + '**').join(', ')}) |`;
22
+ return `${base} (alias${aliases.length > 1 ? 'es' : ''}: ${aliases.map(a => '**:' + (0, html_hover_over_1.textWithTooltip)(a, `Alias of ':${script[0]}'. ${script[1].description}`) + '**').join(', ')}) |`;
23
23
  }
24
24
  function printReplHelpAsMarkdownTable() {
25
25
  const scriptHelp = [];
@@ -807,7 +807,8 @@ ${(0, doc_types_1.printHierarchy)({ program: vertexType.program, hierarchy: vert
807
807
  Let's start by looking at the properties of the dataflow information object: ${Object.keys(result.dataflow).map(k => `\`${k}\``).join(', ')}.
808
808
 
809
809
  ${(() => {
810
- (0, assert_1.guard)(Object.keys(result.dataflow).length === 7, () => 'Update Dataflow Documentation!');
810
+ /* this includes the meta field for timing */
811
+ (0, assert_1.guard)(Object.keys(result.dataflow).length === 8, () => 'Update Dataflow Documentation!');
811
812
  return '';
812
813
  })()}
813
814
 
@@ -18,6 +18,7 @@ const ansi_1 = require("../util/ansi");
18
18
  const flowr_main_options_1 = require("../cli/flowr-main-options");
19
19
  const doc_issue_1 = require("./doc-util/doc-issue");
20
20
  const pipeline_executor_1 = require("../core/pipeline-executor");
21
+ const doc_structure_1 = require("./doc-util/doc-structure");
21
22
  async function explainServer(shell) {
22
23
  (0, doc_data_server_messages_1.documentAllServerMessages)();
23
24
  return `
@@ -27,9 +28,13 @@ Additionally, the server is not well guarded against attacks (e.g., you can theo
27
28
 
28
29
  Every message has to be given in a single line (i.e., without a newline in-between) and end with a newline character. Nevertheless, we will pretty-print example given in the following segments for the ease of reading.
29
30
 
30
- > [!NOTE]
31
- > The default ${(0, doc_cli_option_1.getCliLongOptionOf)('flowr', 'server', false)} uses a simple [TCP](https://de.wikipedia.org/wiki/Transmission_Control_Protocol)
32
- > connection. If you want _flowR_ to expose a [WebSocket](https://de.wikipedia.org/wiki/WebSocket) server instead, add the ${(0, doc_cli_option_1.getCliLongOptionOf)('flowr', 'server', false)} flag (i.e., ${(0, doc_cli_option_1.multipleCliOptions)('flowr', 'server', 'ws')}) when starting _flowR_ from the command line.
31
+ ${(0, doc_structure_1.block)({
32
+ type: 'NOTE',
33
+ content: `
34
+ The default ${(0, doc_cli_option_1.getCliLongOptionOf)('flowr', 'server', false)} uses a simple [TCP](https://de.wikipedia.org/wiki/Transmission_Control_Protocol)
35
+ connection. If you want _flowR_ to expose a [WebSocket](https://de.wikipedia.org/wiki/WebSocket) server instead, add the ${(0, doc_cli_option_1.getCliLongOptionOf)('flowr', 'ws', false)} flag (i.e., ${(0, doc_cli_option_1.multipleCliOptions)('flowr', 'server', 'ws')}) when starting _flowR_ from the command line.
36
+ `
37
+ })}
33
38
 
34
39
  ${await (0, doc_server_message_1.printServerMessages)(shell)}
35
40
 
@@ -6,9 +6,7 @@ const log_1 = require("../../test/functionality/_helper/log");
6
6
  const query_1 = require("../queries/query");
7
7
  const doc_files_1 = require("./doc-util/doc-files");
8
8
  const doc_query_1 = require("./doc-util/doc-query");
9
- const call_context_query_format_1 = require("../queries/catalog/call-context-query/call-context-query-format");
10
9
  const schema_1 = require("../util/schema");
11
- const query_schema_1 = require("../queries/query-schema");
12
10
  const ansi_1 = require("../util/ansi");
13
11
  const call_context_query_executor_1 = require("../queries/catalog/call-context-query/call-context-query-executor");
14
12
  const compound_query_1 = require("../queries/virtual-query/compound-query");
@@ -22,6 +20,11 @@ const normalized_ast_query_executor_1 = require("../queries/catalog/normalized-a
22
20
  const cluster_query_executor_1 = require("../queries/catalog/cluster-query/cluster-query-executor");
23
21
  const static_slice_query_executor_1 = require("../queries/catalog/static-slice-query/static-slice-query-executor");
24
22
  const lineage_query_executor_1 = require("../queries/catalog/lineage-query/lineage-query-executor");
23
+ const dependencies_query_executor_1 = require("../queries/catalog/dependencies-query/dependencies-query-executor");
24
+ const doc_cli_option_1 = require("./doc-util/doc-cli-option");
25
+ const doc_issue_1 = require("./doc-util/doc-issue");
26
+ const location_map_query_executor_1 = require("../queries/catalog/location-map-query/location-map-query-executor");
27
+ const identify_link_to_last_call_relation_1 = require("../queries/catalog/call-context-query/identify-link-to-last-call-relation");
25
28
  (0, doc_query_1.registerQueryDocumentation)('call-context', {
26
29
  name: 'Call-Context Query',
27
30
  type: 'active',
@@ -54,7 +57,7 @@ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode,
54
57
  callName: '^read_',
55
58
  kind: 'input',
56
59
  subkind: 'csv-file',
57
- callTargets: call_context_query_format_1.CallTargets.OnlyGlobal
60
+ callTargets: identify_link_to_last_call_relation_1.CallTargets.OnlyGlobal
58
61
  },
59
62
  {
60
63
  type: 'call-context',
@@ -67,7 +70,7 @@ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode,
67
70
 
68
71
  As you can see, all kinds and subkinds with the same name are grouped together.
69
72
  Yet, re-stating common arguments and kinds may be cumbersome (although you can already use clever regex patterns).
70
- See the [Compound Query](#compound-query) for a way to structure your queries more compactly if you think it gets too verbose.
73
+ See the ${(0, doc_query_1.linkToQueryOfName)('compound')} for a way to structure your queries more compactly if you think it gets too verbose.
71
74
 
72
75
  ${await (async () => {
73
76
  const code = `
@@ -99,7 +102,7 @@ This query type does exactly that!
99
102
  Using the example code \`${exampleCode}\`, the following query returns the dataflow graph of the code:
100
103
  ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
101
104
  type: 'dataflow'
102
- }], { showCode: true })}
105
+ }], { showCode: true, collapseQuery: true })}
103
106
  `;
104
107
  }
105
108
  });
@@ -118,7 +121,7 @@ This query type does exactly that!
118
121
  Using the example code \`${exampleCode}\`, the following query returns the normalized AST of the code:
119
122
  ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
120
123
  type: 'normalized-ast'
121
- }], { showCode: true })}
124
+ }], { showCode: true, collapseQuery: true })}
122
125
  `;
123
126
  }
124
127
  });
@@ -176,7 +179,7 @@ ${(0, doc_structure_1.details)('Example <code>' + exampleB + '</code>', await (0
176
179
  Using the example code from above, the following query returns all clusters:
177
180
  ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode, [{
178
181
  type: 'dataflow-cluster'
179
- }], { showCode: false })}
182
+ }], { showCode: false, collapseQuery: true })}
180
183
  `;
181
184
  }
182
185
  });
@@ -194,7 +197,7 @@ This query provides access to all nodes in the [normalized AST](${doc_files_1.Fl
194
197
  Using the example code \`${exampleCode}\`, the following query returns all nodes from the code:
195
198
  ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
196
199
  type: 'id-map'
197
- }], { showCode: true })}
200
+ }], { showCode: true, collapseQuery: true })}
198
201
  `;
199
202
  }
200
203
  });
@@ -240,10 +243,10 @@ want to resolve to a local definition:
240
243
  ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode, [{
241
244
  type: 'compound',
242
245
  query: 'call-context',
243
- commonArguments: { kind: 'visualize', subkind: 'text', callTargets: call_context_query_format_1.CallTargets.OnlyGlobal },
246
+ commonArguments: { kind: 'visualize', subkind: 'text', callTargets: identify_link_to_last_call_relation_1.CallTargets.OnlyGlobal },
244
247
  arguments: [
245
248
  { callName: '^mean$' },
246
- { callName: '^print$', callTargets: call_context_query_format_1.CallTargets.OnlyLocal }
249
+ { callName: '^print$', callTargets: identify_link_to_last_call_relation_1.CallTargets.OnlyLocal }
247
250
  ]
248
251
  }], { showCode: false })}
249
252
 
@@ -289,6 +292,85 @@ This query replaces the old [\`request-slice\`](${doc_files_1.FlowrWikiBaseRef}/
289
292
  `;
290
293
  }
291
294
  });
295
+ (0, doc_query_1.registerQueryDocumentation)('dependencies', {
296
+ name: 'Dependencies Query',
297
+ type: 'active',
298
+ shortDescription: 'Returns all direct dependencies (in- and outputs) of a given R script',
299
+ functionName: dependencies_query_executor_1.executeDependenciesQuery.name,
300
+ functionFile: '../queries/catalog/dependencies-query/dependencies-query-executor.ts',
301
+ buildExplanation: async (shell) => {
302
+ const exampleCode = 'library(x)';
303
+ const longerCode = `
304
+ source("sample.R")
305
+ foo <- loadNamespace("bar")
306
+
307
+ data <- read.csv("data.csv")
308
+
309
+ #' @importFrom ggplot2 ggplot geom_point aes
310
+ ggplot(data, aes(x=x, y=y)) + geom_point()
311
+
312
+ better::write.csv(data, "data2.csv")
313
+ print("hello world!")
314
+ `;
315
+ return `
316
+ This query extracts all dependencies from an R script, using a combination of a ${(0, doc_query_1.linkToQueryOfName)('call-context')}
317
+ and more advanced tracking in the [Dataflow Graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph).
318
+
319
+ In other words, if you have a script simply reading: \`${exampleCode}\`, the following query returns the loaded library:
320
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
321
+ type: 'dependencies'
322
+ }], { showCode: false, collapseQuery: true })}
323
+
324
+ Of course, this works for more complicated scripts too. The query offers information on the loaded _libraries_, _sourced_ files, data which is _read_ and data which is _written_.
325
+ For example, consider the following script:
326
+ ${(0, doc_code_1.codeBlock)('r', longerCode)}
327
+ The following query returns the dependencies of the script.
328
+ ${await (0, doc_query_1.showQuery)(shell, longerCode, [{
329
+ type: 'dependencies'
330
+ }], { showCode: false, collapseQuery: true, collapseResult: true })}
331
+
332
+ Currently the dependency extraction may fail as it is essentially a set of heuristics guessing the dependencies.
333
+ We welcome any feedback on this (consider opening a [new issue](${doc_issue_1.NewIssueUrl})).
334
+
335
+ In the meantime we offer several properties to overwrite the default behavior (e.g., function names that should be collected)
336
+
337
+ ${await (0, doc_query_1.showQuery)(shell, longerCode, [{
338
+ type: 'dependencies',
339
+ ignoreDefaultFunctions: true,
340
+ libraryFunctions: [{ name: 'print', argIdx: 0, argName: 'library' }],
341
+ sourceFunctions: [],
342
+ readFunctions: [],
343
+ writeFunctions: []
344
+ }], { showCode: false, collapseQuery: false, collapseResult: true })}
345
+
346
+ `;
347
+ }
348
+ });
349
+ (0, doc_query_1.registerQueryDocumentation)('location-map', {
350
+ name: 'Location Map Query',
351
+ type: 'active',
352
+ shortDescription: 'Returns a simple mapping of ids to their location in the source file',
353
+ functionName: location_map_query_executor_1.executeLocationMapQuery.name,
354
+ functionFile: '../queries/catalog/location-map-query/location-map-query-executor.ts',
355
+ buildExplanation: async (shell) => {
356
+ const exampleCode = 'x + 1\nx * 2';
357
+ return `
358
+ A query like the ${(0, doc_query_1.linkToQueryOfName)('id-map')} query can return a really big result, especially for larger scripts.
359
+ If you are not interested in all of the information contained within the full map, you can use the location map query to get a simple mapping of ids to their location in the source file.
360
+
361
+ Consider you have the following code:
362
+
363
+ ${(0, doc_code_1.codeBlock)('r', exampleCode)}
364
+
365
+ The following query then gives you the aforementioned mapping:
366
+
367
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
368
+ type: 'location-map'
369
+ }], { showCode: false, collapseQuery: true })}
370
+
371
+ `;
372
+ }
373
+ });
292
374
  async function getText(shell) {
293
375
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
294
376
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'query API', rVersion: rversion })}
@@ -296,13 +378,22 @@ async function getText(shell) {
296
378
  This page briefly summarizes flowR's query API, represented by the ${query_1.executeQueries.name} function in ${(0, doc_files_1.getFilePathMd)('../queries/query.ts')}.
297
379
  Please see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more information on how to access this API.
298
380
 
381
+ ${(0, doc_structure_1.block)({
382
+ type: 'NOTE',
383
+ content: `
384
+ There are many ways to query a dataflow graph created by flowR.
385
+ For example, you can use the [\`request-query\`](${doc_files_1.FlowrWikiBaseRef}/Interface#message-request-query) message
386
+ with a running flowR server, or the ${(0, doc_cli_option_1.getReplCommand)('query')} command in the flowR [REPL](${doc_files_1.FlowrWikiBaseRef}/Interface#repl).
387
+ `.trim()
388
+ })}
389
+
299
390
  ## The Query Format
300
391
 
301
392
  Queries are JSON arrays of query objects, each of which uses a \`type\` property to specify the query type.
302
393
  In general, we separate two types of queries:
303
394
 
304
- 1. **Active Queries**: Are exactly what you would expect from a query (e.g., the [Call-Context Query](#call-context-query)). They fetch information from the dataflow graph.
305
- 2. **Virtual Queries**: Are used to structure your queries (e.g., the [Compound Query](#compound-query)).
395
+ 1. **Active Queries**: Are exactly what you would expect from a query (e.g., the ${(0, doc_query_1.linkToQueryOfName)('call-context')}). They fetch information from the dataflow graph.
396
+ 2. **Virtual Queries**: Are used to structure your queries (e.g., the ${(0, doc_query_1.linkToQueryOfName)('compound')}).
306
397
 
307
398
  We separate these from a concept perspective.
308
399
  For now, we support the following **active** queries (which we will refer to simply as a \`query\`):
@@ -320,7 +411,7 @@ ${(0, doc_query_1.tocForQueryType)('virtual')}
320
411
 
321
412
  Although it is probably better to consult the detailed explanations below, if you want to have a look at the scehma, here is its description:
322
413
 
323
- ${(0, schema_1.describeSchema)(query_schema_1.QueriesSchema, ansi_1.markdownFormatter)}
414
+ ${(0, schema_1.describeSchema)(query_1.QueriesSchema, ansi_1.markdownFormatter)}
324
415
 
325
416
  </details>
326
417
 
@@ -349,11 +440,11 @@ However, this fails to incorporate
349
440
  3. Context information (e.g., calls like \`points\` may link to the current plot)
350
441
 
351
442
  To solve this, flowR provides a query API which allows you to specify queries on the dataflow graph.
352
- For the specific use-case stated, you could use the [Call-Context Query](#call-context-query) to find all calls to \`read_csv\` which refer functions that are not overwritten.
443
+ For the specific use-case stated, you could use the ${(0, doc_query_1.linkToQueryOfName)('call-context')} to find all calls to \`read_csv\` which refer functions that are not overwritten.
353
444
 
354
- Just as an example, the following [Call-Context Query](#call-context-query) finds all calls to \`read_csv\` that are not overwritten:
445
+ Just as an example, the following ${(0, doc_query_1.linkToQueryOfName)('call-context')} finds all calls to \`read_csv\` that are not overwritten:
355
446
 
356
- ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode, [{ type: 'call-context', callName: '^read_csv$', callTargets: call_context_query_format_1.CallTargets.OnlyGlobal, kind: 'input', subkind: 'csv-file' }], { showCode: false })}
447
+ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode, [{ type: 'call-context', callName: '^read_csv$', callTargets: identify_link_to_last_call_relation_1.CallTargets.OnlyGlobal, kind: 'input', subkind: 'csv-file' }], { showCode: false })}
357
448
 
358
449
  ${await (0, doc_query_1.explainQueries)(shell, 'active')}
359
450
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "repository": {
@@ -1,3 +1,5 @@
1
+ import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
2
+ import type { DataflowGraph } from '../dataflow/graph/graph';
1
3
  export interface BaseQueryFormat {
2
4
  /** used to select the query type :) */
3
5
  readonly type: string;
@@ -9,3 +11,7 @@ export interface BaseQueryMeta {
9
11
  export interface BaseQueryResult {
10
12
  readonly '.meta': BaseQueryMeta;
11
13
  }
14
+ export interface BasicQueryData {
15
+ readonly ast: NormalizedAst;
16
+ readonly graph: DataflowGraph;
17
+ }
@@ -1,5 +1,5 @@
1
1
  import type { CallContextQuery, CallContextQueryResult } from './call-context-query-format';
2
- import type { BasicQueryData } from '../../query';
2
+ import type { BasicQueryData } from '../../base-query-format';
3
3
  /**
4
4
  * Multi-stage call context query resolve.
5
5
  *