@eagleoutice/flowr 2.1.1 → 2.1.3

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 (131) hide show
  1. package/README.md +2 -1
  2. package/cli/repl/commands/repl-parse.js +7 -16
  3. package/cli/repl/commands/repl-query.d.ts +0 -5
  4. package/cli/repl/commands/repl-query.js +2 -73
  5. package/core/print/parse-printer.js +1 -22
  6. package/core/steps/pipeline/default-pipelines.d.ts +64 -0
  7. package/core/steps/pipeline/default-pipelines.js +2 -1
  8. package/dataflow/cluster.d.ts +20 -0
  9. package/dataflow/cluster.js +46 -0
  10. package/dataflow/graph/edge.d.ts +2 -3
  11. package/dataflow/graph/graph.d.ts +1 -1
  12. package/documentation/data/server/doc-data-server-messages.d.ts +1 -1
  13. package/documentation/data/server/doc-data-server-messages.js +16 -5
  14. package/documentation/doc-util/doc-code.d.ts +1 -0
  15. package/documentation/doc-util/doc-code.js +9 -0
  16. package/documentation/doc-util/doc-dfg.d.ts +1 -0
  17. package/documentation/doc-util/doc-dfg.js +5 -4
  18. package/documentation/doc-util/doc-normalized-ast.js +2 -2
  19. package/documentation/doc-util/doc-query.d.ts +5 -1
  20. package/documentation/doc-util/doc-query.js +154 -9
  21. package/documentation/doc-util/doc-server-message.js +3 -5
  22. package/documentation/doc-util/doc-types.js +19 -11
  23. package/documentation/print-dataflow-graph-wiki.js +10 -1
  24. package/documentation/print-interface-wiki.js +1 -1
  25. package/documentation/print-normalized-ast-wiki.js +2 -2
  26. package/documentation/print-query-wiki.js +196 -37
  27. package/package.json +3 -2
  28. package/queries/{call-context-query → catalog/call-context-query}/call-context-query-executor.d.ts +4 -3
  29. package/queries/{call-context-query → catalog/call-context-query}/call-context-query-executor.js +22 -16
  30. package/queries/{call-context-query → catalog/call-context-query}/call-context-query-format.d.ts +6 -2
  31. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +3 -0
  32. package/queries/catalog/cluster-query/cluster-query-executor.js +19 -0
  33. package/queries/catalog/cluster-query/cluster-query-format.d.ts +12 -0
  34. package/queries/catalog/cluster-query/cluster-query-format.js +3 -0
  35. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +3 -0
  36. package/queries/catalog/dataflow-query/dataflow-query-executor.js +17 -0
  37. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +12 -0
  38. package/queries/catalog/dataflow-query/dataflow-query-format.js +3 -0
  39. package/queries/catalog/id-map-query/id-map-query-executor.d.ts +3 -0
  40. package/queries/catalog/id-map-query/id-map-query-executor.js +17 -0
  41. package/queries/catalog/id-map-query/id-map-query-format.d.ts +8 -0
  42. package/{r-bridge/lang-4.x/ast/parser/xml/normalizer-data.js → queries/catalog/id-map-query/id-map-query-format.js} +1 -1
  43. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +3 -0
  44. package/queries/catalog/lineage-query/lineage-query-executor.js +22 -0
  45. package/queries/catalog/lineage-query/lineage-query-format.d.ts +14 -0
  46. package/queries/catalog/lineage-query/lineage-query-format.js +3 -0
  47. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +3 -0
  48. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +17 -0
  49. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +11 -0
  50. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +3 -0
  51. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +4 -0
  52. package/queries/catalog/static-slice-query/static-slice-query-executor.js +40 -0
  53. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +24 -0
  54. package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -0
  55. package/queries/query-schema.d.ts +6 -0
  56. package/queries/query-schema.js +26 -3
  57. package/queries/query.d.ts +22 -4
  58. package/queries/query.js +14 -2
  59. package/r-bridge/lang-4.x/ast/parser/json/format.d.ts +37 -13
  60. package/r-bridge/lang-4.x/ast/parser/json/format.js +59 -6
  61. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +0 -3
  62. package/r-bridge/lang-4.x/ast/parser/json/parser.js +2 -40
  63. package/r-bridge/lang-4.x/ast/parser/main/internal/control/normalize-if-then-else.d.ts +15 -0
  64. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/control/normalize-if-then-else.js +5 -8
  65. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/control/normalize-if-then.d.ts +7 -7
  66. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/control/normalize-if-then.js +11 -12
  67. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/expression/normalize-expression.d.ts +3 -3
  68. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/expression/normalize-expression.js +4 -7
  69. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-argument.d.ts +2 -2
  70. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-argument.js +3 -3
  71. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-call.d.ts +3 -3
  72. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-call.js +6 -9
  73. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-definition.d.ts +3 -3
  74. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-definition.js +1 -3
  75. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-parameter.d.ts +2 -2
  76. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/functions/normalize-parameter.js +6 -5
  77. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-break.d.ts +2 -2
  78. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-for.d.ts +2 -2
  79. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-for.js +5 -6
  80. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-next.d.ts +2 -2
  81. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-repeat.d.ts +2 -2
  82. package/r-bridge/lang-4.x/ast/parser/main/internal/loops/normalize-while.d.ts +4 -0
  83. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-while.js +4 -4
  84. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/normalize-access.d.ts +3 -3
  85. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/normalize-access.js +1 -2
  86. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/operators/normalize-binary.d.ts +2 -2
  87. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/operators/normalize-binary.js +2 -2
  88. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/operators/normalize-unary.d.ts +2 -2
  89. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/other/normalize-comment.d.ts +3 -3
  90. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/other/normalize-comment.js +1 -1
  91. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/other/normalize-line-directive.d.ts +3 -3
  92. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/other/normalize-line-directive.js +1 -1
  93. package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-delimiter.d.ts +3 -0
  94. package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-expressions.d.ts +10 -0
  95. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/structure/normalize-root.d.ts +2 -2
  96. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/structure/normalize-root.js +3 -4
  97. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/structure/normalize-single-node.d.ts +2 -2
  98. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/structure/normalize-single-node.js +2 -2
  99. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/values/normalize-number.d.ts +3 -3
  100. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/values/normalize-number.js +1 -1
  101. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/values/normalize-string.d.ts +3 -3
  102. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/values/normalize-string.js +1 -1
  103. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/values/normalize-symbol.d.ts +3 -3
  104. package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/values/normalize-symbol.js +1 -3
  105. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.d.ts +41 -0
  106. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.js +85 -0
  107. package/r-bridge/lang-4.x/ast/parser/{xml → main}/normalizer-data.d.ts +10 -4
  108. package/r-bridge/lang-4.x/ast/parser/main/normalizer-data.js +14 -0
  109. package/slicing/criterion/parse.d.ts +1 -1
  110. package/statistics/summarizer/post-process/clusterer.d.ts +1 -1
  111. package/util/ansi.js +9 -2
  112. package/util/time.d.ts +4 -0
  113. package/util/time.js +8 -0
  114. package/util/version.js +1 -1
  115. package/documentation/doc-util/doc-ms.d.ts +0 -1
  116. package/documentation/doc-util/doc-ms.js +0 -8
  117. package/r-bridge/lang-4.x/ast/parser/xml/input-format.d.ts +0 -39
  118. package/r-bridge/lang-4.x/ast/parser/xml/input-format.js +0 -38
  119. package/r-bridge/lang-4.x/ast/parser/xml/internal/control/normalize-if-then-else.d.ts +0 -15
  120. package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/normalize-while.d.ts +0 -4
  121. package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/normalize-delimiter.d.ts +0 -3
  122. package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/normalize-expressions.d.ts +0 -10
  123. package/r-bridge/lang-4.x/ast/parser/xml/normalize-meta.d.ts +0 -47
  124. package/r-bridge/lang-4.x/ast/parser/xml/normalize-meta.js +0 -110
  125. /package/queries/{call-context-query → catalog/call-context-query}/call-context-query-format.js +0 -0
  126. /package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-break.js +0 -0
  127. /package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-next.js +0 -0
  128. /package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/loops/normalize-repeat.js +0 -0
  129. /package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/operators/normalize-unary.js +0 -0
  130. /package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/structure/normalize-delimiter.js +0 -0
  131. /package/r-bridge/lang-4.x/ast/parser/{xml → main}/internal/structure/normalize-expressions.js +0 -0
