@eagleoutice/flowr 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -29
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +2 -3
- package/abstract-interpretation/data-frame/absint-visitor.js +14 -16
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +3 -3
- package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
- package/abstract-interpretation/data-frame/semantics.js +7 -10
- package/abstract-interpretation/data-frame/shape-inference.js +2 -8
- package/benchmark/slicer.js +7 -5
- package/benchmark/summarizer/second-phase/graph.js +1 -1
- package/benchmark/summarizer/second-phase/process.js +1 -1
- package/cli/benchmark-app.d.ts +1 -0
- package/cli/benchmark-app.js +1 -0
- package/cli/benchmark-helper-app.d.ts +1 -0
- package/cli/benchmark-helper-app.js +4 -3
- package/cli/common/options.js +2 -0
- package/cli/repl/commands/repl-query.js +1 -1
- package/cli/repl/server/connection.js +14 -5
- package/control-flow/basic-cfg-guided-visitor.d.ts +1 -2
- package/control-flow/basic-cfg-guided-visitor.js +0 -6
- package/control-flow/cfg-simplification.d.ts +6 -0
- package/control-flow/cfg-simplification.js +18 -9
- package/control-flow/control-flow-graph.d.ts +2 -8
- package/control-flow/control-flow-graph.js +1 -6
- package/control-flow/extract-cfg.d.ts +2 -2
- package/control-flow/extract-cfg.js +52 -63
- package/core/steps/all/static-slicing/00-slice.d.ts +7 -1
- package/core/steps/all/static-slicing/00-slice.js +9 -3
- package/core/steps/pipeline/default-pipelines.d.ts +74 -74
- package/dataflow/environments/built-in.d.ts +2 -2
- package/dataflow/environments/built-in.js +13 -12
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/graph.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +2 -0
- package/dataflow/graph/invert-dfg.js +17 -0
- package/documentation/doc-util/doc-query.js +1 -1
- package/documentation/doc-util/doc-search.js +2 -2
- package/documentation/print-cfg-wiki.js +3 -4
- package/documentation/print-core-wiki.js +2 -2
- package/documentation/print-dataflow-graph-wiki.js +7 -0
- package/documentation/print-faq-wiki.js +4 -0
- package/documentation/print-linter-wiki.js +32 -4
- package/documentation/print-linting-and-testing-wiki.js +13 -1
- package/documentation/print-onboarding-wiki.js +4 -0
- package/documentation/print-query-wiki.js +12 -3
- package/linter/linter-executor.js +1 -2
- package/linter/linter-format.d.ts +26 -4
- package/linter/linter-format.js +25 -6
- package/linter/linter-rules.d.ts +40 -12
- package/linter/linter-rules.js +3 -1
- package/linter/rules/absolute-path.d.ts +4 -7
- package/linter/rules/absolute-path.js +9 -6
- package/linter/rules/dataframe-access-validation.d.ts +3 -1
- package/linter/rules/dataframe-access-validation.js +3 -1
- package/linter/rules/dead-code.d.ts +43 -0
- package/linter/rules/dead-code.js +50 -0
- package/linter/rules/deprecated-functions.d.ts +3 -2
- package/linter/rules/deprecated-functions.js +3 -1
- package/linter/rules/file-path-validity.d.ts +4 -4
- package/linter/rules/file-path-validity.js +8 -6
- package/linter/rules/naming-convention.d.ts +4 -3
- package/linter/rules/naming-convention.js +3 -1
- package/linter/rules/seeded-randomness.d.ts +4 -3
- package/linter/rules/seeded-randomness.js +3 -1
- package/linter/rules/unused-definition.d.ts +2 -0
- package/linter/rules/unused-definition.js +3 -1
- package/package.json +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +6 -1
- package/queries/catalog/dependencies-query/function-info/read-functions.js +1 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +1 -0
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-executor.js +7 -5
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +3 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +1 -0
- package/queries/catalog/search-query/search-query-executor.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -1
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +0 -1
- package/queries/query.d.ts +16 -5
- package/queries/query.js +24 -11
- package/search/flowr-search-builder.d.ts +6 -6
- package/search/flowr-search-executor.d.ts +2 -2
- package/search/flowr-search-executor.js +1 -1
- package/search/flowr-search.d.ts +13 -8
- package/search/flowr-search.js +21 -0
- package/search/search-executor/search-enrichers.d.ts +87 -20
- package/search/search-executor/search-enrichers.js +44 -5
- package/search/search-executor/search-generators.d.ts +4 -4
- package/search/search-executor/search-generators.js +12 -7
- package/search/search-executor/search-mappers.js +3 -2
- package/search/search-executor/search-transformer.d.ts +3 -3
- package/search/search-executor/search-transformer.js +2 -2
- package/slicing/static/static-slicer.d.ts +4 -2
- package/slicing/static/static-slicer.js +10 -4
- package/util/collections/arrays.d.ts +2 -0
- package/util/collections/arrays.js +9 -0
- package/util/mermaid/dfg.js +4 -2
- package/util/range.d.ts +1 -0
- package/util/range.js +5 -1
- package/util/version.js +1 -1
|
@@ -8,6 +8,20 @@ import type { RShell } from '../../../r-bridge/shell';
|
|
|
8
8
|
import type { TreeSitterExecutor } from '../../../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor';
|
|
9
9
|
import type { FlowrConfigOptions } from '../../../config';
|
|
10
10
|
export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
|
|
11
|
+
readonly name: "slice";
|
|
12
|
+
readonly humanReadableName: "static slice";
|
|
13
|
+
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
14
|
+
readonly processor: (results: {
|
|
15
|
+
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
16
|
+
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
17
|
+
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
18
|
+
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
19
|
+
readonly printer: {
|
|
20
|
+
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
21
|
+
};
|
|
22
|
+
readonly dependencies: readonly ["dataflow"];
|
|
23
|
+
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
24
|
+
} | {
|
|
11
25
|
readonly name: "parse";
|
|
12
26
|
readonly humanReadableName: "parse with R shell";
|
|
13
27
|
readonly description: "Parse the given R code into an AST";
|
|
@@ -60,20 +74,6 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
|
|
|
60
74
|
readonly 4: typeof import("../../print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
61
75
|
};
|
|
62
76
|
readonly dependencies: readonly ["normalize"];
|
|
63
|
-
} | {
|
|
64
|
-
readonly name: "slice";
|
|
65
|
-
readonly humanReadableName: "static slice";
|
|
66
|
-
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
67
|
-
readonly processor: (results: {
|
|
68
|
-
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
69
|
-
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
70
|
-
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
71
|
-
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
72
|
-
readonly printer: {
|
|
73
|
-
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
74
|
-
};
|
|
75
|
-
readonly dependencies: readonly ["dataflow"];
|
|
76
|
-
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
77
77
|
} | {
|
|
78
78
|
readonly name: "reconstruct";
|
|
79
79
|
readonly humanReadableName: "static code reconstruction";
|
|
@@ -90,6 +90,20 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
|
|
|
90
90
|
readonly requiredInput: import("../all/static-slicing/10-reconstruct").ReconstructRequiredInput;
|
|
91
91
|
}>;
|
|
92
92
|
export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline").Pipeline<{
|
|
93
|
+
readonly name: "slice";
|
|
94
|
+
readonly humanReadableName: "static slice";
|
|
95
|
+
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
96
|
+
readonly processor: (results: {
|
|
97
|
+
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
98
|
+
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
99
|
+
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
100
|
+
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
101
|
+
readonly printer: {
|
|
102
|
+
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
103
|
+
};
|
|
104
|
+
readonly dependencies: readonly ["dataflow"];
|
|
105
|
+
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
106
|
+
} | {
|
|
93
107
|
readonly name: "parse";
|
|
94
108
|
readonly humanReadableName: "parse with R shell";
|
|
95
109
|
readonly description: "Parse the given R code into an AST";
|
|
@@ -142,20 +156,6 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
|
|
|
142
156
|
readonly 4: typeof import("../../print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
143
157
|
};
|
|
144
158
|
readonly dependencies: readonly ["normalize"];
|
|
145
|
-
} | {
|
|
146
|
-
readonly name: "slice";
|
|
147
|
-
readonly humanReadableName: "static slice";
|
|
148
|
-
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
149
|
-
readonly processor: (results: {
|
|
150
|
-
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
151
|
-
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
152
|
-
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
153
|
-
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
154
|
-
readonly printer: {
|
|
155
|
-
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
156
|
-
};
|
|
157
|
-
readonly dependencies: readonly ["dataflow"];
|
|
158
|
-
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
159
159
|
} | {
|
|
160
160
|
readonly name: "reconstruct";
|
|
161
161
|
readonly humanReadableName: "static code reconstruction";
|
|
@@ -172,6 +172,20 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
|
|
|
172
172
|
readonly requiredInput: import("../all/static-slicing/10-reconstruct").ReconstructRequiredInput;
|
|
173
173
|
}>;
|
|
174
174
|
export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipeline").Pipeline<{
|
|
175
|
+
readonly name: "slice";
|
|
176
|
+
readonly humanReadableName: "static slice";
|
|
177
|
+
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
178
|
+
readonly processor: (results: {
|
|
179
|
+
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
180
|
+
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
181
|
+
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
182
|
+
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
183
|
+
readonly printer: {
|
|
184
|
+
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
185
|
+
};
|
|
186
|
+
readonly dependencies: readonly ["dataflow"];
|
|
187
|
+
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
188
|
+
} | {
|
|
175
189
|
readonly name: "parse";
|
|
176
190
|
readonly humanReadableName: "parse with R shell";
|
|
177
191
|
readonly description: "Parse the given R code into an AST";
|
|
@@ -224,22 +238,22 @@ export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipel
|
|
|
224
238
|
readonly 4: typeof import("../../print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
225
239
|
};
|
|
226
240
|
readonly dependencies: readonly ["normalize"];
|
|
227
|
-
}
|
|
241
|
+
}>;
|
|
242
|
+
export declare const TREE_SITTER_SLICING_PIPELINE: import("./pipeline").Pipeline<{
|
|
228
243
|
readonly name: "slice";
|
|
229
244
|
readonly humanReadableName: "static slice";
|
|
230
245
|
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
231
246
|
readonly processor: (results: {
|
|
232
247
|
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
233
248
|
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
234
|
-
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>,
|
|
249
|
+
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
235
250
|
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
236
251
|
readonly printer: {
|
|
237
252
|
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
238
253
|
};
|
|
239
254
|
readonly dependencies: readonly ["dataflow"];
|
|
240
255
|
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
241
|
-
}
|
|
242
|
-
export declare const TREE_SITTER_SLICING_PIPELINE: import("./pipeline").Pipeline<{
|
|
256
|
+
} | {
|
|
243
257
|
readonly humanReadableName: "dataflow";
|
|
244
258
|
readonly processor: (results: {
|
|
245
259
|
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
@@ -259,20 +273,6 @@ export declare const TREE_SITTER_SLICING_PIPELINE: import("./pipeline").Pipeline
|
|
|
259
273
|
readonly 4: typeof import("../../print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
260
274
|
};
|
|
261
275
|
readonly dependencies: readonly ["normalize"];
|
|
262
|
-
} | {
|
|
263
|
-
readonly name: "slice";
|
|
264
|
-
readonly humanReadableName: "static slice";
|
|
265
|
-
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
266
|
-
readonly processor: (results: {
|
|
267
|
-
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
268
|
-
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
269
|
-
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
270
|
-
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
271
|
-
readonly printer: {
|
|
272
|
-
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
273
|
-
};
|
|
274
|
-
readonly dependencies: readonly ["dataflow"];
|
|
275
|
-
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
276
276
|
} | {
|
|
277
277
|
readonly name: "reconstruct";
|
|
278
278
|
readonly humanReadableName: "static code reconstruction";
|
|
@@ -321,6 +321,20 @@ export declare const TREE_SITTER_SLICING_PIPELINE: import("./pipeline").Pipeline
|
|
|
321
321
|
readonly requiredInput: import("../all/core/10-normalize").NormalizeRequiredInput;
|
|
322
322
|
}>;
|
|
323
323
|
export declare const TREE_SITTER_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline").Pipeline<{
|
|
324
|
+
readonly name: "slice";
|
|
325
|
+
readonly humanReadableName: "static slice";
|
|
326
|
+
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
327
|
+
readonly processor: (results: {
|
|
328
|
+
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
329
|
+
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
330
|
+
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
331
|
+
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
332
|
+
readonly printer: {
|
|
333
|
+
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
334
|
+
};
|
|
335
|
+
readonly dependencies: readonly ["dataflow"];
|
|
336
|
+
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
337
|
+
} | {
|
|
324
338
|
readonly humanReadableName: "dataflow";
|
|
325
339
|
readonly processor: (results: {
|
|
326
340
|
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
@@ -340,20 +354,6 @@ export declare const TREE_SITTER_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipel
|
|
|
340
354
|
readonly 4: typeof import("../../print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
341
355
|
};
|
|
342
356
|
readonly dependencies: readonly ["normalize"];
|
|
343
|
-
} | {
|
|
344
|
-
readonly name: "slice";
|
|
345
|
-
readonly humanReadableName: "static slice";
|
|
346
|
-
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
347
|
-
readonly processor: (results: {
|
|
348
|
-
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
349
|
-
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
350
|
-
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
351
|
-
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
352
|
-
readonly printer: {
|
|
353
|
-
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
354
|
-
};
|
|
355
|
-
readonly dependencies: readonly ["dataflow"];
|
|
356
|
-
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
357
357
|
} | {
|
|
358
358
|
readonly name: "reconstruct";
|
|
359
359
|
readonly humanReadableName: "static code reconstruction";
|
|
@@ -402,6 +402,20 @@ export declare const TREE_SITTER_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipel
|
|
|
402
402
|
readonly requiredInput: import("../all/core/10-normalize").NormalizeRequiredInput;
|
|
403
403
|
}>;
|
|
404
404
|
export declare const TREE_SITTER_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipeline").Pipeline<{
|
|
405
|
+
readonly name: "slice";
|
|
406
|
+
readonly humanReadableName: "static slice";
|
|
407
|
+
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
408
|
+
readonly processor: (results: {
|
|
409
|
+
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
410
|
+
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
411
|
+
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
412
|
+
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
413
|
+
readonly printer: {
|
|
414
|
+
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
415
|
+
};
|
|
416
|
+
readonly dependencies: readonly ["dataflow"];
|
|
417
|
+
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
418
|
+
} | {
|
|
405
419
|
readonly humanReadableName: "dataflow";
|
|
406
420
|
readonly processor: (results: {
|
|
407
421
|
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
@@ -421,20 +435,6 @@ export declare const TREE_SITTER_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./p
|
|
|
421
435
|
readonly 4: typeof import("../../print/dataflow-printer").dataflowGraphToMermaidUrl;
|
|
422
436
|
};
|
|
423
437
|
readonly dependencies: readonly ["normalize"];
|
|
424
|
-
} | {
|
|
425
|
-
readonly name: "slice";
|
|
426
|
-
readonly humanReadableName: "static slice";
|
|
427
|
-
readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
|
|
428
|
-
readonly processor: (results: {
|
|
429
|
-
dataflow?: import("../../../dataflow/info").DataflowInformation;
|
|
430
|
-
normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
431
|
-
}, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
|
|
432
|
-
readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
|
|
433
|
-
readonly printer: {
|
|
434
|
-
readonly 0: typeof import("../../print/print").internalPrinter;
|
|
435
|
-
};
|
|
436
|
-
readonly dependencies: readonly ["dataflow"];
|
|
437
|
-
readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
|
|
438
438
|
} | {
|
|
439
439
|
readonly name: "parse";
|
|
440
440
|
readonly humanReadableName: "parse with tree-sitter";
|
|
@@ -54,7 +54,7 @@ export interface DefaultBuiltInProcessorConfiguration extends ForceArguments {
|
|
|
54
54
|
readonly returnsNthArgument?: number | 'last';
|
|
55
55
|
readonly cfg?: ExitPointType;
|
|
56
56
|
readonly readAllArguments?: boolean;
|
|
57
|
-
readonly hasUnknownSideEffects?: boolean | LinkTo
|
|
57
|
+
readonly hasUnknownSideEffects?: boolean | LinkTo;
|
|
58
58
|
/** record mapping the actual function name called to the arguments that should be treated as function calls */
|
|
59
59
|
readonly treatAsFnCall?: Record<string, readonly string[]>;
|
|
60
60
|
/** Name that should be used for the origin (useful when needing to differentiate between
|
|
@@ -63,7 +63,7 @@ export interface DefaultBuiltInProcessorConfiguration extends ForceArguments {
|
|
|
63
63
|
readonly useAsProcessor?: UseAsProcessors;
|
|
64
64
|
}
|
|
65
65
|
export type BuiltInEvalHandler = (resolve: VariableResolve, a: RNodeWithParent, env?: REnvironmentInformation, graph?: DataflowGraph, map?: AstIdMap) => Value;
|
|
66
|
-
declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>,
|
|
66
|
+
declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }: DefaultBuiltInProcessorConfiguration): DataflowInformation;
|
|
67
67
|
export declare function registerBuiltInFunctions<Config extends object, Proc extends BuiltInIdentifierProcessorWithConfig<Config>>(both: boolean, names: readonly Identifier[], processor: Proc, config: Config): void;
|
|
68
68
|
export declare const BuiltInProcessorMapper: {
|
|
69
69
|
readonly 'builtin:default': typeof defaultBuiltInProcessor;
|
|
@@ -41,30 +41,31 @@ function builtInId(name) {
|
|
|
41
41
|
function isBuiltIn(name) {
|
|
42
42
|
return String(name).startsWith('built-in:');
|
|
43
43
|
}
|
|
44
|
-
function defaultBuiltInProcessor(name, args, rootId, data,
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
function defaultBuiltInProcessor(name, args, rootId, data, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }) {
|
|
45
|
+
const activeProcessor = useAsProcessor ?? 'builtin:default';
|
|
46
|
+
const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs, origin: activeProcessor });
|
|
47
|
+
if (returnsNthArgument !== undefined) {
|
|
48
|
+
const arg = returnsNthArgument === 'last' ? processedArguments[args.length - 1] : processedArguments[returnsNthArgument];
|
|
48
49
|
if (arg !== undefined) {
|
|
49
50
|
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Returns);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
|
-
if (
|
|
53
|
+
if (readAllArguments) {
|
|
53
54
|
for (const arg of processedArguments) {
|
|
54
55
|
if (arg) {
|
|
55
56
|
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Reads);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
if (
|
|
60
|
-
if (typeof
|
|
61
|
-
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId,
|
|
60
|
+
if (hasUnknownSideEffects) {
|
|
61
|
+
if (typeof hasUnknownSideEffects !== 'boolean') {
|
|
62
|
+
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId, hasUnknownSideEffects);
|
|
62
63
|
}
|
|
63
64
|
else {
|
|
64
65
|
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId);
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
|
-
const fnCallNames =
|
|
68
|
+
const fnCallNames = treatAsFnCall?.[name.content];
|
|
68
69
|
if (fnCallNames) {
|
|
69
70
|
for (const arg of args) {
|
|
70
71
|
if (arg !== r_function_call_1.EmptyArgument && arg.value && fnCallNames.includes(arg.name?.content)) {
|
|
@@ -90,13 +91,13 @@ function defaultBuiltInProcessor(name, args, rootId, data, config) {
|
|
|
90
91
|
environment: data.environment,
|
|
91
92
|
onlyBuiltin: false,
|
|
92
93
|
cds: data.controlDependencies,
|
|
93
|
-
origin: [
|
|
94
|
+
origin: [activeProcessor]
|
|
94
95
|
});
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
|
-
if (
|
|
99
|
-
res.exitPoints
|
|
99
|
+
if (cfg !== undefined) {
|
|
100
|
+
res.exitPoints.push({ type: cfg, nodeId: rootId, controlDependencies: data.controlDependencies });
|
|
100
101
|
}
|
|
101
102
|
return res;
|
|
102
103
|
}
|
|
@@ -180,7 +180,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
180
180
|
fromId = from.nodeId;
|
|
181
181
|
}
|
|
182
182
|
else {
|
|
183
|
-
const result = (0, flowr_search_executor_1.runSearch)(from.query, data);
|
|
183
|
+
const result = (0, flowr_search_executor_1.runSearch)(from.query, data).getElements();
|
|
184
184
|
(0, assert_1.guard)(result.length === 1, `from query result should yield exactly one node, but yielded ${result.length}`);
|
|
185
185
|
fromId = result[0].node.info.id;
|
|
186
186
|
}
|
|
@@ -189,7 +189,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
189
189
|
toIds = to.target;
|
|
190
190
|
}
|
|
191
191
|
else {
|
|
192
|
-
const result = (0, flowr_search_executor_1.runSearch)(to.query, data);
|
|
192
|
+
const result = (0, flowr_search_executor_1.runSearch)(to.query, data).getElements();
|
|
193
193
|
toIds = result.map(r => r.node.info.id);
|
|
194
194
|
}
|
|
195
195
|
return this.edgeHelper(fromId, toIds, type);
|
package/dataflow/graph/graph.js
CHANGED
|
@@ -376,7 +376,7 @@ function mergeNodeInfos(current, next) {
|
|
|
376
376
|
}
|
|
377
377
|
else if (current.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
378
378
|
(0, assert_1.guard)(current.scope === next.scope, 'nodes to be joined for the same id must have the same scope');
|
|
379
|
-
|
|
379
|
+
current.exitPoints = (0, arrays_1.uniqueArrayMerge)(current.exitPoints, next.exitPoints);
|
|
380
380
|
}
|
|
381
381
|
return current;
|
|
382
382
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.invertDfg = invertDfg;
|
|
4
|
+
const graph_1 = require("./graph");
|
|
5
|
+
function invertDfg(graph) {
|
|
6
|
+
const invertedGraph = new graph_1.DataflowGraph(graph.idMap);
|
|
7
|
+
for (const [, v] of graph.vertices(true)) {
|
|
8
|
+
invertedGraph.addVertex(v);
|
|
9
|
+
}
|
|
10
|
+
for (const [from, targets] of graph.edges()) {
|
|
11
|
+
for (const [to, { types }] of targets) {
|
|
12
|
+
invertedGraph.addEdge(to, from, types);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return invertedGraph;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=invert-dfg.js.map
|
|
@@ -25,7 +25,7 @@ async function showQuery(shell, code, queries, { showCode, collapseResult, colla
|
|
|
25
25
|
parser: shell,
|
|
26
26
|
request: (0, retriever_1.requestFromInput)(code)
|
|
27
27
|
}, config_1.defaultConfigOptions).allRemainingSteps();
|
|
28
|
-
const results = (0, query_1.executeQueries)({ dataflow: analysis.dataflow, ast: analysis.normalize, config: config_1.defaultConfigOptions }, queries);
|
|
28
|
+
const results = await Promise.resolve((0, query_1.executeQueries)({ dataflow: analysis.dataflow, ast: analysis.normalize, config: config_1.defaultConfigOptions }, queries));
|
|
29
29
|
const duration = performance.now() - now;
|
|
30
30
|
const metaInfo = `
|
|
31
31
|
The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
|
|
@@ -53,13 +53,13 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify(search, null, 2))}
|
|
|
53
53
|
${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
|
|
54
54
|
|
|
55
55
|
The query returns the following vetices (all references to \`x\` in the code):
|
|
56
|
-
${result.map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, analysis.dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
|
|
56
|
+
${result.getElements().map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, analysis.dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
|
|
57
57
|
|
|
58
58
|
${metaInfo}
|
|
59
59
|
|
|
60
60
|
The returned results are highlighted thick and blue within the dataflow graph:
|
|
61
61
|
|
|
62
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { showCode: false, switchCodeAndGraph: false, mark: new Set(result.map(({ node }) => node.info.id)) })}
|
|
62
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { showCode: false, switchCodeAndGraph: false, mark: new Set(result.getElements().map(({ node }) => node.info.id)) })}
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
${collapseResult ? '</details>' : ''}
|
|
@@ -224,8 +224,7 @@ ${Object.entries(control_flow_graph_1.CfgVertexType).map(([key, value]) => `- \`
|
|
|
224
224
|
We use the ${(0, doc_types_1.shortLink)('CfgBasicBlockVertex', types.info)} to represent [basic blocks](#cfg-basic-blocks) and separate
|
|
225
225
|
expressions (${(0, doc_types_1.shortLink)('CfgExpressionVertex', types.info)}) and statements (${(0, doc_types_1.shortLink)('CfgStatementVertex', types.info)})
|
|
226
226
|
as control flow units with and without side effects (if you want to, you can see view statements as effectful expressions).
|
|
227
|
-
The markers (${(0, doc_types_1.shortLink)('
|
|
228
|
-
indicate specific segments of larger expressions/statements (e.g., an \`if\` which has a condition and its branches).
|
|
227
|
+
The markers (${(0, doc_types_1.shortLink)('CfgEndMarkerVertex', types.info)}) indicate the end of larger expressions/statements.
|
|
229
228
|
|
|
230
229
|
To signal these links, the expressions and statements contain information about the attached markers:
|
|
231
230
|
|
|
@@ -235,7 +234,7 @@ Similarly, the markers contain a link to their root:
|
|
|
235
234
|
|
|
236
235
|
${(0, doc_types_1.printHierarchy)({ info: types.info, root: 'CfgWithRoot', program: types.program, openTop: true })}
|
|
237
236
|
|
|
238
|
-
In mermaid visualizations, we use rectangles for statements, rounded rectangles for expressions
|
|
237
|
+
In mermaid visualizations, we use rectangles for statements, rounded rectangles for expressions and circles for exit markers.
|
|
239
238
|
Blocks are visualized as boxes around the contained vertices.
|
|
240
239
|
|
|
241
240
|
${(0, doc_structure_1.block)({
|
|
@@ -554,7 +553,7 @@ Hence, you may rely on the corresponding exit point(s) to identify all exits of
|
|
|
554
553
|
|
|
555
554
|
${(0, doc_structure_1.block)({
|
|
556
555
|
type: 'WARNING',
|
|
557
|
-
content: 'Using basic blocks, this works just the same. However please keep in mind that the corresponding exit markers do not (and for control statements usually will not) be part of the same basic block.'
|
|
556
|
+
content: 'Using basic blocks, this works just the same. However, please keep in mind that the corresponding exit markers do not (and for control statements usually will not) be part of the same basic block.'
|
|
558
557
|
})}
|
|
559
558
|
|
|
560
559
|
`;
|
|
@@ -28,7 +28,6 @@ const built_in_access_1 = require("../dataflow/internal/process/functions/call/b
|
|
|
28
28
|
const built_in_for_loop_1 = require("../dataflow/internal/process/functions/call/built-in/built-in-for-loop");
|
|
29
29
|
const built_in_repeat_loop_1 = require("../dataflow/internal/process/functions/call/built-in/built-in-repeat-loop");
|
|
30
30
|
const linker_1 = require("../dataflow/internal/linker");
|
|
31
|
-
const static_slicer_1 = require("../slicing/static/static-slicer");
|
|
32
31
|
const info_1 = require("../dataflow/info");
|
|
33
32
|
const processor_1 = require("../dataflow/processor");
|
|
34
33
|
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
@@ -42,6 +41,7 @@ const normalize_for_1 = require("../r-bridge/lang-4.x/ast/parser/main/internal/l
|
|
|
42
41
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
43
42
|
const pipeline_executor_1 = require("../core/pipeline-executor");
|
|
44
43
|
const pipeline_1 = require("../core/steps/pipeline/pipeline");
|
|
44
|
+
const static_slicer_1 = require("../slicing/static/static-slicer");
|
|
45
45
|
const config_1 = require("../config");
|
|
46
46
|
async function getText(shell) {
|
|
47
47
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
@@ -373,7 +373,7 @@ Of course, all of these endeavors work not just with the ${(0, doc_types_1.short
|
|
|
373
373
|
The slicing is available as an extra step as you can see by inspecting he ${(0, doc_types_1.shortLink)('DEFAULT_SLICING_PIPELINE', info)}.
|
|
374
374
|
Besides ${(0, doc_types_1.shortLink)('STATIC_SLICE', info)} it contains a ${(0, doc_types_1.shortLink)('NAIVE_RECONSTRUCT', info)} to print the slice as (executable) R code.
|
|
375
375
|
|
|
376
|
-
Your main point of interesting here is the ${(0, doc_types_1.shortLink)(static_slicer_1.
|
|
376
|
+
Your main point of interesting here is the ${(0, doc_types_1.shortLink)(static_slicer_1.staticSlice.name, info)} function which relies on a modified
|
|
377
377
|
breadth-first search to collect all nodes which are part of the slice.
|
|
378
378
|
For more information on how the slicing works, please refer to the [tool demonstration (Section 3.2)](https://doi.org/10.1145/3691620.3695359),
|
|
379
379
|
or the [original master's thesis (Chapter 4)](https://doi.org/10.18725/OPARU-50107).
|
|
@@ -835,6 +835,13 @@ The following sections present details on the different types of vertices and ed
|
|
|
835
835
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', 'const node = graph.idMap.get(id);'), '> ')}
|
|
836
836
|
> In case you just need the name (\`lexeme\`) of the respective vertex, ${(0, doc_types_1.shortLink)(node_id_1.recoverName.name, vertexType.info)} can help you out:
|
|
837
837
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = ${node_id_1.recoverName.name}(id, graph.idMap);`), '> ')}
|
|
838
|
+
>
|
|
839
|
+
> Please note that not every node in the normalized AST is represented in the dataflow graph.
|
|
840
|
+
> For example, if the node is unreachable in a way that can be detected during the analysis and flowR
|
|
841
|
+
> is configured to ignore dead code. Likewise, empty argument wrappers do not have a corresponding
|
|
842
|
+
> dataflow graph vertex (as they are not relevant for the dataflow graph). It depends on the scenario what to do in such a case.
|
|
843
|
+
> For argument wrappers you can access the dataflow information for their value. For dead code, however, flowR currently contains
|
|
844
|
+
> some core heuristics that remove it which cannot be reversed easily. So please open [an issue](${doc_issue_1.NewIssueUrl}) if you encounter such a case and require the node to be present in the dataflow graph.
|
|
838
845
|
|
|
839
846
|
${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
|
|
840
847
|
|
|
@@ -39,6 +39,10 @@ With \`npm\` you have to pass arguments in a specific way. The \`--\` operator i
|
|
|
39
39
|
${(0, doc_code_1.codeBlock)('shell', 'npm run flowR -- --help')}
|
|
40
40
|
`)}
|
|
41
41
|
|
|
42
|
+
${qAndA('How to do logging in flowR?', `
|
|
43
|
+
Check out the [Logging Section in the Linting and Testing wiki page](${doc_files_1.FlowrWikiBaseRef}/Linting-and-Testing#logging) for more information on how to do logging in *flowR*.
|
|
44
|
+
`)}
|
|
45
|
+
|
|
42
46
|
## 🇷 R FAQ
|
|
43
47
|
|
|
44
48
|
### 📦 R Packages
|
|
@@ -20,11 +20,12 @@ const strings_1 = require("../util/text/strings");
|
|
|
20
20
|
const assert_1 = require("../util/assert");
|
|
21
21
|
const doc_print_1 = require("./doc-util/doc-print");
|
|
22
22
|
const doc_functions_1 = require("./doc-util/doc-functions");
|
|
23
|
+
const linter_format_1 = require("../linter/linter-format");
|
|
23
24
|
const SpecialTagColors = {
|
|
24
25
|
[linter_tags_1.LintingRuleTag.Bug]: 'red',
|
|
25
26
|
[linter_tags_1.LintingRuleTag.Security]: 'orange',
|
|
26
27
|
[linter_tags_1.LintingRuleTag.Smell]: 'yellow',
|
|
27
|
-
[linter_tags_1.LintingRuleTag.QuickFix]: 'lightgray'
|
|
28
|
+
[linter_tags_1.LintingRuleTag.QuickFix]: 'lightgray'
|
|
28
29
|
};
|
|
29
30
|
function makeTagBadge(name, info) {
|
|
30
31
|
const doc = (0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, info, '', true).replaceAll('\n', ' ');
|
|
@@ -112,6 +113,7 @@ print(myVar)
|
|
|
112
113
|
df <- data.frame(id = 1:5, name = 6:10)
|
|
113
114
|
df[6, "value"]
|
|
114
115
|
`, tagTypes);
|
|
116
|
+
rule(shell, 'dead-code', 'DeadCodeConfig', 'DEAD_CODE', 'lint-dead-code', 'if(TRUE) 1 else 2', tagTypes);
|
|
115
117
|
function rule(shell, name, configType, ruleType, testfile, example, types) {
|
|
116
118
|
const rule = linter_rules_1.LintingRules[name];
|
|
117
119
|
const tags = rule.info.tags.toSorted((a, b) => {
|
|
@@ -130,6 +132,8 @@ df[6, "value"]
|
|
|
130
132
|
}
|
|
131
133
|
return a.localeCompare(b);
|
|
132
134
|
}).map(t => makeTagBadge(t, types)).join(' ');
|
|
135
|
+
const certaintyDoc = (0, doc_types_1.getDocumentationForType)(`LintingRuleCertainty::${rule.info.certainty}`, types, '', true).replaceAll('\n', ' ');
|
|
136
|
+
const certaintyText = `\`${(0, html_hover_over_1.textWithTooltip)(rule.info.certainty, certaintyDoc)}\``;
|
|
133
137
|
if (format === 'short') {
|
|
134
138
|
ruleExplanations.set(name, () => Promise.resolve(`
|
|
135
139
|
**[${rule.info.name}](${doc_files_1.FlowrWikiBaseRef}/lint-${name}):** ${rule.info.description} [see ${(0, doc_types_1.shortLinkFile)(ruleType, types)}]\\
|
|
@@ -144,6 +148,9 @@ ${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'linte
|
|
|
144
148
|
${(0, doc_structure_1.section)(rule.info.name + ` <sup>[<a href="${doc_files_1.FlowrWikiBaseRef}/Linter">overview</a>]</sup>`, 2, name)}
|
|
145
149
|
|
|
146
150
|
${tags}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
This rule is a ${certaintyText} rule.
|
|
147
154
|
|
|
148
155
|
${rule.info.description}\\
|
|
149
156
|
_This linting rule is implemented in ${(0, doc_types_1.shortLinkFile)(ruleType, types)}._
|
|
@@ -171,9 +178,12 @@ ${buildSamplesFromLinterTestCases(shell, `${testfile}.test.ts`)}
|
|
|
171
178
|
}
|
|
172
179
|
return ruleExplanations;
|
|
173
180
|
}
|
|
174
|
-
function
|
|
181
|
+
function getAllLintingRulesWithTag(tag) {
|
|
175
182
|
return Object.entries(linter_rules_1.LintingRules).filter(([_, rule]) => rule.info.tags.includes(tag)).map(([name]) => name);
|
|
176
183
|
}
|
|
184
|
+
function getAllLintingRulesWitCertainty(certainty) {
|
|
185
|
+
return Object.entries(linter_rules_1.LintingRules).filter(([_, rule]) => rule.info.certainty === certainty).map(([name]) => name);
|
|
186
|
+
}
|
|
177
187
|
function linkToRule(name) {
|
|
178
188
|
return `[${name}](${doc_files_1.FlowrWikiBaseRef}/lint-${name})`;
|
|
179
189
|
}
|
|
@@ -214,14 +224,32 @@ ${await (async () => {
|
|
|
214
224
|
|
|
215
225
|
${(0, doc_structure_1.section)('Tags', 2, 'tags')}
|
|
216
226
|
|
|
217
|
-
We use tags to categorize linting rules. The following tags are available:
|
|
227
|
+
We use tags to categorize linting rules for users. The following tags are available:
|
|
218
228
|
|
|
219
229
|
| Tag/Badge   | Description |
|
|
220
230
|
| --- | :-- |
|
|
221
231
|
${Object.entries(linter_tags_1.LintingRuleTag).map(([name, tag]) => {
|
|
222
|
-
return `| <a id="${tag}"></a> ${makeTagBadge(tag, tagTypes.info)} | ${(0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, tagTypes.info).replaceAll(/\n/g, ' ')} (rule${
|
|
232
|
+
return `| <a id="${tag}"></a> ${(makeTagBadge(tag, tagTypes.info))} | ${(0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, tagTypes.info).replaceAll(/\n/g, ' ')} (rule${getAllLintingRulesWithTag(tag).length === 1 ? '' : 's'}: ${(0, strings_1.joinWithLast)(getAllLintingRulesWithTag(tag).map(l => linkToRule(l))) || '_none_'}) | `;
|
|
233
|
+
}).join('\n')}
|
|
234
|
+
|
|
235
|
+
${(0, doc_structure_1.section)('Certainty', 2, 'certainty')}
|
|
236
|
+
|
|
237
|
+
Both linting rules and their individual results are additionally categorized by how certain the linter is that the results it is returning are valid.
|
|
238
|
+
|
|
239
|
+
${(0, doc_structure_1.section)('Rule Certainty', 3, 'rule-certainty')}
|
|
240
|
+
|
|
241
|
+
| Rule Certainty | Description |
|
|
242
|
+
| -------------- | :---------- |
|
|
243
|
+
${Object.entries(linter_format_1.LintingRuleCertainty).map(([name, certainty]) => {
|
|
244
|
+
return `| <a id="${certainty}"></a> \`${certainty}\` | ${(0, doc_types_1.getDocumentationForType)('LintingRuleCertainty::' + name, tagTypes.info).replaceAll(/\n/g, ' ')} (rule${getAllLintingRulesWitCertainty(certainty).length === 1 ? '' : 's'}: ${(0, strings_1.joinWithLast)(getAllLintingRulesWitCertainty(certainty).map(l => linkToRule(l))) || '_none_'}) |`;
|
|
223
245
|
}).join('\n')}
|
|
224
246
|
|
|
247
|
+
${(0, doc_structure_1.section)('Result Certainty', 3, 'result-certainty')}
|
|
248
|
+
|
|
249
|
+
| Result Certainty | Description |
|
|
250
|
+
| ---------------- | :---------- |
|
|
251
|
+
${Object.entries(linter_format_1.LintingResultCertainty).map(([name, certainty]) => `| <a id="${certainty}"></a> \`${certainty}\` | ${(0, doc_types_1.getDocumentationForType)('LintingResultCertainty::' + name, tagTypes.info).replaceAll(/\n/g, ' ')} |`).join('\n')}
|
|
252
|
+
|
|
225
253
|
`.trim();
|
|
226
254
|
}
|
|
227
255
|
async function getRulesPages(shell, tagTypes, rVersion) {
|
|
@@ -4,16 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const log_1 = require("../../test/functionality/_helper/log");
|
|
7
|
+
const log_2 = require("../util/log");
|
|
7
8
|
const doc_code_1 = require("./doc-util/doc-code");
|
|
8
9
|
const doc_files_1 = require("./doc-util/doc-files");
|
|
9
10
|
const doc_structure_1 = require("./doc-util/doc-structure");
|
|
10
11
|
const doc_types_1 = require("./doc-util/doc-types");
|
|
11
12
|
const path_1 = __importDefault(require("path"));
|
|
12
13
|
const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
|
|
14
|
+
const doc_cli_option_1 = require("./doc-util/doc-cli-option");
|
|
13
15
|
function getText() {
|
|
14
16
|
const { info } = (0, doc_types_1.getTypesFromFolder)({
|
|
15
17
|
rootFolder: path_1.default.resolve('./test'),
|
|
16
|
-
files: [path_1.default.resolve('./src/dataflow/graph/dataflowgraph-builder.ts')],
|
|
18
|
+
files: [path_1.default.resolve('./src/dataflow/graph/dataflowgraph-builder.ts'), path_1.default.resolve('./src/util/log.ts'), path_1.default.resolve('./src/slicing/static/static-slicer.ts')],
|
|
17
19
|
typeNameForMermaid: 'parameter',
|
|
18
20
|
inlineTypes: doc_types_1.mermaidHide
|
|
19
21
|
});
|
|
@@ -39,6 +41,7 @@ for the latest benchmark results, see the [benchmark results](${doc_files_1.Flow
|
|
|
39
41
|
- [License Checker](#license-checker)
|
|
40
42
|
- [🐛 Debugging](#debugging)
|
|
41
43
|
- [VS Code](#vs-code-1)
|
|
44
|
+
- [Logging](#logging)
|
|
42
45
|
|
|
43
46
|
<a id='testing-suites'></a>
|
|
44
47
|
## 🏨 Testing Suites
|
|
@@ -254,6 +257,15 @@ However, in case you think that the linter is wrong, please do not hesitate to o
|
|
|
254
257
|
### VS Code
|
|
255
258
|
When working with VS Code, you can attach a debugger to the REPL. This works automatically by running the \`Start Debugging\` command (\`F5\` by default).
|
|
256
259
|
You can also set the \`Auto Attach Filter\` setting to automatically attach the debugger, when running \`npm run flowr\`.
|
|
260
|
+
|
|
261
|
+
### Logging
|
|
262
|
+
|
|
263
|
+
*flowR* uses a wrapper around [tslog](https://www.npmjs.com/package/tslog) using a class named
|
|
264
|
+
${(0, doc_types_1.shortLink)(log_2.FlowrLogger.name, info)}. They obey to, for example, the ${(0, doc_cli_option_1.getCliLongOptionOf)('flowr', 'verbose')}
|
|
265
|
+
option. Throughout *flowR*, we use the \`log\` object (or subloggers of it) for logging.
|
|
266
|
+
To create your own logger, you can use ${(0, doc_types_1.shortLink)(log_2.FlowrLogger.name + '::' + (new log_2.FlowrLogger().getSubLogger.name), info, true, 'i')}.
|
|
267
|
+
For example, check out the ${(0, doc_types_1.shortLink)('slicerLogger', info)} for the static slicer.
|
|
268
|
+
|
|
257
269
|
`;
|
|
258
270
|
}
|
|
259
271
|
if (require.main === module) {
|
|
@@ -13,6 +13,10 @@ To get started developing on *flowR*, we recommend carefully reading the followi
|
|
|
13
13
|
- 💖 [Contributing guidelines](${doc_files_1.FlowrGithubBaseRef}/flowr/tree/main/.github/CONTRIBUTING.md).\
|
|
14
14
|
This page also includes information about how to set up **git-lfs** and several **git hooks**.
|
|
15
15
|
|
|
16
|
+
If you have any questions, please check out the [FAQ](${doc_files_1.FlowrWikiBaseRef}/FAQ) first, but if the question
|
|
17
|
+
is not answered there (or in the wiki in general), feel free to ask a question.
|
|
18
|
+
|
|
19
|
+
|
|
16
20
|
## ⌛ TL;DR
|
|
17
21
|
|
|
18
22
|
The most important steps to get the *flowR* development environment set up (after installing **R** and **Node.js**) can be seen below. For convenience, they can be executed all at once using the following command:
|