@eagleoutice/flowr 2.9.2 → 2.9.4

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 (73) hide show
  1. package/README.md +18 -18
  2. package/cli/flowr.js +4 -2
  3. package/control-flow/basic-cfg-guided-visitor.js +10 -4
  4. package/control-flow/cfg-dead-code.js +6 -3
  5. package/control-flow/control-flow-graph.js +3 -2
  6. package/control-flow/simple-visitor.d.ts +2 -1
  7. package/control-flow/simple-visitor.js +6 -7
  8. package/core/print/slice-diff-ansi.js +3 -3
  9. package/dataflow/environments/built-in.d.ts +10 -1
  10. package/dataflow/environments/environment.js +12 -7
  11. package/dataflow/eval/resolve/alias-tracking.d.ts +8 -8
  12. package/dataflow/eval/resolve/alias-tracking.js +33 -34
  13. package/dataflow/eval/resolve/resolve.d.ts +7 -41
  14. package/dataflow/eval/resolve/resolve.js +24 -54
  15. package/dataflow/extractor.js +2 -2
  16. package/dataflow/fn/higher-order-function.d.ts +2 -1
  17. package/dataflow/fn/higher-order-function.js +5 -4
  18. package/dataflow/graph/graph.js +7 -12
  19. package/dataflow/internal/process/functions/call/argument/make-argument.js +1 -2
  20. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +2 -2
  21. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -2
  22. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +2 -2
  23. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +1 -1
  24. package/documentation/doc-util/doc-search.js +2 -2
  25. package/linter/linter-executor.js +1 -2
  26. package/linter/linter-format.d.ts +37 -11
  27. package/linter/linter-format.js +59 -16
  28. package/linter/linter-rules.d.ts +8 -23
  29. package/linter/rules/absolute-path.d.ts +2 -2
  30. package/linter/rules/absolute-path.js +6 -7
  31. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  32. package/linter/rules/dataframe-access-validation.js +3 -4
  33. package/linter/rules/dead-code.d.ts +2 -2
  34. package/linter/rules/dead-code.js +5 -6
  35. package/linter/rules/deprecated-functions.d.ts +4 -7
  36. package/linter/rules/file-path-validity.d.ts +2 -2
  37. package/linter/rules/file-path-validity.js +9 -6
  38. package/linter/rules/function-finder-util.d.ts +8 -11
  39. package/linter/rules/function-finder-util.js +21 -12
  40. package/linter/rules/naming-convention.d.ts +4 -11
  41. package/linter/rules/naming-convention.js +10 -10
  42. package/linter/rules/network-functions.d.ts +5 -8
  43. package/linter/rules/network-functions.js +14 -1
  44. package/linter/rules/seeded-randomness.d.ts +3 -3
  45. package/linter/rules/seeded-randomness.js +5 -5
  46. package/linter/rules/unused-definition.d.ts +2 -2
  47. package/linter/rules/unused-definition.js +13 -14
  48. package/linter/rules/useless-loop.d.ts +3 -3
  49. package/linter/rules/useless-loop.js +4 -4
  50. package/package.json +1 -1
  51. package/project/plugins/file-plugins/files/flowr-namespace-file.js +2 -2
  52. package/queries/catalog/does-call-query/does-call-query-format.js +2 -2
  53. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +5 -4
  54. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +6 -1
  55. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
  56. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +5 -4
  57. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +4 -3
  58. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  59. package/queries/catalog/linter-query/linter-query-format.js +13 -9
  60. package/queries/query.d.ts +1 -1
  61. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.d.ts +1 -1
  62. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.js +2 -2
  63. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +1 -1
  64. package/r-bridge/roxygen2/roxygen-parse.js +1 -1
  65. package/statistics/features/supported/defined-functions/defined-functions.d.ts +1 -1
  66. package/statistics/features/supported/defined-functions/defined-functions.js +4 -4
  67. package/statistics/features/supported/used-functions/used-functions.js +3 -3
  68. package/statistics/features/supported/variables/variables.js +4 -4
  69. package/util/mermaid/dfg.d.ts +0 -5
  70. package/util/mermaid/dfg.js +2 -19
  71. package/util/range.d.ts +137 -54
  72. package/util/range.js +249 -88
  73. package/util/version.js +1 -1
@@ -1,81 +1,47 @@
1
- import type { AstIdMap, RNodeWithParent } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
2
- import type { REnvironmentInformation } from '../../environments/environment';
3
- import type { DataflowGraph } from '../../graph/graph';
1
+ import type { BuiltInEvalHandlerArgs } from '../../environments/built-in';
4
2
  import { type Lift, Top, type Value, type ValueNumber, type ValueVector } from '../values/r-value';