@@ -6,36 +6,42 @@ 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/call-context-query/call-context-query-format");
9
+ const call_context_query_format_1 = require("../queries/catalog/call-context-query/call-context-query-format");
10
10
  const schema_1 = require("../util/schema");
11
11
  const query_schema_1 = require("../queries/query-schema");
12
12
  const ansi_1 = require("../util/ansi");
13
- const call_context_query_executor_1 = require("../queries/call-context-query/call-context-query-executor");
13
+ const call_context_query_executor_1 = require("../queries/catalog/call-context-query/call-context-query-executor");
14
14
  const compound_query_1 = require("../queries/virtual-query/compound-query");
15
15
  const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
16
16
  const example_query_code_1 = require("./data/query/example-query-code");
17
17
  const doc_structure_1 = require("./doc-util/doc-structure");
18
18
  const doc_code_1 = require("./doc-util/doc-code");
19
+ const dataflow_query_executor_1 = require("../queries/catalog/dataflow-query/dataflow-query-executor");
20
+ const id_map_query_executor_1 = require("../queries/catalog/id-map-query/id-map-query-executor");
21
+ const normalized_ast_query_executor_1 = require("../queries/catalog/normalized-ast-query/normalized-ast-query-executor");
22
+ const cluster_query_executor_1 = require("../queries/catalog/cluster-query/cluster-query-executor");
23
+ const static_slice_query_executor_1 = require("../queries/catalog/static-slice-query/static-slice-query-executor");
24
+ const lineage_query_executor_1 = require("../queries/catalog/lineage-query/lineage-query-executor");
19
25
  (0, doc_query_1.registerQueryDocumentation)('call-context', {
20
26
  name: 'Call-Context Query',
21
27
  type: 'active',
22
28
  shortDescription: 'Finds all calls in a set of files that matches specified criteria.',
23
29
  functionName: call_context_query_executor_1.executeCallContextQueries.name,
24
- functionFile: '../queries/call-context-query/call-context-query-executor.ts',
30
+ functionFile: '../queries/catalog/call-context-query/call-context-query-executor.ts',
25
31
  buildExplanation: async (shell) => {
26
32
  return `
27
- Call context queries may be used to identify calls to specific functions that match criteria of your interest.
33
+ Call context queries can be used to identify calls to specific functions that match criteria of your interest.
28
34
  For now, we support two criteria:
29
35
 
30
- 1. **Function Name** (\`callName\`): The function name is specified by a regular expression. This allows you to find all calls to functions that match a specific pattern.
36
+ 1. **Function Name** (\`callName\`): The function name is specified by a regular expression. This allows you to find all calls to functions that match a specific pattern. Please note, that if you do not use Regex-Anchors, the query will match any function name that contains the given pattern (you can set the \`callNameExact\` property to \`true\` to automatically add the \`^...$\` anchors).
31
37
  2. **Call Targets** (\`callTargets\`): This specifies to what the function call targets. For example, you may want to find all calls to a function that is not defined locally.
32
38
 
33
- Besides this we provide the following ways to automatically categorize and link identified invocations:
39
+ Besides this, we provide the following ways to automatically categorize and link identified invocations:
34
40
 
35
41
  1. **Kind** (\`kind\`): This is a general category that can be used to group calls together. For example, you may want to link all calls to \`plot\` to \`visualize\`.
36
42
  2. **Subkind** (\`subkind\`): This is used to uniquely identify the respective call type when grouping the output. For example, you may want to link all calls to \`ggplot\` to \`plot\`.
37
43
  3. **Linked Calls** (\`linkTo\`): This links the current call to the last call of the given kind. This way, you can link a call like \`points\` to the latest graphics plot etc.
38
- For now, we _only_offer support for linking to the last call_ as the current flow dependency over-approximation is not stable.
44
+ For now, we _only_ offer support for linking to the last call, as the current flow dependency over-approximation is not stable.
39
45
  4. **Aliases** (\`includeAliases\`): Consider a case like \`f <- function_of_interest\`, do you want calls to \`f\` to be included in the results? There is probably no need to combine this with a global call target!
40
46
 
41
47
  Re-using the example code from above, the following query attaches all calls to \`mean\` to the kind \`visualize\` and the subkind \`text\`,
@@ -78,6 +84,120 @@ my_test_function()
78
84
  `;
79
85
  }
80
86
  });
