@eagleoutice/flowr 2.2.14 → 2.2.15

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 (83) hide show
  1. package/README.md +4 -4
  2. package/cli/repl/commands/repl-commands.js +1 -1
  3. package/cli/repl/commands/repl-execute.js +2 -1
  4. package/config.js +1 -1
  5. package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
  6. package/control-flow/cfg-dead-code.d.ts +4 -0
  7. package/control-flow/cfg-dead-code.js +81 -0
  8. package/control-flow/cfg-simplification.d.ts +17 -6
  9. package/control-flow/cfg-simplification.js +23 -19
  10. package/control-flow/control-flow-graph.d.ts +2 -1
  11. package/control-flow/control-flow-graph.js +1 -0
  12. package/control-flow/dfg-cfg-guided-visitor.d.ts +4 -4
  13. package/control-flow/dfg-cfg-guided-visitor.js +1 -1
  14. package/control-flow/extract-cfg.d.ts +1 -1
  15. package/control-flow/extract-cfg.js +60 -57
  16. package/control-flow/semantic-cfg-guided-visitor.d.ts +17 -8
  17. package/control-flow/semantic-cfg-guided-visitor.js +50 -17
  18. package/control-flow/simple-visitor.d.ts +4 -0
  19. package/control-flow/simple-visitor.js +14 -0
  20. package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
  21. package/dataflow/environments/built-in-config.d.ts +1 -0
  22. package/dataflow/environments/built-in.d.ts +10 -1
  23. package/dataflow/environments/built-in.js +9 -3
  24. package/dataflow/environments/default-builtin-config.js +1 -1
  25. package/dataflow/environments/resolve-by-name.d.ts +0 -36
  26. package/dataflow/environments/resolve-by-name.js +0 -240
  27. package/dataflow/eval/resolve/alias-tracking.d.ts +87 -0
  28. package/dataflow/eval/resolve/alias-tracking.js +349 -0
  29. package/dataflow/eval/resolve/resolve.d.ts +34 -0
  30. package/dataflow/eval/resolve/resolve.js +93 -0
  31. package/dataflow/eval/values/general.d.ts +27 -0
  32. package/dataflow/eval/values/general.js +73 -0
  33. package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
  34. package/dataflow/eval/values/intervals/interval-constants.js +27 -0
  35. package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
  36. package/dataflow/eval/values/logical/logical-constants.js +31 -0
  37. package/dataflow/eval/values/r-value.d.ts +58 -0
  38. package/dataflow/eval/values/r-value.js +90 -0
  39. package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
  40. package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
  41. package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
  42. package/dataflow/eval/values/sets/set-constants.js +34 -0
  43. package/dataflow/eval/values/string/string-constants.d.ts +8 -0
  44. package/dataflow/eval/values/string/string-constants.js +40 -0
  45. package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
  46. package/dataflow/eval/values/vectors/vector-constants.js +35 -0
  47. package/dataflow/graph/unknown-replacement.d.ts +11 -0
  48. package/dataflow/graph/unknown-replacement.js +12 -0
  49. package/dataflow/graph/unknown-side-effect.d.ts +7 -0
  50. package/dataflow/graph/unknown-side-effect.js +13 -0
  51. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
  52. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +4 -2
  53. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +12 -9
  54. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
  55. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +9 -2
  56. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +12 -15
  57. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
  58. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  59. package/documentation/doc-util/doc-query.d.ts +6 -3
  60. package/documentation/doc-util/doc-query.js +3 -1
  61. package/documentation/print-cfg-wiki.js +6 -6
  62. package/documentation/print-dataflow-graph-wiki.js +4 -3
  63. package/documentation/print-engines-wiki.js +1 -1
  64. package/documentation/print-query-wiki.js +80 -0
  65. package/linter/rules/1-deprecated-functions.js +1 -1
  66. package/linter/rules/2-file-path-validity.js +1 -1
  67. package/package.json +1 -1
  68. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
  69. package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
  70. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
  71. package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
  72. package/queries/catalog/dependencies-query/dependencies-query-executor.js +33 -32
  73. package/queries/catalog/linter-query/linter-query-format.js +2 -1
  74. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +3 -3
  75. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +2 -1
  76. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -22
  77. package/queries/query.d.ts +61 -1
  78. package/queries/query.js +2 -0
  79. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +11 -4
  80. package/search/search-executor/search-enrichers.js +5 -2
  81. package/slicing/criterion/parse.d.ts +8 -0
  82. package/slicing/criterion/parse.js +20 -0
  83. package/util/version.js +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.2.14",