5
- import type { VariableResolve } from '../../../config';
6
- import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';
7
3
  /**
8
4
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
9
5
  * you want to resolve the value of an identifier / node
10
6
  *
11
7
  * This function converts an RNode to its Value, but also recursively resolves
12
- * aliases and vectors (in case of a vector).
13
- * @param a - Ast node to resolve
14
- * @param resolve - Variable resolve mode
15
- * @param ctx - Analyzer context
16
- * @param env - Environment to use
17
- * @param graph - Dataflow Graph to use
18
- * @param map - Idmap of Dataflow Graph
8
+ * aliases and vectors (in case of node vector).
19
9
  * @returns resolved value or top/bottom
20
10
  */
21
- export declare function resolveNode(resolve: VariableResolve, a: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, env?: REnvironmentInformation, graph?: DataflowGraph, map?: AstIdMap): Value;
11
+ export declare function resolveNode({ resolve, node, ctx, blocked, environment, graph, idMap }: BuiltInEvalHandlerArgs): Value;
22
12
  /**
23
13
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
24
14
  * you want to resolve the value of an identifier / node
25
15
  *
26
16
  * This function resolves a vector function call `c` to a {@link ValueVector}
27
17
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
28
- * @param resolve - Variable resolve mode
29
- * @param node - Node of the vector function to resolve
30
- * @param environment - Environment to use
31
- * @param ctx - Analyzer context
32
- * @param graph - Dataflow graph
33
- * @param idMap - ID map of the dataflow graph
34
18
  * @returns ValueVector or Top
35
19
  */
