@eagleoutice/flowr 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/benchmark/slicer.js +1 -1
- package/cli/repl/commands/repl-parse.js +1 -1
- package/cli/repl/commands/repl-query.js +4 -5
- package/cli/repl/server/connection.js +6 -1
- package/cli/repl/server/messages/message-query.js +2 -2
- package/cli/repl/server/net.js +1 -1
- package/cli/repl/server/send.js +3 -6
- package/cli/repl/server/server.d.ts +2 -2
- package/cli/repl/server/server.js +1 -1
- package/config.js +1 -1
- package/core/pipeline-executor.js +2 -1
- package/core/steps/all/core/00-parse.d.ts +11 -4
- package/core/steps/all/core/00-parse.js +5 -5
- package/core/steps/all/core/10-normalize.d.ts +2 -1
- package/core/steps/all/core/20-dataflow.d.ts +2 -2
- package/core/steps/all/core/20-dataflow.js +2 -2
- package/core/steps/pipeline/default-pipelines.d.ts +41 -23
- package/core/steps/pipeline/pipeline.d.ts +15 -3
- package/core/steps/pipeline/pipeline.js +2 -2
- package/dataflow/environments/built-in.d.ts +8 -6
- package/dataflow/environments/built-in.js +6 -1
- package/dataflow/environments/default-builtin-config.js +21 -5
- package/dataflow/environments/environment.d.ts +1 -0
- package/dataflow/environments/environment.js +5 -5
- package/dataflow/extractor.js +23 -0
- package/dataflow/graph/dataflowgraph-builder.d.ts +2 -0
- package/dataflow/graph/dataflowgraph-builder.js +9 -0
- package/dataflow/graph/diff.js +1 -1
- package/dataflow/graph/graph.d.ts +7 -2
- package/dataflow/graph/graph.js +10 -2
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +13 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/processor.d.ts +3 -3
- package/documentation/data/server/doc-data-server-messages.js +8 -14
- package/documentation/doc-util/doc-cli-option.js +4 -4
- package/documentation/doc-util/doc-query.d.ts +4 -6
- package/documentation/doc-util/doc-query.js +16 -156
- package/documentation/doc-util/doc-repl.js +2 -2
- package/documentation/print-dataflow-graph-wiki.js +2 -1
- package/documentation/print-interface-wiki.js +8 -3
- package/documentation/print-query-wiki.js +107 -16
- package/package.json +1 -1
- package/queries/base-query-format.d.ts +6 -0
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +26 -80
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +14 -13
- package/queries/catalog/call-context-query/call-context-query-format.js +32 -14
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +17 -0
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +99 -0
- package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +59 -0
- package/queries/catalog/cluster-query/cluster-query-format.js +29 -0
- package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +59 -0
- package/queries/catalog/dataflow-query/dataflow-query-format.js +21 -0
- package/queries/catalog/dependencies-query/dependencies-query-executor.d.ts +3 -0
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +144 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +102 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.js +187 -0
- package/queries/catalog/id-map-query/id-map-query-executor.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +59 -0
- package/queries/catalog/id-map-query/id-map-query-format.js +21 -0
- package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +59 -0
- package/queries/catalog/lineage-query/lineage-query-format.js +24 -0
- package/queries/catalog/location-map-query/location-map-query-executor.d.ts +3 -0
- package/queries/catalog/location-map-query/location-map-query-executor.js +21 -0
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +17 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +24 -0
- package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +59 -0
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +21 -0
- package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +8 -3
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +59 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +40 -0
- package/queries/query-print.d.ts +8 -0
- package/queries/query-print.js +94 -0
- package/queries/query.d.ts +431 -26
- package/queries/query.js +36 -18
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +2 -1
- package/r-bridge/retriever.js +1 -1
- package/r-bridge/shell-executor.js +1 -1
- package/r-bridge/shell.d.ts +1 -2
- package/r-bridge/shell.js +22 -18
- package/slicing/static/static-slicer.js +3 -1
- package/statistics/features/supported/used-functions/used-functions.js +1 -1
- package/{documentation/doc-util/doc-hover-over.js → util/html-hover-over.js} +1 -1
- package/util/json.d.ts +2 -1
- package/util/json.js +101 -3
- package/util/objects.d.ts +2 -1
- package/util/objects.js +3 -0
- package/util/version.js +1 -1
- package/queries/query-schema.d.ts +0 -13
- package/queries/query-schema.js +0 -54
- /package/{documentation/doc-util/doc-hover-over.d.ts → util/html-hover-over.d.ts} +0 -0
|
@@ -40,5 +40,6 @@ export interface REnvironmentInformation {
|
|
|
40
40
|
readonly level: number;
|
|
41
41
|
}
|
|
42
42
|
export declare const BuiltInEnvironment: Environment;
|
|
43
|
+
export declare const EmptyBuiltInEnvironment: IEnvironment;
|
|
43
44
|
export declare function initializeCleanEnvironments(fullBuiltIns?: boolean): REnvironmentInformation;
|
|
44
45
|
export declare function builtInEnvJsonReplacer(k: unknown, v: unknown): unknown;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BuiltInEnvironment = exports.Environment = void 0;
|
|
3
|
+
exports.EmptyBuiltInEnvironment = exports.BuiltInEnvironment = exports.Environment = void 0;
|
|
4
4
|
exports.makeReferenceMaybe = makeReferenceMaybe;
|
|
5
5
|
exports.makeAllMaybe = makeAllMaybe;
|
|
6
6
|
exports.initializeCleanEnvironments = initializeCleanEnvironments;
|
|
@@ -55,16 +55,16 @@ exports.Environment = Environment;
|
|
|
55
55
|
/* the built-in environment is the root of all environments */
|
|
56
56
|
exports.BuiltInEnvironment = new Environment(undefined);
|
|
57
57
|
exports.BuiltInEnvironment.memory = undefined;
|
|
58
|
-
|
|
58
|
+
exports.EmptyBuiltInEnvironment = {
|
|
59
59
|
id: exports.BuiltInEnvironment.id,
|
|
60
60
|
memory: undefined,
|
|
61
61
|
parent: undefined
|
|
62
62
|
};
|
|
63
63
|
function initializeCleanEnvironments(fullBuiltIns = true) {
|
|
64
64
|
exports.BuiltInEnvironment.memory ??= built_in_1.BuiltInMemory;
|
|
65
|
-
EmptyBuiltInEnvironment.memory ??= built_in_1.EmptyBuiltInMemory;
|
|
65
|
+
exports.EmptyBuiltInEnvironment.memory ??= built_in_1.EmptyBuiltInMemory;
|
|
66
66
|
return {
|
|
67
|
-
current: new Environment(fullBuiltIns ? exports.BuiltInEnvironment : EmptyBuiltInEnvironment),
|
|
67
|
+
current: new Environment(fullBuiltIns ? exports.BuiltInEnvironment : exports.EmptyBuiltInEnvironment),
|
|
68
68
|
level: 0
|
|
69
69
|
};
|
|
70
70
|
}
|
|
@@ -72,7 +72,7 @@ function builtInEnvJsonReplacer(k, v) {
|
|
|
72
72
|
if (v === exports.BuiltInEnvironment) {
|
|
73
73
|
return '<BuiltInEnvironment>';
|
|
74
74
|
}
|
|
75
|
-
else if (v === EmptyBuiltInEnvironment) {
|
|
75
|
+
else if (v === exports.EmptyBuiltInEnvironment) {
|
|
76
76
|
return '<EmptyBuiltInEnvironment>';
|
|
77
77
|
}
|
|
78
78
|
else {
|
package/dataflow/extractor.js
CHANGED
|
@@ -17,6 +17,9 @@ const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
|
|
|
17
17
|
const retriever_1 = require("../r-bridge/retriever");
|
|
18
18
|
const environment_1 = require("./environments/environment");
|
|
19
19
|
const built_in_source_1 = require("./internal/process/functions/call/built-in/built-in-source");
|
|
20
|
+
const cfg_1 = require("../util/cfg/cfg");
|
|
21
|
+
const edge_1 = require("./graph/edge");
|
|
22
|
+
const identify_link_to_last_call_relation_1 = require("../queries/catalog/call-context-query/identify-link-to-last-call-relation");
|
|
20
23
|
exports.processors = {
|
|
21
24
|
[type_1.RType.Number]: process_value_1.processValue,
|
|
22
25
|
[type_1.RType.String]: process_value_1.processValue,
|
|
@@ -47,6 +50,25 @@ exports.processors = {
|
|
|
47
50
|
namespace: n.grouping?.[0].content ? undefined : 'base'
|
|
48
51
|
}, (0, make_argument_1.wrapArgumentsUnnamed)(n.children, d.completeAst.idMap), n.info.id, d)
|
|
49
52
|
};
|
|
53
|
+
function resolveLinkToSideEffects(ast, graph) {
|
|
54
|
+
let cfg = undefined;
|
|
55
|
+
for (const s of graph.unknownSideEffects) {
|
|
56
|
+
if (typeof s !== 'object') {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (!cfg) {
|
|
60
|
+
cfg = (0, cfg_1.extractCFG)(ast).graph;
|
|
61
|
+
}
|
|
62
|
+
/* this has to change whenever we add a new link to relations because we currently offer no abstraction for the type */
|
|
63
|
+
const potentials = (0, identify_link_to_last_call_relation_1.identifyLinkToLastCallRelation)(s.id, cfg, graph, s.linkTo.callName);
|
|
64
|
+
for (const pot of potentials) {
|
|
65
|
+
graph.addEdge(s.id, pot, edge_1.EdgeType.Reads);
|
|
66
|
+
}
|
|
67
|
+
if (potentials.length > 0) {
|
|
68
|
+
graph.unknownSideEffects.delete(s);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
50
72
|
function produceDataFlowGraph(request, ast) {
|
|
51
73
|
const multifile = Array.isArray(request);
|
|
52
74
|
let firstRequest;
|
|
@@ -70,6 +92,7 @@ function produceDataFlowGraph(request, ast) {
|
|
|
70
92
|
df = (0, built_in_source_1.standaloneSourceFile)(request[i], dfData, `root-${i}`, df);
|
|
71
93
|
}
|
|
72
94
|
}
|
|
95
|
+
resolveLinkToSideEffects(ast, df.graph);
|
|
73
96
|
return df;
|
|
74
97
|
}
|
|
75
98
|
//# sourceMappingURL=extractor.js.map
|
|
@@ -5,6 +5,7 @@ import { DataflowGraph } from './graph';
|
|
|
5
5
|
import type { REnvironmentInformation } from '../environments/environment';
|
|
6
6
|
import type { DataflowGraphVertexUse } from './vertex';
|
|
7
7
|
import type { ControlDependency } from '../info';
|
|
8
|
+
import type { LinkTo } from '../../queries/catalog/call-context-query/call-context-query-format';
|
|
8
9
|
export declare function emptyGraph(idMap?: AstIdMap): DataflowGraphBuilder;
|
|
9
10
|
export type DataflowGraphEdgeTarget = NodeId | (readonly NodeId[]);
|
|
10
11
|
/**
|
|
@@ -137,3 +138,4 @@ export declare class DataflowGraphBuilder extends DataflowGraph {
|
|
|
137
138
|
*/
|
|
138
139
|
overwriteRootIds(ids: readonly NodeId[]): this;
|
|
139
140
|
}
|
|
141
|
+
export declare function getBuiltInSideEffect(name: string): LinkTo<RegExp> | undefined;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DataflowGraphBuilder = void 0;
|
|
4
4
|
exports.emptyGraph = emptyGraph;
|
|
5
|
+
exports.getBuiltInSideEffect = getBuiltInSideEffect;
|
|
5
6
|
const objects_1 = require("../../util/objects");
|
|
6
7
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
7
8
|
const graph_1 = require("./graph");
|
|
@@ -10,6 +11,7 @@ const vertex_1 = require("./vertex");
|
|
|
10
11
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
11
12
|
const built_in_1 = require("../environments/built-in");
|
|
12
13
|
const edge_1 = require("./edge");
|
|
14
|
+
const default_builtin_config_1 = require("../environments/default-builtin-config");
|
|
13
15
|
function emptyGraph(idMap) {
|
|
14
16
|
return new DataflowGraphBuilder(idMap);
|
|
15
17
|
}
|
|
@@ -244,4 +246,11 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
248
|
exports.DataflowGraphBuilder = DataflowGraphBuilder;
|
|
249
|
+
function getBuiltInSideEffect(name) {
|
|
250
|
+
const got = default_builtin_config_1.DefaultBuiltinConfig.find(e => e.names.includes(name));
|
|
251
|
+
if (got?.type !== 'function') {
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
return (got?.config).hasUnknownSideEffects;
|
|
255
|
+
}
|
|
247
256
|
//# sourceMappingURL=dataflowgraph-builder.js.map
|
package/dataflow/graph/diff.js
CHANGED
|
@@ -100,7 +100,7 @@ function diffOutgoingEdges(ctx) {
|
|
|
100
100
|
}
|
|
101
101
|
function diffRootVertices(ctx) {
|
|
102
102
|
(0, diff_1.setDifference)(ctx.left.rootIds(), ctx.right.rootIds(), { ...ctx, position: `${ctx.position}Root vertices differ in graphs. ` });
|
|
103
|
-
(0, diff_1.setDifference)(ctx.left.unknownSideEffects, ctx.right.unknownSideEffects, { ...ctx, position: `${ctx.position}Unknown side effects differ in graphs. ` });
|
|
103
|
+
(0, diff_1.setDifference)(new Set([...ctx.left.unknownSideEffects].map(n => typeof n === 'object' ? n.id : n)), new Set([...ctx.right.unknownSideEffects].map(n => typeof n === 'object' ? n.id : n)), { ...ctx, position: `${ctx.position}Unknown side effects differ in graphs. ` });
|
|
104
104
|
}
|
|
105
105
|
function diffOfDataflowGraphs(left, right, config) {
|
|
106
106
|
if (left.graph === right.graph) {
|
|
@@ -6,6 +6,7 @@ import { EmptyArgument } from '../../r-bridge/lang-4.x/ast/model/nodes/r-functio
|
|
|
6
6
|
import type { IdentifierDefinition, IdentifierReference } from '../environments/identifier';
|
|
7
7
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
8
8
|
import type { AstIdMap } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
9
|
+
import type { LinkTo } from '../../queries/catalog/call-context-query/call-context-query-format';
|
|
9
10
|
export type DataflowFunctionFlowInformation = Omit<DataflowInformation, 'graph' | 'exitPoints'> & {
|
|
10
11
|
graph: Set<NodeId>;
|
|
11
12
|
};
|
|
@@ -45,6 +46,10 @@ export interface DataflowGraphJson {
|
|
|
45
46
|
readonly vertexInformation: [NodeId, DataflowGraphVertexInfo][];
|
|
46
47
|
readonly edgeInformation: [NodeId, [NodeId, DataflowGraphEdge][]][];
|
|
47
48
|
}
|
|
49
|
+
export type UnknownSidEffect = NodeId | {
|
|
50
|
+
id: NodeId;
|
|
51
|
+
linkTo: LinkTo<RegExp>;
|
|
52
|
+
};
|
|
48
53
|
/**
|
|
49
54
|
* The dataflow graph holds the dataflow information found within the given AST.
|
|
50
55
|
* We differentiate the directed edges in {@link EdgeType} and the vertices indicated by {@link DataflowGraphVertexArgument}
|
|
@@ -94,7 +99,7 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
94
99
|
/**
|
|
95
100
|
* Retrieves the set of vertices which have side effects that we do not know anything about.
|
|
96
101
|
*/
|
|
97
|
-
get unknownSideEffects():
|
|
102
|
+
get unknownSideEffects(): Set<UnknownSidEffect>;
|
|
98
103
|
/** Allows setting the id-map explicitly (which should only be used when, e.g., you plan to compare two dataflow graphs on the same AST-basis) */
|
|
99
104
|
setIdMap(idMap: AstIdMap): void;
|
|
100
105
|
/**
|
|
@@ -162,7 +167,7 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
162
167
|
/** If you do not pass the `to` node, this will just mark the node as maybe */
|
|
163
168
|
addControlDependency(from: NodeId, to?: NodeId, when?: boolean): this;
|
|
164
169
|
/** Marks the given node as having unknown side effects */
|
|
165
|
-
markIdForUnknownSideEffects(id: NodeId): this;
|
|
170
|
+
markIdForUnknownSideEffects(id: NodeId, target?: LinkTo<RegExp | string>): this;
|
|
166
171
|
/**
|
|
167
172
|
* Constructs a dataflow graph instance from the given JSON data and returns the result.
|
|
168
173
|
* This can be useful for data sent by the flowR server when analyzing it further.
|
package/dataflow/graph/graph.js
CHANGED
|
@@ -47,7 +47,11 @@ function extractEdgeIds(from, to) {
|
|
|
47
47
|
class DataflowGraph {
|
|
48
48
|
static DEFAULT_ENVIRONMENT = undefined;
|
|
49
49
|
_idMap;
|
|
50
|
-
/*
|
|
50
|
+
/*
|
|
51
|
+
* Set of vertices which have sideEffects that we do not know anything about.
|
|
52
|
+
* As a (temporary) solution until we have FD edges, a side effect may also store known target links
|
|
53
|
+
* that have to be/should be resolved (as globals) as a separate pass before the df analysis ends.
|
|
54
|
+
*/
|
|
51
55
|
_unknownSideEffects = new Set();
|
|
52
56
|
constructor(idMap) {
|
|
53
57
|
DataflowGraph.DEFAULT_ENVIRONMENT ??= (0, environment_1.initializeCleanEnvironments)();
|
|
@@ -306,7 +310,11 @@ class DataflowGraph {
|
|
|
306
310
|
return this;
|
|
307
311
|
}
|
|
308
312
|
/** Marks the given node as having unknown side effects */
|
|
309
|
-
markIdForUnknownSideEffects(id) {
|
|
313
|
+
markIdForUnknownSideEffects(id, target) {
|
|
314
|
+
if (target) {
|
|
315
|
+
this._unknownSideEffects.add({ id: (0, node_id_1.normalizeIdToNumberIfPossible)(id), linkTo: typeof target.callName === 'string' ? { ...target, callName: new RegExp(target.callName) } : target });
|
|
316
|
+
return this;
|
|
317
|
+
}
|
|
310
318
|
this._unknownSideEffects.add((0, node_id_1.normalizeIdToNumberIfPossible)(id));
|
|
311
319
|
return this;
|
|
312
320
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
2
2
|
import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model';
|
|
3
|
-
export declare function unpackArgument<OtherInfo>(arg: RFunctionArgument<OtherInfo
|
|
3
|
+
export declare function unpackArgument<OtherInfo>(arg: RFunctionArgument<OtherInfo>, noNameOnly?: boolean): RNode<OtherInfo> | undefined;
|
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.unpackArgument = unpackArgument;
|
|
4
4
|
const log_1 = require("../../../../../../util/log");
|
|
5
5
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
6
|
-
function unpackArgument(arg) {
|
|
6
|
+
function unpackArgument(arg, noNameOnly = true) {
|
|
7
7
|
if (arg === r_function_call_1.EmptyArgument) {
|
|
8
8
|
log_1.log.trace('Argument is empty, skipping');
|
|
9
9
|
return undefined;
|
|
10
10
|
}
|
|
11
|
-
else if (arg.name !== undefined) {
|
|
11
|
+
else if (noNameOnly && arg.name !== undefined) {
|
|
12
12
|
log_1.log.trace(`Argument ${JSON.stringify(arg)} is not unnamed, skipping`);
|
|
13
13
|
return undefined;
|
|
14
14
|
}
|
|
@@ -111,8 +111,8 @@ args, rootId, data, config) {
|
|
|
111
111
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args: effectiveArgs, rootId, data, forceArgs: config.forceArgs }).information;
|
|
112
112
|
}
|
|
113
113
|
function extractSourceAndTarget(args, name) {
|
|
114
|
-
const source = (0, unpack_argument_1.unpackArgument)(args[1]);
|
|
115
|
-
const target = (0, unpack_argument_1.unpackArgument)(args[0]);
|
|
114
|
+
const source = (0, unpack_argument_1.unpackArgument)(args[1], false);
|
|
115
|
+
const target = (0, unpack_argument_1.unpackArgument)(args[0], false);
|
|
116
116
|
(0, assert_1.guard)(source !== undefined, () => `Assignment ${name.content} has no source, impossible!`);
|
|
117
117
|
(0, assert_1.guard)(target !== undefined, () => `Assignment ${name.content} has no target, impossible!`);
|
|
118
118
|
return { source, target };
|
|
@@ -82,7 +82,7 @@ function updateSideEffectsForCalledFunctions(calledEnvs, inputEnvironment, nextG
|
|
|
82
82
|
return inputEnvironment;
|
|
83
83
|
}
|
|
84
84
|
function processExpressionList(name, args, rootId, data) {
|
|
85
|
-
const expressions = args.map(unpack_argument_1.unpackArgument);
|
|
85
|
+
const expressions = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
86
86
|
logger_1.dataflowLogger.trace(() => `[expr list] with ${expressions.length} expressions`);
|
|
87
87
|
let { environment } = data;
|
|
88
88
|
// used to detect if a "write" happens within the same expression list
|
|
@@ -20,7 +20,7 @@ function processForLoop(name, args, rootId, data) {
|
|
|
20
20
|
logger_1.dataflowLogger.warn(`For-Loop ${name.content} does not have three arguments, skipping`);
|
|
21
21
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
22
22
|
}
|
|
23
|
-
const [variableArg, vectorArg, bodyArg] = args.map(unpack_argument_1.unpackArgument);
|
|
23
|
+
const [variableArg, vectorArg, bodyArg] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
24
24
|
(0, assert_1.guard)(variableArg !== undefined && vectorArg !== undefined && bodyArg !== undefined, () => `For-Loop ${JSON.stringify(args)} has missing arguments! Bad!`);
|
|
25
25
|
const vector = (0, processor_1.processDataflowFor)(vectorArg, data);
|
|
26
26
|
if ((0, info_1.alwaysExits)(vector)) {
|
|
@@ -17,7 +17,7 @@ function processIfThenElse(name, args, rootId, data) {
|
|
|
17
17
|
logger_1.dataflowLogger.warn(`If-then-else ${name.content} has something different from 2 or 3 arguments, skipping`);
|
|
18
18
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
19
19
|
}
|
|
20
|
-
const [condArg, thenArg, otherwiseArg] = args.map(unpack_argument_1.unpackArgument);
|
|
20
|
+
const [condArg, thenArg, otherwiseArg] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
21
21
|
if (condArg === undefined || thenArg === undefined) {
|
|
22
22
|
logger_1.dataflowLogger.warn(`If-then-else ${name.content} has empty condition or then case in ${JSON.stringify(args)}, skipping`);
|
|
23
23
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
@@ -15,7 +15,7 @@ function processPipe(name, args, rootId, data) {
|
|
|
15
15
|
logger_1.dataflowLogger.warn(`Pipe ${name.content} has something else than 2 arguments, skipping`);
|
|
16
16
|
return information;
|
|
17
17
|
}
|
|
18
|
-
const [lhs, rhs] = args.map(unpack_argument_1.unpackArgument);
|
|
18
|
+
const [lhs, rhs] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
19
19
|
(0, assert_1.guard)(lhs !== undefined && rhs !== undefined, () => `lhs and rhs must be present, but ${JSON.stringify(lhs)} and ${JSON.stringify(rhs)} were found instead.`);
|
|
20
20
|
if (rhs.type !== type_1.RType.FunctionCall) {
|
|
21
21
|
logger_1.dataflowLogger.warn(`Expected rhs of pipe to be a function call, but got ${rhs.type} instead.`);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.setSourceProvider = setSourceProvider;
|
|
4
7
|
exports.processSourceCall = processSourceCall;
|
|
@@ -17,6 +20,7 @@ const logger_1 = require("../../../../../logger");
|
|
|
17
20
|
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
18
21
|
const overwrite_1 = require("../../../../../environments/overwrite");
|
|
19
22
|
const log_1 = require("../../../../../../util/log");
|
|
23
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
24
|
let sourceProvider = (0, retriever_1.requestProviderFromFile)();
|
|
21
25
|
function setSourceProvider(provider) {
|
|
22
26
|
sourceProvider = provider;
|
|
@@ -49,13 +53,21 @@ function processSourceCall(name, args, rootId, data, config) {
|
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
function sourceRequest(rootId, request, data, information, getId) {
|
|
56
|
+
if (request.request === 'file') {
|
|
57
|
+
/* check if the file exists and if not, fail */
|
|
58
|
+
if (!fs_1.default.existsSync(request.content)) {
|
|
59
|
+
logger_1.dataflowLogger.warn(`Failed to analyze sourced file ${JSON.stringify(request)}: file does not exist`);
|
|
60
|
+
information.graph.markIdForUnknownSideEffects(rootId);
|
|
61
|
+
return information;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
52
64
|
const executor = new shell_executor_1.RShellExecutor();
|
|
53
65
|
// parse, normalize and dataflow the sourced file
|
|
54
66
|
let normalized;
|
|
55
67
|
let dataflow;
|
|
56
68
|
try {
|
|
57
69
|
const parsed = (0, retriever_1.retrieveParseDataFromRCode)(request, executor);
|
|
58
|
-
normalized = (0, parser_1.normalize)(parsed, getId);
|
|
70
|
+
normalized = (0, parser_1.normalize)({ parsed }, getId);
|
|
59
71
|
dataflow = (0, processor_1.processDataflowFor)(normalized.ast, {
|
|
60
72
|
...data,
|
|
61
73
|
currentRequest: request,
|
|
@@ -16,7 +16,7 @@ function processWhileLoop(name, args, rootId, data) {
|
|
|
16
16
|
logger_1.dataflowLogger.warn(`While-Loop ${name.content} does not have 2 arguments, skipping`);
|
|
17
17
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
18
18
|
}
|
|
19
|
-
const unpackedArgs = args.map(unpack_argument_1.unpackArgument);
|
|
19
|
+
const unpackedArgs = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
20
20
|
if (unpackedArgs.some(assert_1.isUndefined)) {
|
|
21
21
|
logger_1.dataflowLogger.warn(`While-Loop ${name.content} has empty arguments in ${JSON.stringify(args)}, skipping`);
|
|
22
22
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
@@ -33,7 +33,7 @@ function processNamedCall(name, args, rootId, data) {
|
|
|
33
33
|
let information = undefined;
|
|
34
34
|
let builtIn = false;
|
|
35
35
|
for (const resolvedFunction of resolved) {
|
|
36
|
-
if (resolvedFunction.type === identifier_1.ReferenceType.BuiltInFunction) {
|
|
36
|
+
if (resolvedFunction.type === identifier_1.ReferenceType.BuiltInFunction && typeof resolvedFunction.processor === 'function') {
|
|
37
37
|
builtIn = true;
|
|
38
38
|
information = mergeInformation(information, resolvedFunction.processor(name, args, rootId, data));
|
|
39
39
|
}
|
package/dataflow/processor.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import type { RParseRequest } from '../r-bridge/retriever';
|
|
|
8
8
|
import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
9
9
|
export interface DataflowProcessorInformation<OtherInfo> {
|
|
10
10
|
/**
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
* Initial and frozen ast-information
|
|
12
|
+
*/
|
|
13
13
|
readonly completeAst: NormalizedAst<OtherInfo>;
|
|
14
14
|
/**
|
|
15
15
|
* Correctly contains pushed local scopes introduced by `function` scopes.
|
|
@@ -30,7 +30,7 @@ export interface DataflowProcessorInformation<OtherInfo> {
|
|
|
30
30
|
*/
|
|
31
31
|
readonly referenceChain: string[];
|
|
32
32
|
/**
|
|
33
|
-
* The chain of control-flow {@link NodeId}s that lead to the current node (e.g
|
|
33
|
+
* The chain of control-flow {@link NodeId}s that lead to the current node (e.g., of known ifs).
|
|
34
34
|
*/
|
|
35
35
|
readonly controlDependencies: ControlDependency[] | undefined;
|
|
36
36
|
}
|
|
@@ -16,9 +16,8 @@ const message_slice_1 = require("../../../cli/repl/server/messages/message-slice
|
|
|
16
16
|
const message_repl_1 = require("../../../cli/repl/server/messages/message-repl");
|
|
17
17
|
const message_query_1 = require("../../../cli/repl/server/messages/message-query");
|
|
18
18
|
const example_query_code_1 = require("../query/example-query-code");
|
|
19
|
-
const call_context_query_format_1 = require("../../../queries/catalog/call-context-query/call-context-query-format");
|
|
20
19
|
const message_lineage_1 = require("../../../cli/repl/server/messages/message-lineage");
|
|
21
|
-
const
|
|
20
|
+
const identify_link_to_last_call_relation_1 = require("../../../queries/catalog/call-context-query/identify-link-to-last-call-relation");
|
|
22
21
|
function documentAllServerMessages() {
|
|
23
22
|
(0, doc_server_message_1.documentServerMessage)({
|
|
24
23
|
title: 'Hello',
|
|
@@ -202,6 +201,7 @@ While the context is derived from the \`filename\`, we currently offer no way to
|
|
|
202
201
|
`;
|
|
203
202
|
}
|
|
204
203
|
});
|
|
204
|
+
const deprecatedByQuery = `(<a href="${doc_files_1.FlowrWikiBaseRef}/Query%20API">deprecated</a>)`;
|
|
205
205
|
(0, doc_server_message_1.documentServerMessage)({
|
|
206
206
|
title: 'Slice',
|
|
207
207
|
type: 'request',
|
|
@@ -218,13 +218,10 @@ While the context is derived from the \`filename\`, we currently offer no way to
|
|
|
218
218
|
end
|
|
219
219
|
deactivate Server
|
|
220
220
|
`,
|
|
221
|
-
shortDescription:
|
|
221
|
+
shortDescription: `${deprecatedByQuery} The server slices a file based on the given criteria.`,
|
|
222
222
|
text: async (shell) => {
|
|
223
223
|
return `
|
|
224
|
-
${
|
|
225
|
-
type: 'WARNING',
|
|
226
|
-
content: `We deprecated the slice request in favor of the \`static-slice\` [Query](${doc_files_1.FlowrWikiBaseRef}/Query%20API).`
|
|
227
|
-
})}
|
|
224
|
+
**We deprecated the slice request in favor of the \`static-slice\` [Query](${doc_files_1.FlowrWikiBaseRef}/Query%20API).**
|
|
228
225
|
|
|
229
226
|
To slice, you have to send a file analysis request first. The \`filetoken\` you assign is of use here as you can re-use it to repeatedly slice the same file.
|
|
230
227
|
Besides that, you only need to add an array of slicing criteria, using one of the formats described on the [terminology wiki page](${doc_files_1.FlowrWikiBaseRef}/Terminology#slicing-criterion)
|
|
@@ -427,7 +424,7 @@ See [above](#message-request-file-analysis) for the general structure of the res
|
|
|
427
424
|
commonArguments: {
|
|
428
425
|
kind: 'visualize',
|
|
429
426
|
subkind: 'text',
|
|
430
|
-
callTargets:
|
|
427
|
+
callTargets: identify_link_to_last_call_relation_1.CallTargets.OnlyGlobal,
|
|
431
428
|
},
|
|
432
429
|
arguments: [
|
|
433
430
|
{
|
|
@@ -435,7 +432,7 @@ See [above](#message-request-file-analysis) for the general structure of the res
|
|
|
435
432
|
},
|
|
436
433
|
{
|
|
437
434
|
callName: '^print$',
|
|
438
|
-
callTargets:
|
|
435
|
+
callTargets: identify_link_to_last_call_relation_1.CallTargets.OnlyLocal
|
|
439
436
|
}
|
|
440
437
|
]
|
|
441
438
|
}
|
|
@@ -467,14 +464,11 @@ See [above](#message-request-file-analysis) for the general structure of the res
|
|
|
467
464
|
end
|
|
468
465
|
deactivate Server
|
|
469
466
|
`,
|
|
470
|
-
shortDescription:
|
|
467
|
+
shortDescription: `${deprecatedByQuery} Obtain the lineage of a given slicing criterion.`,
|
|
471
468
|
text: async (shell) => {
|
|
472
469
|
return `
|
|
473
470
|
|
|
474
|
-
${
|
|
475
|
-
type: 'WARNING',
|
|
476
|
-
content: `We deprecated the lineage request in favor of the \`lineage\` [Query](${doc_files_1.FlowrWikiBaseRef}/Query%20API).`
|
|
477
|
-
})}
|
|
471
|
+
**We deprecated the lineage request in favor of the \`lineage\` [Query](${doc_files_1.FlowrWikiBaseRef}/Query%20API).**
|
|
478
472
|
|
|
479
473
|
In order to retrieve the lineage of an object, you have to send a file analysis request first. The \`filetoken\` you assign is of use here as you can re-use it to repeatedly retrieve the lineage of the same file.
|
|
480
474
|
Besides that, you will need to add a [criterion](${doc_files_1.FlowrWikiBaseRef}/Terminology#slicing-criterion) that specifies the object whose lineage you're interested in.
|
|
@@ -6,7 +6,7 @@ exports.getReplCommand = getReplCommand;
|
|
|
6
6
|
/** Automatically provides hover over with the documentation for these! */
|
|
7
7
|
const scripts_info_1 = require("../../cli/common/scripts-info");
|
|
8
8
|
const assert_1 = require("../../util/assert");
|
|
9
|
-
const
|
|
9
|
+
const html_hover_over_1 = require("../../util/html-hover-over");
|
|
10
10
|
const flowr_main_options_1 = require("../../cli/flowr-main-options");
|
|
11
11
|
const repl_commands_1 = require("../../cli/repl/commands/repl-commands");
|
|
12
12
|
function getCliLongOptionOf(scriptName, optionName, withAlias = false, quote = true) {
|
|
@@ -15,10 +15,10 @@ function getCliLongOptionOf(scriptName, optionName, withAlias = false, quote = t
|
|
|
15
15
|
const option = script.find(({ name }) => name === optionName);
|
|
16
16
|
(0, assert_1.guard)(option !== undefined, () => `Unknown option ${optionName}, pick one of ${JSON.stringify(script.map(o => o.name))}.`);
|
|
17
17
|
const char = quote ? '`' : '';
|
|
18
|
-
const alias = withAlias && option.alias ? ' (alias:' + (0,
|
|
18
|
+
const alias = withAlias && option.alias ? ' (alias:' + (0, html_hover_over_1.textWithTooltip)(`${char}-${option.alias}${char}`, option.description) + ')' : '';
|
|
19
19
|
const ligatureBreaker = quote ? '' : '<span/>';
|
|
20
20
|
// span ensures split even with ligatures
|
|
21
|
-
return (0,
|
|
21
|
+
return (0, html_hover_over_1.textWithTooltip)(`${char}-${ligatureBreaker}-${optionName}${char}`, 'Description (Command Line Argument): ' + option.description) + alias;
|
|
22
22
|
}
|
|
23
23
|
function multipleCliOptions(scriptName, ...options) {
|
|
24
24
|
return options.map(o => getCliLongOptionOf(scriptName, o, false, true)).join(' ');
|
|
@@ -31,6 +31,6 @@ function getReplCommand(commandName, quote = true, showStar = false) {
|
|
|
31
31
|
const aliases = commands.aliases.length > 0 ? ' (aliases: ' + commands.aliases.map(a => `:${a}`).join(', ') + ')' : '';
|
|
32
32
|
const starredComment = commandName.endsWith('*') ? ', starred version' : '';
|
|
33
33
|
const baseDescription = commandName.endsWith('*') ? '; Base Command: ' + availableNames[commandName.slice(0, -1)].description : '';
|
|
34
|
-
return (0,
|
|
34
|
+
return (0, html_hover_over_1.textWithTooltip)(`${char}:${commandName}${showStar ? '[*]' : ''}${char}`, `Description (Repl Command${starredComment}): ` + commands.description + baseDescription + aliases);
|
|
35
35
|
}
|
|
36
36
|
//# sourceMappingURL=doc-cli-option.js.map
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import type { RShell } from '../../r-bridge/shell';
|
|
2
|
-
import type { Queries,
|
|
3
|
-
import { DEFAULT_DATAFLOW_PIPELINE } from '../../core/steps/pipeline/default-pipelines';
|
|
4
|
-
import { type OutputFormatter } from '../../util/ansi';
|
|
2
|
+
import type { Queries, SupportedQueryTypes } from '../../queries/query';
|
|
5
3
|
import type { SupportedVirtualQueryTypes } from '../../queries/virtual-query/virtual-queries';
|
|
6
4
|
import type { VirtualCompoundConstraint } from '../../queries/virtual-query/compound-query';
|
|
7
|
-
import type { PipelineOutput } from '../../core/steps/pipeline/pipeline';
|
|
8
5
|
export interface ShowQueryOptions {
|
|
9
6
|
readonly showCode?: boolean;
|
|
10
7
|
readonly collapseResult?: boolean;
|
|
8
|
+
readonly collapseQuery?: boolean;
|
|
11
9
|
}
|
|
12
|
-
export declare function
|
|
13
|
-
export declare function showQuery<Base extends SupportedQueryTypes, VirtualArguments extends VirtualCompoundConstraint<Base> = VirtualCompoundConstraint<Base>>(shell: RShell, code: string, queries: Queries<Base, VirtualArguments>, { showCode, collapseResult }?: ShowQueryOptions): Promise<string>;
|
|
10
|
+
export declare function showQuery<Base extends SupportedQueryTypes, VirtualArguments extends VirtualCompoundConstraint<Base> = VirtualCompoundConstraint<Base>>(shell: RShell, code: string, queries: Queries<Base, VirtualArguments>, { showCode, collapseResult, collapseQuery }?: ShowQueryOptions): Promise<string>;
|
|
14
11
|
export interface QueryDocumentation {
|
|
15
12
|
readonly name: string;
|
|
16
13
|
readonly type: 'virtual' | 'active';
|
|
@@ -24,5 +21,6 @@ export declare const RegisteredQueries: {
|
|
|
24
21
|
virtual: Map<string, QueryDocumentation>;
|
|
25
22
|
};
|
|
26
23
|
export declare function registerQueryDocumentation(query: SupportedQueryTypes | SupportedVirtualQueryTypes, doc: QueryDocumentation): void;
|
|
24
|
+
export declare function linkToQueryOfName(id: SupportedQueryTypes | SupportedVirtualQueryTypes): string;
|
|
27
25
|
export declare function tocForQueryType(type: 'active' | 'virtual'): string;
|
|
28
26
|
export declare function explainQueries(shell: RShell, type: 'active' | 'virtual'): Promise<string>;
|