87
+ (0, doc_query_1.registerQueryDocumentation)('dataflow', {
88
+ name: 'Dataflow Query',
89
+ type: 'active',
90
+ shortDescription: 'Returns the dataflow graph of the given code.',
91
+ functionName: dataflow_query_executor_1.executeDataflowQuery.name,
92
+ functionFile: '../queries/catalog/dataflow-query/dataflow-query-executor.ts',
93
+ buildExplanation: async (shell) => {
94
+ const exampleCode = 'x + 1';
95
+ return `
96
+ Maybe you want to handle only the result of the query execution, or you just need the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph) again.
97
+ This query type does exactly that!
98
+
99
+ Using the example code \`${exampleCode}\`, the following query returns the dataflow graph of the code:
100
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
101
+ type: 'dataflow'
102
+ }], { showCode: true })}
103
+ `;
104
+ }
105
+ });
106
+ (0, doc_query_1.registerQueryDocumentation)('normalized-ast', {
107
+ name: 'Normalized AST Query',
108
+ type: 'active',
109
+ shortDescription: 'Returns the normalized AST of the given code.',
110
+ functionName: normalized_ast_query_executor_1.executeNormalizedAstQuery.name,
111
+ functionFile: '../queries/catalog/normalized-ast-query/normalized-ast-query-executor.ts',
112
+ buildExplanation: async (shell) => {
113
+ const exampleCode = 'x + 1';
114
+ return `
115
+ Maybe you want to handle only the result of the query execution, or you just need the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized%20AST) again.
116
+ This query type does exactly that!
117
+
118
+ Using the example code \`${exampleCode}\`, the following query returns the normalized AST of the code:
119
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
120
+ type: 'normalized-ast'
121
+ }], { showCode: true })}
122
+ `;
123
+ }
124
+ });
125
+ (0, doc_query_1.registerQueryDocumentation)('lineage', {
126
+ name: 'Lineage Query',
127
+ type: 'active',
128
+ shortDescription: 'Returns lineage of a criteria.',
129
+ functionName: lineage_query_executor_1.executeLineageQuery.name,
130
+ functionFile: '../queries/catalog/lineage-query/lineage-query-executor.ts',
131
+ buildExplanation: async (shell) => {
132
+ const exampleCode = 'x <- 1\nx';
133
+ return `
134
+ This query calculates the _lineage_ of a given slicing criterion. The lineage traces back all parts that the
135
+ respective variables stems from given the reads, definitions, and returns in the dataflow graph.
136
+
137
+ To understand this, let's start with a simple example query, to get the lineage of the second use of \`x\` in the following code:
138
+ ${(0, doc_code_1.codeBlock)('r', exampleCode)}
139
+
140
+ For this, we use the criterion \`2@x\` (which is the first use of \`x\` in the second line).
141
+
142
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
143
+ type: 'lineage',
144
+ criterion: '2@x'
145
+ }], { showCode: false })}
146
+
147
+ In this simple scenario, the _lineage_ is equivalent to the slice (and in-fact the complete code).
148
+ In general the lineage is smaller and makes no executability guarantees.
149
+ It is just a quick and neither complete nor sound way to get information on where the variable originates from.
150
+
151
+ This query replaces the old [\`request-lineage\`](${doc_files_1.FlowrWikiBaseRef}/Interface#message-request-lineage) message.
152
+
153
+ `;
154
+ }
155
+ });
156
+ (0, doc_query_1.registerQueryDocumentation)('dataflow-cluster', {
157
+ name: 'Dataflow Cluster Query',
158
+ type: 'active',
159
+ shortDescription: 'Calculates and returns all the clusters present in the dataflow graph.',
160
+ functionName: cluster_query_executor_1.executeDataflowClusterQuery.name,
161
+ functionFile: '../queries/catalog/cluster-query/cluster-query-executor.ts',
162
+ buildExplanation: async (shell) => {
163
+ const exampleA = 'x <- 1; x';
164
+ const exampleB = 'x <- 1; y';
165
+ return `
166
+ This query automatically calculates clusters in flowR's dataflow graph
167
+ and returns a list of all clusters found.
168
+ Clusters are to be interpreted as literal clusters on the graph traversing
169
+ edges in both directions. From this perspective,
170
+ the code \`${exampleA}\` has one cluster (given that all code is related),
171
+ while the code \`${exampleB}\` has two clusters (given that the \`y\` has no relation to the previous definition).
172
+
173
+ ${(0, doc_structure_1.details)('Example <code>' + exampleA + '</code>', await (0, doc_query_1.showQuery)(shell, exampleA, [{ type: 'dataflow-cluster' }], { showCode: false }))}
174
+ ${(0, doc_structure_1.details)('Example <code>' + exampleB + '</code>', await (0, doc_query_1.showQuery)(shell, exampleB, [{ type: 'dataflow-cluster' }], { showCode: false }))}
175
+
176
+ Using the example code from above, the following query returns all clusters:
177
+ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode, [{
178
+ type: 'dataflow-cluster'
179
+ }], { showCode: false })}
180
+ `;
181
+ }
182
+ });
183
+ (0, doc_query_1.registerQueryDocumentation)('id-map', {
184
+ name: 'Id-Map Query',
185
+ type: 'active',
186
+ shortDescription: 'Returns the id-map of the normalized AST of the given code.',
187
+ functionName: id_map_query_executor_1.executeIdMapQuery.name,
188
+ functionFile: '../queries/catalog/id-map-query/id-map-query-executor.ts',
189
+ buildExplanation: async (shell) => {
190
+ const exampleCode = 'x + 1';
191
+ return `
192
+ This query provides access to all nodes in the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized%20AST) as a mapping from their id to the node itself.
193
+
194
+ Using the example code \`${exampleCode}\`, the following query returns all nodes from the code:
195
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
196
+ type: 'id-map'
197
+ }], { showCode: true })}
198
+ `;
199
+ }
200
+ });
81
201
  (0, doc_query_1.registerQueryDocumentation)('compound', {
82
202
  name: 'Compound Query',
83
203
  type: 'virtual',
@@ -113,7 +233,7 @@ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode,
113
233
  ], { showCode: false, collapseResult: true })}
