@eagleoutice/flowr 1.3.11 → 1.3.13
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/cli/common/scripts-info.d.ts +1 -1
- package/package.json +3 -4
- package/benchmark/benchmark-slicer.js +0 -223
- package/core/pipeline-executor.js +0 -221
- package/core/stepping-slicer.js +0 -160
- package/core/steps/all/00-parse.js +0 -19
- package/core/steps/all/10-normalize.js +0 -21
- package/core/steps/all/20-dataflow.js +0 -21
- package/core/steps/all/30-slice.js +0 -16
- package/core/steps/all/40-reconstruct.js +0 -16
- package/core/steps/all/core/00-parse.js +0 -24
- package/core/steps/all/core/10-normalize.js +0 -46
- package/core/steps/all/core/20-dataflow.js +0 -39
- package/core/steps/all/static-slicing/00-slice.js +0 -21
- package/core/steps/all/static-slicing/10-reconstruct.js +0 -21
- package/core/steps/index.js +0 -21
- package/core/steps/input.js +0 -3
- package/core/steps/output.js +0 -3
- package/core/steps/pipeline/create.js +0 -130
- package/core/steps/pipeline/default.js +0 -15
- package/core/steps/pipeline/dependency-checker.js +0 -76
- package/core/steps/pipeline/index.js +0 -20
- package/core/steps/pipeline/invalid-pipeline-error.js +0 -14
- package/core/steps/pipeline/pipeline.js +0 -28
- package/core/steps/step.js +0 -8
- package/core/steps/steps-provider.js +0 -3
- package/core/steps/steps.js +0 -35
- package/dataflow/common/environments/append.js +0 -48
- package/dataflow/common/environments/environment.js +0 -165
- package/dataflow/common/environments/index.js +0 -23
- package/dataflow/common/environments/overwrite.js +0 -82
- package/dataflow/common/environments/register.js +0 -49
- package/dataflow/common/environments/resolve-by-name.js +0 -35
- package/dataflow/common/environments/scopes.js +0 -6
- package/dataflow/common/environments/scoping.js +0 -27
- package/dataflow/graph/equal.js +0 -127
- package/dataflow/v1/extractor.js +0 -60
- package/dataflow/v1/graph/diff.js +0 -206
- package/dataflow/v1/graph/edge.js +0 -32
- package/dataflow/v1/graph/graph.js +0 -298
- package/dataflow/v1/graph/index.js +0 -21
- package/dataflow/v1/graph/quads.js +0 -27
- package/dataflow/v1/graph/vertex.js +0 -3
- package/dataflow/v1/index.js +0 -24
- package/dataflow/v1/internal/info.js +0 -16
- package/dataflow/v1/internal/linker.js +0 -255
- package/dataflow/v1/internal/process/access.js +0 -54
- package/dataflow/v1/internal/process/expression-list.js +0 -154
- package/dataflow/v1/internal/process/functions/argument.js +0 -46
- package/dataflow/v1/internal/process/functions/exit-points.js +0 -125
- package/dataflow/v1/internal/process/functions/function-call.js +0 -99
- package/dataflow/v1/internal/process/functions/function-definition.js +0 -176
- package/dataflow/v1/internal/process/functions/parameter.js +0 -47
- package/dataflow/v1/internal/process/if-then-else.js +0 -57
- package/dataflow/v1/internal/process/loops/for-loop.js +0 -54
- package/dataflow/v1/internal/process/loops/repeat-loop.js +0 -21
- package/dataflow/v1/internal/process/loops/while-loop.js +0 -31
- package/dataflow/v1/internal/process/operators/assignment.js +0 -129
- package/dataflow/v1/internal/process/operators/non-assignment-binary-op.js +0 -25
- package/dataflow/v1/internal/process/operators/pipe.js +0 -46
- package/dataflow/v1/internal/process/operators/unary-op.js +0 -10
- package/dataflow/v1/internal/process/symbol.js +0 -21
- package/dataflow/v1/internal/process/uninteresting-leaf.js +0 -9
- package/dataflow/v1/processor.js +0 -20
- package/dataflow/v2/entry.js +0 -11
- package/flowr-1.3.7.tgz +0 -0
- package/r-bridge/lang-4.x/ast/parser/xml/common/config.js +0 -16
- package/r-bridge/lang-4.x/ast/parser/xml/common/input-format.js +0 -42
- package/r-bridge/lang-4.x/ast/parser/xml/common/meta.js +0 -118
- package/r-bridge/lang-4.x/ast/parser/xml/common/xml-to-json.js +0 -58
- package/r-bridge/lang-4.x/ast/parser/xml/v1/data.js +0 -3
- package/r-bridge/lang-4.x/ast/parser/xml/v1/hooks.js +0 -136
- package/r-bridge/lang-4.x/ast/parser/xml/v1/index.js +0 -22
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/access.js +0 -107
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/control/if-then-else.js +0 -32
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/control/if-then.js +0 -46
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/control/index.js +0 -19
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/expression/expression.js +0 -65
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/expression/index.js +0 -18
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/argument.js +0 -74
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/call.js +0 -149
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/definition.js +0 -60
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/index.js +0 -20
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/parameter.js +0 -64
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/index.js +0 -27
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/break.js +0 -24
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/for.js +0 -72
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/index.js +0 -22
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/next.js +0 -24
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/repeat.js +0 -42
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/while.js +0 -45
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/binary.js +0 -162
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/index.js +0 -20
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/special.js +0 -24
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/unary.js +0 -59
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/other/comment.js +0 -34
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/other/index.js +0 -18
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/other/line-directive.js +0 -55
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/elements.js +0 -159
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/index.js +0 -20
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/root.js +0 -34
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/single-element.js +0 -64
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/index.js +0 -20
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/number.js +0 -56
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/string.js +0 -41
- package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/symbol.js +0 -56
- package/r-bridge/lang-4.x/ast/parser/xml/v1/normalize.js +0 -30
- package/r-bridge/lang-4.x/ast/parser/xml/v2/data.js +0 -3
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/access.js +0 -95
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/expression.js +0 -99
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/functions/argument.js +0 -71
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/operators/binary.js +0 -30
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/operators/index.js +0 -19
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/operators/unary.js +0 -35
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/other/comment.js +0 -25
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/other/index.js +0 -18
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/other/line-directive.js +0 -38
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/root.js +0 -26
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/single-element.js +0 -63
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/index.js +0 -18
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/number.js +0 -46
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/string.js +0 -33
- package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/symbol.js +0 -63
- package/r-bridge/lang-4.x/ast/parser/xml/v2/normalize.js +0 -25
- package/util/summarizer/benchmark/benchmark-summarizer.js +0 -208
|
@@ -20,5 +20,5 @@ export interface HelperScriptInformation extends BaseScriptInformation {
|
|
|
20
20
|
masterScripts: string[];
|
|
21
21
|
}
|
|
22
22
|
export type ScriptInformation = MasterScriptInformation | HelperScriptInformation;
|
|
23
|
-
export declare const scripts: Record<"slicer" | "benchmark" | "
|
|
23
|
+
export declare const scripts: Record<"slicer" | "benchmark" | "stats" | "summarizer" | "export-quads" | "stats-helper" | "benchmark-helper", ScriptInformation>;
|
|
24
24
|
export {};
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagleoutice/flowr",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.13",
|
|
4
4
|
"description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
|
|
5
|
-
"main": "dist/src/flowr.js",
|
|
6
5
|
"types": "dist/src/index.d.ts",
|
|
7
6
|
"repository": {
|
|
8
7
|
"type": "git",
|
|
@@ -337,7 +336,6 @@
|
|
|
337
336
|
"@types/n-readlines": "^1.0.6",
|
|
338
337
|
"@types/n3": "^1.16.4",
|
|
339
338
|
"@types/object-hash": "^3.0.6",
|
|
340
|
-
"@types/semver": "^7.5.6",
|
|
341
339
|
"@types/tmp": "^0.2.6",
|
|
342
340
|
"@types/xml2js": "^0.4.14",
|
|
343
341
|
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
|
@@ -355,7 +353,6 @@
|
|
|
355
353
|
"mocha-multi-reporters": "^1.5.1",
|
|
356
354
|
"nyc": "^15.1.0",
|
|
357
355
|
"release-it": "^17.0.1",
|
|
358
|
-
"ts-essentials": "^9.4.1",
|
|
359
356
|
"ts-node": "^10.9.2",
|
|
360
357
|
"typedoc": "^0.25.4",
|
|
361
358
|
"typedoc-plugin-missing-exports": "^2.1.0",
|
|
@@ -364,6 +361,7 @@
|
|
|
364
361
|
"typescript": "^5.3.3"
|
|
365
362
|
},
|
|
366
363
|
"dependencies": {
|
|
364
|
+
"@types/semver": "^7.5.6",
|
|
367
365
|
"@types/tar": "^6.1.10",
|
|
368
366
|
"@xmldom/xmldom": "^0.8.10",
|
|
369
367
|
"command-line-args": "^5.2.1",
|
|
@@ -377,6 +375,7 @@
|
|
|
377
375
|
"semver": "^7.5.4",
|
|
378
376
|
"tar": "^6.2.0",
|
|
379
377
|
"tmp": "^0.2.1",
|
|
378
|
+
"ts-essentials": "^9.4.1",
|
|
380
379
|
"tslog": "^4.9.2",
|
|
381
380
|
"xml2js": "^0.6.2",
|
|
382
381
|
"xpath-ts2": "^1.4.2"
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Provides a top-level slicer that can be used to slice code *and* retrieve stats.
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
-
};
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.BenchmarkSlicer = exports.benchmarkLogger = void 0;
|
|
11
|
-
const r_bridge_1 = require("../r-bridge");
|
|
12
|
-
const stopwatch_1 = require("./stopwatch");
|
|
13
|
-
const assert_1 = require("../util/assert");
|
|
14
|
-
const slicing_1 = require("../slicing");
|
|
15
|
-
const fs_1 = __importDefault(require("fs"));
|
|
16
|
-
const log_1 = require("../util/log");
|
|
17
|
-
const core_1 = require("../core");
|
|
18
|
-
const strings_1 = require("../util/strings");
|
|
19
|
-
exports.benchmarkLogger = log_1.log.getSubLogger({ name: 'benchmark' });
|
|
20
|
-
/**
|
|
21
|
-
* A slicer that can be used to slice exactly one file (multiple times).
|
|
22
|
-
* It holds its own {@link RShell} instance, maintains a cached dataflow and keeps measurements.
|
|
23
|
-
*
|
|
24
|
-
* Make sure to call {@link init} to initialize the slicer, before calling {@link slice}.
|
|
25
|
-
* After slicing, call {@link finish} to close the R session and retrieve the stats.
|
|
26
|
-
*
|
|
27
|
-
* @note Under the hood, the benchmark slicer maintains a {@link SteppingSlicer}.
|
|
28
|
-
*/
|
|
29
|
-
class BenchmarkSlicer {
|
|
30
|
-
/** Measures all data that is recorded *once* per slicer (complete setup up to the dataflow graph creation) */
|
|
31
|
-
commonMeasurements = new stopwatch_1.Measurements();
|
|
32
|
-
perSliceMeasurements = new Map;
|
|
33
|
-
shell;
|
|
34
|
-
stats;
|
|
35
|
-
loadedXml;
|
|
36
|
-
tokenMap;
|
|
37
|
-
dataflow;
|
|
38
|
-
normalizedAst;
|
|
39
|
-
totalStopwatch;
|
|
40
|
-
finished = false;
|
|
41
|
-
// Yes this is dirty, but we know that we assign the stepper during the initialization and this saves us from having to check for nullability every time
|
|
42
|
-
stepper = null;
|
|
43
|
-
constructor() {
|
|
44
|
-
this.totalStopwatch = this.commonMeasurements.start('total');
|
|
45
|
-
this.shell = this.commonMeasurements.measure('initialize R session', () => new r_bridge_1.RShell());
|
|
46
|
-
this.commonMeasurements.measure('inject home path', () => this.shell.tryToInjectHomeLibPath());
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Initialize the slicer on the given request.
|
|
50
|
-
* Can only be called once for each instance.
|
|
51
|
-
*/
|
|
52
|
-
async init(request) {
|
|
53
|
-
(0, assert_1.guard)(this.stats === undefined, 'cannot initialize the slicer twice');
|
|
54
|
-
await this.commonMeasurements.measureAsync('ensure installation of xmlparsedata', () => this.shell.ensurePackageInstalled('xmlparsedata', true));
|
|
55
|
-
this.tokenMap = await this.commonMeasurements.measureAsync('retrieve token map',
|
|
56
|
-
// with this being the first time, there is no preexisting caching!
|
|
57
|
-
() => this.shell.tokenMap());
|
|
58
|
-
this.stepper = new core_1.SteppingSlicer({
|
|
59
|
-
shell: this.shell,
|
|
60
|
-
request: {
|
|
61
|
-
...request,
|
|
62
|
-
ensurePackageInstalled: true
|
|
63
|
-
},
|
|
64
|
-
stepOfInterest: core_1.LAST_STEP,
|
|
65
|
-
criterion: [],
|
|
66
|
-
tokenMap: this.tokenMap
|
|
67
|
-
});
|
|
68
|
-
this.loadedXml = await this.measureCommonStep('parse', 'retrieve AST from R code');
|
|
69
|
-
this.normalizedAst = await this.measureCommonStep('normalize', 'normalize R AST');
|
|
70
|
-
this.dataflow = await this.measureCommonStep('dataflow', 'produce dataflow information');
|
|
71
|
-
this.stepper.switchToSliceStage();
|
|
72
|
-
await this.calculateStatsAfterInit(request);
|
|
73
|
-
}
|
|
74
|
-
async calculateStatsAfterInit(request) {
|
|
75
|
-
const loadedContent = request.request === 'text' ? request.content : fs_1.default.readFileSync(request.content, 'utf-8');
|
|
76
|
-
// retrieve number of R tokens - flowr_parsed should still contain the last parsed code
|
|
77
|
-
const numberOfRTokens = await (0, r_bridge_1.retrieveNumberOfRTokensOfLastParse)(this.shell);
|
|
78
|
-
(0, assert_1.guard)(this.normalizedAst !== undefined, 'normalizedAst should be defined after initialization');
|
|
79
|
-
(0, assert_1.guard)(this.dataflow !== undefined, 'dataflow should be defined after initialization');
|
|
80
|
-
// collect dataflow graph size
|
|
81
|
-
const vertices = [...this.dataflow.graph.vertices(true)];
|
|
82
|
-
let numberOfEdges = 0;
|
|
83
|
-
let numberOfCalls = 0;
|
|
84
|
-
let numberOfDefinitions = 0;
|
|
85
|
-
for (const [n, info] of vertices) {
|
|
86
|
-
const outgoingEdges = this.dataflow.graph.outgoingEdges(n);
|
|
87
|
-
numberOfEdges += outgoingEdges?.size ?? 0;
|
|
88
|
-
if (info.tag === 'function-call') {
|
|
89
|
-
numberOfCalls++;
|
|
90
|
-
}
|
|
91
|
-
else if (info.tag === 'function-definition') {
|
|
92
|
-
numberOfDefinitions++;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
this.stats = {
|
|
96
|
-
commonMeasurements: new Map(),
|
|
97
|
-
perSliceMeasurements: this.perSliceMeasurements,
|
|
98
|
-
request,
|
|
99
|
-
input: {
|
|
100
|
-
numberOfLines: loadedContent.split('\n').length,
|
|
101
|
-
numberOfCharacters: loadedContent.length,
|
|
102
|
-
numberOfNonWhitespaceCharacters: (0, strings_1.withoutWhitespace)(loadedContent).length,
|
|
103
|
-
numberOfRTokens: numberOfRTokens,
|
|
104
|
-
numberOfNormalizedTokens: [...(0, r_bridge_1.collectAllIds)(this.normalizedAst.ast)].length
|
|
105
|
-
},
|
|
106
|
-
dataflow: {
|
|
107
|
-
numberOfNodes: [...this.dataflow.graph.vertices(true)].length,
|
|
108
|
-
numberOfEdges: numberOfEdges,
|
|
109
|
-
numberOfCalls: numberOfCalls,
|
|
110
|
-
numberOfFunctionDefinitions: numberOfDefinitions
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Slice for the given {@link SlicingCriteria}.
|
|
116
|
-
* @see SingleSlicingCriterion
|
|
117
|
-
*
|
|
118
|
-
* @returns The per slice stats retrieved for this slicing criteria
|
|
119
|
-
*/
|
|
120
|
-
async slice(...slicingCriteria) {
|
|
121
|
-
exports.benchmarkLogger.trace(`try to slice for criteria ${JSON.stringify(slicingCriteria)}`);
|
|
122
|
-
this.guardActive();
|
|
123
|
-
(0, assert_1.guard)(!this.perSliceMeasurements.has(slicingCriteria), 'do not slice the same criteria combination twice');
|
|
124
|
-
const measurements = new stopwatch_1.Measurements();
|
|
125
|
-
const stats = {
|
|
126
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
127
|
-
measurements: undefined,
|
|
128
|
-
slicingCriteria: [],
|
|
129
|
-
numberOfDataflowNodesSliced: 0,
|
|
130
|
-
timesHitThreshold: 0,
|
|
131
|
-
reconstructedCode: {
|
|
132
|
-
code: '',
|
|
133
|
-
autoSelected: 0
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
this.perSliceMeasurements.set(slicingCriteria, stats);
|
|
137
|
-
this.stepper.updateCriterion(slicingCriteria);
|
|
138
|
-
const totalStopwatch = measurements.start('total');
|
|
139
|
-
const slicedOutput = await this.measureSliceStep('slice', measurements, 'static slicing');
|
|
140
|
-
stats.slicingCriteria = slicedOutput.decodedCriteria;
|
|
141
|
-
stats.reconstructedCode = await this.measureSliceStep('reconstruct', measurements, 'reconstruct code');
|
|
142
|
-
totalStopwatch.stop();
|
|
143
|
-
exports.benchmarkLogger.debug(`Produced code for ${JSON.stringify(slicingCriteria)}: ${stats.reconstructedCode.code}`);
|
|
144
|
-
const results = this.stepper.getResults(false);
|
|
145
|
-
if (exports.benchmarkLogger.settings.minLevel >= 3 /* LogLevel.Info */) {
|
|
146
|
-
exports.benchmarkLogger.info(`mapped slicing criteria: ${slicedOutput.decodedCriteria.map(c => {
|
|
147
|
-
const node = results.normalize.idMap.get(c.id);
|
|
148
|
-
return `\n- id: ${c.id}, location: ${JSON.stringify(node?.location)}, lexeme: ${JSON.stringify(node?.lexeme)}`;
|
|
149
|
-
}).join('')}`);
|
|
150
|
-
}
|
|
151
|
-
// if it is not in the dataflow graph it was kept to be safe and should not count to the included nodes
|
|
152
|
-
stats.numberOfDataflowNodesSliced = [...slicedOutput.result].filter(id => results.dataflow.graph.hasNode(id, false)).length;
|
|
153
|
-
stats.timesHitThreshold = slicedOutput.timesHitThreshold;
|
|
154
|
-
stats.measurements = measurements.get();
|
|
155
|
-
return {
|
|
156
|
-
stats,
|
|
157
|
-
slice: slicedOutput,
|
|
158
|
-
code: stats.reconstructedCode
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
/** Bridging the gap between the new internal and the old names for the benchmarking */
|
|
162
|
-
async measureCommonStep(expectedStep, keyToMeasure) {
|
|
163
|
-
const { result } = await this.commonMeasurements.measureAsync(keyToMeasure, () => this.stepper.nextStep(expectedStep));
|
|
164
|
-
return result;
|
|
165
|
-
}
|
|
166
|
-
async measureSliceStep(expectedStep, measure, keyToMeasure) {
|
|
167
|
-
const { result } = await measure.measureAsync(keyToMeasure, () => this.stepper.nextStep(expectedStep));
|
|
168
|
-
return result;
|
|
169
|
-
}
|
|
170
|
-
guardActive() {
|
|
171
|
-
(0, assert_1.guard)(this.stats !== undefined && !this.finished, 'need to call init before, and can not do after finish!');
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Call {@link slice} for all slicing criteria that match the given filter.
|
|
175
|
-
* See {@link collectAllSlicingCriteria} for details.
|
|
176
|
-
* <p>
|
|
177
|
-
* the `report` function will be called *before* each individual slice is performed.
|
|
178
|
-
*
|
|
179
|
-
* @returns The number of slices that were produced
|
|
180
|
-
*
|
|
181
|
-
* @see collectAllSlicingCriteria
|
|
182
|
-
* @see SlicingCriteriaFilter
|
|
183
|
-
*/
|
|
184
|
-
async sliceForAll(filter, report = () => { }) {
|
|
185
|
-
this.guardActive();
|
|
186
|
-
let count = 0;
|
|
187
|
-
const allCriteria = [...(0, slicing_1.collectAllSlicingCriteria)(this.normalizedAst.ast, filter)];
|
|
188
|
-
for (const slicingCriteria of allCriteria) {
|
|
189
|
-
report(count, allCriteria.length, allCriteria);
|
|
190
|
-
await this.slice(...slicingCriteria);
|
|
191
|
-
count++;
|
|
192
|
-
}
|
|
193
|
-
return count;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Retrieves the final stats and closes the shell session.
|
|
197
|
-
* Can be called multiple times to retrieve the stored stats, but will only close the session once (the first time).
|
|
198
|
-
*/
|
|
199
|
-
finish() {
|
|
200
|
-
(0, assert_1.guard)(this.stats !== undefined, 'need to call init before finish');
|
|
201
|
-
if (!this.finished) {
|
|
202
|
-
this.commonMeasurements.measure('close R session', () => this.shell.close());
|
|
203
|
-
this.totalStopwatch.stop();
|
|
204
|
-
this.finished = true;
|
|
205
|
-
}
|
|
206
|
-
this.stats.commonMeasurements = this.commonMeasurements.get();
|
|
207
|
-
return {
|
|
208
|
-
stats: this.stats,
|
|
209
|
-
parse: this.loadedXml,
|
|
210
|
-
dataflow: this.dataflow,
|
|
211
|
-
normalize: this.normalizedAst,
|
|
212
|
-
tokenMap: this.tokenMap,
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Only call in case of an error - if the session must be closed and the benchmark itself is to be considered failed/dead.
|
|
217
|
-
*/
|
|
218
|
-
ensureSessionClosed() {
|
|
219
|
-
this.shell.close();
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
exports.BenchmarkSlicer = BenchmarkSlicer;
|
|
223
|
-
//# sourceMappingURL=benchmark-slicer.js.map
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PipelineExecutor = void 0;
|
|
4
|
-
const assert_1 = require("../util/assert");
|
|
5
|
-
/**
|
|
6
|
-
* The pipeline executor allows to execute arbitrary {@link Pipeline|pipelines} in a step-by-step fashion.
|
|
7
|
-
* If you are not yet in the possession of a {@link Pipeline|pipeline}, you can use the {@link createPipeline} function
|
|
8
|
-
* to create one for yourself, based on the steps that you want to execute.
|
|
9
|
-
*
|
|
10
|
-
* Those steps are split into two phases or "stages" (which is the name that we will use in the following), represented
|
|
11
|
-
* by the {@link PipelineStepStage} type. These allow us to separate things that have to be done
|
|
12
|
-
* once per-file, e.g., actually parsing the AST, from those, that we need to repeat 'once per request' (whatever this
|
|
13
|
-
* request may be). In other words, what can be cached between operations and what can not.
|
|
14
|
-
*
|
|
15
|
-
* Furthermore, this executor follows an iterable fashion to be *as flexible as possible*
|
|
16
|
-
* (e.g., to be instrumented with measurements). So, you can use the pipeline executor like this:
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* const stepper = new PipelineExecutor( ... )
|
|
20
|
-
* while(stepper.hasNextStep()) {
|
|
21
|
-
* await stepper.nextStep()
|
|
22
|
-
* }
|
|
23
|
-
*
|
|
24
|
-
* stepper.switchToRequestStage()
|
|
25
|
-
*
|
|
26
|
-
* while(stepper.hasNextStep()) {
|
|
27
|
-
* await stepper.nextStep()
|
|
28
|
-
* }
|
|
29
|
-
*
|
|
30
|
-
* const result = stepper.getResults()
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* Of course, you might think, that this is rather overkill if you simply want to receive the result.
|
|
34
|
-
* And this is true. Therefore, if you do not want to perform some kind of magic in-between steps, you can use the
|
|
35
|
-
* **{@link allRemainingSteps}** function like this:
|
|
36
|
-
*
|
|
37
|
-
* ```ts
|
|
38
|
-
* const stepper = new PipelineExecutor( ... )
|
|
39
|
-
* const result = await stepper.allRemainingSteps()
|
|
40
|
-
* ```
|
|
41
|
-
*
|
|
42
|
-
* As the name suggest, you can combine this name with previous calls to {@link nextStep} to only execute the remaining
|
|
43
|
-
* steps in case, for whatever reason you only want to instrument some steps.
|
|
44
|
-
*
|
|
45
|
-
* By default, the {@link PipelineExecutor} does not offer an automatic way to repeat requests (mostly to prevent accidental errors).
|
|
46
|
-
* However, you can use the
|
|
47
|
-
* **{@link updateRequest}** function to reset the request steps and re-execute them for a new request. This allows something like the following:
|
|
48
|
-
*
|
|
49
|
-
* ```ts
|
|
50
|
-
* const stepper = new PipelineExecutor( ... )
|
|
51
|
-
* const result = await stepper.allRemainingSteps()
|
|
52
|
-
*
|
|
53
|
-
* stepper.updateRequest( ... )
|
|
54
|
-
* const result2 = await stepper.allRemainingSteps()
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* **Example - Slicing With the Pipeline Executor**:
|
|
58
|
-
*
|
|
59
|
-
* Suppose, you want to... you know _slice_ a file (which was, at one point the origin of flowR), then you can
|
|
60
|
-
* either create a pipeline yourself with the respective steps, or you can use the {@link DEFAULT_SLICING_PIPELINE} (and friends).
|
|
61
|
-
* With it, slicing essentially becomes 'easy-as-pie':
|
|
62
|
-
*
|
|
63
|
-
* ```ts
|
|
64
|
-
* const slicer = new PipelineExecutor(DEFAULT_SLICING_PIPELINE, {
|
|
65
|
-
* shell: new RShell(),
|
|
66
|
-
* // of course, the criterion and request given here are just examples, you can use whatever you want to slice!
|
|
67
|
-
* criterion: ['2@b'],
|
|
68
|
-
* request: requestFromInput('b <- 3; x <- 5\ncat(b)'),
|
|
69
|
-
* })
|
|
70
|
-
* const result = await slicer.allRemainingSteps()
|
|
71
|
-
* ```
|
|
72
|
-
*
|
|
73
|
-
* But now, we want to slice for `x` in the first line as well! We can do that by adding:
|
|
74
|
-
*
|
|
75
|
-
* ```ts
|
|
76
|
-
* stepper.updateRequest({ criterion: ['1@x'] })
|
|
77
|
-
* const result2 = await stepper.allRemainingSteps()
|
|
78
|
-
* ```
|
|
79
|
-
*
|
|
80
|
-
* @note Even though using the pipeline executor introduces a small performance overhead, we consider
|
|
81
|
-
* it to be the baseline for performance benchmarking. It may very well be possible to squeeze out a little bit more by
|
|
82
|
-
* directly constructing the steps in the right order. However, we consider this to be negligible when compared with the time required
|
|
83
|
-
* for, for example, the dataflow analysis of larger files.
|
|
84
|
-
*
|
|
85
|
-
* @see PipelineExecutor#allRemainingSteps
|
|
86
|
-
* @see PipelineExecutor#nextStep
|
|
87
|
-
*/
|
|
88
|
-
class PipelineExecutor {
|
|
89
|
-
pipeline;
|
|
90
|
-
length;
|
|
91
|
-
input;
|
|
92
|
-
output = {};
|
|
93
|
-
currentExecutionStage = 0 /* PipelineStepStage.OncePerFile */;
|
|
94
|
-
stepCounter = 0;
|
|
95
|
-
/**
|
|
96
|
-
* Construct a new pipeline executor.
|
|
97
|
-
* The required additional input is specified by the {@link IPipelineStep#requiredInput|required input configuration} of each step in the `pipeline`.
|
|
98
|
-
*
|
|
99
|
-
* @param pipeline - The {@link Pipeline} to execute, probably created with {@link createPipeline}.
|
|
100
|
-
* @param input - External {@link PipelineInput|configuration and input} required to execute the given pipeline.
|
|
101
|
-
*/
|
|
102
|
-
constructor(pipeline, input) {
|
|
103
|
-
this.pipeline = pipeline;
|
|
104
|
-
this.length = pipeline.order.length;
|
|
105
|
-
this.input = input;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Retrieve the current {@link PipelineStepStage|stage} the pipeline executor is in.
|
|
109
|
-
*
|
|
110
|
-
* @see currentExecutionStage
|
|
111
|
-
* @see switchToRequestStage
|
|
112
|
-
* @see PipelineStepStage
|
|
113
|
-
*/
|
|
114
|
-
getCurrentStage() {
|
|
115
|
-
return this.currentExecutionStage;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Switch to the next {@link PipelineStepStage|stage} of the pipeline executor.
|
|
119
|
-
*
|
|
120
|
-
* This will fail if either a step change is currently not valid (as not all steps have been executed),
|
|
121
|
-
* or if there is no next stage (i.e., the pipeline is already completed or in the last stage).
|
|
122
|
-
*
|
|
123
|
-
* @see PipelineExecutor
|
|
124
|
-
* @see getCurrentStage
|
|
125
|
-
*/
|
|
126
|
-
switchToRequestStage() {
|
|
127
|
-
(0, assert_1.guard)(this.stepCounter === this.pipeline.firstStepPerRequest, 'First need to complete all steps before switching');
|
|
128
|
-
(0, assert_1.guard)(this.currentExecutionStage === 0 /* PipelineStepStage.OncePerFile */, 'Cannot switch to next stage, already in per-request stage.');
|
|
129
|
-
this.currentExecutionStage = 1 /* PipelineStepStage.OncePerRequest */;
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Returns the results of the pipeline.
|
|
133
|
-
*
|
|
134
|
-
* @param intermediate - Normally you can only receive the results *after* the stepper completed the step of interested.
|
|
135
|
-
* However, if you pass `true` to this parameter, you can also receive the results *before* the {@link PipelineExecutor|pipeline executor}
|
|
136
|
-
* completed, although the typing system then can not guarantee which of the steps have already happened.
|
|
137
|
-
*/
|
|
138
|
-
getResults(intermediate = false) {
|
|
139
|
-
(0, assert_1.guard)(intermediate || this.stepCounter >= this.length, 'Without the intermediate flag, the pipeline must be completed before providing access to the results.');
|
|
140
|
-
return this.output;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Returns true only if
|
|
144
|
-
* 1) there are more {@link IPipelineStep|steps} to-do for the current {@link PipelineStepStage|stage} and
|
|
145
|
-
* 2) we have not yet reached the end of the {@link Pipeline|pipeline}.
|
|
146
|
-
*/
|
|
147
|
-
hasNextStep() {
|
|
148
|
-
return (this.stepCounter < this.length && this.currentExecutionStage !== 0 /* PipelineStepStage.OncePerFile */)
|
|
149
|
-
|| this.stepCounter < this.pipeline.firstStepPerRequest;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Execute the next {@link IPipelineStep|step} and return the name of the {@link IPipelineStep|step} that was executed,
|
|
153
|
-
* so you can guard if the {@link IPipelineStep|step} differs from what you are interested in.
|
|
154
|
-
* Furthermore, it returns the {@link IPipelineStep|step's} result.
|
|
155
|
-
*
|
|
156
|
-
* @param expectedStepName - A safeguard if you want to retrieve the result.
|
|
157
|
-
* If given, it causes the execution to fail if the next step is not the one you expect.
|
|
158
|
-
*
|
|
159
|
-
* _Without `expectedStepName`, please refrain from accessing the result, as you have no safeguards if the pipeline changes._
|
|
160
|
-
*/
|
|
161
|
-
async nextStep(expectedStepName) {
|
|
162
|
-
const [step, result] = this._doNextStep(expectedStepName);
|
|
163
|
-
const awaitedResult = await result;
|
|
164
|
-
this.output[step] = awaitedResult;
|
|
165
|
-
this.stepCounter++;
|
|
166
|
-
return { name: step, result: awaitedResult };
|
|
167
|
-
}
|
|
168
|
-
_doNextStep(expectedStepName) {
|
|
169
|
-
const step = this.pipeline.steps.get(this.pipeline.order[this.stepCounter]);
|
|
170
|
-
(0, assert_1.guard)(step !== undefined, () => `Cannot execute next step, step ${this.pipeline.order[this.stepCounter]} does not exist.`);
|
|
171
|
-
if (expectedStepName !== undefined) {
|
|
172
|
-
(0, assert_1.guard)(step.name === expectedStepName, () => `Cannot execute next step, expected step ${JSON.stringify(expectedStepName)} but got ${step.name}.`);
|
|
173
|
-
}
|
|
174
|
-
return [step.name, step.processor(this.output, this.input)];
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* This only makes sense if you have already run a request and want to re-use the per-file results for a new one.
|
|
178
|
-
* (or if for whatever reason you did not pass information for the pipeline with the constructor).
|
|
179
|
-
*
|
|
180
|
-
* @param newRequestData - Data for the new request
|
|
181
|
-
*/
|
|
182
|
-
updateRequest(newRequestData) {
|
|
183
|
-
const requestStep = this.pipeline.firstStepPerRequest;
|
|
184
|
-
(0, assert_1.guard)(this.stepCounter >= requestStep, 'Cannot reset request prior to once-per-request stage');
|
|
185
|
-
this.input = {
|
|
186
|
-
...this.input,
|
|
187
|
-
...newRequestData
|
|
188
|
-
};
|
|
189
|
-
this.stepCounter = requestStep;
|
|
190
|
-
// clear the results for all steps with an index >= firstStepPerRequest, this is more of a sanity check
|
|
191
|
-
for (let i = requestStep; i < this.length; i++) {
|
|
192
|
-
this.output[this.pipeline.order[i]] = undefined;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Execute all remaining steps and automatically call {@link switchToRequestStage} if necessary.
|
|
197
|
-
* @param canSwitchStage - If true, automatically switch to the request stage if necessary
|
|
198
|
-
* (i.e., this is what you want if you have never executed {@link nextStep} and you want to execute *all* steps).
|
|
199
|
-
* However, passing false allows you to only execute the steps of the 'once-per-file' stage (i.e., the steps that can be cached).
|
|
200
|
-
*
|
|
201
|
-
* @note There is a small type difference if you pass 'false' and already have manually switched to the 'once-per-request' stage.
|
|
202
|
-
* Because now, the results of these steps are no longer part of the result type (although they are still included).
|
|
203
|
-
* In such a case, you may be better off with simply passing 'true' as the function will detect that the stage is already switched.
|
|
204
|
-
* We could solve this type problem by separating the {@link PipelineExecutor} class into two for each stage,
|
|
205
|
-
* but this would break the improved readability and unified handling of the executor that I wanted to achieve with this class.
|
|
206
|
-
*/
|
|
207
|
-
async allRemainingSteps(canSwitchStage = true) {
|
|
208
|
-
while (this.hasNextStep()) {
|
|
209
|
-
await this.nextStep();
|
|
210
|
-
}
|
|
211
|
-
if (canSwitchStage && this.stepCounter < this.length && this.currentExecutionStage === 0 /* PipelineStepStage.OncePerFile */) {
|
|
212
|
-
this.switchToRequestStage();
|
|
213
|
-
while (this.hasNextStep()) {
|
|
214
|
-
await this.nextStep();
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return this.stepCounter < this.length ? this.getResults(true) : this.getResults();
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
exports.PipelineExecutor = PipelineExecutor;
|
|
221
|
-
//# sourceMappingURL=pipeline-executor.js.map
|
package/core/stepping-slicer.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SteppingSlicer = void 0;
|
|
4
|
-
const steps_1 = require("./steps");
|
|
5
|
-
const pipeline_1 = require("./steps/pipeline");
|
|
6
|
-
const _00_parse_1 = require("./steps/all/core/00-parse");
|
|
7
|
-
const _10_normalize_1 = require("./steps/all/core/10-normalize");
|
|
8
|
-
const _20_dataflow_1 = require("./steps/all/core/20-dataflow");
|
|
9
|
-
const _00_slice_1 = require("./steps/all/static-slicing/00-slice");
|
|
10
|
-
const _10_reconstruct_1 = require("./steps/all/static-slicing/10-reconstruct");
|
|
11
|
-
const pipeline_executor_1 = require("./pipeline-executor");
|
|
12
|
-
const legacyPipelines = {
|
|
13
|
-
// brrh, but who cares, it is legacy!
|
|
14
|
-
'parse': (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP),
|
|
15
|
-
'normalize': (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE),
|
|
16
|
-
'dataflow': (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE, _20_dataflow_1.LEGACY_STATIC_DATAFLOW),
|
|
17
|
-
'slice': (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE, _20_dataflow_1.LEGACY_STATIC_DATAFLOW, _00_slice_1.STATIC_SLICE),
|
|
18
|
-
'reconstruct': (0, pipeline_1.createPipeline)(_00_parse_1.PARSE_WITH_R_SHELL_STEP, _10_normalize_1.NORMALIZE, _20_dataflow_1.LEGACY_STATIC_DATAFLOW, _00_slice_1.STATIC_SLICE, _10_reconstruct_1.NAIVE_RECONSTRUCT)
|
|
19
|
-
};
|
|
20
|
-
function getLegacyPipeline(interestedIn) {
|
|
21
|
-
return legacyPipelines[interestedIn];
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* This is ultimately the root of flowR's static slicing procedure.
|
|
25
|
-
* It clearly defines the steps that are to be executed and splits them into two stages.
|
|
26
|
-
* - `once-per-file`: for steps that are executed once per file. These can be performed *without* the knowledge of a slicing criteria,
|
|
27
|
-
* and they can be cached and re-used if you want to slice the same file multiple times.
|
|
28
|
-
* - `once-per-slice`: for steps that are executed once per slice. These can only be performed *with* a slicing criteria.
|
|
29
|
-
*
|
|
30
|
-
* Furthermore, this stepper follows an iterable fashion to be *as flexible as possible* (e.g., to be instrumented with measurements).
|
|
31
|
-
* So, you can use the stepping slicer like this:
|
|
32
|
-
*
|
|
33
|
-
* ```ts
|
|
34
|
-
* const slicer = new SteppingSlicer({ ... })
|
|
35
|
-
* while(slicer.hasNextStep()) {
|
|
36
|
-
* await slicer.nextStep()
|
|
37
|
-
* }
|
|
38
|
-
*
|
|
39
|
-
* slicer.switchToSliceStage()
|
|
40
|
-
*
|
|
41
|
-
* while(slicer.hasNextStep()) {
|
|
42
|
-
* await slicer.nextStep()
|
|
43
|
-
* }
|
|
44
|
-
*
|
|
45
|
-
* const result = slicer.getResults()
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* Of course, you might think, that this is rather overkill if you simply want to receive the slice of a given input source or in general
|
|
49
|
-
* the result of any step. And this is true. Therefore, if you do not want to perform some kind of magic in-between steps, you can use the
|
|
50
|
-
* **{@link allRemainingSteps}** function like this:
|
|
51
|
-
*
|
|
52
|
-
* ```ts
|
|
53
|
-
* const slicer = new SteppingSlicer({ ... })
|
|
54
|
-
* const result = await slicer.allRemainingSteps()
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* As the name suggest, you can combine this name with previous calls to {@link nextStep} to only execute the remaining steps.
|
|
58
|
-
*
|
|
59
|
-
* Giving the **step of interest** allows you to declare the maximum step to execute.
|
|
60
|
-
* So, if you pass `dataflow` as the step of interest, the stepping slicer will stop after the dataflow step.
|
|
61
|
-
* If you do not pass a step, the stepping slicer will execute all steps.
|
|
62
|
-
*
|
|
63
|
-
* By default, the {@link SteppingSlicer} does not offer an automatic way to repeat the per-slice steps for multiple slices (this is mostly to prevent accidental errors).
|
|
64
|
-
* However, you can use the **{@link updateCriterion}** function to reset the per-slice steps and re-execute them for a new slice. This allows something like the following:
|
|
65
|
-
*
|
|
66
|
-
* ```ts
|
|
67
|
-
* const slicer = new SteppingSlicer({ ... })
|
|
68
|
-
* const result = await slicer.allRemainingSteps()
|
|
69
|
-
*
|
|
70
|
-
* slicer.updateCriterion(...)
|
|
71
|
-
* const result2 = await slicer.allRemainingSteps()
|
|
72
|
-
* ```
|
|
73
|
-
*
|
|
74
|
-
* @note Even though, using the stepping slicer introduces some performance overhead, we consider
|
|
75
|
-
* it to be the baseline for performance benchmarking. It may very well be possible to squeeze out some more performance by
|
|
76
|
-
* directly constructing the steps in the right order. However, we consider this to be negligible when compared with the time required
|
|
77
|
-
* for, for example, the dataflow analysis.
|
|
78
|
-
*
|
|
79
|
-
* @see retrieveResultOfStep
|
|
80
|
-
* @see StepName
|
|
81
|
-
*/
|
|
82
|
-
class SteppingSlicer {
|
|
83
|
-
executor;
|
|
84
|
-
/**
|
|
85
|
-
* Create a new stepping slicer. For more details on the arguments please see {@link SteppingSlicerInput}.
|
|
86
|
-
*/
|
|
87
|
-
constructor(input) {
|
|
88
|
-
this.executor = new pipeline_executor_1.PipelineExecutor(getLegacyPipeline(input.stepOfInterest ?? steps_1.LAST_STEP), input);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Retrieve the current stage the stepping slicer is in.
|
|
92
|
-
* @see PipelineStepStage
|
|
93
|
-
* @see switchToSliceStage
|
|
94
|
-
*/
|
|
95
|
-
getCurrentStage() {
|
|
96
|
-
return this.executor.getCurrentStage();
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Switch to the next stage of the stepping slicer.
|
|
100
|
-
* @see SteppingSlicer
|
|
101
|
-
* @see getCurrentStage
|
|
102
|
-
*/
|
|
103
|
-
switchToSliceStage() {
|
|
104
|
-
this.executor.switchToRequestStage();
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Returns the result of the step of interest, as well as the results of all steps before it.
|
|
108
|
-
*
|
|
109
|
-
* @param intermediate - normally you can only receive the results *after* the stepper completed the step of interested.
|
|
110
|
-
* However, if you pass `true` to this parameter, you can also receive the results *before* the step of interest,
|
|
111
|
-
* although the typing system then can not guarantee which of the steps have already happened.
|
|
112
|
-
*/
|
|
113
|
-
getResults(intermediate = false) {
|
|
114
|
-
return this.executor.getResults(intermediate);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Returns true only if 1) there are more steps to-do for the current stage and 2) we have not yet reached the step we are interested in
|
|
118
|
-
*/
|
|
119
|
-
hasNextStep() {
|
|
120
|
-
return this.executor.hasNextStep();
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Execute the next step (guarded with {@link hasNextStep}) and return the name of the step that was executed, so you can guard if the step differs from what you are interested in.
|
|
124
|
-
* Furthermore, it returns the step's result.
|
|
125
|
-
*
|
|
126
|
-
* The `step` parameter is a safeguard if you want to retrieve the result.
|
|
127
|
-
* If given, it causes the execution to fail if the next step is not the one you expect.
|
|
128
|
-
* *Without step, please refrain from accessing the result.*
|
|
129
|
-
*/
|
|
130
|
-
async nextStep(expectedStepName) {
|
|
131
|
-
return this.executor.nextStep(expectedStepName);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* This only makes sense if you have already sliced a file (e.g., by running up to the `slice` step) and want to do so again while caching the results.
|
|
135
|
-
* Or if for whatever reason you did not pass a criterion with the constructor.
|
|
136
|
-
*
|
|
137
|
-
* @param newCriterion - the new slicing criterion to use for the next slice
|
|
138
|
-
*/
|
|
139
|
-
updateCriterion(newCriterion) {
|
|
140
|
-
// @ts-expect-error -- it is legacy
|
|
141
|
-
this.executor.updateRequest({ criterion: newCriterion });
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Execute all remaining steps and automatically call {@link switchToSliceStage} if necessary.
|
|
145
|
-
* @param canSwitchStage - if true, automatically switch to the slice stage if necessary
|
|
146
|
-
* (i.e., this is what you want if you have never executed {@link nextStep} and you want to execute *all* steps).
|
|
147
|
-
* However, passing false allows you to only execute the steps of the 'once-per-file' stage (i.e., the steps that can be cached).
|
|
148
|
-
*
|
|
149
|
-
* @note There is a small type difference if you pass 'false' and already have manually switched to the 'once-per-slice' stage.
|
|
150
|
-
* Because now, the results of these steps are no longer part of the result type (although they are still included).
|
|
151
|
-
* In such a case, you may be better off with simply passing 'true' as the function will detect that the stage is already switched.
|
|
152
|
-
* We could solve this type problem by separating the SteppingSlicer class into two for each stage, but this would break the improved readability and unified handling
|
|
153
|
-
* of the slicer that I wanted to achieve with this class.
|
|
154
|
-
*/
|
|
155
|
-
async allRemainingSteps(canSwitchStage = true) {
|
|
156
|
-
return this.executor.allRemainingSteps(canSwitchStage);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
exports.SteppingSlicer = SteppingSlicer;
|
|
160
|
-
//# sourceMappingURL=stepping-slicer.js.map
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PARSE_WITH_R_SHELL_STEP = void 0;
|
|
4
|
-
const print_1 = require("../../print/print");
|
|
5
|
-
const parse_printer_1 = require("../../print/parse-printer");
|
|
6
|
-
const r_bridge_1 = require("../../../r-bridge");
|
|
7
|
-
exports.PARSE_WITH_R_SHELL_STEP = {
|
|
8
|
-
name: 'parse',
|
|
9
|
-
description: 'Parse the given R code into an AST',
|
|
10
|
-
processor: r_bridge_1.retrieveXmlFromRCode,
|
|
11
|
-
required: 'once-per-file',
|
|
12
|
-
printer: {
|
|
13
|
-
[0 /* StepOutputFormat.Internal */]: print_1.internalPrinter,
|
|
14
|
-
[2 /* StepOutputFormat.Json */]: text => text,
|
|
15
|
-
[5 /* StepOutputFormat.RdfQuads */]: parse_printer_1.parseToQuads
|
|
16
|
-
},
|
|
17
|
-
dependencies: []
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=00-parse.js.map
|