@eagleoutice/flowr 2.9.13 → 2.10.1
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 +52 -28
- package/abstract-interpretation/absint-visitor.d.ts +1 -1
- package/abstract-interpretation/absint-visitor.js +20 -20
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -2
- package/benchmark/slicer.d.ts +1 -1
- package/benchmark/slicer.js +7 -5
- package/benchmark/stats/stats.d.ts +2 -2
- package/cli/repl/commands/repl-dataflow.js +5 -5
- package/cli/repl/parser/slice-query-parser.d.ts +3 -3
- package/cli/repl/parser/slice-query-parser.js +2 -2
- package/cli/repl/server/connection.js +2 -2
- package/cli/repl/server/messages/message-slice.d.ts +1 -1
- package/cli/repl/server/messages/message-slice.js +2 -2
- package/config.d.ts +12 -8
- package/config.js +5 -3
- package/control-flow/extract-cfg.js +2 -2
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +43 -43
- package/control-flow/useless-loop.d.ts +1 -1
- package/control-flow/useless-loop.js +3 -3
- package/core/print/dataflow-printer.d.ts +0 -14
- package/core/print/dataflow-printer.js +0 -21
- package/core/steps/all/core/20-dataflow.d.ts +3 -3
- package/core/steps/all/core/20-dataflow.js +3 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -5
- package/core/steps/all/static-slicing/00-slice.js +6 -8
- package/core/steps/pipeline/default-pipelines.d.ts +89 -89
- package/dataflow/environments/built-in-proc-name.d.ts +83 -0
- package/dataflow/environments/built-in-proc-name.js +88 -0
- package/dataflow/environments/built-in.d.ts +1 -83
- package/dataflow/environments/built-in.js +37 -120
- package/dataflow/environments/default-builtin-config.d.ts +1 -1
- package/dataflow/environments/default-builtin-config.js +75 -75
- package/dataflow/environments/identifier.d.ts +5 -0
- package/dataflow/environments/identifier.js +18 -0
- package/dataflow/eval/resolve/resolve.js +2 -2
- package/dataflow/fn/exceptions-of-function.d.ts +1 -1
- package/dataflow/fn/exceptions-of-function.js +2 -2
- package/dataflow/graph/call-graph.d.ts +46 -19
- package/dataflow/graph/call-graph.js +95 -114
- package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/df-helper.d.ts +133 -0
- package/dataflow/graph/df-helper.js +138 -0
- package/dataflow/graph/diff-dataflow-graph.d.ts +5 -10
- package/dataflow/graph/diff-dataflow-graph.js +3 -28
- package/dataflow/graph/edge.d.ts +1 -0
- package/dataflow/graph/edge.js +1 -0
- package/dataflow/graph/graph-helper.d.ts +60 -0
- package/dataflow/graph/graph-helper.js +128 -0
- package/dataflow/graph/graph.d.ts +19 -3
- package/dataflow/graph/graph.js +32 -5
- package/dataflow/graph/vertex.d.ts +3 -1
- package/dataflow/info.d.ts +14 -4
- package/dataflow/info.js +28 -16
- package/dataflow/internal/linker.d.ts +14 -10
- package/dataflow/internal/linker.js +29 -32
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +8 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +6 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-local.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +7 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +6 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +2 -2
- package/dataflow/internal/process/functions/call/common.js +2 -1
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +1 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +2 -2
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/dataflow/internal/process/process-uninteresting-leaf.d.ts +1 -1
- package/dataflow/internal/process/process-uninteresting-leaf.js +1 -1
- package/dataflow/origin/dfg-get-origin.d.ts +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.js +6 -6
- package/documentation/doc-readme.js +2 -1
- package/documentation/doc-util/doc-dfg.d.ts +3 -0
- package/documentation/doc-util/doc-dfg.js +5 -7
- package/documentation/doc-util/doc-normalized-ast.d.ts +0 -6
- package/documentation/doc-util/doc-normalized-ast.js +0 -23
- package/documentation/doc-util/doc-structure.js +3 -3
- package/documentation/doc-util/doc-types.js +3 -3
- package/documentation/wiki-core.js +5 -4
- package/documentation/wiki-dataflow-graph.js +14 -12
- package/documentation/wiki-interface.js +3 -3
- package/documentation/wiki-linter.js +6 -0
- package/documentation/wiki-normalized-ast.js +5 -4
- package/documentation/wiki-query.js +28 -3
- package/linter/linter-rules.d.ts +49 -1
- package/linter/linter-rules.js +5 -1
- package/linter/rules/problematic-eval.d.ts +44 -0
- package/linter/rules/problematic-eval.js +83 -0
- package/linter/rules/seeded-randomness.js +2 -2
- package/linter/rules/stop-with-call-arg.d.ts +35 -0
- package/linter/rules/stop-with-call-arg.js +72 -0
- package/linter/rules/useless-loop.d.ts +1 -1
- package/package.json +7 -7
- package/project/cache/flowr-analyzer-cache.d.ts +1 -1
- package/project/cache/flowr-analyzer-cache.js +1 -1
- package/project/flowr-analyzer-builder.d.ts +3 -0
- package/project/flowr-analyzer.d.ts +1 -1
- package/queries/catalog/call-context-query/identify-link-to-nested-call-relation.js +2 -2
- package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +1 -1
- package/queries/catalog/call-graph-query/call-graph-query-format.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -2
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
- package/queries/catalog/does-call-query/does-call-query-executor.js +2 -2
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
- package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
- package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +90 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +308 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
- package/queries/catalog/location-map-query/location-map-query-executor.js +2 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.js +3 -3
- package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +6 -0
- package/queries/catalog/provenance-query/provenance-query-executor.js +34 -0
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +35 -0
- package/queries/catalog/provenance-query/provenance-query-format.js +62 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +4 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -3
- package/queries/query.d.ts +17 -1
- package/queries/query.js +4 -0
- package/r-bridge/lang-4.x/ast/model/model.d.ts +9 -0
- package/r-bridge/lang-4.x/ast/model/model.js +10 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +29 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +29 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
- package/search/flowr-search-filters.d.ts +1 -1
- package/search/flowr-search-printer.js +3 -3
- package/search/search-executor/search-enrichers.js +2 -2
- package/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +43 -18
- package/slicing/criterion/parse.js +68 -63
- package/slicing/static/slicer-types.d.ts +2 -3
- package/slicing/static/static-slicer.d.ts +3 -4
- package/slicing/static/static-slicer.js +32 -12
- package/util/collections/arrays.d.ts +4 -0
- package/util/collections/arrays.js +7 -0
- package/util/diff.d.ts +2 -2
- package/util/mermaid/ast.js +4 -4
- package/util/mermaid/cfg.js +5 -5
- package/util/mermaid/dfg.d.ts +33 -18
- package/util/mermaid/dfg.js +47 -31
- package/util/mermaid/mermaid.d.ts +57 -12
- package/util/mermaid/mermaid.js +74 -67
- package/util/range.d.ts +8 -0
- package/util/range.js +13 -1
- package/util/slice-direction.d.ts +7 -0
- package/util/slice-direction.js +12 -0
- package/util/version.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +0 -6
- package/dataflow/graph/invert-dfg.js +0 -20
- package/dataflow/graph/resolve-graph.d.ts +0 -8
- package/dataflow/graph/resolve-graph.js +0 -59
|
@@ -0,0 +1,63 @@
|
|
|
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.InputSourcesDefinition = void 0;
|
|
7
|
+
const ansi_1 = require("../../../util/text/ansi");
|
|
8
|
+
const time_1 = require("../../../util/text/time");
|
|
9
|
+
const joi_1 = __importDefault(require("joi"));
|
|
10
|
+
const slice_query_parser_1 = require("../../../cli/repl/parser/slice-query-parser");
|
|
11
|
+
const input_sources_query_executor_1 = require("./input-sources-query-executor");
|
|
12
|
+
const range_1 = require("../../../util/range");
|
|
13
|
+
function inputSourcesQueryLineParser(output, line, _config) {
|
|
14
|
+
const criterion = (0, slice_query_parser_1.sliceCriteriaParser)(line[0]);
|
|
15
|
+
if (!criterion || criterion.length !== 1) {
|
|
16
|
+
output.stderr(output.formatter.format('Invalid provenance query format, a single slicing criterion must be given in the form "(criterion1)"', { color: 1 /* Colors.Red */, effect: ansi_1.ColorEffect.Foreground, style: 1 /* FontStyles.Bold */ }));
|
|
17
|
+
return { query: [] };
|
|
18
|
+
}
|
|
19
|
+
return { query: [{
|
|
20
|
+
type: 'input-sources',
|
|
21
|
+
criterion: criterion[0],
|
|
22
|
+
}], rCode: line[1] };
|
|
23
|
+
}
|
|
24
|
+
exports.InputSourcesDefinition = {
|
|
25
|
+
executor: input_sources_query_executor_1.executeInputSourcesQuery,
|
|
26
|
+
asciiSummarizer: async (formatter, analyzer, queryResults, result) => {
|
|
27
|
+
const out = queryResults;
|
|
28
|
+
result.push(`Query: ${(0, ansi_1.bold)('input-sources', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
|
|
29
|
+
const nast = (await analyzer.normalize()).idMap;
|
|
30
|
+
for (const [key, sources] of Object.entries(out.results)) {
|
|
31
|
+
result.push(` ╰ Input Sources for ${key}`);
|
|
32
|
+
for (const { id, trace, type } of sources) {
|
|
33
|
+
const kNode = nast.get(id);
|
|
34
|
+
const kLoc = kNode ? range_1.SourceLocation.format(range_1.SourceLocation.fromNode(kNode)) : 'unknown location';
|
|
35
|
+
result.push(` ╰ ${kLoc} (id: ${id}), type: ${JSON.stringify(type)}, trace: ${trace}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
},
|
|
40
|
+
fromLine: inputSourcesQueryLineParser,
|
|
41
|
+
schema: joi_1.default.object({
|
|
42
|
+
type: joi_1.default.string().valid('input-sources').required().description('The type of the query.'),
|
|
43
|
+
criterion: joi_1.default.string().required().description('The slicing criterion to use.'),
|
|
44
|
+
config: joi_1.default.object({
|
|
45
|
+
networkFunctions: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that fetch data from the network.'),
|
|
46
|
+
randomnessConsumers: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that consume randomness.'),
|
|
47
|
+
randomnessProducers: joi_1.default.array().items(joi_1.default.object({ type: joi_1.default.string().valid('function', 'assignment'), name: joi_1.default.string().required() })).optional().description('Functions or assignments that produce randomness seeds.'),
|
|
48
|
+
configurableFunctions: joi_1.default.array().items(joi_1.default.string()).optional().description('Functions that read configuration (options/env).'),
|
|
49
|
+
pureFunctions: joi_1.default.array().items(joi_1.default.string()).optional().description('Deterministic functions that keep constant inputs constant.'),
|
|
50
|
+
}).optional()
|
|
51
|
+
}).description('Input Sources query definition'),
|
|
52
|
+
flattenInvolvedNodes: (queryResults) => {
|
|
53
|
+
const flattened = [];
|
|
54
|
+
const out = queryResults;
|
|
55
|
+
for (const obj of Object.values(out.results)) {
|
|
56
|
+
for (const e of obj) {
|
|
57
|
+
flattened.push(e.id);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return flattened;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=input-sources-query-format.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
|
+
import type { DataflowGraph } from '../../../dataflow/graph/graph';
|
|
3
|
+
import type { MergeableRecord } from '../../../util/objects';
|
|
4
|
+
import { Identifier } from '../../../dataflow/environments/identifier';
|
|
5
|
+
/**
|
|
6
|
+
* Lattice flattening until we have a taint engine :)
|
|
7
|
+
*
|
|
8
|
+
*```
|
|
9
|
+
* [ Unknown ]
|
|
10
|
+
* / / | \ \
|
|
11
|
+
*[Param] [File] [Net] [Rand] [Scope]
|
|
12
|
+
* \ \ | / /
|
|
13
|
+
* [ DerivedConstant ]
|
|
14
|
+
* |
|
|
15
|
+
* [ Constant ]
|
|
16
|
+
*```
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
export declare enum InputType {
|
|
20
|
+
Parameter = "param",
|
|
21
|
+
File = "file",
|
|
22
|
+
Network = "net",
|
|
23
|
+
Random = "rand",
|
|
24
|
+
Constant = "const",
|
|
25
|
+
/** Read from environment/call scope */
|
|
26
|
+
Scope = "scope",
|
|
27
|
+
/** Pure calculations from constants that lead to a constant */
|
|
28
|
+
DerivedConstant = "dconst",
|
|
29
|
+
Unknown = "unknown"
|
|
30
|
+
}
|
|
31
|
+
export declare enum InputTraceType {
|
|
32
|
+
/** Derived only from aliasing */
|
|
33
|
+
Alias = "alias",
|
|
34
|
+
/** Derived from pure function chains */
|
|
35
|
+
Pure = "pure",
|
|
36
|
+
/** Derived from known but not necessarily all pure function chains */
|
|
37
|
+
Known = "known",
|
|
38
|
+
/** Not fully known origin */
|
|
39
|
+
Unknown = "unknown"
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Object attached to an input source
|
|
43
|
+
* @see {@link InputSources}
|
|
44
|
+
*/
|
|
45
|
+
export interface InputSource extends MergeableRecord {
|
|
46
|
+
id: NodeId;
|
|
47
|
+
type: InputType[];
|
|
48
|
+
trace: InputTraceType;
|
|
49
|
+
/** if the trace is affected by control dependencies, they are classified too, this is a duplicate free array */
|
|
50
|
+
cds?: InputType[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Map of input sources, keyed by the node id of the input source. Each input source is classified with an {@link InputSource} object.
|
|
54
|
+
*/
|
|
55
|
+
export type InputSources = InputSource[];
|
|
56
|
+
/**
|
|
57
|
+
* This is either an {@link NodeId|id} of a known functions all of that category (e.g., you can issue a dependencies query before and then pass all
|
|
58
|
+
* identified ids to this query here).
|
|
59
|
+
*/
|
|
60
|
+
export type InputClassifierFunctionIdentifier = Identifier | NodeId;
|
|
61
|
+
/**
|
|
62
|
+
* For the specifications of `pureFns` etc. please have a look at {@link InputClassifierFunctionIdentifier}.
|
|
63
|
+
*/
|
|
64
|
+
export interface InputClassifierConfig extends MergeableRecord {
|
|
65
|
+
/**
|
|
66
|
+
* Functions which are considered to be pure (i.e., deterministic, trusted, safe, idempotent on the lub of the input types)
|
|
67
|
+
*/
|
|
68
|
+
pureFns: readonly InputClassifierFunctionIdentifier[];
|
|
69
|
+
/**
|
|
70
|
+
* Functions that read from the network
|
|
71
|
+
*/
|
|
72
|
+
networkFns: readonly InputClassifierFunctionIdentifier[];
|
|
73
|
+
/**
|
|
74
|
+
* Functions that produce a random value
|
|
75
|
+
* Note: may need to check with respect to seeded randomness
|
|
76
|
+
*/
|
|
77
|
+
randomFns: readonly InputClassifierFunctionIdentifier[];
|
|
78
|
+
/**
|
|
79
|
+
* Functions that read from the file system
|
|
80
|
+
*/
|
|
81
|
+
readFileFns: readonly InputClassifierFunctionIdentifier[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Takes the given id which is expected to either be:
|
|
85
|
+
* - a function call - in this case all arguments are considered to be inputs (additionally to all read edges from the function call in the dataflow graph)
|
|
86
|
+
* - anything else - in that case the node itself is considered as an "input" - please note that in these scenarios the *return* value will only contain one mapping - that for the id you pased in.
|
|
87
|
+
*
|
|
88
|
+
* This method traces the dependencies in the dataflow graph using the specification of functions passed in
|
|
89
|
+
*/
|
|
90
|
+
export declare function classifyInput(id: NodeId, dfg: DataflowGraph, config: InputClassifierConfig): InputSources;
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InputTraceType = exports.InputType = void 0;
|
|
4
|
+
exports.classifyInput = classifyInput;
|
|
5
|
+
const graph_1 = require("../../../dataflow/graph/graph");
|
|
6
|
+
const objects_1 = require("../../../util/objects");
|
|
7
|
+
const vertex_1 = require("../../../dataflow/graph/vertex");
|
|
8
|
+
const df_helper_1 = require("../../../dataflow/graph/df-helper");
|
|
9
|
+
const identifier_1 = require("../../../dataflow/environments/identifier");
|
|
10
|
+
const assert_1 = require("../../../util/assert");
|
|
11
|
+
const arrays_1 = require("../../../util/collections/arrays");
|
|
12
|
+
const built_in_proc_name_1 = require("../../../dataflow/environments/built-in-proc-name");
|
|
13
|
+
class InputClassifier {
|
|
14
|
+
dfg;
|
|
15
|
+
config;
|
|
16
|
+
cache = new Map();
|
|
17
|
+
constructor(dfg, config) {
|
|
18
|
+
this.dfg = dfg;
|
|
19
|
+
this.config = config;
|
|
20
|
+
}
|
|
21
|
+
classifyEntry(vertex) {
|
|
22
|
+
const cached = this.cache.get(vertex.id);
|
|
23
|
+
if (cached) {
|
|
24
|
+
return cached;
|
|
25
|
+
}
|
|
26
|
+
// insert temporary unknown to break cycles
|
|
27
|
+
this.cache.set(vertex.id, { id: vertex.id, type: [InputType.Unknown], trace: InputTraceType.Unknown });
|
|
28
|
+
switch (vertex.tag) {
|
|
29
|
+
case vertex_1.VertexType.Value:
|
|
30
|
+
return this.classifyCdsAndReturn(vertex, { id: vertex.id, type: [InputType.Constant], trace: InputTraceType.Unknown });
|
|
31
|
+
case vertex_1.VertexType.FunctionCall:
|
|
32
|
+
return this.classifyFunctionCall(vertex);
|
|
33
|
+
case vertex_1.VertexType.VariableDefinition:
|
|
34
|
+
return this.classifyVariableDefinition(vertex);
|
|
35
|
+
case vertex_1.VertexType.Use:
|
|
36
|
+
return this.classifyVariable(vertex);
|
|
37
|
+
default:
|
|
38
|
+
return this.classifyCdsAndReturn(vertex, { id: vertex.id, type: [InputType.Unknown], trace: InputTraceType.Unknown });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
classifyFunctionCall(call) {
|
|
42
|
+
if (call.origin.includes(built_in_proc_name_1.BuiltInProcName.IfThenElse) || call.origin.includes(built_in_proc_name_1.BuiltInProcName.WhileLoop)) {
|
|
43
|
+
const condition = graph_1.FunctionArgument.getReference(call.args[0]);
|
|
44
|
+
if (condition) {
|
|
45
|
+
const vtx = this.dfg.getVertex(condition);
|
|
46
|
+
if (vtx) {
|
|
47
|
+
return this.classifyCdsAndReturn(call, this.classifyEntry(vtx));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (call.origin.includes(built_in_proc_name_1.BuiltInProcName.ForLoop)) {
|
|
52
|
+
const condition = graph_1.FunctionArgument.getReference(call.args[1]);
|
|
53
|
+
if (condition) {
|
|
54
|
+
const vtx = this.dfg.getVertex(condition);
|
|
55
|
+
if (vtx) {
|
|
56
|
+
return this.classifyCdsAndReturn(call, this.classifyEntry(vtx));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!matchesList(call, this.config.pureFns)) {
|
|
61
|
+
if (matchesList(call, this.config.readFileFns)) {
|
|
62
|
+
return this.classifyCdsAndReturn(call, { id: call.id, type: [InputType.File], trace: InputTraceType.Unknown });
|
|
63
|
+
}
|
|
64
|
+
else if (matchesList(call, this.config.networkFns)) {
|
|
65
|
+
return this.classifyCdsAndReturn(call, { id: call.id, type: [InputType.Network], trace: InputTraceType.Unknown });
|
|
66
|
+
}
|
|
67
|
+
else if (matchesList(call, this.config.randomFns)) {
|
|
68
|
+
return this.classifyCdsAndReturn(call, { id: call.id, type: [InputType.Random], trace: InputTraceType.Unknown });
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// if it is not pure, we cannot classify based on the inputs, in that case we do not know!
|
|
72
|
+
return this.classifyCdsAndReturn(call, { id: call.id, type: [InputType.Unknown], trace: InputTraceType.Unknown });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Otherwise, classify by arguments; pure functions get Known/Pure handling
|
|
76
|
+
const argTypes = [];
|
|
77
|
+
const cdTypes = [];
|
|
78
|
+
for (const arg of call.args) {
|
|
79
|
+
if (graph_1.FunctionArgument.isEmpty(arg)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const ref = graph_1.FunctionArgument.getReference(arg);
|
|
83
|
+
if (ref === undefined) {
|
|
84
|
+
argTypes.push(InputType.Unknown);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const argVtx = this.dfg.getVertex(ref);
|
|
88
|
+
if (!argVtx) {
|
|
89
|
+
argTypes.push(InputType.Unknown);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const classified = this.classifyEntry(argVtx);
|
|
93
|
+
// collect all observed types from this argument
|
|
94
|
+
argTypes.push(...classified.type);
|
|
95
|
+
if (classified.cds) {
|
|
96
|
+
cdTypes.push(...classified.cds);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const cds = cdTypes.length > 0 ? (0, arrays_1.uniqueArray)(cdTypes) : undefined;
|
|
100
|
+
// all arguments only contain constant-like types -> derived constant
|
|
101
|
+
const allConstLike = argTypes.length > 0 && argTypes.every(t => t === InputType.Constant || t === InputType.DerivedConstant);
|
|
102
|
+
if (allConstLike) {
|
|
103
|
+
return this.classifyCdsAndReturn(call, (0, objects_1.compactRecord)({ id: call.id, type: [InputType.DerivedConstant], trace: InputTraceType.Pure, cds }));
|
|
104
|
+
}
|
|
105
|
+
const types = argTypes.length === 0 ? [InputType.DerivedConstant] : (0, arrays_1.uniqueArray)(argTypes);
|
|
106
|
+
return this.classifyCdsAndReturn(call, (0, objects_1.compactRecord)({ id: call.id, type: types, trace: InputTraceType.Known, cds }));
|
|
107
|
+
}
|
|
108
|
+
classifyVariable(vtx) {
|
|
109
|
+
const origins = df_helper_1.Dataflow.origin(this.dfg, vtx.id);
|
|
110
|
+
if (origins === undefined) {
|
|
111
|
+
return this.classifyCdsAndReturn(vtx, { id: vtx.id, type: [InputType.Unknown], trace: InputTraceType.Unknown });
|
|
112
|
+
}
|
|
113
|
+
const types = [];
|
|
114
|
+
const cds = [];
|
|
115
|
+
let allPure = true;
|
|
116
|
+
for (const o of origins) {
|
|
117
|
+
if (o.type === 4 /* OriginType.ConstantOrigin */) {
|
|
118
|
+
types.push(InputType.Constant);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (o.type === 0 /* OriginType.ReadVariableOrigin */ || o.type === 1 /* OriginType.WriteVariableOrigin */) {
|
|
122
|
+
const v = this.dfg.getVertex(o.id);
|
|
123
|
+
if (v) {
|
|
124
|
+
// if this is a variable definition that is a parameter, classify as Parameter
|
|
125
|
+
if (v.tag === vertex_1.VertexType.VariableDefinition && this.dfg.idMap?.get(v.id)?.info.role === "param-n" /* RoleInParent.ParameterName */) {
|
|
126
|
+
types.push(InputType.Parameter);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const c = this.classifyEntry(v);
|
|
130
|
+
types.push(...c.type);
|
|
131
|
+
if (c.cds) {
|
|
132
|
+
cds.push(...c.cds);
|
|
133
|
+
}
|
|
134
|
+
if (c.trace !== InputTraceType.Pure) {
|
|
135
|
+
allPure = false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
types.push(InputType.Unknown);
|
|
140
|
+
}
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (o.type === 2 /* OriginType.FunctionCallOrigin */ || o.type === 3 /* OriginType.BuiltInFunctionOrigin */) {
|
|
144
|
+
const v = this.dfg.getVertex(o.id);
|
|
145
|
+
if (v) {
|
|
146
|
+
const c = this.classifyEntry(v);
|
|
147
|
+
types.push(...c.type);
|
|
148
|
+
if (c.cds) {
|
|
149
|
+
cds.push(...c.cds);
|
|
150
|
+
}
|
|
151
|
+
if (c.trace !== InputTraceType.Pure) {
|
|
152
|
+
allPure = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
types.push(InputType.Unknown);
|
|
157
|
+
}
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// unknown origin type
|
|
161
|
+
types.push(InputType.Unknown);
|
|
162
|
+
}
|
|
163
|
+
const t = types.length === 0 ? [InputType.Unknown] : (0, arrays_1.uniqueArray)(types);
|
|
164
|
+
const trace = allPure ? InputTraceType.Pure : InputTraceType.Alias;
|
|
165
|
+
return this.classifyCdsAndReturn(vtx, { id: vtx.id, type: t, trace, cds: cds.length === 0 ? undefined : (0, arrays_1.uniqueArray)(cds) });
|
|
166
|
+
}
|
|
167
|
+
classifyVariableDefinition(vtx) {
|
|
168
|
+
// parameter definitions are classified as Parameter
|
|
169
|
+
if (this.dfg.idMap?.get(vtx.id)?.info.role === "param-n" /* RoleInParent.ParameterName */) {
|
|
170
|
+
return this.classifyCdsAndReturn(vtx, { id: vtx.id, type: [InputType.Parameter], trace: InputTraceType.Unknown });
|
|
171
|
+
}
|
|
172
|
+
const sources = vtx.source;
|
|
173
|
+
if (sources === undefined || sources.length === 0) {
|
|
174
|
+
// fallback to unknown if we cannot find the value
|
|
175
|
+
return this.classifyCdsAndReturn(vtx, { id: vtx.id, type: [InputType.Unknown], trace: InputTraceType.Unknown });
|
|
176
|
+
}
|
|
177
|
+
const types = [];
|
|
178
|
+
const cds = [];
|
|
179
|
+
let allPure = true;
|
|
180
|
+
for (const tid of sources) {
|
|
181
|
+
const tv = this.dfg.getVertex(tid);
|
|
182
|
+
if (tv) {
|
|
183
|
+
const c = this.classifyEntry(tv);
|
|
184
|
+
types.push(...c.type);
|
|
185
|
+
if (c.cds) {
|
|
186
|
+
cds.push(...c.cds);
|
|
187
|
+
}
|
|
188
|
+
if (c.trace !== InputTraceType.Pure) {
|
|
189
|
+
allPure = false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
types.push(InputType.Unknown);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const t = types.length === 0 ? [InputType.Unknown] : (0, arrays_1.uniqueArray)(types);
|
|
197
|
+
const trace = allPure ? InputTraceType.Pure : InputTraceType.Alias;
|
|
198
|
+
return this.classifyCdsAndReturn(vtx, { id: vtx.id, type: t, trace, cds: cds.length === 0 ? undefined : (0, arrays_1.uniqueArray)(cds) });
|
|
199
|
+
}
|
|
200
|
+
classifyCdsAndReturn(vtx, src) {
|
|
201
|
+
if (vtx.cds) {
|
|
202
|
+
const cds = (0, arrays_1.uniqueArray)(vtx.cds.flatMap(c => {
|
|
203
|
+
const cv = this.dfg.getVertex(c.id);
|
|
204
|
+
if (!cv) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
const e = this.classifyEntry(cv);
|
|
208
|
+
return e.cds ? [...e.type, ...e.cds] : [...e.type];
|
|
209
|
+
}).filter(assert_1.isNotUndefined).concat(src.cds ?? []));
|
|
210
|
+
if (cds.length > 0) {
|
|
211
|
+
src.cds = cds;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (src.cds?.length === 0) {
|
|
215
|
+
delete src.cds;
|
|
216
|
+
}
|
|
217
|
+
this.cache.set(vtx.id, src);
|
|
218
|
+
return src;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Lattice flattening until we have a taint engine :)
|
|
223
|
+
*
|
|
224
|
+
*```
|
|
225
|
+
* [ Unknown ]
|
|
226
|
+
* / / | \ \
|
|
227
|
+
*[Param] [File] [Net] [Rand] [Scope]
|
|
228
|
+
* \ \ | / /
|
|
229
|
+
* [ DerivedConstant ]
|
|
230
|
+
* |
|
|
231
|
+
* [ Constant ]
|
|
232
|
+
*```
|
|
233
|
+
*
|
|
234
|
+
*/
|
|
235
|
+
var InputType;
|
|
236
|
+
(function (InputType) {
|
|
237
|
+
InputType["Parameter"] = "param";
|
|
238
|
+
InputType["File"] = "file";
|
|
239
|
+
InputType["Network"] = "net";
|
|
240
|
+
InputType["Random"] = "rand";
|
|
241
|
+
InputType["Constant"] = "const";
|
|
242
|
+
/** Read from environment/call scope */
|
|
243
|
+
InputType["Scope"] = "scope";
|
|
244
|
+
/** Pure calculations from constants that lead to a constant */
|
|
245
|
+
InputType["DerivedConstant"] = "dconst";
|
|
246
|
+
InputType["Unknown"] = "unknown";
|
|
247
|
+
})(InputType || (exports.InputType = InputType = {}));
|
|
248
|
+
var InputTraceType;
|
|
249
|
+
(function (InputTraceType) {
|
|
250
|
+
/** Derived only from aliasing */
|
|
251
|
+
InputTraceType["Alias"] = "alias";
|
|
252
|
+
/** Derived from pure function chains */
|
|
253
|
+
InputTraceType["Pure"] = "pure";
|
|
254
|
+
/** Derived from known but not necessarily all pure function chains */
|
|
255
|
+
InputTraceType["Known"] = "known";
|
|
256
|
+
/** Not fully known origin */
|
|
257
|
+
InputTraceType["Unknown"] = "unknown";
|
|
258
|
+
})(InputTraceType || (exports.InputTraceType = InputTraceType = {}));
|
|
259
|
+
function matchesList(fn, list) {
|
|
260
|
+
if (!list || list.length === 0) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
for (const id of list) {
|
|
264
|
+
if (fn.id === id || identifier_1.Identifier.matches(id, fn.name)) {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Takes the given id which is expected to either be:
|
|
272
|
+
* - a function call - in this case all arguments are considered to be inputs (additionally to all read edges from the function call in the dataflow graph)
|
|
273
|
+
* - anything else - in that case the node itself is considered as an "input" - please note that in these scenarios the *return* value will only contain one mapping - that for the id you pased in.
|
|
274
|
+
*
|
|
275
|
+
* This method traces the dependencies in the dataflow graph using the specification of functions passed in
|
|
276
|
+
*/
|
|
277
|
+
function classifyInput(id, dfg, config) {
|
|
278
|
+
const vtx = dfg.getVertex(id);
|
|
279
|
+
if (!vtx) {
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
const c = new InputClassifier(dfg, config);
|
|
283
|
+
if (vtx.tag === vertex_1.VertexType.FunctionCall) {
|
|
284
|
+
const ret = [];
|
|
285
|
+
const args = vtx.args;
|
|
286
|
+
for (const arg of args) {
|
|
287
|
+
if (graph_1.FunctionArgument.isEmpty(arg)) {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const ref = graph_1.FunctionArgument.getReference(arg);
|
|
291
|
+
if (ref === undefined) {
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const argVtx = dfg.getVertex(ref);
|
|
295
|
+
if (argVtx === undefined) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
ret.push(c.classifyEntry(argVtx));
|
|
299
|
+
}
|
|
300
|
+
return ret;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
return [
|
|
304
|
+
c.classifyEntry(vtx)
|
|
305
|
+
];
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=simple-input-classifier.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { InspectExceptionQuery, InspectExceptionQueryResult } from './inspect-exception-query-format';
|
|
2
2
|
import type { BasicQueryData } from '../../base-query-format';
|
|
3
|
-
import {
|
|
3
|
+
import { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
4
4
|
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
5
5
|
import type { ReadonlyFlowrAnalysisProvider } from '../../../project/flowr-analyzer';
|
|
6
6
|
/**
|
|
7
7
|
* Get the functions to consider in the call graph based on the given queries.
|
|
8
8
|
*/
|
|
9
9
|
export declare function getFunctionsToConsiderInCallGraph(queries: readonly {
|
|
10
|
-
filter?: readonly
|
|
10
|
+
filter?: readonly SlicingCriterion[];
|
|
11
11
|
}[], analyzer: ReadonlyFlowrAnalysisProvider, onlyDefinitions?: boolean): Promise<{
|
|
12
12
|
cg: import("../../../dataflow/graph/call-graph").CallGraph;
|
|
13
13
|
fns: MapIterator<[NodeId, Required<import("../../../dataflow/graph/vertex").DataflowGraphVertexFunctionCall | import("../../../dataflow/graph/vertex").DataflowGraphVertexFunctionDefinition>]>;
|
|
@@ -25,7 +25,7 @@ async function getFunctionsToConsiderInCallGraph(queries, analyzer, onlyDefiniti
|
|
|
25
25
|
const filterFor = new Set();
|
|
26
26
|
if (filters) {
|
|
27
27
|
for (const f of filters) {
|
|
28
|
-
const i =
|
|
28
|
+
const i = parse_1.SlicingCriterion.tryParse(f, ast.idMap);
|
|
29
29
|
if (i !== undefined) {
|
|
30
30
|
filterFor.add(i);
|
|
31
31
|
}
|
|
@@ -6,7 +6,7 @@ import { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id'
|
|
|
6
6
|
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
7
7
|
import type { FlowrConfig } from '../../../config';
|
|
8
8
|
import type { ExceptionPoint } from '../../../dataflow/fn/exceptions-of-function';
|
|
9
|
-
import type {
|
|
9
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
10
10
|
/**
|
|
11
11
|
* Either returns all function definitions alongside exception information,
|
|
12
12
|
* or just those matching the filters.
|
|
@@ -14,7 +14,7 @@ import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
|
|
|
14
14
|
export interface InspectExceptionQuery extends BaseQueryFormat {
|
|
15
15
|
readonly type: 'inspect-exception';
|
|
16
16
|
/** If given, only function definitions that match one of the given slicing criteria are considered. */
|
|
17
|
-
readonly filter?:
|
|
17
|
+
readonly filter?: SlicingCriterion[];
|
|
18
18
|
}
|
|
19
19
|
export interface InspectExceptionQueryResult extends BaseQueryResult {
|
|
20
20
|
/**
|
|
@@ -4,7 +4,7 @@ exports.executeHigherOrderQuery = executeHigherOrderQuery;
|
|
|
4
4
|
const higher_order_function_1 = require("../../../dataflow/fn/higher-order-function");
|
|
5
5
|
const parse_1 = require("../../../slicing/criterion/parse");
|
|
6
6
|
const vertex_1 = require("../../../dataflow/graph/vertex");
|
|
7
|
-
const
|
|
7
|
+
const df_helper_1 = require("../../../dataflow/graph/df-helper");
|
|
8
8
|
/**
|
|
9
9
|
* Execute higher-order function inspection queries on the given analyzer.
|
|
10
10
|
*/
|
|
@@ -26,7 +26,7 @@ async function executeHigherOrderQuery({ analyzer }, queries) {
|
|
|
26
26
|
const filterFor = new Set();
|
|
27
27
|
if (filters) {
|
|
28
28
|
for (const f of filters) {
|
|
29
|
-
const i =
|
|
29
|
+
const i = parse_1.SlicingCriterion.tryParse(f, ast.idMap);
|
|
30
30
|
if (i !== undefined) {
|
|
31
31
|
filterFor.add(i);
|
|
32
32
|
}
|
|
@@ -37,7 +37,7 @@ async function executeHigherOrderQuery({ analyzer }, queries) {
|
|
|
37
37
|
.filter(([, v]) => filterFor.size === 0 || filterFor.has(v.id));
|
|
38
38
|
let invertedGraph;
|
|
39
39
|
if (filterFor.size === 0 || filterFor.size > 10) {
|
|
40
|
-
invertedGraph =
|
|
40
|
+
invertedGraph = df_helper_1.Dataflow.invertGraph(graph, analyzer.inspectContext().env.makeCleanEnv());
|
|
41
41
|
}
|
|
42
42
|
const result = {};
|
|
43
43
|
for (const [id] of fns) {
|
|
@@ -3,7 +3,7 @@ import Joi from 'joi';
|
|
|
3
3
|
import type { ParsedQueryLine } from '../../query';
|
|
4
4
|
import { executeHigherOrderQuery } from './inspect-higher-order-query-executor';
|
|
5
5
|
import { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
|
-
import type {
|
|
6
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
7
7
|
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
8
8
|
import type { FlowrConfig } from '../../../config';
|
|
9
9
|
/**
|
|
@@ -12,7 +12,7 @@ import type { FlowrConfig } from '../../../config';
|
|
|
12
12
|
*/
|
|
13
13
|
export interface InspectHigherOrderQuery extends BaseQueryFormat {
|
|
14
14
|
readonly type: 'inspect-higher-order';
|
|
15
|
-
readonly filter?:
|
|
15
|
+
readonly filter?: SlicingCriterion[];
|
|
16
16
|
}
|
|
17
17
|
export interface InspectHigherOrderQueryResult extends BaseQueryResult {
|
|
18
18
|
readonly higherOrder: Record<NodeId, boolean>;
|
|
@@ -3,7 +3,7 @@ import Joi from 'joi';
|
|
|
3
3
|
import type { ParsedQueryLine } from '../../query';
|
|
4
4
|
import { executeRecursionQuery } from './inspect-recursion-query-executor';
|
|
5
5
|
import { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
|
-
import type {
|
|
6
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
7
7
|
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
8
8
|
import type { FlowrConfig } from '../../../config';
|
|
9
9
|
/**
|
|
@@ -12,7 +12,7 @@ import type { FlowrConfig } from '../../../config';
|
|
|
12
12
|
*/
|
|
13
13
|
export interface InspectRecursionQuery extends BaseQueryFormat {
|
|
14
14
|
readonly type: 'inspect-recursion';
|
|
15
|
-
readonly filter?:
|
|
15
|
+
readonly filter?: SlicingCriterion[];
|
|
16
16
|
}
|
|
17
17
|
export interface InspectRecursionQueryResult extends BaseQueryResult {
|
|
18
18
|
readonly recursive: Record<NodeId, boolean>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.executeLocationMapQuery = executeLocationMapQuery;
|
|
4
|
-
const parse_1 = require("../../../slicing/criterion/parse");
|
|
5
4
|
const assert_1 = require("../../../util/assert");
|
|
5
|
+
const parse_1 = require("../../../slicing/criterion/parse");
|
|
6
6
|
const fileIdRegex = /^(?<file>.*(\.[rR]))-/;
|
|
7
7
|
function fuzzyFindFile(node, idMap) {
|
|
8
8
|
if (node?.info.file) {
|
|
@@ -31,7 +31,7 @@ async function executeLocationMapQuery({ analyzer }, queries) {
|
|
|
31
31
|
const start = Date.now();
|
|
32
32
|
const criteriaOfInterest = new Set(queries
|
|
33
33
|
.flatMap(q => q.ids ?? [])
|
|
34
|
-
.map(c =>
|
|
34
|
+
.map(c => parse_1.SlicingCriterion.tryParse(c, ast.idMap))
|
|
35
35
|
.filter(assert_1.isNotUndefined));
|
|
36
36
|
const locationMap = {
|
|
37
37
|
files: {},
|
|
@@ -4,14 +4,14 @@ import { type OutputFormatter } from '../../../util/text/ansi';
|
|
|
4
4
|
import Joi from 'joi';
|
|
5
5
|
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
6
|
import type { SourceRange } from '../../../util/range';
|
|
7
|
-
import type {
|
|
7
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
8
8
|
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
9
9
|
import type { FlowrConfig } from '../../../config';
|
|
10
10
|
import type { ParsedQueryLine } from '../../query';
|
|
11
11
|
export interface LocationMapQuery extends BaseQueryFormat {
|
|
12
12
|
readonly type: 'location-map';
|
|
13
13
|
/** Optional list of ids to filter the results by. If not provided, all ids will be included. */
|
|
14
|
-
readonly ids?: readonly
|
|
14
|
+
readonly ids?: readonly SlicingCriterion[];
|
|
15
15
|
}
|
|
16
16
|
export type FileId = number & {
|
|
17
17
|
readonly __fileId?: unique symbol;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { BasicQueryData } from '../../base-query-format';
|
|
2
|
-
import {
|
|
2
|
+
import { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
3
3
|
import type { OriginQuery, OriginQueryResult } from './origin-query-format';
|
|
4
4
|
/**
|
|
5
5
|
* Produce a fingerprint string for an origin query
|
|
6
6
|
*/
|
|
7
|
-
export declare function fingerPrintOfQuery(query: OriginQuery):
|
|
7
|
+
export declare function fingerPrintOfQuery(query: OriginQuery): SlicingCriterion;
|
|
8
8
|
/**
|
|
9
9
|
* Execute origin queries, catching duplicates with the same fingerprint
|
|
10
10
|
*/
|
|
@@ -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
|
|
7
|
+
const df_helper_1 = require("../../../dataflow/graph/df-helper");
|
|
8
8
|
/**
|
|
9
9
|
* Produce a fingerprint string for an origin query
|
|
10
10
|
*/
|
|
@@ -22,12 +22,12 @@ async function executeResolveValueQuery({ analyzer }, queries) {
|
|
|
22
22
|
if (results[key]) {
|
|
23
23
|
log_1.log.warn(`Duplicate Key for origin-query: ${key}, skipping...`);
|
|
24
24
|
}
|
|
25
|
-
const astId =
|
|
25
|
+
const astId = parse_1.SlicingCriterion.tryParse(key, (await analyzer.normalize()).idMap);
|
|
26
26
|
if (astId === undefined) {
|
|
27
27
|
log_1.log.warn(`Could not resolve id for ${key}, skipping...`);
|
|
28
28
|
continue;
|
|
29
29
|
}
|
|
30
|
-
results[key] =
|
|
30
|
+
results[key] = df_helper_1.Dataflow.origin((await analyzer.dataflow()).graph, astId);
|
|
31
31
|
}
|
|
32
32
|
return {
|
|
33
33
|
'.meta': {
|