114
234
 
115
235
  However, compound queries become more useful whenever common arguments can not be expressed as a union in one of their properties.
116
- Additionally, you can still overwrite default arguments.
236
+ Additionally, you can still overwrite default arguments.
117
237
  In the following, we (by default) want all calls to not resolve to a local definition, except for those to \`print\` for which we explicitly
118
238
  want to resolve to a local definition:
119
239
 
@@ -127,8 +247,45 @@ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode,
127
247
  ]
128
248
  }], { showCode: false })}
129
249
 
130
- Now, the results no longer contain calls to \`plot\` that are not defined locally.
250
+ Now, the results no longer contain calls to \`plot\` that are not defined locally.
251
+
252
+ `;
253
+ }
254
+ });
255
+ (0, doc_query_1.registerQueryDocumentation)('static-slice', {
256
+ name: 'Static Slice Query',
257
+ type: 'active',
258
+ shortDescription: 'Slice the dataflow graph reducing the code to just the parts relevant for the given criteria.',
259
+ functionName: static_slice_query_executor_1.executeStaticSliceClusterQuery.name,
260
+ functionFile: '../queries/catalog/static-slice-query/static-slice-query-executor.ts',
261
+ buildExplanation: async (shell) => {
262
+ const exampleCode = 'x <- 1\ny <- 2\nx';
263
+ return `
264
+ To slice, _flowR_ needs one thing from you: a variable or a list of variables (function calls are supported to, referring to the anonymous
265
+ return of the call) that you want to slice the dataflow graph for.
266
+ Given this, the slice is essentially the subpart of the program that may influence the value of the variables you are interested in.
267
+ To specify a variable of interest, you have to present flowR with a [slicing criterion](${doc_files_1.FlowrWikiBaseRef}/Terminology#slicing-criterion) (or, respectively, an array of them).
268
+
269
+ To exemplify the capabilities, consider the following code:
270
+ ${(0, doc_code_1.codeBlock)('r', exampleCode)}
271
+ If you are interested in the parts required for the use of \`x\` in the last line, you can use the following query:
272
+
273
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
274
+ type: 'static-slice',
275
+ criteria: ['3@x']
276
+ }], { showCode: false })}
277
+
278
+ In general you may be uninterested in seeing the reconstructed version and want to save some computation time, for this,
279
+ you can use the \`noReconstruction\` flag.
131
280
 
281
+ ${(0, doc_structure_1.details)('No Reconstruction Example', await (0, doc_query_1.showQuery)(shell, exampleCode, [{
282
+ type: 'static-slice',
283
+ criteria: ['3@x'],
284
+ noReconstruction: true
285
+ }], { showCode: false }))}
286
+
287
+ You can disable [magic comments](${doc_files_1.FlowrWikiBaseRef}/Interface#slice-magic-comments) using the \`noMagicComments\` flag.
288
+ This query replaces the old [\`request-slice\`](${doc_files_1.FlowrWikiBaseRef}/Interface#message-request-slice) message.
132
289
  `;
133
290
  }
134
291
  });
