@eagleoutice/flowr 2.4.6 → 2.4.8
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 +37 -33
- package/abstract-interpretation/data-frame/absint-visitor.js +3 -2
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +40 -0
- package/abstract-interpretation/data-frame/dataframe-domain.js +62 -0
- package/abstract-interpretation/data-frame/domain.js +1 -1
- package/abstract-interpretation/domains/abstract-domain.d.ts +56 -0
- package/abstract-interpretation/domains/abstract-domain.js +19 -0
- package/abstract-interpretation/domains/bounded-set-domain.d.ts +43 -0
- package/abstract-interpretation/domains/bounded-set-domain.js +121 -0
- package/abstract-interpretation/domains/interval-domain.d.ts +61 -0
- package/abstract-interpretation/domains/interval-domain.js +208 -0
- package/abstract-interpretation/domains/lattice.d.ts +62 -0
- package/abstract-interpretation/domains/lattice.js +12 -0
- package/abstract-interpretation/domains/positive-interval-domain.d.ts +32 -0
- package/abstract-interpretation/domains/positive-interval-domain.js +91 -0
- package/abstract-interpretation/domains/product-domain.d.ts +37 -0
- package/abstract-interpretation/domains/product-domain.js +133 -0
- package/abstract-interpretation/domains/set-bounded-set-domain.d.ts +43 -0
- package/abstract-interpretation/domains/set-bounded-set-domain.js +164 -0
- package/abstract-interpretation/domains/singleton-domain.d.ts +38 -0
- package/abstract-interpretation/domains/singleton-domain.js +115 -0
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +32 -0
- package/abstract-interpretation/domains/state-abstract-domain.js +179 -0
- package/benchmark/slicer.js +1 -1
- package/benchmark/summarizer/first-phase/process.js +1 -1
- package/cli/repl/commands/repl-query.js +11 -2
- package/cli/repl/core.d.ts +2 -2
- package/cli/repl/core.js +26 -7
- package/cli/repl/server/connection.js +3 -1
- package/cli/repl/server/messages/message-slice.d.ts +3 -0
- package/cli/repl/server/messages/message-slice.js +2 -0
- package/control-flow/extract-cfg.d.ts +3 -3
- package/control-flow/extract-cfg.js +4 -4
- package/control-flow/useless-loop.js +30 -21
- package/dataflow/environments/built-in.d.ts +1 -1
- package/dataflow/environments/default-builtin-config.d.ts +9 -0
- package/dataflow/environments/default-builtin-config.js +21 -21
- package/dataflow/environments/environment.js +18 -9
- package/dataflow/environments/overwrite.js +2 -2
- package/dataflow/extractor.js +1 -1
- package/dataflow/graph/diff-dataflow-graph.js +4 -4
- package/dataflow/graph/graph.d.ts +3 -3
- package/dataflow/graph/graph.js +4 -1
- package/dataflow/graph/quads.js +4 -4
- package/dataflow/info.js +1 -1
- package/dataflow/internal/linker.d.ts +2 -0
- package/dataflow/internal/linker.js +18 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +68 -21
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +1 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -18
- 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-while-loop.js +4 -5
- package/dataflow/internal/process/functions/call/common.js +4 -3
- package/documentation/doc-util/doc-query.js +6 -2
- package/documentation/doc-util/doc-types.d.ts +7 -2
- package/documentation/doc-util/doc-types.js +20 -4
- package/documentation/print-core-wiki.js +5 -1
- package/documentation/print-dataflow-graph-wiki.js +21 -12
- package/documentation/print-faq-wiki.js +5 -0
- package/documentation/print-interface-wiki.js +2 -0
- package/documentation/print-linter-wiki.js +2 -3
- package/documentation/print-query-wiki.js +22 -7
- package/linter/linter-executor.js +25 -17
- package/linter/linter-format.d.ts +10 -1
- package/linter/linter-format.js +8 -0
- package/linter/linter-rules.d.ts +1 -0
- package/linter/rules/absolute-path.js +8 -8
- package/linter/rules/dataframe-access-validation.js +1 -1
- package/linter/rules/file-path-validity.js +8 -11
- package/linter/rules/naming-convention.d.ts +5 -1
- package/linter/rules/naming-convention.js +24 -8
- package/linter/rules/seeded-randomness.js +2 -2
- package/linter/rules/unused-definition.js +1 -1
- package/package.json +17 -15
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +5 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +14 -12
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +6 -5
- package/queries/catalog/call-context-query/call-context-query-format.js +1 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +2 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +1 -1
- package/queries/catalog/config-query/config-query-executor.js +7 -1
- package/queries/catalog/config-query/config-query-format.d.ts +7 -0
- package/queries/catalog/config-query/config-query-format.js +72 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +50 -75
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +50 -26
- package/queries/catalog/dependencies-query/dependencies-query-format.js +75 -20
- package/queries/catalog/dependencies-query/function-info/function-info.d.ts +2 -2
- package/queries/catalog/dependencies-query/function-info/visualize-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/visualize-functions.js +13 -0
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +1 -1
- package/queries/catalog/linter-query/linter-query-format.js +4 -0
- package/queries/query-print.d.ts +2 -2
- package/queries/query-print.js +3 -2
- package/queries/query.d.ts +28 -21
- package/search/flowr-search-builder.d.ts +1 -1
- package/search/flowr-search-builder.js +1 -1
- package/search/flowr-search-filters.d.ts +20 -10
- package/search/flowr-search-filters.js +19 -3
- package/search/search-executor/search-enrichers.d.ts +1 -1
- package/search/search-executor/search-enrichers.js +3 -2
- package/search/search-executor/search-generators.js +1 -1
- package/search/search-executor/search-transformer.js +1 -1
- package/util/objects.d.ts +11 -0
- package/util/objects.js +26 -0
- package/util/version.js +1 -1
|
@@ -3,15 +3,22 @@ import { executeConfigQuery } from './config-query-executor';
|
|
|
3
3
|
import { type OutputFormatter } from '../../../util/text/ansi';
|
|
4
4
|
import Joi from 'joi';
|
|
5
5
|
import type { FlowrConfigOptions } from '../../../config';
|
|
6
|
+
import type { DeepPartial } from 'ts-essentials';
|
|
6
7
|
export interface ConfigQuery extends BaseQueryFormat {
|
|
7
8
|
readonly type: 'config';
|
|
9
|
+
readonly update?: DeepPartial<FlowrConfigOptions>;
|
|
8
10
|
}
|
|
9
11
|
export interface ConfigQueryResult extends BaseQueryResult {
|
|
10
12
|
readonly config: FlowrConfigOptions;
|
|
11
13
|
}
|
|
14
|
+
declare function configReplCompleter(partialLine: readonly string[], config: FlowrConfigOptions): string[];
|
|
15
|
+
declare function configQueryLineParser(line: readonly string[], _config: FlowrConfigOptions): [ConfigQuery];
|
|
12
16
|
export declare const ConfigQueryDefinition: {
|
|
13
17
|
readonly executor: typeof executeConfigQuery;
|
|
14
18
|
readonly asciiSummarizer: (formatter: OutputFormatter, _processed: unknown, queryResults: BaseQueryResult, result: string[]) => boolean;
|
|
19
|
+
readonly completer: typeof configReplCompleter;
|
|
20
|
+
readonly fromLine: typeof configQueryLineParser;
|
|
15
21
|
readonly schema: Joi.ObjectSchema<any>;
|
|
16
22
|
readonly flattenInvolvedNodes: () => never[];
|
|
17
23
|
};
|
|
24
|
+
export {};
|
|
@@ -9,6 +9,74 @@ const ansi_1 = require("../../../util/text/ansi");
|
|
|
9
9
|
const time_1 = require("../../../util/text/time");
|
|
10
10
|
const joi_1 = __importDefault(require("joi"));
|
|
11
11
|
const json_1 = require("../../../util/json");
|
|
12
|
+
function configReplCompleter(partialLine, config) {
|
|
13
|
+
if (partialLine.length === 0) {
|
|
14
|
+
// update specific fields
|
|
15
|
+
return ['+'];
|
|
16
|
+
}
|
|
17
|
+
else if (partialLine.length === 1 && partialLine[0].startsWith('+')) {
|
|
18
|
+
const path = partialLine[0].slice(1).split('.').filter(p => p.length > 0);
|
|
19
|
+
const fullPath = path.slice();
|
|
20
|
+
const lastPath = partialLine[0].endsWith('.') ? '' : path.pop() ?? '';
|
|
21
|
+
if (lastPath.endsWith('=')) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const subConfig = path.reduce((obj, key) => (obj && obj[key] !== undefined && typeof obj[key] === 'object') ? obj[key] : obj, config);
|
|
25
|
+
if (subConfig && !(subConfig[lastPath] !== undefined && typeof subConfig[lastPath] !== 'object')) {
|
|
26
|
+
const have = Object.keys(subConfig)
|
|
27
|
+
.filter(k => k.startsWith(lastPath) && k !== lastPath)
|
|
28
|
+
.map(k => `${partialLine[0].slice(0, 1)}${[...path, k].join('.')}`);
|
|
29
|
+
if (have.length > 0) {
|
|
30
|
+
return have;
|
|
31
|
+
}
|
|
32
|
+
else if (lastPath.length > 0) {
|
|
33
|
+
return [`${partialLine[0].slice(0, 1)}${fullPath.join('.')}.`];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return [`${partialLine[0].slice(0, 1)}${fullPath.join('.')}=`];
|
|
37
|
+
}
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
function configQueryLineParser(line, _config) {
|
|
41
|
+
if (line.length > 0 && line[0].startsWith('+')) {
|
|
42
|
+
const [pathPart, ...valueParts] = line[0].slice(1).split('=');
|
|
43
|
+
// build the update object
|
|
44
|
+
const path = pathPart.split('.').filter(p => p.length > 0);
|
|
45
|
+
if (path.length === 0 || valueParts.length !== 1) {
|
|
46
|
+
console.error('Invalid config update syntax, must be of the form +path.to.field=value');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const update = {};
|
|
50
|
+
const value = valueParts[0];
|
|
51
|
+
let current = update;
|
|
52
|
+
for (let i = 0; i < path.length; i++) {
|
|
53
|
+
const key = path[i];
|
|
54
|
+
if (i === path.length - 1) {
|
|
55
|
+
// last part, set the value
|
|
56
|
+
// try to parse as JSON first
|
|
57
|
+
try {
|
|
58
|
+
current[key] = JSON.parse(value);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// fallback to string
|
|
62
|
+
current[key] = value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
current[key] = {};
|
|
67
|
+
current = current[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return [{
|
|
71
|
+
type: 'config',
|
|
72
|
+
update
|
|
73
|
+
}];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return [{
|
|
77
|
+
type: 'config'
|
|
78
|
+
}];
|
|
79
|
+
}
|
|
12
80
|
exports.ConfigQueryDefinition = {
|
|
13
81
|
executor: config_query_executor_1.executeConfigQuery,
|
|
14
82
|
asciiSummarizer: (formatter, _processed, queryResults, result) => {
|
|
@@ -17,9 +85,12 @@ exports.ConfigQueryDefinition = {
|
|
|
17
85
|
result.push(` ╰ Config:\n${JSON.stringify(out.config, json_1.jsonReplacer, 4)}`);
|
|
18
86
|
return true;
|
|
19
87
|
},
|
|
88
|
+
completer: configReplCompleter,
|
|
89
|
+
fromLine: configQueryLineParser,
|
|
20
90
|
schema: joi_1.default.object({
|
|
21
91
|
type: joi_1.default.string().valid('config').required().description('The type of the query.'),
|
|
22
|
-
|
|
92
|
+
update: joi_1.default.object().optional().description('An optional partial configuration to update the current configuration with before returning it. Only the provided fields will be updated, all other fields will remain unchanged.')
|
|
93
|
+
}).description('The config query retrieves the current configuration of the flowR instance and optionally also updates it.'),
|
|
23
94
|
flattenInvolvedNodes: () => []
|
|
24
95
|
};
|
|
25
96
|
//# sourceMappingURL=config-query-format.js.map
|
|
@@ -6,29 +6,11 @@ const dependencies_query_format_1 = require("./dependencies-query-format");
|
|
|
6
6
|
const vertex_1 = require("../../../dataflow/graph/vertex");
|
|
7
7
|
const log_1 = require("../../../util/log");
|
|
8
8
|
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
9
|
-
const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visitor");
|
|
10
9
|
const objects_1 = require("../../../util/objects");
|
|
11
|
-
const library_functions_1 = require("./function-info/library-functions");
|
|
12
|
-
const source_functions_1 = require("./function-info/source-functions");
|
|
13
|
-
const read_functions_1 = require("./function-info/read-functions");
|
|
14
|
-
const write_functions_1 = require("./function-info/write-functions");
|
|
15
10
|
const function_info_1 = require("./function-info/function-info");
|
|
16
11
|
const identify_link_to_last_call_relation_1 = require("../call-context-query/identify-link-to-last-call-relation");
|
|
17
12
|
const resolve_argument_1 = require("../../../dataflow/eval/resolve/resolve-argument");
|
|
18
13
|
const assert_1 = require("../../../util/assert");
|
|
19
|
-
function collectNamespaceAccesses(data, libraries) {
|
|
20
|
-
/* for libraries, we have to additionally track all uses of `::` and `:::`, for this we currently simply traverse all uses */
|
|
21
|
-
(0, visitor_1.visitAst)(data.ast.ast, n => {
|
|
22
|
-
if (n.type === type_1.RType.Symbol && n.namespace) {
|
|
23
|
-
/* we should improve the identification of ':::' */
|
|
24
|
-
libraries.push({
|
|
25
|
-
nodeId: n.info.id,
|
|
26
|
-
functionName: (n.info.fullLexeme ?? n.lexeme).includes(':::') ? ':::' : '::',
|
|
27
|
-
libraryName: n.namespace,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
14
|
function executeDependenciesQuery(data, queries) {
|
|
33
15
|
if (queries.length !== 1) {
|
|
34
16
|
log_1.log.warn('Dependencies query expects only up to one query, but got ', queries.length, 'only using the first query');
|
|
@@ -36,64 +18,28 @@ function executeDependenciesQuery(data, queries) {
|
|
|
36
18
|
const now = Date.now();
|
|
37
19
|
const [query] = queries;
|
|
38
20
|
const ignoreDefault = query.ignoreDefaultFunctions ?? false;
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
const readFunctions = getFunctionsToCheck(query.readFunctions, ignoreDefault, read_functions_1.ReadFunctions);
|
|
42
|
-
const writeFunctions = getFunctionsToCheck(query.writeFunctions, ignoreDefault, write_functions_1.WriteFunctions);
|
|
43
|
-
const numberOfFunctions = libraryFunctions.length + sourceFunctions.length + readFunctions.length + writeFunctions.length;
|
|
44
|
-
const results = numberOfFunctions === 0 ? { kinds: {}, '.meta': { timing: 0 } } : (0, query_1.executeQueriesOfSameType)(data, [
|
|
45
|
-
makeCallContextQuery(libraryFunctions, 'library'),
|
|
46
|
-
makeCallContextQuery(sourceFunctions, 'source'),
|
|
47
|
-
makeCallContextQuery(readFunctions, 'read'),
|
|
48
|
-
makeCallContextQuery(writeFunctions, 'write')
|
|
49
|
-
].flat());
|
|
50
|
-
function getLexeme(argument, id) {
|
|
51
|
-
if ((argument && argument !== dependencies_query_format_1.Unknown) || !id) {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
let get = data.ast.idMap.get(id);
|
|
55
|
-
if (get?.type === type_1.RType.Argument) {
|
|
56
|
-
get = get.value;
|
|
57
|
-
}
|
|
58
|
-
return get?.info.fullLexeme ?? get?.lexeme;
|
|
59
|
-
}
|
|
60
|
-
const libraries = getResults(data, results, 'library', libraryFunctions, (id, vertex, argId, value, linkedIds) => ({
|
|
61
|
-
nodeId: id,
|
|
62
|
-
functionName: vertex.name,
|
|
63
|
-
lexemeOfArgument: getLexeme(value, argId),
|
|
64
|
-
libraryName: value ?? dependencies_query_format_1.Unknown,
|
|
65
|
-
linkedIds: linkedIds?.length ? linkedIds : undefined
|
|
21
|
+
const functions = new Map(Object.entries(dependencies_query_format_1.DefaultDependencyCategories).map(([c, v]) => {
|
|
22
|
+
return [c, getFunctionsToCheck(query[`${c}Functions`], c, query.enabledCategories, ignoreDefault, v.functions)];
|
|
66
23
|
}));
|
|
67
|
-
if (
|
|
68
|
-
|
|
24
|
+
if (query.additionalCategories !== undefined) {
|
|
25
|
+
for (const [category, value] of Object.entries(query.additionalCategories)) {
|
|
26
|
+
// custom categories only use the "functions" collection and do not allow specifying additional functions in the object itself, so we "undefined" a lot here
|
|
27
|
+
functions.set(category, getFunctionsToCheck(undefined, category, undefined, false, value.functions));
|
|
28
|
+
}
|
|
69
29
|
}
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const readData = getResults(data, results, 'read', readFunctions, (id, vertex, argId, value, linkedIds) => ({
|
|
78
|
-
nodeId: id,
|
|
79
|
-
functionName: vertex.name,
|
|
80
|
-
source: value ?? dependencies_query_format_1.Unknown,
|
|
81
|
-
lexemeOfArgument: getLexeme(value, argId),
|
|
82
|
-
linkedIds: linkedIds?.length ? linkedIds : undefined
|
|
83
|
-
}));
|
|
84
|
-
const writtenData = getResults(data, results, 'write', writeFunctions, (id, vertex, argId, value, linkedIds) => ({
|
|
85
|
-
nodeId: id,
|
|
86
|
-
functionName: vertex.name,
|
|
87
|
-
// write functions that don't have argIndex are assumed to write to stdout
|
|
88
|
-
destination: value ?? 'stdout',
|
|
89
|
-
lexemeOfArgument: getLexeme(value, argId),
|
|
90
|
-
linkedIds: linkedIds?.length ? linkedIds : undefined
|
|
30
|
+
const queryResults = functions.values().toArray().flat().length === 0 ? { kinds: {}, '.meta': { timing: 0 } } :
|
|
31
|
+
(0, query_1.executeQueriesOfSameType)(data, functions.entries().map(([c, f]) => makeCallContextQuery(f, c)).toArray().flat());
|
|
32
|
+
const results = Object.fromEntries(functions.entries().map(([c, f]) => {
|
|
33
|
+
const results = getResults(queries, data, queryResults, c, f);
|
|
34
|
+
// only default categories allow additional analyses, so we null coalese here!
|
|
35
|
+
dependencies_query_format_1.DefaultDependencyCategories[c]?.additionalAnalysis?.(data, ignoreDefault, f, queryResults, results);
|
|
36
|
+
return [c, results];
|
|
91
37
|
}));
|
|
92
38
|
return {
|
|
93
39
|
'.meta': {
|
|
94
40
|
timing: Date.now() - now
|
|
95
41
|
},
|
|
96
|
-
|
|
42
|
+
...results
|
|
97
43
|
};
|
|
98
44
|
}
|
|
99
45
|
function makeCallContextQuery(functions, kind) {
|
|
@@ -116,19 +62,28 @@ function dropInfoOnLinkedIds(linkedIds) {
|
|
|
116
62
|
}
|
|
117
63
|
const readOnlyModes = new Set(['r', 'rt', 'rb']);
|
|
118
64
|
const writeOnlyModes = new Set(['w', 'wt', 'wb', 'a', 'at', 'ab']);
|
|
119
|
-
function getResults(data, results, kind, functions
|
|
65
|
+
function getResults(queries, data, results, kind, functions) {
|
|
66
|
+
const defaultValue = (0, dependencies_query_format_1.getAllCategories)(queries)[kind].defaultValue;
|
|
67
|
+
const functionMap = new Map(functions.map(f => [f.name, f]));
|
|
120
68
|
const kindEntries = Object.entries(results?.kinds[kind]?.subkinds ?? {});
|
|
121
69
|
return kindEntries.flatMap(([name, results]) => results.flatMap(({ id, linkedIds }) => {
|
|
122
70
|
const vertex = data.dataflow.graph.getVertex(id);
|
|
123
|
-
const info =
|
|
71
|
+
const info = functionMap.get(name);
|
|
124
72
|
const args = (0, resolve_argument_1.getArgumentStringValue)(data.config.solver.variables, data.dataflow.graph, vertex, info.argIdx, info.argName, info.resolveValue);
|
|
125
73
|
const linkedArgs = collectValuesFromLinks(args, data, linkedIds);
|
|
74
|
+
const linked = dropInfoOnLinkedIds(linkedIds);
|
|
126
75
|
const foundValues = linkedArgs ?? args;
|
|
127
76
|
if (!foundValues) {
|
|
128
77
|
if (info.ignoreIf === 'arg-missing') {
|
|
129
78
|
return [];
|
|
130
79
|
}
|
|
131
|
-
const record = (0, objects_1.compactRecord)(
|
|
80
|
+
const record = (0, objects_1.compactRecord)({
|
|
81
|
+
nodeId: id,
|
|
82
|
+
functionName: vertex.name,
|
|
83
|
+
lexemeOfArgument: undefined,
|
|
84
|
+
linkedIds: linked?.length ? linked : undefined,
|
|
85
|
+
value: defaultValue
|
|
86
|
+
});
|
|
132
87
|
return record ? [record] : [];
|
|
133
88
|
}
|
|
134
89
|
else if (info.ignoreIf === 'mode-only-read' || info.ignoreIf === 'mode-only-write') {
|
|
@@ -136,7 +91,7 @@ function getResults(data, results, kind, functions, makeInfo) {
|
|
|
136
91
|
const margs = info.additionalArgs?.mode;
|
|
137
92
|
(0, assert_1.guard)(margs, 'Need additional argument mode when checking for mode');
|
|
138
93
|
const modeArgs = (0, resolve_argument_1.getArgumentStringValue)(data.config.solver.variables, data.dataflow.graph, vertex, margs.argIdx, margs.argName, margs.resolveValue);
|
|
139
|
-
const modeValues =
|
|
94
|
+
const modeValues = modeArgs?.values().flatMap(v => [...v]) ?? [];
|
|
140
95
|
if (info.ignoreIf === 'mode-only-read' && modeValues.every(m => m && readOnlyModes.has(m))) {
|
|
141
96
|
// all modes are read-only, so we can ignore this
|
|
142
97
|
return [];
|
|
@@ -149,7 +104,13 @@ function getResults(data, results, kind, functions, makeInfo) {
|
|
|
149
104
|
const results = [];
|
|
150
105
|
for (const [arg, values] of foundValues.entries()) {
|
|
151
106
|
for (const value of values) {
|
|
152
|
-
const result = (0, objects_1.compactRecord)(
|
|
107
|
+
const result = (0, objects_1.compactRecord)({
|
|
108
|
+
nodeId: id,
|
|
109
|
+
functionName: vertex.name,
|
|
110
|
+
lexemeOfArgument: getLexeme(value, arg),
|
|
111
|
+
linkedIds: linked?.length ? linked : undefined,
|
|
112
|
+
value: value ?? defaultValue
|
|
113
|
+
});
|
|
153
114
|
if (result) {
|
|
154
115
|
results.push(result);
|
|
155
116
|
}
|
|
@@ -157,6 +118,16 @@ function getResults(data, results, kind, functions, makeInfo) {
|
|
|
157
118
|
}
|
|
158
119
|
return results;
|
|
159
120
|
})) ?? [];
|
|
121
|
+
function getLexeme(argument, id) {
|
|
122
|
+
if ((argument && argument !== dependencies_query_format_1.Unknown) || !id) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
let get = data.ast.idMap.get(id);
|
|
126
|
+
if (get?.type === type_1.RType.Argument) {
|
|
127
|
+
get = get.value;
|
|
128
|
+
}
|
|
129
|
+
return get?.info.fullLexeme ?? get?.lexeme;
|
|
130
|
+
}
|
|
160
131
|
}
|
|
161
132
|
function collectValuesFromLinks(args, data, linkedIds) {
|
|
162
133
|
if (!linkedIds || linkedIds.length === 0) {
|
|
@@ -192,7 +163,11 @@ function collectValuesFromLinks(args, data, linkedIds) {
|
|
|
192
163
|
}
|
|
193
164
|
return map.size ? map : undefined;
|
|
194
165
|
}
|
|
195
|
-
function getFunctionsToCheck(customFunctions, ignoreDefaultFunctions, defaultFunctions) {
|
|
166
|
+
function getFunctionsToCheck(customFunctions, functionFlag, enabled, ignoreDefaultFunctions, defaultFunctions) {
|
|
167
|
+
// "If unset or empty, all function types are searched for."
|
|
168
|
+
if (enabled?.length && enabled.indexOf(functionFlag) < 0) {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
196
171
|
let functions = ignoreDefaultFunctions ? [] : [...defaultFunctions];
|
|
197
172
|
if (customFunctions) {
|
|
198
173
|
functions = functions.concat(customFunctions);
|
|
@@ -1,42 +1,66 @@
|
|
|
1
|
-
import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
|
|
1
|
+
import type { BaseQueryFormat, BaseQueryResult, BasicQueryData } from '../../base-query-format';
|
|
2
2
|
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import { executeDependenciesQuery } from './dependencies-query-executor';
|
|
5
5
|
import type { FunctionInfo } from './function-info/function-info';
|
|
6
|
+
import type { CallContextQueryResult } from '../call-context-query/call-context-query-format';
|
|
6
7
|
export declare const Unknown = "unknown";
|
|
7
|
-
export interface
|
|
8
|
+
export interface DependencyCategorySettings {
|
|
9
|
+
queryDisplayName?: string;
|
|
10
|
+
functions: FunctionInfo[];
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
additionalAnalysis?: (data: BasicQueryData, ignoreDefault: boolean, functions: FunctionInfo[], queryResults: CallContextQueryResult, result: DependencyInfo[]) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const DefaultDependencyCategories: {
|
|
15
|
+
readonly library: {
|
|
16
|
+
readonly queryDisplayName: "Libraries";
|
|
17
|
+
readonly functions: FunctionInfo[];
|
|
18
|
+
readonly defaultValue: "unknown";
|
|
19
|
+
readonly additionalAnalysis: (data: BasicQueryData, ignoreDefault: boolean, _functions: FunctionInfo[], _queryResults: CallContextQueryResult, result: DependencyInfo[]) => void;
|
|
20
|
+
};
|
|
21
|
+
readonly source: {
|
|
22
|
+
readonly queryDisplayName: "Sourced Files";
|
|
23
|
+
readonly functions: FunctionInfo[];
|
|
24
|
+
readonly defaultValue: "unknown";
|
|
25
|
+
};
|
|
26
|
+
readonly read: {
|
|
27
|
+
readonly queryDisplayName: "Read Data";
|
|
28
|
+
readonly functions: FunctionInfo[];
|
|
29
|
+
readonly defaultValue: "unknown";
|
|
30
|
+
};
|
|
31
|
+
readonly write: {
|
|
32
|
+
readonly queryDisplayName: "Written Data";
|
|
33
|
+
readonly functions: FunctionInfo[];
|
|
34
|
+
readonly defaultValue: "stdout";
|
|
35
|
+
};
|
|
36
|
+
readonly visualize: {
|
|
37
|
+
readonly queryDisplayName: "Visualizations";
|
|
38
|
+
readonly functions: FunctionInfo[];
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type DefaultDependencyCategoryName = keyof typeof DefaultDependencyCategories;
|
|
42
|
+
export type DependencyCategoryName = DefaultDependencyCategoryName | string;
|
|
43
|
+
export interface DependenciesQuery extends BaseQueryFormat, Partial<Record<`${DefaultDependencyCategoryName}Functions`, FunctionInfo[]>> {
|
|
8
44
|
readonly type: 'dependencies';
|
|
45
|
+
readonly enabledCategories?: DependencyCategoryName[];
|
|
9
46
|
readonly ignoreDefaultFunctions?: boolean;
|
|
10
|
-
readonly
|
|
11
|
-
readonly sourceFunctions?: FunctionInfo[];
|
|
12
|
-
readonly readFunctions?: FunctionInfo[];
|
|
13
|
-
readonly writeFunctions?: FunctionInfo[];
|
|
14
|
-
}
|
|
15
|
-
export interface DependenciesQueryResult extends BaseQueryResult {
|
|
16
|
-
libraries: LibraryInfo[];
|
|
17
|
-
sourcedFiles: SourceInfo[];
|
|
18
|
-
readData: ReadInfo[];
|
|
19
|
-
writtenData: WriteInfo[];
|
|
47
|
+
readonly additionalCategories?: Record<string, Omit<DependencyCategorySettings, 'additionalAnalysis'>>;
|
|
20
48
|
}
|
|
49
|
+
export type DependenciesQueryResult = BaseQueryResult & {
|
|
50
|
+
[C in DefaultDependencyCategoryName]: DependencyInfo[];
|
|
51
|
+
} & {
|
|
52
|
+
[S in string]?: DependencyInfo[];
|
|
53
|
+
};
|
|
21
54
|
export interface DependencyInfo extends Record<string, unknown> {
|
|
22
55
|
nodeId: NodeId;
|
|
23
56
|
functionName: string;
|
|
24
57
|
linkedIds?: readonly NodeId[];
|
|
25
58
|
/** the lexeme is presented whenever the specific info is of {@link Unknown} */
|
|
26
59
|
lexemeOfArgument?: string;
|
|
60
|
+
/** The library name, file, source, destination etc. being sourced, read from, or written to. */
|
|
61
|
+
value?: string;
|
|
27
62
|
}
|
|
28
|
-
export
|
|
29
|
-
libraryName: 'unknown' | string;
|
|
30
|
-
});
|
|
31
|
-
export type SourceInfo = (DependencyInfo & {
|
|
32
|
-
file: string;
|
|
33
|
-
});
|
|
34
|
-
export type ReadInfo = (DependencyInfo & {
|
|
35
|
-
source: string;
|
|
36
|
-
});
|
|
37
|
-
export type WriteInfo = (DependencyInfo & {
|
|
38
|
-
destination: 'stdout' | string;
|
|
39
|
-
});
|
|
63
|
+
export declare function getAllCategories(queries: readonly DependenciesQuery[]): Record<DependencyCategoryName, DependencyCategorySettings>;
|
|
40
64
|
export declare const DependenciesQueryDefinition: {
|
|
41
65
|
readonly executor: typeof executeDependenciesQuery;
|
|
42
66
|
readonly asciiSummarizer: (formatter: import("../../../util/text/ansi").OutputFormatter, _processed: import("../../../core/steps/pipeline/pipeline").PipelineOutput<import("../../../core/steps/pipeline/pipeline").Pipeline<{
|
|
@@ -92,7 +116,7 @@ export declare const DependenciesQueryDefinition: {
|
|
|
92
116
|
readonly 4: typeof import("../../../core/print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
93
117
|
};
|
|
94
118
|
readonly dependencies: readonly ["normalize"];
|
|
95
|
-
}>>, queryResults: BaseQueryResult, result: string[]) => true;
|
|
119
|
+
}>>, queryResults: BaseQueryResult, result: string[], queries: readonly import("../../query").Query[]) => true;
|
|
96
120
|
readonly schema: Joi.ObjectSchema<any>;
|
|
97
|
-
readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
|
|
121
|
+
readonly flattenInvolvedNodes: (queryResults: BaseQueryResult, query: readonly import("../../query").Query[]) => NodeId[];
|
|
98
122
|
};
|
|
@@ -3,13 +3,62 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DependenciesQueryDefinition = exports.Unknown = void 0;
|
|
6
|
+
exports.DependenciesQueryDefinition = exports.DefaultDependencyCategories = exports.Unknown = void 0;
|
|
7
|
+
exports.getAllCategories = getAllCategories;
|
|
7
8
|
const ansi_1 = require("../../../util/text/ansi");
|
|
8
9
|
const time_1 = require("../../../util/text/time");
|
|
9
10
|
const joi_1 = __importDefault(require("joi"));
|
|
10
11
|
const dependencies_query_executor_1 = require("./dependencies-query-executor");
|
|
12
|
+
const library_functions_1 = require("./function-info/library-functions");
|
|
13
|
+
const source_functions_1 = require("./function-info/source-functions");
|
|
14
|
+
const read_functions_1 = require("./function-info/read-functions");
|
|
15
|
+
const write_functions_1 = require("./function-info/write-functions");
|
|
16
|
+
const visualize_functions_1 = require("./function-info/visualize-functions");
|
|
17
|
+
const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visitor");
|
|
18
|
+
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
11
19
|
exports.Unknown = 'unknown';
|
|
12
|
-
|
|
20
|
+
exports.DefaultDependencyCategories = {
|
|
21
|
+
'library': {
|
|
22
|
+
queryDisplayName: 'Libraries',
|
|
23
|
+
functions: library_functions_1.LibraryFunctions,
|
|
24
|
+
defaultValue: exports.Unknown,
|
|
25
|
+
/* for libraries, we have to additionally track all uses of `::` and `:::`, for this we currently simply traverse all uses */
|
|
26
|
+
additionalAnalysis: (data, ignoreDefault, _functions, _queryResults, result) => {
|
|
27
|
+
if (!ignoreDefault) {
|
|
28
|
+
(0, visitor_1.visitAst)(data.ast.ast, n => {
|
|
29
|
+
if (n.type === type_1.RType.Symbol && n.namespace) {
|
|
30
|
+
/* we should improve the identification of ':::' */
|
|
31
|
+
result.push({
|
|
32
|
+
nodeId: n.info.id,
|
|
33
|
+
functionName: (n.info.fullLexeme ?? n.lexeme).includes(':::') ? ':::' : '::',
|
|
34
|
+
value: n.namespace,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
'source': {
|
|
42
|
+
queryDisplayName: 'Sourced Files',
|
|
43
|
+
functions: source_functions_1.SourceFunctions,
|
|
44
|
+
defaultValue: exports.Unknown
|
|
45
|
+
},
|
|
46
|
+
'read': {
|
|
47
|
+
queryDisplayName: 'Read Data',
|
|
48
|
+
functions: read_functions_1.ReadFunctions,
|
|
49
|
+
defaultValue: exports.Unknown
|
|
50
|
+
},
|
|
51
|
+
'write': {
|
|
52
|
+
queryDisplayName: 'Written Data',
|
|
53
|
+
functions: write_functions_1.WriteFunctions,
|
|
54
|
+
defaultValue: 'stdout'
|
|
55
|
+
},
|
|
56
|
+
'visualize': {
|
|
57
|
+
queryDisplayName: 'Visualizations',
|
|
58
|
+
functions: visualize_functions_1.VisualizeFunctions
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function printResultSection(title, infos, result) {
|
|
13
62
|
if (infos.length <= 0) {
|
|
14
63
|
return;
|
|
15
64
|
}
|
|
@@ -26,9 +75,18 @@ function printResultSection(title, infos, result, sectionSpecifics) {
|
|
|
26
75
|
}, new Map());
|
|
27
76
|
for (const [functionName, infos] of grouped) {
|
|
28
77
|
result.push(` ╰ \`${functionName}\``);
|
|
29
|
-
result.push(infos.map(i => ` ╰ Node Id: ${i.nodeId}
|
|
78
|
+
result.push(infos.map(i => ` ╰ Node Id: ${i.nodeId}${i.value !== undefined ? `, \`${i.value}\`` : ''}`).join('\n'));
|
|
30
79
|
}
|
|
31
80
|
}
|
|
81
|
+
function getAllCategories(queries) {
|
|
82
|
+
let categories = exports.DefaultDependencyCategories;
|
|
83
|
+
for (const query of queries) {
|
|
84
|
+
if (query.additionalCategories) {
|
|
85
|
+
categories = { ...categories, ...query.additionalCategories };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return categories;
|
|
89
|
+
}
|
|
32
90
|
const functionInfoSchema = joi_1.default.array().items(joi_1.default.object({
|
|
33
91
|
name: joi_1.default.string().required().description('The name of the library function.'),
|
|
34
92
|
package: joi_1.default.string().optional().description('The package name of the library function'),
|
|
@@ -37,31 +95,28 @@ const functionInfoSchema = joi_1.default.array().items(joi_1.default.object({
|
|
|
37
95
|
})).optional();
|
|
38
96
|
exports.DependenciesQueryDefinition = {
|
|
39
97
|
executor: dependencies_query_executor_1.executeDependenciesQuery,
|
|
40
|
-
asciiSummarizer: (formatter, _processed, queryResults, result) => {
|
|
98
|
+
asciiSummarizer: (formatter, _processed, queryResults, result, queries) => {
|
|
41
99
|
const out = queryResults;
|
|
42
100
|
result.push(`Query: ${(0, ansi_1.bold)('dependencies', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
printResultSection('Written Data', out.writtenData, result, w => `\`${w.destination}\``);
|
|
101
|
+
for (const [category, value] of Object.entries(getAllCategories(queries))) {
|
|
102
|
+
printResultSection(value.queryDisplayName ?? category, out[category] ?? [], result);
|
|
103
|
+
}
|
|
47
104
|
return true;
|
|
48
105
|
},
|
|
49
106
|
schema: joi_1.default.object({
|
|
50
107
|
type: joi_1.default.string().valid('dependencies').required().description('The type of the query.'),
|
|
51
|
-
ignoreDefaultFunctions: joi_1.default.boolean().optional().description('Should the set of functions that are detected by default be ignored/skipped?'),
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
108
|
+
ignoreDefaultFunctions: joi_1.default.boolean().optional().description('Should the set of functions that are detected by default be ignored/skipped? Defaults to false.'),
|
|
109
|
+
...Object.fromEntries(Object.keys(exports.DefaultDependencyCategories).map(c => [`${c}Functions`, functionInfoSchema.description(`The set of ${c} functions to search for.`)])),
|
|
110
|
+
enabledCategories: joi_1.default.array().optional().items(joi_1.default.string().valid(...Object.keys(exports.DefaultDependencyCategories))).description('A set of flags that determines what types of dependencies are searched for. If unset or empty, all dependency types are searched for.'),
|
|
111
|
+
additionalCategories: joi_1.default.object().allow(joi_1.default.object({
|
|
112
|
+
queryDisplayName: joi_1.default.string().description('The display name in the query result.'),
|
|
113
|
+
functions: functionInfoSchema.description('The functions that this additional category should search for.'),
|
|
114
|
+
defaultValue: joi_1.default.string().description('The default value to return when there is no value to gather from the function information.').optional()
|
|
115
|
+
})).description('A set of additional, user-supplied dependency categories, whose results will be included in the query return value.').optional()
|
|
56
116
|
}).description('The dependencies query retrieves and returns the set of all dependencies in the dataflow graph, which includes libraries, sourced files, read data, and written data.'),
|
|
57
|
-
flattenInvolvedNodes: (queryResults) => {
|
|
117
|
+
flattenInvolvedNodes: (queryResults, query) => {
|
|
58
118
|
const out = queryResults;
|
|
59
|
-
return [
|
|
60
|
-
...out.libraries.map(library => library.nodeId),
|
|
61
|
-
...out.sourcedFiles.map(sourced => sourced.nodeId),
|
|
62
|
-
...out.readData.map(read => read.nodeId),
|
|
63
|
-
...out.writtenData.map(write => write.nodeId)
|
|
64
|
-
];
|
|
119
|
+
return Object.keys(getAllCategories(query)).flatMap(c => out[c] ?? []).map(o => o.nodeId);
|
|
65
120
|
}
|
|
66
121
|
};
|
|
67
122
|
//# sourceMappingURL=dependencies-query-format.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LinkTo } from '../../call-context-query/call-context-query-format';
|
|
1
|
+
import type { CallNameTypes, LinkTo } from '../../call-context-query/call-context-query-format';
|
|
2
2
|
/** when to read the argument value from a linked function */
|
|
3
3
|
export declare enum DependencyInfoLinkConstraint {
|
|
4
4
|
Always = "always",
|
|
@@ -8,7 +8,7 @@ export declare enum DependencyInfoLinkConstraint {
|
|
|
8
8
|
* A dependency link may have attached information. If you pass it, we try to resolve the argument value from the linked function
|
|
9
9
|
* if the `when` constraint is met.
|
|
10
10
|
*/
|
|
11
|
-
export type DependencyInfoLink = LinkTo<
|
|
11
|
+
export type DependencyInfoLink = LinkTo<CallNameTypes, Omit<FunctionInfo, 'name' | 'linkTo' | 'package'> & {
|
|
12
12
|
when: DependencyInfoLinkConstraint;
|
|
13
13
|
} | undefined>;
|
|
14
14
|
export type DependencyInfoLinkAttachedInfo = DependencyInfoLink['attachLinkInfo'];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VisualizeFunctions = void 0;
|
|
4
|
+
const default_builtin_config_1 = require("../../../../dataflow/environments/default-builtin-config");
|
|
5
|
+
const LinkToPlotCreation = [
|
|
6
|
+
{ type: 'link-to-last-call', callName: default_builtin_config_1.PlotCreate }
|
|
7
|
+
];
|
|
8
|
+
exports.VisualizeFunctions =
|
|
9
|
+
// plot creation
|
|
10
|
+
default_builtin_config_1.GgPlotCreate.map(f => ({ package: 'ggplot2', name: f })).concat(default_builtin_config_1.TinyPlotCrate.map(f => ({ package: 'tinyplot', name: f })), default_builtin_config_1.GraphicsPlotCreate.map(f => ({ name: f })),
|
|
11
|
+
// plot modification
|
|
12
|
+
default_builtin_config_1.GgPlotImplicitAddons.concat(default_builtin_config_1.GgPlotAddons).map(f => ({ package: 'ggplot2', name: f, linkTo: LinkToPlotCreation })), default_builtin_config_1.TinyPlotAddons.map(f => ({ package: 'tinyplot', name: f, linkTo: LinkToPlotCreation })), default_builtin_config_1.GraphicsPlotAddons.map(f => ({ name: f, linkTo: LinkToPlotCreation })));
|
|
13
|
+
//# sourceMappingURL=visualize-functions.js.map
|
|
@@ -9,7 +9,7 @@ const parse_1 = require("../../../slicing/criterion/parse");
|
|
|
9
9
|
function executeHappensBefore({ ast }, queries) {
|
|
10
10
|
const start = Date.now();
|
|
11
11
|
const results = {};
|
|
12
|
-
const cfg = (0, extract_cfg_1.
|
|
12
|
+
const cfg = (0, extract_cfg_1.extractCfgQuick)(ast);
|
|
13
13
|
for (const query of queries) {
|
|
14
14
|
const { a, b } = query;
|
|
15
15
|
const fingerprint = `${a}<${b}`;
|
|
@@ -33,6 +33,10 @@ exports.LinterQueryDefinition = {
|
|
|
33
33
|
function addLintingRuleResult(ruleName, results, result) {
|
|
34
34
|
const rule = linter_rules_1.LintingRules[ruleName];
|
|
35
35
|
result.push(` ╰ **${rule.info.name}** (${ruleName}):`);
|
|
36
|
+
if ((0, linter_format_1.isLintingResultsError)(results)) {
|
|
37
|
+
result.push(` ╰ Error during execution of Rule: ${results.error}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
36
40
|
for (const certainty of [linter_format_1.LintingResultCertainty.Certain, linter_format_1.LintingResultCertainty.Uncertain]) {
|
|
37
41
|
const certaintyResults = results.results.filter(r => r.certainty === certainty);
|
|
38
42
|
if (certaintyResults.length) {
|
package/queries/query-print.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { OutputFormatter } from '../util/text/ansi';
|
|
2
|
-
import type { QueryResults, SupportedQueryTypes } from './query';
|
|
2
|
+
import type { Queries, QueryResults, SupportedQueryTypes } from './query';
|
|
3
3
|
import type { PipelineOutput } from '../core/steps/pipeline/pipeline';
|
|
4
4
|
import type { DEFAULT_DATAFLOW_PIPELINE } from '../core/steps/pipeline/default-pipelines';
|
|
5
5
|
import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
6
|
export declare function asciiCallContext(formatter: OutputFormatter, results: QueryResults<'call-context'>['call-context'], processed: PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>): string;
|
|
7
7
|
export declare function summarizeIdsIfTooLong(formatter: OutputFormatter, ids: readonly NodeId[]): string;
|
|
8
|
-
export declare function asciiSummaryOfQueryResult<S extends SupportedQueryTypes>(formatter: OutputFormatter, totalInMs: number, results: Awaited<QueryResults<S>>, processed: PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>): string;
|
|
8
|
+
export declare function asciiSummaryOfQueryResult<S extends SupportedQueryTypes>(formatter: OutputFormatter, totalInMs: number, results: Awaited<QueryResults<S>>, processed: PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>, queries: Queries<S>): string;
|
package/queries/query-print.js
CHANGED
|
@@ -69,14 +69,15 @@ function summarizeIdsIfTooLong(formatter, ids) {
|
|
|
69
69
|
}
|
|
70
70
|
return formatter === ansi_1.markdownFormatter ? (0, html_hover_over_1.textWithTooltip)(acc, JSON.stringify(ids)) : acc;
|
|
71
71
|
}
|
|
72
|
-
function asciiSummaryOfQueryResult(formatter, totalInMs, results, processed) {
|
|
72
|
+
function asciiSummaryOfQueryResult(formatter, totalInMs, results, processed, queries) {
|
|
73
73
|
const result = [];
|
|
74
74
|
for (const [query, queryResults] of Object.entries(results)) {
|
|
75
75
|
if (query === '.meta') {
|
|
76
76
|
continue;
|
|
77
77
|
}
|
|
78
78
|
const queryType = query_1.SupportedQueries[query];
|
|
79
|
-
|
|
79
|
+
const relevantQueries = queries.filter(q => q.type === query);
|
|
80
|
+
if (queryType.asciiSummarizer(formatter, processed, queryResults, result, relevantQueries)) {
|
|
80
81
|
continue;
|
|
81
82
|
}
|
|
82
83
|
result.push(`Query: ${(0, ansi_1.bold)(query, formatter)}`);
|