36
- export declare function resolveAsVector(resolve: VariableResolve, node: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueVector<Lift<Value[]>> | typeof Top;
20
+ export declare function resolveAsVector({ resolve, environment, node, graph, idMap, ctx, blocked }: BuiltInEvalHandlerArgs): ValueVector | typeof Top;
37
21
  /**
38
22
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
39
23
  * you want to resolve the value of an identifier / node
40
24
  *
41
25
  * This function resolves a binary sequence operator `:` to a {@link ValueVector} of {@link ValueNumber}s
42
26
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
43
- * @param resolve - Variable resolve mode
44
- * @param operator - Node of the sequence operator to resolve
45
- * @param graph - Dataflow graph
46
- * @param ctx - Analyzer context
47
- * @param idMap - Id map of the dataflow graph
48
- * @param environment - Environment to use
49
27
  * @returns ValueVector of ValueNumbers or Top
50
28
  */
51
- export declare function resolveAsSeq(resolve: VariableResolve, operator: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueVector<Lift<ValueNumber[]>> | typeof Top;
29
+ export declare function resolveAsSeq({ node: operator, environment, resolve, ctx, graph, idMap, blocked }: BuiltInEvalHandlerArgs): ValueVector<Lift<ValueNumber[]>> | typeof Top;
52
30
  /**
53
31
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
54
32
  * you want to resolve the value of an identifier / node
55
33
  *
56
34
  * This function resolves a unary plus operator `+` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
57
35
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
58
- * @param resolve - Variable resolve mode
59
- * @param operator - Node of the plus operator to resolve
60
- * @param graph - Dataflow graph
61
- * @param ctx - Analyzer context
62
- * @param idMap - Id map of the dataflow graph
63
- * @param environment - Environment to use
64
36
  * @returns ValueNumber, ValueVector of ValueNumbers, or Top
65
37
  */
66
- export declare function resolveAsPlus(resolve: VariableResolve, operator: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
38
+ export declare function resolveAsPlus({ node: operator, environment, resolve, ctx, graph, idMap, blocked }: BuiltInEvalHandlerArgs): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
67
39
  /**
68
40
  * Helper function used by {@link resolveIdToValue}, please use that instead, if
69
41
  * you want to resolve the value of an identifier / node
70
42
  *
71
43
  * This function resolves a unary minus operator `-` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
72
44
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
73
- * @param resolve - Variable resolve mode
74
- * @param operator - Node of the minus operator to resolve
75
- * @param graph - Dataflow graph
76
- * @param ctx - Analyzer context
77
- * @param idMap - Id map of the dataflow graph
78
- * @param environment - Environment to use
79
45
  * @returns ValueNumber, ValueVector of ValueNumbers, or Top
80
46
  */
81
- export declare function resolveAsMinus(resolve: VariableResolve, operator: RNodeWithParent, ctx: ReadOnlyFlowrAnalyzerContext, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
47
+ export declare function resolveAsMinus({ node: operator, environment, resolve, ctx, graph, idMap, blocked }: BuiltInEvalHandlerArgs): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
@@ -23,30 +23,24 @@ const identifier_1 = require("../../environments/identifier");
23
23
  * you want to resolve the value of an identifier / node
24
24
  *
25
25
  * This function converts an RNode to its Value, but also recursively resolves
26
- * aliases and vectors (in case of a vector).
27
- * @param a - Ast node to resolve
28
- * @param resolve - Variable resolve mode
29
- * @param ctx - Analyzer context
30
- * @param env - Environment to use
31
- * @param graph - Dataflow Graph to use
32
- * @param map - Idmap of Dataflow Graph
26
+ * aliases and vectors (in case of node vector).
33
27
  * @returns resolved value or top/bottom
34
28
  */
35
- function resolveNode(resolve, a, ctx, env, graph, map) {
36
- if (a.type === type_1.RType.String) {
37
- return (0, string_constants_1.stringFrom)(a.content.str);
29
+ function resolveNode({ resolve, node, ctx, blocked, environment, graph, idMap }) {
30
+ if (node.type === type_1.RType.String) {
31
+ return (0, string_constants_1.stringFrom)(node.content.str);
38
32
  }
39
- else if (a.type === type_1.RType.Number) {
40
- return (0, interval_constants_1.intervalFrom)(a.content.num, a.content.num);
33
+ else if (node.type === type_1.RType.Number) {
34
+ return (0, interval_constants_1.intervalFrom)(node.content.num, node.content.num);
41
35
  }
42
- else if (a.type === type_1.RType.Logical) {
43
- return a.content.valueOf() ? logical_constants_1.ValueLogicalTrue : logical_constants_1.ValueLogicalFalse;
36
+ else if (node.type === type_1.RType.Logical) {
37
+ return node.content.valueOf() ? logical_constants_1.ValueLogicalTrue : logical_constants_1.ValueLogicalFalse;
44
38
  }
45
- else if (a.type === type_1.RType.FunctionDefinition) {
39
+ else if (node.type === type_1.RType.FunctionDefinition) {
46
40
  return { type: 'function-definition' };
47
41
  }
48
- else if ((a.type === type_1.RType.FunctionCall || a.type === type_1.RType.BinaryOp || a.type === type_1.RType.UnaryOp) && graph) {
49
- const origin = (0, dfg_get_origin_1.getOriginInDfg)(graph, a.info.id)?.[0];
42
+ else if ((node.type === type_1.RType.FunctionCall || node.type === type_1.RType.BinaryOp || node.type === type_1.RType.UnaryOp) && graph) {
43
+ const origin = (0, dfg_get_origin_1.getOriginInDfg)(graph, node.info.id)?.[0];
50
44
  if (origin === undefined || origin.type !== 3 /* OriginType.BuiltInFunctionOrigin */) {
51
45
  return r_value_2.Top;
52
46
  }
@@ -54,18 +48,18 @@ function resolveNode(resolve, a, ctx, env, graph, map) {
54
48
  if ((0, built_in_1.isBuiltIn)(origin.proc)) {
55
49
  builtInName = origin.proc;
56
50
  }
57
- else if (a.type === type_1.RType.FunctionCall && a.named) {
58
- builtInName = (0, built_in_1.builtInId)(identifier_1.Identifier.getName(a.functionName.content));
51
+ else if (node.type === type_1.RType.FunctionCall && node.named) {
52
+ builtInName = (0, built_in_1.builtInId)(identifier_1.Identifier.getName(node.functionName.content));
59
53
  }
60
- else if (a.type === type_1.RType.BinaryOp || a.type === type_1.RType.UnaryOp) {
61
- builtInName = (0, built_in_1.builtInId)(a.operator);
54
+ else if (node.type === type_1.RType.BinaryOp || node.type === type_1.RType.UnaryOp) {
55
+ builtInName = (0, built_in_1.builtInId)(node.operator);
62
56
  }
63
57
  else {
64
58
  return r_value_2.Top;
65
59
  }
66
60
  if (Object.hasOwn(built_in_1.BuiltInEvalHandlerMapper, builtInName)) {
67
61
  const handler = built_in_1.BuiltInEvalHandlerMapper[builtInName];
68
- return handler(resolve, a, ctx, env, graph, map);
62
+ return handler({ resolve, node, ctx, blocked, environment, graph, idMap });
69
63
  }
70
64
  }
71
65
  return r_value_2.Top;
@@ -76,19 +70,13 @@ function resolveNode(resolve, a, ctx, env, graph, map) {
76
70
  *
77
71
  * This function resolves a vector function call `c` to a {@link ValueVector}
78
72
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
79
- * @param resolve - Variable resolve mode
80
- * @param node - Node of the vector function to resolve
81
- * @param environment - Environment to use
82
- * @param ctx - Analyzer context
83
- * @param graph - Dataflow graph
84
- * @param idMap - ID map of the dataflow graph
85
73
  * @returns ValueVector or Top
86
74
  */
87
- function resolveAsVector(resolve, node, ctx, environment, graph, idMap) {
75
+ function resolveAsVector({ resolve, environment, node, graph, idMap, ctx, blocked }) {
88
76
  if (node.type !== type_1.RType.FunctionCall) {
89
77
  return r_value_2.Top;
90
78
  }
91
- const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx };
79
+ const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx, blocked };
92
80
  const values = node.arguments.map(arg => arg !== r_function_call_1.EmptyArgument ? (0, alias_tracking_1.resolveIdToValue)(arg.value, resolveInfo) : r_value_2.Top);
93
81
  return (0, vector_constants_1.vectorFrom)((0, vector_constants_1.flattenVectorElements)(values));
94
82
  }
@@ -98,19 +86,13 @@ function resolveAsVector(resolve, node, ctx, environment, graph, idMap) {
98
86
  *
99
87
  * This function resolves a binary sequence operator `:` to a {@link ValueVector} of {@link ValueNumber}s
100
88
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
101
- * @param resolve - Variable resolve mode
102
- * @param operator - Node of the sequence operator to resolve
103
- * @param graph - Dataflow graph
104
- * @param ctx - Analyzer context
105
- * @param idMap - Id map of the dataflow graph
106
- * @param environment - Environment to use
107
89
  * @returns ValueVector of ValueNumbers or Top
108
90
  */
109
- function resolveAsSeq(resolve, operator, ctx, environment, graph, idMap) {
91
+ function resolveAsSeq({ node: operator, environment, resolve, ctx, graph, idMap, blocked }) {
110
92
  if (operator.type !== type_1.RType.BinaryOp) {
111
93
  return r_value_2.Top;
112
94
  }
113
- const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx };
95
+ const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx, blocked };
114
96
  const leftArg = (0, alias_tracking_1.resolveIdToValue)(operator.lhs, resolveInfo);
115
97
  const rightArg = (0, alias_tracking_1.resolveIdToValue)(operator.rhs, resolveInfo);
116
98
  const leftValue = (0, r_value_1.unliftRValue)(leftArg);
@@ -126,19 +108,13 @@ function resolveAsSeq(resolve, operator, ctx, environment, graph, idMap) {
126
108
  *
127
109
  * This function resolves a unary plus operator `+` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
128
110
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
129
- * @param resolve - Variable resolve mode
130
- * @param operator - Node of the plus operator to resolve
131
- * @param graph - Dataflow graph
132
- * @param ctx - Analyzer context
133
- * @param idMap - Id map of the dataflow graph
134
- * @param environment - Environment to use
135
111
  * @returns ValueNumber, ValueVector of ValueNumbers, or Top
136
112
  */
137
- function resolveAsPlus(resolve, operator, ctx, environment, graph, idMap) {
113
+ function resolveAsPlus({ node: operator, environment, resolve, ctx, graph, idMap, blocked }) {
138
114
  if (operator.type !== type_1.RType.UnaryOp) {
139
115
  return r_value_2.Top;
140
116
  }
141
- const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx };
117
+ const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx, blocked };
142
118
  const arg = (0, alias_tracking_1.resolveIdToValue)(operator.operand, resolveInfo);
143
119
  const argValue = (0, r_value_1.unliftRValue)(arg);
144
120
  if ((0, r_value_1.isRNumberValue)(argValue)) {
@@ -155,19 +131,13 @@ function resolveAsPlus(resolve, operator, ctx, environment, graph, idMap) {
155
131
  *
156
132
  * This function resolves a unary minus operator `-` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
157
133
  * by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
158
- * @param resolve - Variable resolve mode
159
- * @param operator - Node of the minus operator to resolve
160
- * @param graph - Dataflow graph
161
- * @param ctx - Analyzer context
162
- * @param idMap - Id map of the dataflow graph
163
- * @param environment - Environment to use
164
134
  * @returns ValueNumber, ValueVector of ValueNumbers, or Top
165
135
  */
166
- function resolveAsMinus(resolve, operator, ctx, environment, graph, idMap) {
136
+ function resolveAsMinus({ node: operator, environment, resolve, ctx, graph, idMap, blocked }) {
167
137
  if (operator.type !== type_1.RType.UnaryOp) {
168
138
  return r_value_2.Top;
169
139
  }
170
- const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx };
140
+ const resolveInfo = { environment, graph, idMap, full: true, resolve, ctx, blocked };
171
141
  const arg = (0, alias_tracking_1.resolveIdToValue)(operator.operand, resolveInfo);
172
142
  const argValue = (0, r_value_1.unliftRValue)(arg);
173
143
  if ((0, r_value_1.isRNumberValue)(argValue)) {
@@ -12,7 +12,6 @@ const process_named_call_1 = require("./internal/process/process-named-call");
12
12
  const process_value_1 = require("./internal/process/process-value");
13
13
  const named_call_handling_1 = require("./internal/process/functions/call/named-call-handling");
14
14
  const make_argument_1 = require("./internal/process/functions/call/argument/make-argument");
15
- const range_1 = require("../util/range");
16
15
  const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
17
16
  const built_in_source_1 = require("./internal/process/functions/call/built-in/built-in-source");
18
17
  const extract_cfg_1 = require("../control-flow/extract-cfg");
@@ -21,6 +20,7 @@ const identify_link_to_last_call_relation_1 = require("../queries/catalog/call-c
21
20
  const built_in_function_definition_1 = require("./internal/process/functions/call/built-in/built-in-function-definition");
22
21
  const flowr_file_1 = require("../project/context/flowr-file");
23
22
  const identifier_1 = require("./environments/identifier");
23
+ const range_1 = require("../util/range");
24
24
  /**
25
25
  * The best friend of {@link produceDataFlowGraph} and {@link processDataflowFor}.
26
26
  * Maps every {@link RType} in the normalized AST to a processor.
@@ -53,7 +53,7 @@ exports.processors = {
53
53
  info: info,
54
54
  content: groupStart?.content ?? '{',
55
55
  lexeme: groupStart?.lexeme ?? '{',
56
- location: location ?? (0, range_1.invalidRange)(),
56
+ location: location ?? range_1.SourceRange.invalid(),
57
57
  ns: groupStart?.content ? undefined : 'base'
58
58
  }, (0, make_argument_1.wrapArgumentsUnnamed)(children, d.completeAst.idMap), info.id, d);
59
59
  }
@@ -6,5 +6,6 @@ import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-a
6
6
  * either takes a function as an argument or (may) returns a function.
7
7
  * If the return is an identity, e.g., `function(x) x`, this is not considered higher-order,
8
8
  * if no function is passed as an argument.
9
+ * Please note that inspecting higher order functions can be sped up (if queries multiple times) by providing an inverted graph as well!
9
10
  */
10
- export declare function isFunctionHigherOrder(id: NodeId, graph: DataflowGraph, ctx: ReadOnlyFlowrAnalyzerContext): boolean;
11
+ export declare function isFunctionHigherOrder(id: NodeId, graph: DataflowGraph, ctx: ReadOnlyFlowrAnalyzerContext, invertedGraph?: DataflowGraph): boolean;
@@ -32,8 +32,8 @@ function isAnyReturnAFunction(def, graph) {
32
32
  }
33
33
  return false;
34
34
  }
35
- function inspectCallSitesArgumentsFns(def, graph, ctx) {
36
- const callSites = graph.ingoingEdges(def.id);
35
+ function inspectCallSitesArgumentsFns(def, graph, ctx, invertedGraph) {
36
+ const callSites = invertedGraph?.outgoingEdges(def.id) ?? graph.ingoingEdges(def.id);
37
37
  for (const [callerId, e] of callSites ?? []) {
38
38
  if (!edge_1.DfEdge.includesType(e, edge_1.EdgeType.Calls)) {
39
39
  continue;
@@ -59,8 +59,9 @@ function inspectCallSitesArgumentsFns(def, graph, ctx) {
59
59
  * either takes a function as an argument or (may) returns a function.
60
60
  * If the return is an identity, e.g., `function(x) x`, this is not considered higher-order,
61
61
  * if no function is passed as an argument.
62
+ * Please note that inspecting higher order functions can be sped up (if queries multiple times) by providing an inverted graph as well!
62
63
  */
63
- function isFunctionHigherOrder(id, graph, ctx) {
64
+ function isFunctionHigherOrder(id, graph, ctx, invertedGraph) {
64
65
  const vert = graph.getVertex(id);
65
66
  if (!vert || !(0, vertex_1.isFunctionDefinitionVertex)(vert)) {
66
67
  return false;
@@ -70,6 +71,6 @@ function isFunctionHigherOrder(id, graph, ctx) {
70
71
  return true;
71
72
  }
72
73
  // 2. check whether any of the callsites passes a function
73
- return inspectCallSitesArgumentsFns(vert, graph, ctx);
74
+ return inspectCallSitesArgumentsFns(vert, graph, ctx, invertedGraph);
74
75
  }
75
76
  //# sourceMappingURL=higher-order-function.js.map
@@ -8,8 +8,6 @@ const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-fun
8
8
  const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
9
9
  const environment_1 = require("../environments/environment");
10
10
  const clone_1 = require("../environments/clone");
11
- const json_1 = require("../../util/json");
12
- const logger_1 = require("../logger");
13
11
  /**
14
12
  * Helper functions to work with {@link FunctionArgument}s.
15
13
  * @see {@link EmptyArgument} - the marker for empty arguments
@@ -171,8 +169,9 @@ class DataflowGraph {
171
169
  ingoingEdges(id) {
172
170
  const edges = new Map();
173
171
  for (const [source, outgoing] of this.edgeInformation.entries()) {
174
- if (outgoing.has(id)) {
175
- edges.set(source, outgoing.get(id));
172
+ const o = outgoing.get(id);
173
+ if (o) {
174
+ edges.set(source, o);
176
175
  }
177
176
  }
178
177
  return edges;
@@ -448,18 +447,14 @@ class DataflowGraph {
448
447
  exports.DataflowGraph = DataflowGraph;
449
448
  function mergeNodeInfos(current, next) {
450
449
  if (current.tag !== next.tag) {
451
- logger_1.dataflowLogger.warn(() => `nodes to be joined for the same id should have the same tag, but ${JSON.stringify(current, json_1.jsonReplacer)} vs. ${JSON.stringify(next, json_1.jsonReplacer)} -- we are currently not handling cases in which vertices may be either! Keeping current.`);
452
450
  return current;
453
451
  }
454
- if (current.tag === vertex_1.VertexType.VariableDefinition) {
455
- (0, assert_1.guard)(current.scope === next.scope, 'nodes to be joined for the same id must have the same scope');
456
- }
457
452
  else if (current.tag === vertex_1.VertexType.FunctionDefinition) {
458
- (0, assert_1.guard)(current.scope === next.scope, 'nodes to be joined for the same id must have the same scope');
459
- current.exitPoints = (0, arrays_1.uniqueArrayMerge)(current.exitPoints, next.exitPoints);
460
- if (next.tag === vertex_1.VertexType.FunctionDefinition && next.mode && next.mode.length > 0) {
453
+ const n = next;
454
+ current.exitPoints = (0, arrays_1.uniqueArrayMerge)(current.exitPoints, n.exitPoints);
455
+ if (n.mode && n.mode.length > 0) {
461
456
  current.mode ??= [];
462
- for (const m of next.mode) {
457
+ for (const m of n.mode) {
463
458
  if (!current.mode.includes(m)) {
464
459
  current.mode.push(m);
465
460
  }
@@ -5,7 +5,6 @@ exports.wrapArgumentsUnnamed = wrapArgumentsUnnamed;
5
5
  const range_1 = require("../../../../../../util/range");
6
6
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
7
7
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
8
- const voidRange = (0, range_1.rangeFrom)(-1, -1, -1, -1);
9
8
  /**
10
9
  * Converts a normalized node into an unnamed argument (wraps it with an argument node).
11
10
  */
@@ -16,7 +15,7 @@ function toUnnamedArgument(node, idMap) {
16
15
  const arg = {
17
16
  type: type_1.RType.Argument,
18
17
  lexeme: node.lexeme ?? '',
19
- location: node.location ?? voidRange,
18
+ location: node.location ?? range_1.SourceRange.invalid(),
20
19
  info: {
21
20
  ...node.info,
22
21
  id: node.info.id + '-arg'
@@ -6,11 +6,11 @@ const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model
6
6
  const linker_1 = require("../../../../linker");
7
7
  const common_1 = require("../common");
8
8
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
9
- const range_1 = require("../../../../../../util/range");
10
9
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
11
10
  const general_1 = require("../../../../../eval/values/general");
12
11
  const unknown_side_effect_1 = require("../../../../../graph/unknown-side-effect");
13
12
  const built_in_1 = require("../../../../../environments/built-in");
13
+ const range_1 = require("../../../../../../util/range");
14
14
  /**
15
15
  * Process a hook such as `on.exit`
16
16
  */
@@ -41,7 +41,7 @@ function processRegisterHook(name, args, rootId, data, config) {
41
41
  wrappedFunctions.add(wrapId);
42
42
  const wrapped = {
43
43
  type: type_1.RType.FunctionDefinition,
44
- location: val.location ?? name.location ?? (0, range_1.invalidRange)(),
44
+ location: val.location ?? name.location ?? range_1.SourceRange.invalid(),
45
45
  parameters: [],
46
46
  body: val,
47
47
  lexeme: 'function',
@@ -17,8 +17,8 @@ const unknown_replacement_1 = require("../../../../../graph/unknown-replacement"
17
17
  const built_in_s_seven_dispatch_1 = require("./built-in-s-seven-dispatch");
18
18
  const make_argument_1 = require("../argument/make-argument");
19
19
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
20
- const range_1 = require("../../../../../../util/range");
21
20
  const graph_1 = require("../../../../../graph/graph");
21
+ const range_1 = require("../../../../../../util/range");
22
22
  /**
23
23
  * Process a replacement function call like `<-`, `[[<-`, `$<-`, etc.
24
24
  * These are automatically created when doing assignments like `x[y] <- value` or in general `fun(x) <- value` will call `fun<- (x, value)`.
@@ -44,7 +44,7 @@ args, rootId, data, config) {
44
44
  type: type_1.RType.Symbol,
45
45
  info: uArg.info,
46
46
  lexeme: tarName,
47
- location: uArg.location ?? targetArg.location ?? name.location ?? (0, range_1.invalidRange)()
47
+ location: uArg.location ?? targetArg.location ?? name.location ?? range_1.SourceRange.invalid()
48
48
  }, data.completeAst.idMap);
49
49
  }
50
50
  /* we assign the first argument by the last for now and maybe mark as maybe!, we can keep the symbol as we now know we have an assignment */
@@ -10,12 +10,12 @@ const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/node
10
10
  const built_in_1 = require("../../../../../environments/built-in");
11
11
  const edge_1 = require("../../../../../graph/edge");
12
12
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
13
- const range_1 = require("../../../../../../util/range");
14
13
  const assert_1 = require("../../../../../../util/assert");
15
14
  const identifier_1 = require("../../../../../environments/identifier");
16
15
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
17
16
  const r_value_1 = require("../../../../../eval/values/r-value");
18
17
  const vertex_1 = require("../../../../../graph/vertex");
18
+ const range_1 = require("../../../../../../util/range");
19
19
  /**
20
20
  * Process an S7 new generic dispatch call like `new_generic` or `setGeneric`.
21
21
  */
@@ -72,7 +72,7 @@ function processS7NewGeneric(name, args, rootId, data, config) {
72
72
  // 'function([dispatch_args],...) S7_dispatch()'; returns the value id
73
73
  function makeS7DispatchFDef(name, names, rootId, args, idMap) {
74
74
  const argNameId = rootId + '-s7-new-generic-fun-arg-name';
75
- const r = name.location ?? (0, range_1.invalidRange)();
75
+ const r = name.location ?? range_1.SourceRange.invalid();
76
76
  const argName = {
77
77
  type: type_1.RType.Symbol,
78
78
  lexeme: 'fun',
@@ -87,7 +87,7 @@ function processS3Dispatch(name, args, rootId, data, config) {
87
87
  info: generic.info,
88
88
  content: accessedIdentifiers[0],
89
89
  lexeme: accessedIdentifiers[0],
90
- location: generic.location ?? (0, range_1.invalidRange)()
90
+ location: generic.location ?? range_1.SourceRange.invalid()
91
91
  };
92
92
  (0, common_1.patchFunctionCall)({
93
93
  nextGraph: dfGeneric.graph,
@@ -6,8 +6,8 @@ const doc_code_1 = require("./doc-code");
6
6
  const time_1 = require("../../util/text/time");
7
7
  const flowr_search_printer_1 = require("../../search/flowr-search-printer");
8
8
  const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
9
- const dfg_1 = require("../../util/mermaid/dfg");
10
9
  const flowr_analyzer_builder_1 = require("../../project/flowr-analyzer-builder");
10
+ const range_1 = require("../../util/range");
11
11
  /**
12
12
  * Visualizes a search and its results in markdown format.
13
13
  */
@@ -47,7 +47,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify(search, null, 2))}
47
47
  ${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
48
48
 
49
49
  The query returns the following vetices (all references to \`x\` in the code):
50
- ${result.getElements().map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
50
+ ${result.getElements().map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, dataflow.graph)}')</b> at L${range_1.SourceRange.format(node.location)}`).join(', ')}
51
51
 
52
52
  ${metaInfo}
53
53
 
@@ -34,9 +34,8 @@ async function executeLintingRule(ruleName, input, lintingRuleConfig) {
34
34
  };
35
35
  }
36
36
  catch (e) {
37
- const msg = typeof e === 'string' ? e : e instanceof Error ? e.message : JSON.stringify(e);
38
37
  return {
39
- error: msg
38
+ error: e
40
39
  };
41
40
  }
42
41
  }
@@ -7,7 +7,7 @@ import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/
7
7
  import type { LintingRuleConfig, LintingRuleMetadata, LintingRuleNames, LintingRuleResult } from './linter-rules';
8
8
  import type { AsyncOrSync, DeepPartial, DeepReadonly } from 'ts-essentials';
9
9
  import type { LintingRuleTag } from './linter-tags';
10
- import type { SourceRange } from '../util/range';
10
+ import type { SourceLocation } from '../util/range';
11
11
  import type { DataflowInformation } from '../dataflow/info';
12
12
  import type { ControlFlowInformation } from '../control-flow/control-flow-graph';
13
13
  import type { ReadonlyFlowrAnalysisProvider } from '../project/flowr-analyzer';
@@ -78,7 +78,7 @@ interface BaseQuickFix {
78
78
  /**
79
79
  * The range of the text that should be replaced.
80
80
  */
81
- readonly range: SourceRange;
81
+ readonly loc: SourceLocation;
82
82
  }
83
83
  export interface LintQuickFixReplacement extends BaseQuickFix {
84
84
  readonly type: 'replace';
@@ -114,7 +114,8 @@ export interface ConfiguredLintingRule<Name extends LintingRuleNames = LintingRu
114
114
  * For when a linting rule throws an error during execution
115
115
  */
116
116
  export interface LintingResultsError {
117
- readonly error: string;
117
+ /** the error thrown */
118
+ readonly error: unknown;
118
119
  }
119
120
  export interface LintingResultsSuccess<Name extends LintingRuleNames> {
120
121
  results: LintingRuleResult<Name>[];
@@ -124,20 +125,45 @@ export interface LintingResultsSuccess<Name extends LintingRuleNames> {
124
125
  };
125
126
  }
126
127
  /**
127
- * Checks whether the given linting results represent an error.
128
- * @see {@link isLintingResultsSuccess}
128
+ * The results of executing a linting rule.
129
+ * @see {@link LintingResults.isError} and {@link LintingResults.isSuccess} to differentiate between success and error results.
129
130
  */
130
- export declare function isLintingResultsError<Name extends LintingRuleNames>(o: LintingResults<Name>): o is LintingResultsError;
131
+ export type LintingResults<Name extends LintingRuleNames> = LintingResultsSuccess<Name> | LintingResultsError;
131
132
  /**
132
- * Checks whether the given linting results represent a successful linting result.
133
- * @see {@link isLintingResultsError}
133
+ * Helper functions for working with {@link LintingResults}.
134
134
  */
135
- export declare function isLintingResultsSuccess<Name extends LintingRuleNames>(o: LintingResults<Name>): o is LintingResultsSuccess<Name>;
136
- export type LintingResults<Name extends LintingRuleNames> = LintingResultsSuccess<Name> | LintingResultsError;
135
+ export declare const LintingResults: {
136
+ /**
137
+ * Checks whether the given linting results represent an error.
138
+ * @see {@link LintingResultsError}
139
+ * @see {@link LintingResults.isSuccess}
140
+ */
141
+ readonly isError: <Name extends LintingRuleNames>(this: void, o: LintingResults<Name>) => o is LintingResultsError;
142
+ /**
143
+ * Checks whether the given linting results represent a successful execution.
144
+ * @see {@link LintingResultsSuccess}
145
+ * @see {@link LintingResults.isError}
146
+ * @see {@link LintingResults.unpackSuccess}
147
+ */
148
+ readonly isSuccess: <Name extends LintingRuleNames>(this: void, o: LintingResults<Name>) => o is LintingResultsSuccess<Name>;
149
+ /**
150
+ * Unpacks the given linting results, throwing an error if they represent an error.
151
+ */
152
+ readonly unpackSuccess: <Name extends LintingRuleNames>(this: void, o: LintingResults<Name>) => LintingResultsSuccess<Name>;
153
+ /**
154
+ * Gets all involved node IDs from the given linting results.
155
+ * If the results represent an error, an empty set is returned.
156
+ */
157
+ readonly allInvolvedIds: <L extends LintingRuleNames>(this: void, res: LintingResults<L> | undefined) => Set<NodeId>;
158
+ /**
159
+ * Stringifies the error contained in the given linting results error.
160
+ */
161
+ readonly stringifyError: (this: void, { error }: LintingResultsError) => string;
162
+ };
137
163
  export declare enum LintingResultCertainty {
138
164
  /**
139
165
  * The linting rule cannot say for sure whether the result is correct or not.
140
- * This linting certainty should be used for linting results whose calculations are based on estimations involving unknown side-effects, reflection, etc.
166
+ * This linting certainty should be used for linting results whose calculations are based on estimations involving unknown side effects, reflection, etc.
141
167
  */
142
168
  Uncertain = "uncertain",
143
169
  /**