3
+ "version": "2.2.15",
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": {
@@ -0,0 +1,3 @@
1
+ import type { ControlFlowQuery, ControlFlowQueryResult } from './control-flow-query-format';
2
+ import type { BasicQueryData } from '../../base-query-format';
3
+ export declare function executeControlFlowQuery({ dataflow: { graph }, ast }: BasicQueryData, queries: readonly ControlFlowQuery[]): ControlFlowQueryResult;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeControlFlowQuery = executeControlFlowQuery;
4
+ const log_1 = require("../../../util/log");
5
+ const extract_cfg_1 = require("../../../control-flow/extract-cfg");
6
+ function executeControlFlowQuery({ dataflow: { graph }, ast }, queries) {
7
+ if (queries.length !== 1) {
8
+ log_1.log.warn('The control flow query expects only up to one query, but got', queries.length);
9
+ }
10
+ const query = queries[0];
11
+ const start = Date.now();
12
+ const controlFlow = (0, extract_cfg_1.extractCfg)(ast, graph, query.config?.simplificationPasses);
13
+ return {
14
+ '.meta': {
15
+ timing: Date.now() - start
16
+ },
17
+ controlFlow
18
+ };
19
+ }
20
+ //# sourceMappingURL=control-flow-query-executor.js.map
@@ -0,0 +1,81 @@
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import Joi from 'joi';
3
+ import { executeControlFlowQuery } from './control-flow-query-executor';
4
+ import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
5
+ import type { ControlFlowInformation } from '../../../control-flow/control-flow-graph';
6
+ import type { CfgSimplificationPassName } from '../../../control-flow/cfg-simplification';
7
+ /**
8
+ * Provides the control flow graph with an optional, fixed configuration
9
+ */
10
+ export interface ControlFlowQuery extends BaseQueryFormat {
11
+ readonly type: 'control-flow';
12
+ readonly config?: {
13
+ /**
14
+ * If set, the control flow graph will be simplified using the given passes.
15
+ * Defaults to the default simplification order.
16
+ */
17
+ simplificationPasses?: readonly CfgSimplificationPassName[];
18
+ };
19
+ }
20
+ export interface ControlFlowQueryResult extends BaseQueryResult {
21
+ readonly controlFlow: ControlFlowInformation;
22
+ }
23
+ export declare const ControlFlowQueryDefinition: {
24
+ readonly executor: typeof executeControlFlowQuery;
25
+ readonly asciiSummarizer: (formatter: import("../../../util/text/ansi").OutputFormatter, processed: import("../../../core/steps/pipeline/pipeline").PipelineOutput<import("../../../core/steps/pipeline/pipeline").Pipeline<{
26
+ readonly name: "parse";
27
+ readonly humanReadableName: "parse with R shell";
28
+ readonly description: "Parse the given R code into an AST";
29
+ readonly processor: (_results: unknown, input: Partial<import("../../../r-bridge/parser").ParseRequiredInput<string>>) => Promise<import("../../../r-bridge/parser").ParseStepOutput<string>>;
30
+ readonly executed: import("../../../core/steps/pipeline-step").PipelineStepStage.OncePerFile;
31
+ readonly printer: {
32
+ readonly 0: typeof import("../../../core/print/print").internalPrinter;
33
+ readonly 2: {
34
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
35
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
36
+ };
37
+ readonly 5: ({ parsed }: import("../../../r-bridge/parser").ParseStepOutput<string>, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
38
+ };
39
+ readonly dependencies: readonly [];
40
+ readonly requiredInput: import("../../../r-bridge/parser").ParseRequiredInput<string>;
41
+ } | {
42
+ readonly name: "normalize";
43
+ readonly humanReadableName: "normalize";
44
+ readonly description: "Normalize the AST to flowR's AST";
45
+ readonly processor: (results: {
46
+ parse?: import("../../../r-bridge/parser").ParseStepOutput<string>;
47
+ }, input: Partial<import("../../../core/steps/all/core/10-normalize").NormalizeRequiredInput>) => import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
48
+ readonly executed: import("../../../core/steps/pipeline-step").PipelineStepStage.OncePerFile;
49
+ readonly printer: {
50
+ readonly 0: typeof import("../../../core/print/print").internalPrinter;
51
+ readonly 2: typeof import("../../../core/print/normalize-printer").normalizedAstToJson;
52
+ readonly 5: typeof import("../../../core/print/normalize-printer").normalizedAstToQuads;
53
+ readonly 3: typeof import("../../../core/print/normalize-printer").printNormalizedAstToMermaid;
54
+ readonly 4: typeof import("../../../core/print/normalize-printer").printNormalizedAstToMermaidUrl;
55
+ };
56
+ readonly dependencies: readonly ["parse"];
57
+ readonly requiredInput: import("../../../core/steps/all/core/10-normalize").NormalizeRequiredInput;
58
+ } | {
59
+ readonly humanReadableName: "dataflow";
60
+ readonly processor: (results: {
61
+ normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
62
+ }, input: {
63
+ request?: import("../../../r-bridge/retriever").RParseRequests;
64
+ parser?: import("../../../r-bridge/parser").Parser<import("../../../r-bridge/parser").KnownParserType>;
65
+ }) => import("../../../dataflow/info").DataflowInformation;
66
+ readonly requiredInput: {};
67
+ readonly name: "dataflow";
68
+ readonly description: "Construct the dataflow graph";
69
+ readonly executed: import("../../../core/steps/pipeline-step").PipelineStepStage.OncePerFile;
70
+ readonly printer: {
71
+ readonly 0: typeof import("../../../core/print/print").internalPrinter;
72
+ readonly 2: typeof import("../../../core/print/dataflow-printer").dataflowGraphToJson;
73
+ readonly 5: typeof import("../../../core/print/dataflow-printer").dataflowGraphToQuads;
74
+ readonly 3: typeof import("../../../core/print/dataflow-printer").dataflowGraphToMermaid;
75
+ readonly 4: typeof import("../../../core/print/dataflow-printer").dataflowGraphToMermaidUrl;
76
+ };
77
+ readonly dependencies: readonly ["normalize"];
78
+ }>>, queryResults: BaseQueryResult, result: string[]) => true;
79
+ readonly schema: Joi.ObjectSchema<any>;
80
+ readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
81
+ };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ControlFlowQueryDefinition = void 0;
7
+ const ansi_1 = require("../../../util/text/ansi");
8
+ const joi_1 = __importDefault(require("joi"));
9
+ const control_flow_query_executor_1 = require("./control-flow-query-executor");
10
+ const control_flow_graph_1 = require("../../../control-flow/control-flow-graph");
11
+ const cfg_1 = require("../../../util/mermaid/cfg");
12
+ const cfg_simplification_1 = require("../../../control-flow/cfg-simplification");
13
+ exports.ControlFlowQueryDefinition = {
14
+ executor: control_flow_query_executor_1.executeControlFlowQuery,
15
+ asciiSummarizer: (formatter, processed, queryResults, result) => {
16
+ const out = queryResults;
17
+ result.push(`Query: ${(0, ansi_1.bold)('control-flow', formatter)} (${out['.meta'].timing.toFixed(0)}ms)`);
18
+ result.push(` ╰ CFG: ${(0, cfg_1.cfgToMermaidUrl)(out.controlFlow, processed.normalize)}`);
19
+ return true;
20
+ },
21
+ schema: joi_1.default.object({
22
+ type: joi_1.default.string().valid('control-flow').required().description('The type of the query.'),
23
+ config: joi_1.default.object({
24
+ simplificationPasses: joi_1.default.array().items(joi_1.default.string().valid(...Object.keys(cfg_simplification_1.CfgSimplificationPasses))).description('The simplification passes to apply to the control flow graph. If unset, the default simplification order will be used.')
25
+ }).optional().description('Optional configuration for the control flow query.')
26
+ }).description('The control flow query provides the control flow graph of the analysis, optionally simplified.'),
27
+ flattenInvolvedNodes: (queryResults) => {
28
+ const out = queryResults;
29
+ return [...out.controlFlow.graph.vertices(true)]
30
+ .filter(([, v]) => v.type !== control_flow_graph_1.CfgVertexType.Block)
31
+ .map(v => v[0]);
32
+ }
33
+ };
34
+ //# sourceMappingURL=control-flow-query-format.js.map
@@ -11,13 +11,16 @@ const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-
11
11
  const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visitor");
12
12
  const assert_1 = require("../../../util/assert");
13
13
  const objects_1 = require("../../../util/objects");
14
- const resolve_by_name_1 = require("../../../dataflow/environments/resolve-by-name");
15
14
  const library_functions_1 = require("./function-info/library-functions");
16
15
  const source_functions_1 = require("./function-info/source-functions");
17
16
  const read_functions_1 = require("./function-info/read-functions");
18
17
  const write_functions_1 = require("./function-info/write-functions");
19
18
  const function_info_1 = require("./function-info/function-info");
20
19
  const identify_link_to_last_call_relation_1 = require("../call-context-query/identify-link-to-last-call-relation");
20
+ const r_value_1 = require("../../../dataflow/eval/values/r-value");
21
+ const general_1 = require("../../../dataflow/eval/values/general");
22
+ const alias_tracking_1 = require("../../../dataflow/eval/resolve/alias-tracking");
23
+ const string_constants_1 = require("../../../dataflow/eval/values/string/string-constants");
21
24
  function collectNamespaceAccesses(data, libraries) {
22
25
  /* for libraries, we have to additionally track all uses of `::` and `:::`, for this we currently simply traverse all uses */
23
26
  (0, visitor_1.visitAst)(data.ast.ast, n => {
@@ -203,31 +206,32 @@ function resolveBasedOnConfig(data, vertex, argument, environment, idMap, resolv
203
206
  full = false;
204
207
  }
205
208
  }
206
- return (0, resolve_by_name_1.resolveIdToValue)(argument, { environment, graph: data.dataflow.graph, full });
207
- }
208
- function unwrapRValue(value) {
209
- if (value === undefined) {
210
- return undefined;
211
- }
212
- switch (typeof value) {
213
- case 'string':
214
- return value;
215
- case 'number':
216
- return value.toString();
217
- case 'boolean':
218
- return value ? 'TRUE' : 'FALSE';
219
- }
220
- if (typeof value !== 'object' || value === null) {
221
- return JSON.stringify(value);
222
- }
223
- if ('str' in value) {
224
- return value.str;
225
- }
226
- else if ('num' in value) {
227
- return value.num.toString();
228
- }
229
- else {
230
- return JSON.stringify(value);
209
+ full = true;
210
+ const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(argument, { environment, graph: data.dataflow.graph, full: full }));
211
+ if (resolved) {
212
+ const values = [];
213
+ for (const value of resolved.elements) {
214
+ if (!(0, r_value_1.isValue)(value)) {
215
+ return undefined;
216
+ }
217
+ if (value.type === 'string' && (0, r_value_1.isValue)(value.value)) {
218
+ values.push(value.value.str);
219
+ }
220
+ else if (value.type === 'logical' && (0, r_value_1.isValue)(value.value)) {
221
+ values.push(value.value.valueOf() ? 'TRUE' : 'FALSE');
222
+ }
223
+ else if (value.type === 'vector' && (0, r_value_1.isValue)(value.elements)) {
224
+ const elements = (0, string_constants_1.collectStrings)(value.elements);
225
+ if (elements === undefined) {
226
+ return undefined;
227
+ }
228
+ values.push(...elements);
229
+ }
230
+ else {
231
+ return undefined;
232
+ }
233
+ }
234
+ return values;
231
235
  }
232
236
  }
233
237
  /**
@@ -254,16 +258,14 @@ function getArgumentValue(data, vertex, argumentIndex, argumentName, resolveValu
254
258
  valueNode = valueNode.value;
255
259
  }
256
260
  if (valueNode) {
257
- // TDODO: extend vector support etc.
258
261
  // this should be evaluated in the callee-context
259
- const values = resolveBasedOnConfig(data, vertex, valueNode, vertex.environment, graph.idMap, resolveValue)
260
- ?.map(unwrapRValue) ?? [dependencies_query_format_1.Unknown];
262
+ const values = resolveBasedOnConfig(data, vertex, valueNode, vertex.environment, graph.idMap, resolveValue) ?? [dependencies_query_format_1.Unknown];
261
263
  map.set(ref, new Set(values));
262
264
  }
263
265
  }
264
266
  return map;
265
267
  }
266
- if (vertex.args.length > argumentIndex) {
268
+ if (argumentIndex < vertex.args.length) {
267
269
  const arg = (0, graph_1.getReferenceOfArgument)(vertex.args[argumentIndex]);
268
270
  if (!arg) {
269
271
  return undefined;
@@ -273,8 +275,7 @@ function getArgumentValue(data, vertex, argumentIndex, argumentName, resolveValu
273
275
  valueNode = valueNode.value;
274
276
  }
275
277
  if (valueNode) {
276
- const values = resolveBasedOnConfig(data, vertex, valueNode, vertex.environment, graph.idMap, resolveValue)
277
- ?.map(unwrapRValue) ?? [dependencies_query_format_1.Unknown];
278
+ const values = resolveBasedOnConfig(data, vertex, valueNode, vertex.environment, graph.idMap, resolveValue) ?? [dependencies_query_format_1.Unknown];
278
279
  return new Map([[arg, new Set(values)]]);
279
280
  }
280
281
  }
@@ -10,6 +10,7 @@ const linter_rules_1 = require("../../../linter/linter-rules");
10
10
  const linter_format_1 = require("../../../linter/linter-format");
11
11
  const ansi_1 = require("../../../util/text/ansi");
12
12
  const time_1 = require("../../../util/text/time");
13
+ const doc_code_1 = require("../../../documentation/doc-util/doc-code");
13
14
  exports.LinterQueryDefinition = {
14
15
  executor: linter_query_executor_1.executeLinterQuery,
15
16
  asciiSummarizer: (formatter, _processed, queryResults, result) => {
@@ -27,7 +28,7 @@ exports.LinterQueryDefinition = {
27
28
  }
28
29
  }
29
30
  }
30
- result.push(` ╰ Metadata: ${JSON.stringify(results['.meta'])}`);
31
+ result.push(` ╰ _Metadata_: ${(0, doc_code_1.codeInline)(JSON.stringify(results['.meta']))}`);
31
32
  }
32
33
  return true;
33
34
  },
@@ -4,7 +4,7 @@ exports.fingerPrintOfQuery = fingerPrintOfQuery;
4
4
  exports.executeResolveValueQuery = executeResolveValueQuery;
5
5
  const log_1 = require("../../../util/log");
6
6
  const parse_1 = require("../../../slicing/criterion/parse");
7
- const resolve_by_name_1 = require("../../../dataflow/environments/resolve-by-name");
7
+ const alias_tracking_1 = require("../../../dataflow/eval/resolve/alias-tracking");
8
8
  function fingerPrintOfQuery(query) {
9
9
  return JSON.stringify(query);
10
10
  }
@@ -18,9 +18,9 @@ function executeResolveValueQuery({ dataflow: { graph }, ast }, queries) {
18
18
  }
19
19
  const values = query.criteria
20
20
  .map(criteria => (0, parse_1.slicingCriterionToId)(criteria, ast.idMap))
21
- .flatMap(ident => (0, resolve_by_name_1.resolveIdToValue)(ident, { graph, full: true, idMap: ast.idMap }) ?? []);
21
+ .flatMap(ident => (0, alias_tracking_1.resolveIdToValue)(ident, { graph, full: true, idMap: ast.idMap }));
22
22
  results[key] = {
23
- values: values ? [...new Set(values)] : []
23
+ values: values
24
24
  };
25
25
  }
26
26
  return {
@@ -2,6 +2,7 @@ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
2
  import type { SlicingCriteria } from '../../../slicing/criterion/parse';
3
3
  import Joi from 'joi';
4
4
  import { executeResolveValueQuery } from './resolve-value-query-executor';
5
+ import type { ResolveResult } from '../../../dataflow/eval/resolve/alias-tracking';
5
6
  export interface ResolveValueQuery extends BaseQueryFormat {
6
7
  readonly type: 'resolve-value';
7
8
  /** The slicing criteria to use */
@@ -9,7 +10,7 @@ export interface ResolveValueQuery extends BaseQueryFormat {
9
10
  }
10
11
  export interface ResolveValueQueryResult extends BaseQueryResult {
11
12
  results: Record<string, {
12
- values: unknown[];
13
+ values: ResolveResult[];
13
14
  }>;
14
15
  }
15
16
  export declare const ResolveValueQueryDefinition: {
@@ -8,27 +8,7 @@ const ansi_1 = require("../../../util/text/ansi");
8
8
  const time_1 = require("../../../util/text/time");
9
9
  const joi_1 = __importDefault(require("joi"));
10
10
  const resolve_value_query_executor_1 = require("./resolve-value-query-executor");
11
- function rValueToAscii(value) {
12
- if (value === null || value === undefined) {
13
- return 'undefined';
14
- }
15
- else if (typeof value === 'string') {
16
- return value;
17
- }
18
- else if (typeof value === 'object') {
19
- if ('num' in value) {
20
- return value.num.toString();
21
- }
22
- else if ('str' in value) {
23
- return `${value.quotes}${value.str}${value.quotes}`;
24
- }
25
- else {
26
- console.warn('omega lul');
27
- return JSON.stringify(value);
28
- }
29
- }
30
- return value;
31
- }
11
+ const r_value_1 = require("../../../dataflow/eval/values/r-value");
32
12
  exports.ResolveValueQueryDefinition = {
33
13
  executor: resolve_value_query_executor_1.executeResolveValueQuery,
34
14
  asciiSummarizer: (formatter, _processed, queryResults, result) => {
@@ -37,7 +17,7 @@ exports.ResolveValueQueryDefinition = {
37
17
  for (const [fingerprint, obj] of Object.entries(out.results)) {
38
18
  const { criteria } = JSON.parse(fingerprint);
39
19
  result.push(` ╰ Values for {${criteria.join(', ')}}`);
40
- result.push(` ╰ ${obj.values.map(v => rValueToAscii(v)).join(', ')}`);
20
+ result.push(` ╰ ${obj.values.map(v => (0, r_value_1.stringifyValue)(v)).join(', ')}`);
41
21
  }
42
22
  return true;
43
23
  },
@@ -23,7 +23,8 @@ import type { ProjectQuery } from './catalog/project-query/project-query-format'
23
23
  import type { OriginQuery } from './catalog/origin-query/origin-query-format';
24
24
  import type { LinterQuery } from './catalog/linter-query/linter-query-format';
25
25
  import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
26
- export type Query = CallContextQuery | ConfigQuery | SearchQuery | DataflowQuery | DataflowLensQuery | NormalizedAstQuery | IdMapQuery | DataflowClusterQuery | StaticSliceQuery | LineageQuery | DependenciesQuery | LocationMapQuery | HappensBeforeQuery | ResolveValueQuery | ProjectQuery | OriginQuery | LinterQuery;
26
+ import type { ControlFlowQuery } from './catalog/control-flow-query/control-flow-query-format';
27
+ export type Query = CallContextQuery | ConfigQuery | SearchQuery | DataflowQuery | ControlFlowQuery | DataflowLensQuery | NormalizedAstQuery | IdMapQuery | DataflowClusterQuery | StaticSliceQuery | LineageQuery | DependenciesQuery | LocationMapQuery | HappensBeforeQuery | ResolveValueQuery | ProjectQuery | OriginQuery | LinterQuery;
27
28
  export type QueryArgumentsWithType<QueryType extends BaseQueryFormat['type']> = Query & {
28
29
  type: QueryType;
29
30
  };
@@ -54,6 +55,65 @@ export declare const SupportedQueries: {
54
55
  readonly schema: Joi.ObjectSchema<any>;
55
56
  readonly flattenInvolvedNodes: () => never[];
56
57
  };
58
+ readonly 'control-flow': {
59
+ readonly executor: typeof import("./catalog/control-flow-query/control-flow-query-executor").executeControlFlowQuery;
60
+ readonly asciiSummarizer: (formatter: OutputFormatter, processed: PipelineOutput<import("../core/steps/pipeline/pipeline").Pipeline<{
61
+ readonly name: "parse";
62
+ readonly humanReadableName: "parse with R shell";
63
+ readonly description: "Parse the given R code into an AST";
64
+ readonly processor: (_results: unknown, input: Partial<import("../r-bridge/parser").ParseRequiredInput<string>>) => Promise<import("../r-bridge/parser").ParseStepOutput<string>>;
65
+ readonly executed: import("../core/steps/pipeline-step").PipelineStepStage.OncePerFile;
66
+ readonly printer: {
67
+ readonly 0: typeof import("../core/print/print").internalPrinter;
68
+ readonly 2: {
69
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
70
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
71
+ };
72
+ readonly 5: ({ parsed }: import("../r-bridge/parser").ParseStepOutput<string>, config: import("../util/quads").QuadSerializationConfiguration) => string;
73
+ };
74
+ readonly dependencies: readonly [];
75
+ readonly requiredInput: import("../r-bridge/parser").ParseRequiredInput<string>;
76
+ } | {
77
+ readonly name: "normalize";
78
+ readonly humanReadableName: "normalize";
79
+ readonly description: "Normalize the AST to flowR's AST";
80
+ readonly processor: (results: {
81
+ parse?: import("../r-bridge/parser").ParseStepOutput<string>;
82
+ }, input: Partial<import("../core/steps/all/core/10-normalize").NormalizeRequiredInput>) => import("../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../r-bridge/lang-4.x/ast/model/model").RNode<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
83
+ readonly executed: import("../core/steps/pipeline-step").PipelineStepStage.OncePerFile;
84
+ readonly printer: {
85
+ readonly 0: typeof import("../core/print/print").internalPrinter;
86
+ readonly 2: typeof import("../core/print/normalize-printer").normalizedAstToJson;
87
+ readonly 5: typeof import("../core/print/normalize-printer").normalizedAstToQuads;
88
+ readonly 3: typeof import("../core/print/normalize-printer").printNormalizedAstToMermaid;
89
+ readonly 4: typeof import("../core/print/normalize-printer").printNormalizedAstToMermaidUrl;
90
+ };
91
+ readonly dependencies: readonly ["parse"];
92
+ readonly requiredInput: import("../core/steps/all/core/10-normalize").NormalizeRequiredInput;
93
+ } | {
94
+ readonly humanReadableName: "dataflow";
95
+ readonly processor: (results: {
96
+ normalize?: import("../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
97
+ }, input: {
98
+ request?: import("../r-bridge/retriever").RParseRequests;
99
+ parser?: import("../r-bridge/parser").Parser<import("../r-bridge/parser").KnownParserType>;
100
+ }) => import("../dataflow/info").DataflowInformation;
101
+ readonly requiredInput: {};
102
+ readonly name: "dataflow";
103
+ readonly description: "Construct the dataflow graph";
104
+ readonly executed: import("../core/steps/pipeline-step").PipelineStepStage.OncePerFile;
105
+ readonly printer: {
106
+ readonly 0: typeof import("../core/print/print").internalPrinter;
107
+ readonly 2: typeof import("../core/print/dataflow-printer").dataflowGraphToJson;
108
+ readonly 5: typeof import("../core/print/dataflow-printer").dataflowGraphToQuads;
109
+ readonly 3: typeof import("../core/print/dataflow-printer").dataflowGraphToMermaid;
110
+ readonly 4: typeof import("../core/print/dataflow-printer").dataflowGraphToMermaidUrl;
111
+ };
112
+ readonly dependencies: readonly ["normalize"];
113
+ }>>, queryResults: BaseQueryResult, result: string[]) => true;
114
+ readonly schema: Joi.ObjectSchema<any>;
115
+ readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
116
+ };
57
117
  readonly dataflow: {
58
118
  readonly executor: typeof import("./catalog/dataflow-query/dataflow-query-executor").executeDataflowQuery;
59
119
  readonly asciiSummarizer: (formatter: OutputFormatter, _processed: PipelineOutput<import("../core/steps/pipeline/pipeline").Pipeline<{
package/queries/query.js CHANGED
@@ -30,9 +30,11 @@ const dataflow_lens_query_format_1 = require("./catalog/dataflow-lens-query/data
30
30
  const project_query_format_1 = require("./catalog/project-query/project-query-format");
31
31
  const origin_query_format_1 = require("./catalog/origin-query/origin-query-format");
32
32
  const linter_query_format_1 = require("./catalog/linter-query/linter-query-format");
33
+ const control_flow_query_format_1 = require("./catalog/control-flow-query/control-flow-query-format");
33
34
  exports.SupportedQueries = {
34
35
  'call-context': call_context_query_format_1.CallContextQueryDefinition,
35
36
  'config': config_query_format_1.ConfigQueryDefinition,
37
+ 'control-flow': control_flow_query_format_1.ControlFlowQueryDefinition,
36
38
  'dataflow': dataflow_query_format_1.DataflowQueryDefinition,
37
39
  'dataflow-lens': dataflow_lens_query_format_1.DataflowLensQueryDefinition,
38
40
  'id-map': id_map_query_format_1.IdMapQueryDefinition,
@@ -293,13 +293,20 @@ function convertTreeNode(node) {
293
293
  ...defaultInfo
294
294
  };
295
295
  }
296
- const args = (0, arrays_1.splitArrayOn)(nonErrorChildren(argsParentheses).slice(1, -1), x => x.type === 'comma');
296
+ const rawArgs = nonErrorChildren(argsParentheses);
297
+ const [comments, noCommentrawArgs] = splitComments(rawArgs);
298
+ const args = (0, arrays_1.splitArrayOn)(noCommentrawArgs.slice(1, -1), x => x.type === 'comma');
297
299
  const funcRange = makeSourceRange(func);
300
+ const mappedArgs = args.map(n => n.length == 0 ? r_function_call_1.EmptyArgument : convertTreeNode(n[0]));
298
301
  const call = {
299
- arguments: args.map(n => n.length == 0 ? r_function_call_1.EmptyArgument : convertTreeNode(n[0])),
302
+ arguments: mappedArgs,
300
303
  location: funcRange,
301
304
  lexeme: func.text,
302
- ...defaultInfo
305
+ ...defaultInfo,
306
+ info: {
307
+ ...defaultInfo.info,
308
+ additionalTokens: comments.map(c => c[1]),
309
+ }
303
310
  };
304
311
  if (func.type === tree_sitter_types_1.TreeSitterType.Identifier || func.type === tree_sitter_types_1.TreeSitterType.String || func.type === tree_sitter_types_1.TreeSitterType.NamespaceOperator || func.type === tree_sitter_types_1.TreeSitterType.Return) {
305
312
  let funcNode = convertTreeNode(func);
@@ -491,7 +498,7 @@ function convertTreeNode(node) {
491
498
  const nameRange = makeSourceRange(nameNode);
492
499
  return {
493
500
  type: type_1.RType.Argument,
494
- name: name,
501
+ name,
495
502
  value: valueNode ? convertTreeNode(valueNode) : undefined,
496
503
  location: nameRange,
497
504
  lexeme: nameNode.text,
@@ -4,11 +4,11 @@ exports.Enrichments = exports.Enrichment = void 0;
4
4
  exports.enrichmentContent = enrichmentContent;
5
5
  exports.enrich = enrich;
6
6
  const vertex_1 = require("../../dataflow/graph/vertex");
7
- const log_1 = require("../../util/log");
8
7
  const identify_link_to_last_call_relation_1 = require("../../queries/catalog/call-context-query/identify-link-to-last-call-relation");
9
8
  const assert_1 = require("../../util/assert");
10
9
  const extract_cfg_1 = require("../../control-flow/extract-cfg");
11
10
  const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin");
11
+ const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
12
12
  /**
13
13
  * An enumeration that stores the names of the available enrichments that can be applied to a set of search elements.
14
14
  * See {@link FlowrSearchBuilder.with} for more information on how to apply enrichments.
@@ -31,7 +31,7 @@ exports.Enrichments = {
31
31
  if (callVertex?.tag === vertex_1.VertexType.FunctionCall) {
32
32
  const origins = (0, dfg_get_origin_1.getOriginInDfg)(data.dataflow.graph, callVertex.id);
33
33
  if (!origins || origins.length === 0) {
34
- log_1.log.warn(`No origin found for call vertex ${callVertex.id}, cannot resolve call targets.`);
34
+ content.targets = [(0, node_id_1.recoverName)(callVertex.id, data.normalize.idMap)];
35
35
  return content;
36
36
  }
37
37
  // find call targets in user code (which have ids!)
@@ -47,6 +47,9 @@ exports.Enrichments = {
47
47
  return undefined;
48
48
  }
49
49
  }).filter(assert_1.isNotUndefined));
50
+ if (content.targets.length === 0) {
51
+ content.targets = [(0, node_id_1.recoverName)(callVertex.id, data.normalize.idMap)];
52
+ }
50
53
  }
51
54
  return content;
52
55
  },
@@ -11,8 +11,16 @@ export declare class CriteriaParseError extends Error {
11
11
  }
12
12
  /**
13
13
  * Takes a criterion in the form of `line:column` or `line@variable-name` and returns the corresponding node id
14
+ *
15
+ * @see {@link tryResolveSliceCriterionToId} for a version that does not throw an error
14
16
  */
15
17
  export declare function slicingCriterionToId(criterion: SingleSlicingCriterion, idMap: AstIdMap): NodeId;
18
+ /**
19
+ * Tries to resolve a slicing criterion to an id, but does not throw an error if it fails.
20
+ *
21
+ * @see {@link slicingCriterionToId} for the version that throws an error
22
+ */
23
+ export declare function tryResolveSliceCriterionToId(criterion: string | NodeId, idMap: AstIdMap): NodeId | undefined;
16
24
  export interface DecodedCriterion {
17
25
  criterion: SingleSlicingCriterion;
18
26
  id: NodeId;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CriteriaParseError = void 0;
4
4
  exports.slicingCriterionToId = slicingCriterionToId;
5
+ exports.tryResolveSliceCriterionToId = tryResolveSliceCriterionToId;
5
6
  exports.convertAllSlicingCriteriaToIds = convertAllSlicingCriteriaToIds;
6
7
  const log_1 = require("../../util/log");
7
8
  const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
@@ -19,6 +20,8 @@ class CriteriaParseError extends Error {
19
20
  exports.CriteriaParseError = CriteriaParseError;
20
21
  /**
21
22
  * Takes a criterion in the form of `line:column` or `line@variable-name` and returns the corresponding node id
23
+ *
24
+ * @see {@link tryResolveSliceCriterionToId} for a version that does not throw an error
22
25
  */
23
26
  function slicingCriterionToId(criterion, idMap) {
24
27
  let resolved;
@@ -38,6 +41,23 @@ function slicingCriterionToId(criterion, idMap) {
38
41
  }
39
42
  return resolved;
40
43
  }
44
+ /**
45
+ * Tries to resolve a slicing criterion to an id, but does not throw an error if it fails.
46
+ *
47
+ * @see {@link slicingCriterionToId} for the version that throws an error
48
+ */
49
+ function tryResolveSliceCriterionToId(criterion, idMap) {
50
+ try {
51
+ return slicingCriterionToId(criterion, idMap);
52
+ }
53
+ catch (e) {
54
+ if (e instanceof CriteriaParseError) {
55
+ (0, log_1.expensiveTrace)(static_slicer_1.slicerLogger, () => `could not resolve slicing criterion ${criterion}: ${e.message}`);
56
+ return undefined;
57
+ }
58
+ throw e; // rethrow other errors
59
+ }
60
+ }
41
61
  function locationToId(location, dataflowIdMap) {
42
62
  let candidate;
43
63
  for (const [id, nodeInfo] of dataflowIdMap.entries()) {
package/util/version.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.flowrVersion = flowrVersion;
4
4
  const semver_1 = require("semver");
5
5
  // this is automatically replaced with the current version by release-it
6
- const version = '2.2.14';
6
+ const version = '2.2.15';
7
7
  function flowrVersion() {
8
8
  return new semver_1.SemVer(version);
9
9
  }