@@ -139,6 +296,36 @@ async function getText(shell) {
139
296
  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')}.
140
297
  Please see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more information on how to access this API.
141
298
 
299
+ ## The Query Format
300
+
301
+ Queries are JSON arrays of query objects, each of which uses a \`type\` property to specify the query type.
302
+ In general, we separate two types of queries:
303
+
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)).
306
+
307
+ We separate these from a concept perspective.
308
+ For now, we support the following **active** queries (which we will refer to simply as a \`query\`):
309
+
310
+ ${(0, doc_query_1.tocForQueryType)('active')}
311
+
312
+ Similarly, we support the following **virtual** queries:
313
+
314
+ ${(0, doc_query_1.tocForQueryType)('virtual')}
315
+
316
+ <details>
317
+
318
+
319
+ <summary>Detailed Query Format (Automatically Generated)</summary>
320
+
321
+ 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
+
323
+ ${(0, schema_1.describeSchema)(query_schema_1.QueriesSchema, ansi_1.markdownFormatter)}
324
+
325
+ </details>
326
+
327
+ ### Why Queries?
328
+
142
329
  First, consider that you have a file like the following (of course, this is just a simple and artificial example):
143
330
 
144
331
  \`\`\`r
@@ -168,34 +355,6 @@ Just as an example, the following [Call-Context Query](#call-context-query) find
168
355
 
169
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 })}
170
357
 
171
- ## The Query Format
172
-
173
- Queries are JSON arrays of query objects, each of which uses a \`type\` property to specify the query type.
174
- In general, we separate two types of queries:
175
-
176
- 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.
177
- 2. **Virtual Queries**: Are used to structure your queries (e.g., the [Compound Query](#compound-query)).
178
-
179
- We separate these from a concept perspective.
180
- For now, we support the following **active** queries (which we will refer to simply as a \`query\`):
181
-
182
- ${(0, doc_query_1.tocForQueryType)('active')}
183
-
184
- Similarly, we support the following **virtual** queries:
185
-
186
- ${(0, doc_query_1.tocForQueryType)('virtual')}
187
-
188
- <details>
189
-
190
-
191
- <summary>Detailed Query Format (Automatically Generated)</summary>
192
-
193
- 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:
194
-
195
- ${(0, schema_1.describeSchema)(query_schema_1.QueriesSchema, ansi_1.markdownFormatter)}
196
-
197
- </details>
198
-
199
358
  ${await (0, doc_query_1.explainQueries)(shell, 'active')}
200
359
 
201
360
  ${await (0, doc_query_1.explainQueries)(shell, 'virtual')}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
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": {
@@ -38,7 +38,8 @@
38
38
  "test": "nyc --no-clean mocha",
39
39
  "performance-test": "func() { cd test/performance/ && bash run-all-suites.sh $1 $2 $3; cd ../../; }; func",
40
40
  "test-full": "npm run test -- --test-installation",
41
- "detect-circular-deps": "npx madge --extensions ts,tsx --circular src/"
41
+ "detect-circular-deps": "npx madge --extensions ts,tsx --circular src/",
42
+ "checkup": "npm run flowr -- --execute \":version\" && npm run lint && npm run test-full -- --forbid-only && docker build -t test-flowr -f scripts/Dockerfile . && npm run doc && npm-run-all wiki:*"
42
43
  },
43
44
  "keywords": [
44
45
  "static code analysis",
@@ -1,11 +1,12 @@
1
1
  import type { CallContextQuery, CallContextQueryResult } from './call-context-query-format';
2
- import type { BasicQueryData } from '../query';
2
+ import type { BasicQueryData } from '../../query';
3
3
  /**
4
4
  * Multi-stage call context query resolve.
5
5
  *
6
6
  * 1. Resolve all calls in the DF graph that match the respective {@link DefaultCallContextQueryFormat#callName} regex.
7
- * 2. Identify their respective call targets, if {@link DefaultCallContextQueryFormat#callTargets} is set to be non-any.
7
+ * 2. If there is an alias attached, consider all call traces.
8
+ * 3. Identify their respective call targets, if {@link DefaultCallContextQueryFormat#callTargets} is set to be non-any.
8
9
  * This happens during the main resolution!
9
- * 3. Attach `linkTo` calls to the respective calls.
10
+ * 4. Attach `linkTo` calls to the respective calls.
10
11
  */
11
12
  export declare function executeCallContextQueries({ graph, ast }: BasicQueryData, queries: readonly CallContextQuery[]): CallContextQueryResult;
@@ -2,17 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.executeCallContextQueries = executeCallContextQueries;
4
4
  const call_context_query_format_1 = require("./call-context-query-format");
5
- const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
6
- const vertex_1 = require("../../dataflow/graph/vertex");
7
- const assert_1 = require("../../util/assert");
8
- const edge_1 = require("../../dataflow/graph/edge");
9
- const resolve_by_name_1 = require("../../dataflow/environments/resolve-by-name");
10
- const built_in_1 = require("../../dataflow/environments/built-in");
11
- const cfg_1 = require("../../util/cfg/cfg");
12
- const two_layer_collector_1 = require("../two-layer-collector");
13
- const objects_1 = require("../../util/objects");
14
- const visitor_1 = require("../../util/cfg/visitor");
15
- const identifier_1 = require("../../dataflow/environments/identifier");
5
+ const node_id_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/node-id");
6
+ const vertex_1 = require("../../../dataflow/graph/vertex");
7
+ const assert_1 = require("../../../util/assert");
8
+ const edge_1 = require("../../../dataflow/graph/edge");
9
+ const resolve_by_name_1 = require("../../../dataflow/environments/resolve-by-name");
10
+ const built_in_1 = require("../../../dataflow/environments/built-in");
11
+ const cfg_1 = require("../../../util/cfg/cfg");
12
+ const two_layer_collector_1 = require("../../two-layer-collector");
13
+ const objects_1 = require("../../../util/objects");
14
+ const visitor_1 = require("../../../util/cfg/visitor");
15
+ const identifier_1 = require("../../../dataflow/environments/identifier");
16
16
  function satisfiesCallTargets(id, graph, callTarget) {
17
17
  const callVertex = graph.get(id);
18
18
  if (callVertex === undefined || callVertex[0].tag !== vertex_1.VertexType.FunctionCall) {
@@ -35,7 +35,7 @@ function satisfiesCallTargets(id, graph, callTarget) {
35
35
  * including any potential built-in mapping.
36
36
  */
37
37
  const reResolved = (0, resolve_by_name_1.resolveByName)(info.name, info.environment, identifier_1.ReferenceType.Unknown);
38
- if (reResolved && reResolved.some(t => t.definedAt === built_in_1.BuiltIn)) {
38
+ if (reResolved?.some(t => t.definedAt === built_in_1.BuiltIn)) {
39
39
  builtIn = true;
40
40
  }
41
41
  }
@@ -92,6 +92,9 @@ function makeReport(collector) {
92
92
  function isSubCallQuery(query) {
93
93
  return 'linkTo' in query;
94
94
  }
95
+ function exactCallNameRegex(name) {
96
+ return new RegExp(`^(${name})$`);
97
+ }
95
98
  function promoteQueryCallNames(queries) {
96
99
  let requiresCfg = false;
97
100
  const promotedQueries = queries.map(q => {
@@ -99,7 +102,8 @@ function promoteQueryCallNames(queries) {
99
102
  requiresCfg = true;
100
103
  return {
101
104
  ...q,
102
- callName: new RegExp(q.callName),
105
+ callName: q.callNameExact ? exactCallNameRegex(q.callName)
106
+ : new RegExp(q.callName),
103
107
  linkTo: {
104
108
  ...q.linkTo,
105
109
  /* we have to add another promotion layer whenever we add something without this call name */
@@ -110,7 +114,8 @@ function promoteQueryCallNames(queries) {
110
114
  else {
111
115
  return {
112
116
  ...q,
113
- callName: new RegExp(q.callName)
117
+ callName: q.callNameExact ? exactCallNameRegex(q.callName)
118
+ : new RegExp(q.callName)
114
119
  };
115
120
  }
116
121
  });
@@ -186,9 +191,10 @@ function retrieveAllCallAliases(nodeId, graph) {
186
191
  * Multi-stage call context query resolve.
187
192
  *
188
193
  * 1. Resolve all calls in the DF graph that match the respective {@link DefaultCallContextQueryFormat#callName} regex.
189
- * 2. Identify their respective call targets, if {@link DefaultCallContextQueryFormat#callTargets} is set to be non-any.
194
+ * 2. If there is an alias attached, consider all call traces.
195
+ * 3. Identify their respective call targets, if {@link DefaultCallContextQueryFormat#callTargets} is set to be non-any.
190
196
  * This happens during the main resolution!
191
- * 3. Attach `linkTo` calls to the respective calls.
197
+ * 4. Attach `linkTo` calls to the respective calls.
192
198
  */
193
199
  function executeCallContextQueries({ graph, ast }, queries) {
194
200
  /* omit performance page load */
@@ -1,5 +1,5 @@
1
- import type { BaseQueryFormat, BaseQueryResult } from '../base-query-format';
2
- import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
3
3
  export declare enum CallTargets {
4
4
  /** call targets a function that is not defined locally (e.g., the call targets a library function) */
5
5
  OnlyGlobal = "global",
@@ -16,6 +16,10 @@ export interface DefaultCallContextQueryFormat<CallName extends RegExp | string>
16
16
  readonly type: 'call-context';
17
17
  /** Regex regarding the function name, please note that strings will be interpreted as regular expressions too! */
18
18
  readonly callName: CallName;
19
+ /**
20
+ * Should we automatically add the `^` and `$` anchors to the regex to make it an exact match?
21
+ */
22
+ readonly callNameExact?: boolean;
19
23
  /** kind may be a step or anything that you attach to the call, this can be used to group calls together (e.g., linking `ggplot` to `visualize`). Defaults to `.` */
20
24
  readonly kind?: string;
21
25
  /** subkinds are used to uniquely identify the respective call type when grouping the output (e.g., the normalized name, linking `ggplot` to `plot`). Defaults to `.` */
@@ -0,0 +1,3 @@
1
+ import type { BasicQueryData } from '../../query';
2
+ import type { DataflowClusterQuery, DataflowClusterQueryResult } from './cluster-query-format';
3
+ export declare function executeDataflowClusterQuery({ graph }: BasicQueryData, queries: readonly DataflowClusterQuery[]): DataflowClusterQueryResult;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeDataflowClusterQuery = executeDataflowClusterQuery;
4
+ const log_1 = require("../../../util/log");
5
+ const cluster_1 = require("../../../dataflow/cluster");
6
+ function executeDataflowClusterQuery({ graph }, queries) {
7
+ if (queries.length !== 1) {
8
+ log_1.log.warn('The dataflow cluster query expects only up to one query, but got', queries.length);
9
+ }
10
+ const start = Date.now();
11
+ const clusters = (0, cluster_1.findAllClusters)(graph);
12
+ return {
13
+ '.meta': {
14
+ timing: Date.now() - start
15
+ },
16
+ clusters
17
+ };
18
+ }
19
+ //# sourceMappingURL=cluster-query-executor.js.map
@@ -0,0 +1,12 @@
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import type { DataflowGraphClusters } from '../../../dataflow/cluster';
3
+ /**
4
+ * Calculates and returns all clusters encountered in the dataflow graph.
5
+ */
6
+ export interface DataflowClusterQuery extends BaseQueryFormat {
7
+ readonly type: 'dataflow-cluster';
8
+ }
9
+ export interface DataflowClusterQueryResult extends BaseQueryResult {
10
+ /** All clusters found in the respective dataflow */
11
+ readonly clusters: DataflowGraphClusters;
12
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=cluster-query-format.js.map
@@ -0,0 +1,3 @@
1
+ import type { BasicQueryData } from '../../query';
2
+ import type { DataflowQuery, DataflowQueryResult } from './dataflow-query-format';
3
+ export declare function executeDataflowQuery({ graph }: BasicQueryData, queries: readonly DataflowQuery[]): DataflowQueryResult;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeDataflowQuery = executeDataflowQuery;
4
+ const log_1 = require("../../../util/log");
5
+ function executeDataflowQuery({ graph }, queries) {
6
+ if (queries.length !== 1) {
7
+ log_1.log.warn('Dataflow query expects only up to one query, but got', queries.length);
8
+ }
9
+ return {
10
+ '.meta': {
11
+ /* there is no sense in measuring a get */
12
+ timing: 0
13
+ },
14
+ graph
15
+ };
16
+ }
17
+ //# sourceMappingURL=dataflow-query-executor.js.map
@@ -0,0 +1,12 @@
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import type { DataflowGraph } from '../../../dataflow/graph/graph';
3
+ /**
4
+ * Simple re-returns the dataflow graph of the analysis.
5
+ */
6
+ export interface DataflowQuery extends BaseQueryFormat {
7
+ readonly type: 'dataflow';
8
+ }
9
+ export interface DataflowQueryResult extends BaseQueryResult {
10
+ /** Please be aware that this is the graph in its JSON representation, use {@link DataflowGraph#fromJson} if the result is serialized */
11
+ readonly graph: DataflowGraph;
12
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=dataflow-query-format.js.map
@@ -0,0 +1,3 @@
1
+ import type { BasicQueryData } from '../../query';
2
+ import type { IdMapQuery, IdMapQueryResult } from './id-map-query-format';
3
+ export declare function executeIdMapQuery({ ast }: BasicQueryData, queries: readonly IdMapQuery[]): IdMapQueryResult;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeIdMapQuery = executeIdMapQuery;
4
+ const log_1 = require("../../../util/log");
5
+ function executeIdMapQuery({ ast }, queries) {
6
+ if (queries.length !== 1) {
7
+ log_1.log.warn('Id-Map query expects only up to one query, but got', queries.length);
8
+ }
9
+ return {
10
+ '.meta': {
11
+ /* there is no sense in measuring a get */
12
+ timing: 0
13
+ },
14
+ idMap: ast.idMap
15
+ };
16
+ }
17
+ //# sourceMappingURL=id-map-query-executor.js.map
@@ -0,0 +1,8 @@
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import type { AstIdMap } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
3
+ export interface IdMapQuery extends BaseQueryFormat {
4
+ readonly type: 'id-map';
5
+ }
6
+ export interface IdMapQueryResult extends BaseQueryResult {
7
+ readonly idMap: AstIdMap;
8
+ }
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=normalizer-data.js.map
3
+ //# sourceMappingURL=id-map-query-format.js.map
@@ -0,0 +1,3 @@
1
+ import type { BasicQueryData } from '../../query';
2
+ import type { LineageQuery, LineageQueryResult } from './lineage-query-format';
3
+ export declare function executeLineageQuery({ graph, ast }: BasicQueryData, queries: readonly LineageQuery[]): LineageQueryResult;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeLineageQuery = executeLineageQuery;
4
+ const log_1 = require("../../../util/log");
5
+ const repl_lineage_1 = require("../../../cli/repl/commands/repl-lineage");
6
+ function executeLineageQuery({ graph, ast }, queries) {
7
+ const start = Date.now();
8
+ const result = {};
9
+ for (const { criterion } of queries) {
10
+ if (result[criterion]) {
11
+ log_1.log.warn('Duplicate criterion in lineage query:', criterion);
12
+ }
13
+ result[criterion] = (0, repl_lineage_1.getLineage)(criterion, graph, ast.idMap);
14
+ }
15
+ return {
16
+ '.meta': {
17
+ timing: Date.now() - start
18
+ },
19
+ lineages: result
20
+ };
21
+ }
22
+ //# sourceMappingURL=lineage-query-executor.js.map
@@ -0,0 +1,14 @@
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
3
+ import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
4
+ /**
5
+ * Calculates the lineage of the given criterion.
6
+ */
7
+ export interface LineageQuery extends BaseQueryFormat {
8
+ readonly type: 'lineage';
9
+ readonly criterion: SingleSlicingCriterion;
10
+ }
11
+ export interface LineageQueryResult extends BaseQueryResult {
12
+ /** Maps each criterion to the found lineage, duplicates are ignored. */
13
+ readonly lineages: Record<SingleSlicingCriterion, Set<NodeId>>;
14
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=lineage-query-format.js.map
@@ -0,0 +1,3 @@
1
+ import type { BasicQueryData } from '../../query';
2
+ import type { NormalizedAstQuery, NormalizedAstQueryResult } from './normalized-ast-query-format';
3
+ export declare function executeNormalizedAstQuery({ ast }: BasicQueryData, queries: readonly NormalizedAstQuery[]): NormalizedAstQueryResult;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeNormalizedAstQuery = executeNormalizedAstQuery;
4
+ const log_1 = require("../../../util/log");
5
+ function executeNormalizedAstQuery({ ast }, queries) {
6
+ if (queries.length !== 1) {
7
+ log_1.log.warn('Normalized-Ast query expects only up to one query, but got', queries.length);
8
+ }
9
+ return {
10
+ '.meta': {
11
+ /* there is no sense in measuring a get */
12
+ timing: 0
13
+ },
14
+ normalized: ast
15
+ };
16
+ }
17
+ //# sourceMappingURL=normalized-ast-query-executor.js.map