@eagleoutice/flowr 2.7.6 → 2.8.0
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.
- package/README.md +67 -64
- package/cli/wiki.js +1 -1
- package/control-flow/extract-cfg.js +3 -3
- package/control-flow/useless-loop.d.ts +1 -1
- package/control-flow/useless-loop.js +2 -2
- package/dataflow/cluster.js +3 -3
- package/dataflow/environments/built-in-config.d.ts +8 -4
- package/dataflow/environments/built-in.d.ts +27 -14
- package/dataflow/environments/built-in.js +27 -12
- package/dataflow/environments/default-builtin-config.d.ts +614 -3
- package/dataflow/environments/default-builtin-config.js +50 -15
- package/dataflow/environments/environment.js +3 -2
- package/dataflow/environments/identifier.d.ts +5 -1
- package/dataflow/environments/reference-to-maybe.d.ts +2 -2
- package/dataflow/environments/reference-to-maybe.js +23 -14
- package/dataflow/environments/resolve-by-name.d.ts +6 -2
- package/dataflow/environments/resolve-by-name.js +5 -1
- package/dataflow/environments/scoping.js +1 -3
- package/dataflow/eval/resolve/alias-tracking.js +5 -1
- package/dataflow/extractor.js +3 -3
- package/dataflow/fn/exceptions-of-function.d.ts +13 -0
- package/dataflow/fn/exceptions-of-function.js +47 -0
- package/dataflow/fn/higher-order-function.d.ts +1 -1
- package/dataflow/fn/higher-order-function.js +3 -3
- package/dataflow/fn/recursive-function.d.ts +6 -0
- package/dataflow/fn/recursive-function.js +32 -0
- package/dataflow/graph/call-graph.d.ts +10 -0
- package/dataflow/graph/call-graph.js +209 -0
- package/dataflow/graph/dataflowgraph-builder.d.ts +7 -2
- package/dataflow/graph/dataflowgraph-builder.js +14 -9
- package/dataflow/graph/diff-dataflow-graph.js +96 -2
- package/dataflow/graph/graph.d.ts +10 -7
- package/dataflow/graph/graph.js +7 -8
- package/dataflow/graph/vertex.d.ts +6 -3
- package/dataflow/hooks.d.ts +30 -0
- package/dataflow/hooks.js +38 -0
- package/dataflow/info.d.ts +28 -5
- package/dataflow/info.js +66 -31
- package/dataflow/internal/linker.d.ts +13 -3
- package/dataflow/internal/linker.js +155 -53
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -0
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +7 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +19 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +14 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +30 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +24 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +5 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +59 -21
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +34 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +92 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +21 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +129 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +16 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +127 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -3
- package/dataflow/internal/process/functions/call/common.d.ts +13 -1
- package/dataflow/internal/process/functions/call/common.js +33 -2
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +13 -1
- package/dataflow/internal/process/functions/call/known-call-handling.js +29 -3
- package/dataflow/internal/process/functions/call/named-call-handling.js +2 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
- package/dataflow/internal/process/functions/process-argument.js +7 -6
- package/dataflow/internal/process/functions/process-parameter.js +2 -1
- package/dataflow/internal/process/process-named-call.d.ts +2 -2
- package/dataflow/internal/process/process-symbol.js +3 -2
- package/dataflow/internal/process/process-value.d.ts +3 -2
- package/dataflow/internal/process/process-value.js +8 -6
- package/dataflow/origin/dfg-get-origin.js +2 -1
- package/dataflow/origin/dfg-get-symbol-refs.js +1 -1
- package/documentation/doc-readme.d.ts +1 -1
- package/documentation/doc-readme.js +6 -6
- package/documentation/doc-util/doc-code.js +1 -1
- package/documentation/doc-util/doc-dfg.d.ts +1 -0
- package/documentation/doc-util/doc-dfg.js +7 -4
- package/documentation/doc-util/doc-query.d.ts +1 -0
- package/documentation/doc-util/doc-query.js +1 -1
- package/documentation/doc-util/doc-repl.d.ts +2 -1
- package/documentation/doc-util/doc-repl.js +11 -3
- package/documentation/wiki-analyzer.js +2 -0
- package/documentation/wiki-dataflow-graph.js +59 -16
- package/documentation/wiki-interface.js +33 -5
- package/documentation/wiki-mk/doc-context.d.ts +2 -1
- package/documentation/wiki-mk/doc-context.js +2 -2
- package/documentation/wiki-mk/doc-maker.js +4 -3
- package/documentation/wiki-normalized-ast.js +6 -0
- package/documentation/wiki-query.js +109 -1
- package/linter/linter-rules.d.ts +1 -1
- package/linter/rules/seeded-randomness.js +17 -12
- package/linter/rules/useless-loop.d.ts +1 -1
- package/package.json +9 -9
- package/project/cache/flowr-analyzer-cache.d.ts +11 -0
- package/project/cache/flowr-analyzer-cache.js +19 -0
- package/project/context/flowr-analyzer-dependencies-context.d.ts +6 -1
- package/project/context/flowr-analyzer-dependencies-context.js +6 -0
- package/project/context/flowr-analyzer-files-context.d.ts +5 -2
- package/project/context/flowr-analyzer-files-context.js +24 -17
- package/project/context/flowr-file.d.ts +9 -4
- package/project/context/flowr-file.js +20 -6
- package/project/flowr-analyzer.d.ts +11 -0
- package/project/flowr-analyzer.js +6 -0
- package/project/plugins/file-plugins/files/flowr-description-file.d.ts +8 -0
- package/project/plugins/file-plugins/files/flowr-description-file.js +36 -3
- package/project/plugins/file-plugins/files/flowr-jupyter-file.js +1 -1
- package/project/plugins/file-plugins/files/flowr-namespace-file.js +1 -1
- package/project/plugins/file-plugins/files/flowr-news-file.js +1 -1
- package/project/plugins/file-plugins/files/flowr-rmarkdown-file.js +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +4 -1
- package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +3 -0
- package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.d.ts → flowr-analyzer-namespace-files-plugin.d.ts} +1 -1
- package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.js → flowr-analyzer-namespace-files-plugin.js} +4 -4
- package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.d.ts +26 -0
- package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.js +39 -0
- package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.d.ts +26 -0
- package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.js +39 -0
- package/project/plugins/flowr-analyzer-plugin-defaults.js +6 -2
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +3 -13
- package/project/plugins/package-version-plugins/package.d.ts +1 -1
- package/project/plugins/package-version-plugins/package.js +3 -3
- package/project/plugins/plugin-registry.d.ts +4 -2
- package/project/plugins/plugin-registry.js +6 -2
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.d.ts +11 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +5 -2
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +4 -12
- package/queries/catalog/call-graph-query/call-graph-query-executor.d.ts +6 -0
- package/queries/catalog/call-graph-query/call-graph-query-executor.js +21 -0
- package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +21 -0
- package/queries/catalog/call-graph-query/call-graph-query-format.js +32 -0
- package/queries/catalog/dataflow-query/dataflow-query-executor.js +4 -3
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +29 -3
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
- package/queries/catalog/dependencies-query/function-info/function-info.d.ts +8 -1
- package/queries/catalog/dependencies-query/function-info/write-functions.js +13 -0
- package/queries/catalog/does-call-query/does-call-query-executor.d.ts +6 -0
- package/queries/catalog/does-call-query/does-call-query-executor.js +100 -0
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +51 -0
- package/queries/catalog/does-call-query/does-call-query-format.js +102 -0
- package/queries/catalog/files-query/files-query-executor.js +4 -4
- package/queries/catalog/files-query/files-query-format.d.ts +2 -1
- package/queries/catalog/files-query/files-query-format.js +18 -2
- package/queries/catalog/id-map-query/id-map-query-executor.js +4 -3
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +18 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +56 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +34 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +54 -0
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -28
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +6 -0
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +12 -0
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.d.ts +6 -0
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.js +23 -0
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +28 -0
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +44 -0
- package/queries/catalog/linter-query/linter-query-format.js +4 -1
- package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +4 -3
- package/queries/catalog/project-query/project-query-executor.js +9 -3
- package/queries/catalog/project-query/project-query-format.d.ts +6 -1
- package/queries/catalog/project-query/project-query-format.js +35 -9
- package/queries/query.d.ts +34 -2
- package/queries/query.js +9 -0
- package/r-bridge/data/data.d.ts +10 -5
- package/r-bridge/data/data.js +11 -5
- package/r-bridge/lang-4.x/ast/model/model.d.ts +7 -7
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +5 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +8 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/parser/main/internal/other/normalize-comment.js +0 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -2
- package/r-bridge/roxygen2/roxygen-ast.d.ts +218 -0
- package/r-bridge/roxygen2/roxygen-ast.js +82 -0
- package/r-bridge/roxygen2/roxygen-parse.d.ts +24 -0
- package/r-bridge/roxygen2/roxygen-parse.js +214 -0
- package/reconstruct/auto-select/magic-comments.js +4 -4
- package/slicing/static/slice-call.js +3 -4
- package/slicing/static/static-slicer.js +2 -2
- package/statistics/features/supported/defined-functions/defined-functions.js +1 -1
- package/util/collections/defaultmap.d.ts +3 -3
- package/util/mermaid/dfg.js +5 -5
- package/util/objects.js +1 -1
- package/util/r-author.d.ts +5 -0
- package/util/r-author.js +110 -0
- package/util/r-license.d.ts +10 -1
- package/util/r-license.js +27 -6
- package/util/r-version.d.ts +19 -0
- package/util/r-version.js +106 -0
- package/util/range.d.ts +6 -0
- package/util/range.js +7 -0
- package/util/simple-df/dfg-ascii.js +2 -2
- package/util/text/args.d.ts +9 -0
- package/util/text/args.js +65 -0
- package/util/version.js +1 -1
|
@@ -6,6 +6,7 @@ const identify_link_to_last_call_relation_1 = require("../../queries/catalog/cal
|
|
|
6
6
|
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
7
7
|
const cascade_action_1 = require("../../queries/catalog/call-context-query/cascade-action");
|
|
8
8
|
const unnamed_call_handling_1 = require("../internal/process/functions/call/unnamed-call-handling");
|
|
9
|
+
const hooks_1 = require("../hooks");
|
|
9
10
|
exports.GgPlotCreate = [
|
|
10
11
|
'ggplot', 'ggplotly', 'ggMarginal', 'ggcorrplot', 'ggseasonplot', 'ggdendrogram', 'qmap', 'qplot', 'quickplot', 'autoplot', 'grid.arrange',
|
|
11
12
|
'fviz_pca_biplot', 'fviz_pca', 'fviz_pca_ind', 'fviz_pca_var', 'fviz_screeplot', 'fviz_mca_biplot', 'fviz_mca', 'fviz_mca_ind', 'fviz_mca_var', 'fviz_cluster', 'fviz_dend',
|
|
@@ -86,8 +87,9 @@ exports.GgPlotAddons = [
|
|
|
86
87
|
'ggdraw', 'last_plot'
|
|
87
88
|
];
|
|
88
89
|
const PlotAddons = exports.GraphicsPlotAddons.concat(exports.GgPlotImplicitAddons, ...exports.PlotFunctionsWithAddParam);
|
|
90
|
+
const RegexConvIn = /[-/\\^$*+?.()|[\]{}]/g;
|
|
89
91
|
function toRegex(n) {
|
|
90
|
-
return new RegExp(`^(${
|
|
92
|
+
return new RegExp(`^(${Array.from(new Set(n)).map(s => s.replace(RegexConvIn, '\\$&')).filter(s => s.length > 0).join('|')})$`);
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
93
95
|
* Contains the built-in definitions recognized by flowR
|
|
@@ -154,7 +156,7 @@ exports.DefaultBuiltinConfig = [
|
|
|
154
156
|
},
|
|
155
157
|
hasUnknownSideEffects: {
|
|
156
158
|
type: 'link-to-last-call',
|
|
157
|
-
callName: toRegex(
|
|
159
|
+
callName: toRegex(exports.PlotCreate.concat(PlotAddons)),
|
|
158
160
|
ignoreIf: (source, graph) => {
|
|
159
161
|
const sourceVertex = graph.getVertex(source);
|
|
160
162
|
/* map with add = true appends to an existing plot */
|
|
@@ -178,10 +180,11 @@ exports.DefaultBuiltinConfig = [
|
|
|
178
180
|
names: exports.GgPlotAddons,
|
|
179
181
|
processor: 'builtin:default',
|
|
180
182
|
config: {
|
|
183
|
+
libFn: true,
|
|
181
184
|
forceArgs: 'all',
|
|
182
185
|
hasUnknownSideEffects: {
|
|
183
186
|
type: 'link-to-last-call',
|
|
184
|
-
callName: toRegex(
|
|
187
|
+
callName: toRegex(exports.GgPlotCreate.concat(exports.GgPlotAddons))
|
|
185
188
|
}
|
|
186
189
|
}, assumePrimitive: true
|
|
187
190
|
},
|
|
@@ -190,6 +193,7 @@ exports.DefaultBuiltinConfig = [
|
|
|
190
193
|
names: exports.TinyPlotAddons,
|
|
191
194
|
processor: 'builtin:default',
|
|
192
195
|
config: {
|
|
196
|
+
libFn: true,
|
|
193
197
|
forceArgs: 'all',
|
|
194
198
|
hasUnknownSideEffects: {
|
|
195
199
|
type: 'link-to-last-call',
|
|
@@ -202,17 +206,21 @@ exports.DefaultBuiltinConfig = [
|
|
|
202
206
|
names: ['image_write', 'image_capture', 'dev.capture', 'dev.off'],
|
|
203
207
|
processor: 'builtin:default',
|
|
204
208
|
config: {
|
|
209
|
+
libFn: true,
|
|
205
210
|
forceArgs: 'all',
|
|
206
211
|
hasUnknownSideEffects: {
|
|
207
212
|
type: 'link-to-last-call',
|
|
208
|
-
callName: toRegex(
|
|
213
|
+
callName: toRegex(GraphicDeviceOpen.concat(exports.PlotCreate, PlotAddons, exports.GgPlotAddons, exports.TinyPlotAddons))
|
|
209
214
|
}
|
|
210
215
|
}, assumePrimitive: true
|
|
211
216
|
},
|
|
212
217
|
{ type: 'function', names: ['('], processor: 'builtin:default', config: { returnsNthArgument: 0 }, assumePrimitive: true },
|
|
213
218
|
{ type: 'function', names: ['load', 'load_all', 'setwd', 'set.seed'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: false },
|
|
214
219
|
{ type: 'function', names: ['body', 'formals', 'environment'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: true },
|
|
215
|
-
{ type: 'function',
|
|
220
|
+
{ type: 'function',
|
|
221
|
+
names: ['.Call', '.External', '.C', '.Fortran'],
|
|
222
|
+
processor: 'builtin:default',
|
|
223
|
+
config: { hasUnknownSideEffects: true, forceArgs: [true],
|
|
216
224
|
treatAsFnCall: {
|
|
217
225
|
'.Call': ['.NAME'],
|
|
218
226
|
'.External': ['.NAME'],
|
|
@@ -223,9 +231,11 @@ exports.DefaultBuiltinConfig = [
|
|
|
223
231
|
{ type: 'function', names: ['eval'], processor: 'builtin:eval', config: { includeFunctionCall: true }, assumePrimitive: true },
|
|
224
232
|
{ type: 'function', names: ['cat'], processor: 'builtin:default', config: { forceArgs: 'all', hasUnknownSideEffects: { type: 'link-to-last-call', callName: /^sink$/ } }, assumePrimitive: false },
|
|
225
233
|
{ type: 'function', names: ['switch'], processor: 'builtin:default', config: { forceArgs: [true] }, assumePrimitive: false },
|
|
226
|
-
{ type: 'function', names: ['return'], processor: 'builtin:default', config: { returnsNthArgument: 0, cfg: 1 /* ExitPointType.Return */, useAsProcessor: 'builtin:return' }, assumePrimitive:
|
|
227
|
-
{ type: 'function', names: ['stop'], processor: 'builtin:default', config: { useAsProcessor: 'builtin:stop' }, assumePrimitive: false },
|
|
228
|
-
{ type: 'function', names: ['
|
|
234
|
+
{ type: 'function', names: ['return'], processor: 'builtin:default', config: { returnsNthArgument: 0, cfg: 1 /* ExitPointType.Return */, useAsProcessor: 'builtin:return' }, assumePrimitive: true },
|
|
235
|
+
{ type: 'function', names: ['stop', 'abort'], processor: 'builtin:default', config: { useAsProcessor: 'builtin:stop', cfg: 4 /* ExitPointType.Error */, forceArgs: ['all'] }, assumePrimitive: false },
|
|
236
|
+
{ type: 'function', names: ['try'], processor: 'builtin:try', config: { block: 'expr', handlers: {} }, assumePrimitive: true },
|
|
237
|
+
{ type: 'function', names: ['tryCatch', 'tryCatchLog'], processor: 'builtin:try', config: { block: 'expr', handlers: { error: 'error', finally: 'finally' } }, assumePrimitive: true },
|
|
238
|
+
{ type: 'function', names: ['stopifnot'], processor: 'builtin:stopifnot', config: {}, assumePrimitive: false },
|
|
229
239
|
{ type: 'function', names: ['break'], processor: 'builtin:default', config: { useAsProcessor: 'builtin:break', cfg: 2 /* ExitPointType.Break */ }, assumePrimitive: false },
|
|
230
240
|
{ type: 'function', names: ['next'], processor: 'builtin:default', config: { cfg: 3 /* ExitPointType.Next */ }, assumePrimitive: false },
|
|
231
241
|
{ type: 'function', names: ['{'], processor: 'builtin:expression-list', config: {}, assumePrimitive: true },
|
|
@@ -237,7 +247,8 @@ exports.DefaultBuiltinConfig = [
|
|
|
237
247
|
{ type: 'function', names: ['library', 'require'], processor: 'builtin:library', config: {}, assumePrimitive: false },
|
|
238
248
|
{ type: 'function', names: ['<-', '='], processor: 'builtin:assignment', config: { canBeReplacement: true }, assumePrimitive: true },
|
|
239
249
|
{ type: 'function', names: [':='], processor: 'builtin:assignment', config: {}, assumePrimitive: true },
|
|
240
|
-
{ type: 'function', names: ['assign'], processor: 'builtin:assignment', config: { targetVariable: true }, assumePrimitive: true },
|
|
250
|
+
{ type: 'function', names: ['assign', 'setGeneric', 'setValidity'], processor: 'builtin:assignment', config: { targetVariable: true }, assumePrimitive: true },
|
|
251
|
+
{ type: 'function', names: ['setMethod'], processor: 'builtin:assignment-like', config: { targetVariable: true, canBeReplacement: false, target: { idx: 0, name: 'f' }, source: { idx: 2, name: 'definition' } }, assumePrimitive: true },
|
|
241
252
|
{ type: 'function', names: ['delayedAssign'], processor: 'builtin:assignment', config: { quoteSource: true, targetVariable: true }, assumePrimitive: true },
|
|
242
253
|
{ type: 'function', names: ['<<-'], processor: 'builtin:assignment', config: { superAssignment: true, canBeReplacement: true }, assumePrimitive: true },
|
|
243
254
|
{ type: 'function', names: ['->'], processor: 'builtin:assignment', config: { swapSourceAndTarget: true, canBeReplacement: true }, assumePrimitive: true },
|
|
@@ -251,9 +262,10 @@ exports.DefaultBuiltinConfig = [
|
|
|
251
262
|
{ type: 'function', names: ['repeat'], processor: 'builtin:repeat-loop', config: {}, assumePrimitive: true },
|
|
252
263
|
{ type: 'function', names: ['while'], processor: 'builtin:while-loop', config: {}, assumePrimitive: true },
|
|
253
264
|
{ type: 'function', names: ['do.call'], processor: 'builtin:apply', config: { indexOfFunction: 0, unquoteFunction: true }, assumePrimitive: true },
|
|
265
|
+
{ type: 'function', names: ['UseMethod', 'NextMethod'], processor: 'builtin:apply', config: { indexOfFunction: 0, unquoteFunction: true, resolveInEnvironment: 'global' }, assumePrimitive: true },
|
|
254
266
|
{ type: 'function', names: ['.Primitive', '.Internal'], processor: 'builtin:apply', config: { indexOfFunction: 0, unquoteFunction: true, resolveInEnvironment: 'global' }, assumePrimitive: true },
|
|
255
|
-
{ type: 'function', names: ['interference'], processor: 'builtin:apply', config: { unquoteFunction: true, nameOfFunctionArgument: 'propensity_integrand' }, assumePrimitive: false },
|
|
256
|
-
{ type: 'function', names: ['ddply'], processor: 'builtin:apply', config: { unquoteFunction: true, indexOfFunction: 2, nameOfFunctionArgument: '.fun' }, assumePrimitive: false },
|
|
267
|
+
{ type: 'function', names: ['interference'], processor: 'builtin:apply', config: { unquoteFunction: true, nameOfFunctionArgument: 'propensity_integrand', libFn: true }, assumePrimitive: false },
|
|
268
|
+
{ type: 'function', names: ['ddply'], processor: 'builtin:apply', config: { unquoteFunction: true, indexOfFunction: 2, nameOfFunctionArgument: '.fun', libFn: true }, assumePrimitive: false },
|
|
257
269
|
{ type: 'function', names: ['list'], processor: 'builtin:list', config: {}, assumePrimitive: true },
|
|
258
270
|
{ type: 'function', names: ['c'], processor: 'builtin:vector', config: {}, assumePrimitive: true, evalHandler: 'builtin:c' },
|
|
259
271
|
{
|
|
@@ -270,11 +282,9 @@ exports.DefaultBuiltinConfig = [
|
|
|
270
282
|
{
|
|
271
283
|
type: 'function',
|
|
272
284
|
names: [
|
|
273
|
-
'
|
|
285
|
+
'sys.on.exit', 'par', 'tpar', 'sink',
|
|
274
286
|
/* library and require is handled above */
|
|
275
287
|
'requireNamespace', 'loadNamespace', 'attachNamespace', 'asNamespace',
|
|
276
|
-
/* downloader and installer functions (R, devtools, BiocManager) */
|
|
277
|
-
'library.dynam', 'install.packages', 'install', 'install_github', 'install_gitlab', 'install_bitbucket', 'install_url', 'install_git', 'install_svn', 'install_local', 'install_version', 'update_packages',
|
|
278
288
|
/* weird env attachments */
|
|
279
289
|
'attach', 'unname', 'data',
|
|
280
290
|
/* file creation/removal */
|
|
@@ -284,6 +294,31 @@ exports.DefaultBuiltinConfig = [
|
|
|
284
294
|
config: { hasUnknownSideEffects: true },
|
|
285
295
|
assumePrimitive: false
|
|
286
296
|
},
|
|
297
|
+
{
|
|
298
|
+
type: 'function',
|
|
299
|
+
names: [
|
|
300
|
+
'tinytheme', 'theme_set',
|
|
301
|
+
/* downloader and installer functions (R, devtools, BiocManager) */
|
|
302
|
+
'library.dynam', 'install.packages', 'install', 'install_github', 'install_gitlab', 'install_bitbucket', 'install_url', 'install_git', 'install_svn', 'install_local', 'install_version', 'update_packages',
|
|
303
|
+
],
|
|
304
|
+
processor: 'builtin:default',
|
|
305
|
+
config: { hasUnknownSideEffects: true, libFn: true },
|
|
306
|
+
assumePrimitive: false
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
type: 'function',
|
|
310
|
+
names: ['on.exit'],
|
|
311
|
+
processor: 'builtin:register-hook',
|
|
312
|
+
config: {
|
|
313
|
+
hook: hooks_1.KnownHooks.OnFnExit,
|
|
314
|
+
args: {
|
|
315
|
+
expr: { idx: 0, name: 'expr' },
|
|
316
|
+
add: { idx: 1, name: 'add', default: false },
|
|
317
|
+
after: { idx: 2, name: 'after', default: true },
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
assumePrimitive: true
|
|
321
|
+
},
|
|
287
322
|
/* they are all mapped to `<-` but we separate super assignments */
|
|
288
323
|
{
|
|
289
324
|
type: 'replacement',
|
|
@@ -303,7 +338,7 @@ exports.DefaultBuiltinConfig = [
|
|
|
303
338
|
}
|
|
304
339
|
];
|
|
305
340
|
/**
|
|
306
|
-
*
|
|
341
|
+
* Expensive and naive lookup of the default processor for a built-in function name
|
|
307
342
|
*/
|
|
308
343
|
function getDefaultProcessor(name) {
|
|
309
344
|
if (name.startsWith(unnamed_call_handling_1.UnnamedFunctionCallPrefix)) {
|
|
@@ -130,8 +130,9 @@ class Environment {
|
|
|
130
130
|
// we need to make a copy to avoid side effects for old reference in other environments
|
|
131
131
|
const updatedOld = old?.slice() ?? [];
|
|
132
132
|
for (const v of values) {
|
|
133
|
-
const
|
|
134
|
-
|
|
133
|
+
const { nodeId, definedAt } = v;
|
|
134
|
+
const index = updatedOld.find(o => o.nodeId === nodeId && o.definedAt === definedAt);
|
|
135
|
+
if (index) {
|
|
135
136
|
continue;
|
|
136
137
|
}
|
|
137
138
|
if (applyCds === undefined) {
|
|
@@ -74,7 +74,7 @@ export interface IdentifierReference {
|
|
|
74
74
|
* If the reference is only effective, if, for example, an if-then-else condition is true, this references the root of the `if`.
|
|
75
75
|
* As a hacky intermediate solution (until we have pointer-analysis), an empty array may indicate a `maybe` which is due to pointer access (e.g., in `a[x] <- 3`).
|
|
76
76
|
*/
|
|
77
|
-
controlDependencies
|
|
77
|
+
controlDependencies?: ControlDependency[] | undefined;
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
80
|
* The definition of an {@link Identifier|identifier} within the {@link DataflowGraph|graph}.
|
|
@@ -94,6 +94,10 @@ export interface InGraphIdentifierDefinition extends IdentifierReference {
|
|
|
94
94
|
* (the arrow operator for e.g. `x <- 3`, or `assign` call in `assign("x", 3)`)
|
|
95
95
|
*/
|
|
96
96
|
readonly definedAt: NodeId;
|
|
97
|
+
/**
|
|
98
|
+
* For value tracking, this contains all nodeIds of constant values that may be made available to this identifier
|
|
99
|
+
* For example, in `x <- 3; y <- x`, the definition of `y` will have the value `3` in its value set
|
|
100
|
+
*/
|
|
97
101
|
readonly value?: NodeId[];
|
|
98
102
|
/**
|
|
99
103
|
* this attribute links a definition to indices (pointer links) it may be affected by or related to
|
|
@@ -5,9 +5,9 @@ import type { REnvironmentInformation } from './environment';
|
|
|
5
5
|
/**
|
|
6
6
|
* Marks the reference as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
|
|
7
7
|
*/
|
|
8
|
-
export declare function makeReferenceMaybe(ref: IdentifierReference, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference;
|
|
8
|
+
export declare function makeReferenceMaybe(ref: IdentifierReference, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency[] | undefined): IdentifierReference;
|
|
9
9
|
/**
|
|
10
10
|
* Marks all references as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
|
|
11
11
|
* @see {@link makeReferenceMaybe}
|
|
12
12
|
*/
|
|
13
|
-
export declare function makeAllMaybe(references: readonly IdentifierReference[] | undefined, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean,
|
|
13
|
+
export declare function makeAllMaybe(references: readonly IdentifierReference[] | undefined, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, applyCds?: ControlDependency[] | undefined): IdentifierReference[];
|
|
@@ -4,6 +4,19 @@ exports.makeReferenceMaybe = makeReferenceMaybe;
|
|
|
4
4
|
exports.makeAllMaybe = makeAllMaybe;
|
|
5
5
|
const identifier_1 = require("./identifier");
|
|
6
6
|
const resolve_by_name_1 = require("./resolve-by-name");
|
|
7
|
+
function appToCdsUnique(target, toAdd) {
|
|
8
|
+
if (toAdd) {
|
|
9
|
+
target.push(...toAdd.filter(c => !target.find(tc => tc.id === c.id && tc.when === c.when)));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function concatCdsUnique(target, toAdd) {
|
|
13
|
+
if (toAdd) {
|
|
14
|
+
return target.concat(toAdd.filter(c => !target.find(tc => tc.id === c.id && tc.when === c.when)));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
7
20
|
/**
|
|
8
21
|
* Marks the reference as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
|
|
9
22
|
*/
|
|
@@ -13,34 +26,30 @@ function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = u
|
|
|
13
26
|
for (const definition of definitions ?? []) {
|
|
14
27
|
if (definition.type !== identifier_1.ReferenceType.BuiltInFunction && definition.type !== identifier_1.ReferenceType.BuiltInConstant) {
|
|
15
28
|
if (definition.controlDependencies) {
|
|
16
|
-
|
|
17
|
-
definition.controlDependencies.push(defaultCd);
|
|
18
|
-
}
|
|
29
|
+
appToCdsUnique(definition.controlDependencies, defaultCd);
|
|
19
30
|
}
|
|
20
31
|
else {
|
|
21
|
-
definition.controlDependencies = defaultCd ?
|
|
32
|
+
definition.controlDependencies = defaultCd ? Array.from(defaultCd) : [];
|
|
22
33
|
}
|
|
23
34
|
}
|
|
24
35
|
}
|
|
25
36
|
}
|
|
26
37
|
const node = graph.getVertex(ref.nodeId, true);
|
|
27
38
|
if (node) {
|
|
28
|
-
if (node.
|
|
29
|
-
|
|
30
|
-
node.cds.push(defaultCd);
|
|
31
|
-
}
|
|
39
|
+
if (node.controlDependencies) {
|
|
40
|
+
appToCdsUnique(node.controlDependencies, defaultCd);
|
|
32
41
|
}
|
|
33
42
|
else {
|
|
34
|
-
node.
|
|
43
|
+
node.controlDependencies = defaultCd ? Array.from(defaultCd) : [];
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
if (ref.controlDependencies) {
|
|
38
|
-
if (defaultCd
|
|
39
|
-
return { ...ref, controlDependencies: (ref.controlDependencies
|
|
47
|
+
if (defaultCd) {
|
|
48
|
+
return { ...ref, controlDependencies: concatCdsUnique(ref.controlDependencies, defaultCd) };
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
else {
|
|
43
|
-
return { ...ref, controlDependencies:
|
|
52
|
+
return { ...ref, controlDependencies: defaultCd ? Array.from(defaultCd) : [] };
|
|
44
53
|
}
|
|
45
54
|
return ref;
|
|
46
55
|
}
|
|
@@ -48,7 +57,7 @@ function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = u
|
|
|
48
57
|
* Marks all references as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
|
|
49
58
|
* @see {@link makeReferenceMaybe}
|
|
50
59
|
*/
|
|
51
|
-
function makeAllMaybe(references, graph, environments, includeDefs,
|
|
52
|
-
return references?.map(ref => makeReferenceMaybe(ref, graph, environments, includeDefs,
|
|
60
|
+
function makeAllMaybe(references, graph, environments, includeDefs, applyCds = undefined) {
|
|
61
|
+
return references?.map(ref => makeReferenceMaybe(ref, graph, environments, includeDefs, applyCds)) ?? [];
|
|
53
62
|
}
|
|
54
63
|
//# sourceMappingURL=reference-to-maybe.js.map
|
|
@@ -10,12 +10,16 @@ import { type Identifier, type IdentifierDefinition, ReferenceType } from './ide
|
|
|
10
10
|
* @returns A list of possible identifier definitions (one if the definition location is exactly and always known), or `undefined`
|
|
11
11
|
* if the identifier is undefined in the current scope/with the current environment information.
|
|
12
12
|
*/
|
|
13
|
-
export declare function resolveByName(name: Identifier, environment: REnvironmentInformation, target: ReferenceType): IdentifierDefinition[] | undefined;
|
|
13
|
+
export declare function resolveByName(name: Identifier, environment: REnvironmentInformation, target: ReferenceType): readonly IdentifierDefinition[] | undefined;
|
|
14
14
|
/**
|
|
15
15
|
* The more performant version of {@link resolveByName} when the target type is unknown.
|
|
16
16
|
*/
|
|
17
17
|
export declare function resolveByNameAnyType(name: Identifier, environment: REnvironmentInformation): IdentifierDefinition[] | undefined;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Checks whether the given identifier name resolves to a built-in constant with the given value.
|
|
20
|
+
* @param name - The name of the identifier to resolve
|
|
21
|
+
* @param environment - The current environment used for name resolution
|
|
22
|
+
* @param wantedValue - The built-in constant value to check for
|
|
23
|
+
* @returns Whether the identifier always, never, or maybe resolves to the given built-in constant value
|
|
20
24
|
*/
|
|
21
25
|
export declare function resolvesToBuiltInConstant(name: Identifier | undefined, environment: REnvironmentInformation, wantedValue: unknown): Ternary;
|
|
@@ -107,7 +107,11 @@ function resolveByNameAnyType(name, environment) {
|
|
|
107
107
|
return ret;
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
|
-
*
|
|
110
|
+
* Checks whether the given identifier name resolves to a built-in constant with the given value.
|
|
111
|
+
* @param name - The name of the identifier to resolve
|
|
112
|
+
* @param environment - The current environment used for name resolution
|
|
113
|
+
* @param wantedValue - The built-in constant value to check for
|
|
114
|
+
* @returns Whether the identifier always, never, or maybe resolves to the given built-in constant value
|
|
111
115
|
*/
|
|
112
116
|
function resolvesToBuiltInConstant(name, environment, wantedValue) {
|
|
113
117
|
if (name === undefined) {
|
|
@@ -20,10 +20,8 @@ function pushLocalEnvironment({ level, current }) {
|
|
|
20
20
|
*/
|
|
21
21
|
function popLocalEnvironment({ current, level }) {
|
|
22
22
|
(0, assert_1.guard)(level > 0, 'cannot remove the global/root environment');
|
|
23
|
-
const parent = current.parent;
|
|
24
|
-
(0, assert_1.guard)(parent !== undefined, 'level is wrong, parent is undefined even though level suggested depth > 0 (starts with 0)');
|
|
25
23
|
return {
|
|
26
|
-
current: parent,
|
|
24
|
+
current: current.parent,
|
|
27
25
|
level: level - 1
|
|
28
26
|
};
|
|
29
27
|
}
|
|
@@ -126,6 +126,10 @@ function resolveIdToValue(id, { environment, graph, idMap, full = true, resolve,
|
|
|
126
126
|
}
|
|
127
127
|
switch (node.type) {
|
|
128
128
|
case type_1.RType.Argument:
|
|
129
|
+
if (node.value) {
|
|
130
|
+
return resolveIdToValue(node.value.info.id, { environment, graph, idMap, full, resolve: variableResolve, ctx });
|
|
131
|
+
}
|
|
132
|
+
// eslint-disable-next-line no-fallthrough
|
|
129
133
|
case type_1.RType.Symbol:
|
|
130
134
|
if (environment) {
|
|
131
135
|
return full ? trackAliasInEnvironments(variableResolve, node.lexeme, environment, ctx, graph, idMap) : r_value_1.Top;
|
|
@@ -278,7 +282,7 @@ function trackAliasesInGraph(id, graph, ctx, idMap) {
|
|
|
278
282
|
continue;
|
|
279
283
|
}
|
|
280
284
|
const [vertex, outgoingEdges] = res;
|
|
281
|
-
const cds = vertex.
|
|
285
|
+
const cds = vertex.controlDependencies;
|
|
282
286
|
for (const cd of cds ?? []) {
|
|
283
287
|
const target = graph.idMap?.get(cd.id);
|
|
284
288
|
if (target === undefined) {
|
package/dataflow/extractor.js
CHANGED
|
@@ -52,7 +52,7 @@ exports.processors = {
|
|
|
52
52
|
info: info,
|
|
53
53
|
content: groupStart?.content ?? '{',
|
|
54
54
|
lexeme: groupStart?.lexeme ?? '{',
|
|
55
|
-
location: location ?? (0, range_1.
|
|
55
|
+
location: location ?? (0, range_1.invalidRange)(),
|
|
56
56
|
namespace: groupStart?.content ? undefined : 'base'
|
|
57
57
|
}, (0, make_argument_1.wrapArgumentsUnnamed)(children, d.completeAst.idMap), info.id, d);
|
|
58
58
|
}
|
|
@@ -125,8 +125,8 @@ function produceDataFlowGraph(parser, completeAst, ctx) {
|
|
|
125
125
|
}
|
|
126
126
|
// finally, resolve linkages
|
|
127
127
|
(0, built_in_function_definition_1.updateNestedFunctionCalls)(df.graph, df.environment);
|
|
128
|
-
|
|
128
|
+
df.cfgQuick = resolveLinkToSideEffects(completeAst, df.graph);
|
|
129
129
|
// performance optimization: return cfgQuick as part of the result to avoid recomputation
|
|
130
|
-
return
|
|
130
|
+
return df;
|
|
131
131
|
}
|
|
132
132
|
//# sourceMappingURL=extractor.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
|
+
import type { CallGraph } from '../graph/call-graph';
|
|
3
|
+
import type { ControlDependency } from '../info';
|
|
4
|
+
export interface ExceptionPoint {
|
|
5
|
+
id: NodeId;
|
|
6
|
+
cds?: readonly ControlDependency[] | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Collect exception sources of a function in the call graph.
|
|
10
|
+
* This returns the `NodeId`s of functions that may throw exceptions when called by the given function.
|
|
11
|
+
* Please be aware, that these are restricted to functions known by flowR.
|
|
12
|
+
*/
|
|
13
|
+
export declare function calculateExceptionsOfFunction(id: NodeId, graph: CallGraph): ExceptionPoint[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateExceptionsOfFunction = calculateExceptionsOfFunction;
|
|
4
|
+
const vertex_1 = require("../graph/vertex");
|
|
5
|
+
const built_in_1 = require("../environments/built-in");
|
|
6
|
+
const CatchHandlers = new Set(['builtin:try']);
|
|
7
|
+
/**
|
|
8
|
+
* Collect exception sources of a function in the call graph.
|
|
9
|
+
* This returns the `NodeId`s of functions that may throw exceptions when called by the given function.
|
|
10
|
+
* Please be aware, that these are restricted to functions known by flowR.
|
|
11
|
+
*/
|
|
12
|
+
function calculateExceptionsOfFunction(id, graph) {
|
|
13
|
+
const collectedExceptions = [];
|
|
14
|
+
const visited = new Set();
|
|
15
|
+
const toVisit = [id];
|
|
16
|
+
while (toVisit.length > 0) {
|
|
17
|
+
const currentId = toVisit.pop();
|
|
18
|
+
if (visited.has(currentId)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
visited.add(currentId);
|
|
22
|
+
const vtx = graph.getVertex(currentId);
|
|
23
|
+
if (!vtx) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if ((0, built_in_1.isBuiltIn)(currentId)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (vtx.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
30
|
+
for (const e of vtx.exitPoints.filter(e => e.type === 4 /* ExitPointType.Error */)) {
|
|
31
|
+
if (!collectedExceptions.find(x => x.id === e.nodeId)) {
|
|
32
|
+
collectedExceptions.push({ id: e.nodeId, cds: e.controlDependencies });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (vtx.tag === vertex_1.VertexType.FunctionCall && vtx.origin !== 'unnamed' && vtx.origin.some(c => CatchHandlers.has(c))) {
|
|
37
|
+
// skip the try-catch handlers as they catch all exceptions within their body
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const outEdges = graph.outgoingEdges(currentId) ?? [];
|
|
41
|
+
for (const [out] of outEdges) {
|
|
42
|
+
toVisit.push(out);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return collectedExceptions;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=exceptions-of-function.js.map
|
|
@@ -7,4 +7,4 @@ import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-a
|
|
|
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
9
|
*/
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function isFunctionHigherOrder(id: NodeId, graph: DataflowGraph, ctx: ReadOnlyFlowrAnalyzerContext): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isFunctionHigherOrder = isFunctionHigherOrder;
|
|
4
4
|
const vertex_1 = require("../graph/vertex");
|
|
5
5
|
const assert_1 = require("../../util/assert");
|
|
6
6
|
const edge_1 = require("../graph/edge");
|
|
@@ -9,7 +9,7 @@ const config_1 = require("../../config");
|
|
|
9
9
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
10
10
|
const general_1 = require("../eval/values/general");
|
|
11
11
|
function isAnyReturnAFunction(def, graph) {
|
|
12
|
-
const workingQueue = def.exitPoints.map(d => graph.getVertex(d, true)).filter(assert_1.isNotUndefined);
|
|
12
|
+
const workingQueue = def.exitPoints.map(d => graph.getVertex(d.nodeId, true)).filter(assert_1.isNotUndefined);
|
|
13
13
|
const seen = new Set();
|
|
14
14
|
while (workingQueue.length > 0) {
|
|
15
15
|
const current = workingQueue.pop();
|
|
@@ -60,7 +60,7 @@ function inspectCallSitesArgumentsFns(def, graph, ctx) {
|
|
|
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
62
|
*/
|
|
63
|
-
function
|
|
63
|
+
function isFunctionHigherOrder(id, graph, ctx) {
|
|
64
64
|
const vert = graph.getVertex(id);
|
|
65
65
|
if (!vert || !(0, vertex_1.isFunctionDefinitionVertex)(vert)) {
|
|
66
66
|
return false;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
|
+
import type { CallGraph } from '../graph/call-graph';
|
|
3
|
+
/**
|
|
4
|
+
* Determines whether the function with the given ID is recursive.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isFunctionRecursive(id: NodeId, graph: CallGraph): boolean;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isFunctionRecursive = isFunctionRecursive;
|
|
4
|
+
const vertex_1 = require("../graph/vertex");
|
|
5
|
+
/**
|
|
6
|
+
* Determines whether the function with the given ID is recursive.
|
|
7
|
+
*/
|
|
8
|
+
function isFunctionRecursive(id, graph) {
|
|
9
|
+
const vert = graph.getVertex(id);
|
|
10
|
+
if (!vert || !(0, vertex_1.isFunctionDefinitionVertex)(vert)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
const toVisit = [id];
|
|
15
|
+
let gotStart = 0;
|
|
16
|
+
while (toVisit.length > 0) {
|
|
17
|
+
const currentId = toVisit.pop();
|
|
18
|
+
if (currentId === id && gotStart++ > 0) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (seen.has(currentId)) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
seen.add(currentId);
|
|
25
|
+
const out = graph.outgoingEdges(currentId)?.keys() ?? [];
|
|
26
|
+
for (const nextId of out) {
|
|
27
|
+
toVisit.push(nextId);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=recursive-function.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DataflowGraph } from './graph';
|
|
2
|
+
import type { DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefinition } from './vertex';
|
|
3
|
+
/**
|
|
4
|
+
* A call graph is a dataflow graph where all vertices are function calls.
|
|
5
|
+
*/
|
|
6
|
+
export type CallGraph = DataflowGraph<Required<DataflowGraphVertexFunctionCall | DataflowGraphVertexFunctionDefinition>>;
|
|
7
|
+
/**
|
|
8
|
+
* Computes the call graph from the given dataflow graph.
|
|
9
|
+
*/
|
|
10
|
+
export declare function computeCallGraph(graph: DataflowGraph): CallGraph;
|