@eagleoutice/flowr 2.7.0 → 2.7.3
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 +14 -14
- package/abstract-interpretation/absint-visitor.d.ts +160 -0
- package/abstract-interpretation/absint-visitor.js +279 -0
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +2 -2
- package/abstract-interpretation/data-frame/dataframe-domain.js +23 -7
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +6 -6
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +10 -14
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +15 -9
- package/abstract-interpretation/data-frame/mappers/arguments.js +27 -4
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +17 -17
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +55 -67
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +7 -7
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +25 -29
- package/abstract-interpretation/data-frame/resolve-args.d.ts +1 -1
- package/abstract-interpretation/data-frame/resolve-args.js +1 -1
- package/abstract-interpretation/data-frame/semantics.js +5 -6
- package/abstract-interpretation/data-frame/shape-inference.d.ts +52 -28
- package/abstract-interpretation/data-frame/shape-inference.js +67 -90
- package/abstract-interpretation/domains/bounded-set-domain.d.ts +2 -2
- package/abstract-interpretation/domains/interval-domain.d.ts +2 -2
- package/abstract-interpretation/domains/set-range-domain.d.ts +10 -4
- package/abstract-interpretation/domains/set-range-domain.js +7 -1
- package/abstract-interpretation/domains/set-upper-bound-domain.d.ts +2 -2
- package/abstract-interpretation/domains/singleton-domain.d.ts +2 -2
- package/benchmark/slicer.js +13 -14
- package/cli/common/options.d.ts +431 -8
- package/cli/common/options.js +1 -1
- package/cli/common/scripts-info.d.ts +431 -7
- package/cli/flowr-main-options.d.ts +102 -2
- package/cli/flowr.d.ts +102 -2
- package/cli/repl/commands/repl-commands.d.ts +25 -0
- package/cli/repl/commands/repl-query.js +17 -5
- package/cli/wiki.d.ts +13 -0
- package/cli/wiki.js +7 -2
- package/config.d.ts +4 -4
- package/config.js +1 -1
- package/control-flow/basic-cfg-guided-visitor.js +7 -8
- package/control-flow/control-flow-graph.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +1 -1
- package/dataflow/eval/resolve/alias-tracking.js +1 -1
- package/dataflow/internal/linker.d.ts +2 -0
- package/dataflow/internal/linker.js +10 -12
- package/documentation/doc-capabilities.d.ts +1 -1
- package/documentation/doc-readme.d.ts +1 -1
- package/documentation/doc-util/doc-cfg.js +1 -1
- package/documentation/doc-util/doc-cli-option.d.ts +6 -6
- package/documentation/doc-util/doc-cli-option.js +3 -3
- package/documentation/doc-util/doc-dfg.d.ts +1 -1
- package/documentation/doc-util/doc-files.d.ts +3 -0
- package/documentation/doc-util/doc-files.js +4 -1
- package/documentation/doc-util/doc-normalized-ast.js +2 -2
- package/documentation/issue-linting-rule.d.ts +1 -1
- package/documentation/wiki-analyzer.d.ts +1 -1
- package/documentation/wiki-cfg.d.ts +1 -1
- package/documentation/wiki-core.d.ts +1 -1
- package/documentation/wiki-dataflow-graph.d.ts +1 -1
- package/documentation/wiki-dataflow-graph.js +6 -6
- package/documentation/wiki-engine.d.ts +1 -1
- package/documentation/wiki-engine.js +9 -10
- package/documentation/wiki-faq.d.ts +1 -1
- package/documentation/wiki-interface.d.ts +1 -1
- package/documentation/wiki-interface.js +12 -13
- package/documentation/wiki-linter.d.ts +1 -1
- package/documentation/wiki-linting-and-testing.d.ts +1 -1
- package/documentation/wiki-mk/doc-context.d.ts +54 -1
- package/documentation/wiki-mk/doc-context.js +17 -0
- package/documentation/wiki-mk/doc-maker.d.ts +5 -5
- package/documentation/wiki-mk/doc-maker.js +3 -1
- package/documentation/wiki-normalized-ast.d.ts +1 -1
- package/documentation/wiki-onboarding.d.ts +1 -1
- package/documentation/wiki-overview.d.ts +9 -0
- package/documentation/wiki-overview.js +248 -0
- package/documentation/wiki-query.d.ts +1 -1
- package/documentation/wiki-query.js +17 -1
- package/documentation/wiki-search.d.ts +1 -1
- package/documentation/wiki-setup.d.ts +9 -0
- package/documentation/wiki-setup.js +122 -0
- package/linter/rules/dataframe-access-validation.d.ts +1 -1
- package/linter/rules/dataframe-access-validation.js +8 -10
- package/linter/rules/unused-definition.js +1 -1
- package/package.json +1 -1
- package/project/context/flowr-analyzer-context.d.ts +4 -0
- package/project/context/flowr-analyzer-context.js +3 -1
- package/project/context/flowr-analyzer-dependencies-context.d.ts +3 -2
- package/project/context/flowr-analyzer-dependencies-context.js +4 -2
- package/project/context/flowr-analyzer-files-context.d.ts +9 -1
- package/project/context/flowr-analyzer-files-context.js +4 -0
- package/project/context/flowr-analyzer-functions-context.d.ts +29 -0
- package/project/context/flowr-analyzer-functions-context.js +68 -0
- package/project/context/flowr-file.d.ts +2 -0
- package/project/context/flowr-file.js +2 -0
- package/project/plugins/file-plugins/{flowr-description-file.d.ts → files/flowr-description-file.d.ts} +1 -1
- package/project/plugins/file-plugins/files/flowr-description-file.js +75 -0
- package/project/plugins/file-plugins/files/flowr-namespace-file.d.ts +32 -0
- package/project/plugins/file-plugins/files/flowr-namespace-file.js +102 -0
- package/project/plugins/file-plugins/files/flowr-news-file.d.ts +27 -0
- package/project/plugins/file-plugins/files/flowr-news-file.js +152 -0
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-namespace-file-plugin.d.ts +22 -0
- package/project/plugins/file-plugins/flowr-analyzer-namespace-file-plugin.js +34 -0
- package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.d.ts +23 -0
- package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.js +35 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.js +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.js +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.js +1 -1
- package/project/plugins/flowr-analyzer-plugin-defaults.js +4 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +5 -1
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-namespace-file-plugin.d.ts +10 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-namespace-file-plugin.js +56 -0
- package/project/plugins/package-version-plugins/package.d.ts +15 -2
- package/project/plugins/package-version-plugins/package.js +33 -5
- package/project/plugins/plugin-registry.d.ts +3 -1
- package/project/plugins/plugin-registry.js +4 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +7 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -1
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.js +2 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +4 -2
- package/queries/catalog/files-query/files-query-executor.d.ts +6 -0
- package/queries/catalog/files-query/files-query-executor.js +49 -0
- package/queries/catalog/files-query/files-query-format.d.ts +36 -0
- package/queries/catalog/files-query/files-query-format.js +114 -0
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/query.d.ts +10 -1
- package/queries/query.js +3 -1
- package/r-bridge/lang-4.x/ast/model/model.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +8 -8
- package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +8 -8
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-parameter.js +0 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -1
- package/statistics/features/supported/data-access/data-access.js +1 -1
- package/util/containers.js +1 -1
- package/util/files.d.ts +0 -7
- package/util/files.js +0 -41
- package/util/mermaid/ast.d.ts +3 -2
- package/util/mermaid/ast.js +13 -7
- package/util/mermaid/cfg.d.ts +3 -2
- package/util/mermaid/cfg.js +26 -6
- package/util/mermaid/dfg.d.ts +1 -7
- package/util/mermaid/dfg.js +7 -3
- package/util/mermaid/info.d.ts +17 -0
- package/util/mermaid/info.js +5 -0
- package/util/prefix.d.ts +9 -5
- package/util/prefix.js +14 -6
- package/util/r-regex.d.ts +21 -0
- package/util/r-regex.js +25 -0
- package/util/text/args.js +12 -3
- package/util/version.js +1 -1
- package/abstract-interpretation/data-frame/absint-info.d.ts +0 -109
- package/abstract-interpretation/data-frame/absint-info.js +0 -31
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +0 -57
- package/abstract-interpretation/data-frame/absint-visitor.js +0 -176
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +0 -21
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +0 -34
- package/documentation/doc-util/doc-print.d.ts +0 -5
- package/documentation/doc-util/doc-print.js +0 -36
- package/project/plugins/file-plugins/flowr-description-file.js +0 -37
- package/project/plugins/file-plugins/notebooks/notebook.d.ts +0 -0
- package/project/plugins/file-plugins/notebooks/notebook.js +0 -2
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.d.ts +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.js +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.d.ts +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.js +0 -0
|
@@ -1,35 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
|
|
4
|
-
import type { RNode } from '../../r-bridge/lang-4.x/ast/model/model';
|
|
5
|
-
import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
1
|
+
import type { DataflowGraphVertexFunctionCall } from '../../dataflow/graph/vertex';
|
|
2
|
+
import type { NoInfo } from '../../r-bridge/lang-4.x/ast/model/model';
|
|
6
3
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
-
import { type
|
|
8
|
-
import {
|
|
4
|
+
import { AbstractInterpretationVisitor, type AbsintVisitorConfiguration } from '../absint-visitor';
|
|
5
|
+
import { DataFrameDomain, DataFrameStateDomain } from './dataframe-domain';
|
|
6
|
+
import { ConstraintType, type DataFrameOperationArgs, type DataFrameOperationName, type DataFrameOperationOptions } from './semantics';
|
|
7
|
+
interface Operation<Name extends DataFrameOperationName> {
|
|
8
|
+
/** The type of the abstract data frame operation (see {@link DataFrameOperationName}) */
|
|
9
|
+
operation: Name;
|
|
10
|
+
/** The ID of the data frame operand of the operation (may be `undefined`) */
|
|
11
|
+
operand: NodeId | undefined;
|
|
12
|
+
/** The optional constraint type to overwrite the default type of the operation (see {@link ConstraintType}) */
|
|
13
|
+
type?: ConstraintType;
|
|
14
|
+
/** The optional additional options for the abstract operation (see {@link DataFrameOperationOptions}) */
|
|
15
|
+
options?: DataFrameOperationOptions<Name>;
|
|
16
|
+
}
|
|
9
17
|
/**
|
|
10
|
-
*
|
|
11
|
-
* This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
|
|
12
|
-
* @param cfinfo - The control flow information containing the control flow graph
|
|
13
|
-
* @param dfg - The data flow graph to resolve variable origins and function arguments
|
|
14
|
-
* @param ast - The abstract syntax tree to resolve node IDs to AST nodes
|
|
15
|
-
* @param ctx - The current flowr analyzer context
|
|
16
|
-
* @returns The abstract data frame state at the exit node of the control flow graph (see {@link DataFrameStateDomain}).
|
|
17
|
-
* The abstract data frame states for all other nodes are attached to the AST.
|
|
18
|
+
* An abstract data frame operation.
|
|
18
19
|
*/
|
|
19
|
-
export
|
|
20
|
+
export type DataFrameOperation<OperationName extends DataFrameOperationName = DataFrameOperationName> = {
|
|
21
|
+
[Name in OperationName]: Operation<Name> & DataFrameOperationArgs<Name>;
|
|
22
|
+
}[OperationName];
|
|
20
23
|
/**
|
|
21
|
-
*
|
|
22
|
-
* This requires that the data frame shape inference has been executed before using {@link inferDataFrameShapes}.
|
|
23
|
-
* @param id - The node or node ID to get the data frame shape for
|
|
24
|
-
* @param dfg - The data flow graph used to resolve the data frame shape
|
|
25
|
-
* @param domain - An optional abstract data frame state domain used to resolve the data frame shape (defaults to the state at the requested node)
|
|
26
|
-
* @returns The abstract data frame shape of the node, or `undefined` if no data frame shape was inferred for the node
|
|
24
|
+
* An abstract data frame operation without additional options.
|
|
27
25
|
*/
|
|
28
|
-
export
|
|
26
|
+
export type DataFrameOperationType<OperationName extends DataFrameOperationName = DataFrameOperationName> = {
|
|
27
|
+
[Name in OperationName]: Omit<Operation<Name>, 'type' | 'options'> & DataFrameOperationArgs<Name>;
|
|
28
|
+
}[OperationName];
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
* @param node - The node to get the origins for
|
|
32
|
-
* @param dfg - The data flow graph for resolving the origins
|
|
33
|
-
* @returns The origins nodes of the variable
|
|
30
|
+
* A possible `undefined` array of abstract data frame operations (see {@link DataFrameOperation}).
|
|
34
31
|
*/
|
|
35
|
-
export
|
|
32
|
+
export type DataFrameOperations<OperationName extends DataFrameOperationName = DataFrameOperationName> = DataFrameOperation<OperationName>[] | undefined;
|
|
33
|
+
interface DataFrameShapeInferenceConfiguration extends Omit<AbsintVisitorConfiguration<DataFrameDomain>, 'domain'> {
|
|
34
|
+
readonly trackOperations?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The control flow graph visitor to infer the shape of data frames using abstract interpretation
|
|
38
|
+
*/
|
|
39
|
+
export declare class DataFrameShapeInferenceVisitor extends AbstractInterpretationVisitor<DataFrameDomain, NoInfo, DataFrameShapeInferenceConfiguration & {
|
|
40
|
+
domain: DataFrameStateDomain;
|
|
41
|
+
}> {
|
|
42
|
+
/**
|
|
43
|
+
* The abstract data frame operations the function call nodes are mapped to.
|
|
44
|
+
*/
|
|
45
|
+
private readonly operations?;
|
|
46
|
+
constructor({ trackOperations, ...config }: DataFrameShapeInferenceConfiguration);
|
|
47
|
+
/**
|
|
48
|
+
* Gets the mapped abstract data frame operations for an AST node (this only includes direct function calls, replacement calls, or access operations).
|
|
49
|
+
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
50
|
+
* @param id - The ID of the node to get the mapped abstract operations for
|
|
51
|
+
* @returns The mapped abstract data frame operations for the node, or `undefined` if no abstract operation was mapped for the node or storing mapped abstract operations is disabled via the visitor config.
|
|
52
|
+
*/
|
|
53
|
+
getAbstractOperations(id: NodeId | undefined): Readonly<DataFrameOperations>;
|
|
54
|
+
protected evalFunctionCall(call: DataflowGraphVertexFunctionCall, state: DataFrameStateDomain): DataFrameStateDomain;
|
|
55
|
+
protected evalReplacementCall(call: DataflowGraphVertexFunctionCall, target: NodeId, source: NodeId, state: DataFrameStateDomain): DataFrameStateDomain;
|
|
56
|
+
protected evalAccessCall(call: DataflowGraphVertexFunctionCall, state: DataFrameStateDomain): DataFrameStateDomain;
|
|
57
|
+
private applyDataFrameExpression;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -1,109 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
exports.getVariableOrigins = getVariableOrigins;
|
|
6
|
-
const control_flow_graph_1 = require("../../control-flow/control-flow-graph");
|
|
7
|
-
const vertex_1 = require("../../dataflow/graph/vertex");
|
|
8
|
-
const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin");
|
|
9
|
-
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
10
|
-
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
11
|
-
const assert_1 = require("../../util/assert");
|
|
12
|
-
const abstract_domain_1 = require("../domains/abstract-domain");
|
|
13
|
-
const absint_info_1 = require("./absint-info");
|
|
14
|
-
const absint_visitor_1 = require("./absint-visitor");
|
|
3
|
+
exports.DataFrameShapeInferenceVisitor = void 0;
|
|
4
|
+
const absint_visitor_1 = require("../absint-visitor");
|
|
15
5
|
const dataframe_domain_1 = require("./dataframe-domain");
|
|
6
|
+
const access_mapper_1 = require("./mappers/access-mapper");
|
|
7
|
+
const function_mapper_1 = require("./mappers/function-mapper");
|
|
8
|
+
const replacement_mapper_1 = require("./mappers/replacement-mapper");
|
|
9
|
+
const semantics_1 = require("./semantics");
|
|
16
10
|
/**
|
|
17
|
-
*
|
|
18
|
-
* This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
|
|
19
|
-
* @param cfinfo - The control flow information containing the control flow graph
|
|
20
|
-
* @param dfg - The data flow graph to resolve variable origins and function arguments
|
|
21
|
-
* @param ast - The abstract syntax tree to resolve node IDs to AST nodes
|
|
22
|
-
* @param ctx - The current flowr analyzer context
|
|
23
|
-
* @returns The abstract data frame state at the exit node of the control flow graph (see {@link DataFrameStateDomain}).
|
|
24
|
-
* The abstract data frame states for all other nodes are attached to the AST.
|
|
11
|
+
* The control flow graph visitor to infer the shape of data frames using abstract interpretation
|
|
25
12
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* This requires that the data frame shape inference has been executed before using {@link inferDataFrameShapes}.
|
|
37
|
-
* @param id - The node or node ID to get the data frame shape for
|
|
38
|
-
* @param dfg - The data flow graph used to resolve the data frame shape
|
|
39
|
-
* @param domain - An optional abstract data frame state domain used to resolve the data frame shape (defaults to the state at the requested node)
|
|
40
|
-
* @returns The abstract data frame shape of the node, or `undefined` if no data frame shape was inferred for the node
|
|
41
|
-
*/
|
|
42
|
-
function resolveIdToDataFrameShape(id, dfg, domain) {
|
|
43
|
-
const node = id === undefined || typeof id === 'object' ? id : dfg?.idMap?.get(id);
|
|
44
|
-
domain ??= node?.info.dataFrame?.domain;
|
|
45
|
-
if (dfg === undefined || node === undefined || domain === undefined) {
|
|
46
|
-
return;
|
|
13
|
+
class DataFrameShapeInferenceVisitor extends absint_visitor_1.AbstractInterpretationVisitor {
|
|
14
|
+
/**
|
|
15
|
+
* The abstract data frame operations the function call nodes are mapped to.
|
|
16
|
+
*/
|
|
17
|
+
operations;
|
|
18
|
+
constructor({ trackOperations = true, ...config }) {
|
|
19
|
+
super({ ...config, domain: dataframe_domain_1.DataFrameStateDomain.bottom() });
|
|
20
|
+
if (trackOperations) {
|
|
21
|
+
this.operations = new Map();
|
|
22
|
+
}
|
|
47
23
|
}
|
|
48
|
-
|
|
49
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Gets the mapped abstract data frame operations for an AST node (this only includes direct function calls, replacement calls, or access operations).
|
|
26
|
+
* This requires that the abstract interpretation visitor has been completed, or at least started.
|
|
27
|
+
* @param id - The ID of the node to get the mapped abstract operations for
|
|
28
|
+
* @returns The mapped abstract data frame operations for the node, or `undefined` if no abstract operation was mapped for the node or storing mapped abstract operations is disabled via the visitor config.
|
|
29
|
+
*/
|
|
30
|
+
getAbstractOperations(id) {
|
|
31
|
+
return id !== undefined ? this.operations?.get(id) : undefined;
|
|
50
32
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const values = getVariableOrigins(node.info.id, dfg).map(origin => domain.get(origin.info.id));
|
|
56
|
-
if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
|
|
57
|
-
return abstract_domain_1.AbstractDomain.joinAll(values);
|
|
33
|
+
evalFunctionCall(call, state) {
|
|
34
|
+
const node = this.getNormalizedAst(call.id);
|
|
35
|
+
if (node === undefined) {
|
|
36
|
+
return state;
|
|
58
37
|
}
|
|
38
|
+
const operations = (0, function_mapper_1.mapDataFrameFunctionCall)(node, this, this.config.dfg, this.config.ctx);
|
|
39
|
+
return this.applyDataFrameExpression(node, operations, state);
|
|
59
40
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
41
|
+
evalReplacementCall(call, target, source, state) {
|
|
42
|
+
const node = this.getNormalizedAst(call.id);
|
|
43
|
+
const targetNode = this.getNormalizedAst(target);
|
|
44
|
+
const sourceNode = this.getNormalizedAst(source);
|
|
45
|
+
if (node === undefined || targetNode === undefined || sourceNode === undefined) {
|
|
46
|
+
return state;
|
|
47
|
+
}
|
|
48
|
+
const operations = (0, replacement_mapper_1.mapDataFrameReplacementFunction)(node, sourceNode, this, this.config.dfg, this.config.ctx);
|
|
49
|
+
return this.applyDataFrameExpression(node, operations, state);
|
|
65
50
|
}
|
|
66
|
-
|
|
67
|
-
|
|
51
|
+
evalAccessCall(call, state) {
|
|
52
|
+
const node = this.getNormalizedAst(call.id);
|
|
53
|
+
if (node === undefined) {
|
|
54
|
+
return state;
|
|
55
|
+
}
|
|
56
|
+
const operations = (0, access_mapper_1.mapDataFrameAccess)(node, this, this.config.dfg, this.config.ctx);
|
|
57
|
+
return this.applyDataFrameExpression(node, operations, state);
|
|
68
58
|
}
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
return
|
|
59
|
+
applyDataFrameExpression(node, operations, state) {
|
|
60
|
+
if (operations === undefined) {
|
|
61
|
+
return state;
|
|
72
62
|
}
|
|
73
|
-
else if (
|
|
74
|
-
|
|
63
|
+
else if (this.operations !== undefined) {
|
|
64
|
+
this.operations.set(node.info.id, operations);
|
|
75
65
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
const maxColNames = this.config.ctx.config.abstractInterpretation.dataFrame.maxColNames;
|
|
67
|
+
let value = dataframe_domain_1.DataFrameDomain.top(maxColNames);
|
|
68
|
+
for (const { operation, operand, type, options, ...args } of operations) {
|
|
69
|
+
const operandValue = operand !== undefined ? this.getAbstractValue(operand, state) : value;
|
|
70
|
+
value = (0, semantics_1.applyDataFrameSemantics)(operation, operandValue ?? dataframe_domain_1.DataFrameDomain.top(maxColNames), args, options);
|
|
71
|
+
const constraintType = type ?? (0, semantics_1.getConstraintType)(operation);
|
|
72
|
+
if (operand !== undefined && constraintType === semantics_1.ConstraintType.OperandModification) {
|
|
73
|
+
state.set(operand, value);
|
|
74
|
+
for (const origin of this.getVariableOrigins(operand)) {
|
|
75
|
+
state.set(origin, value);
|
|
76
|
+
}
|
|
82
77
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
else if (origins.includes('builtin:if-then-else') && call?.args.every(arg => arg !== r_function_call_1.EmptyArgument)) {
|
|
86
|
-
if (call.args.length === 3) {
|
|
87
|
-
const values = call.args.slice(1, 3).map(entry => resolveIdToDataFrameShape(entry.nodeId, dfg, domain));
|
|
88
|
-
if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
|
|
89
|
-
return abstract_domain_1.AbstractDomain.joinAll(values);
|
|
78
|
+
else if (constraintType === semantics_1.ConstraintType.ResultPostcondition) {
|
|
79
|
+
state.set(node.info.id, value);
|
|
90
80
|
}
|
|
91
81
|
}
|
|
82
|
+
return state;
|
|
92
83
|
}
|
|
93
84
|
}
|
|
94
|
-
|
|
95
|
-
* Gets all origins of a variable in the data flow graph that have already been visited.
|
|
96
|
-
* @param node - The node to get the origins for
|
|
97
|
-
* @param dfg - The data flow graph for resolving the origins
|
|
98
|
-
* @returns The origins nodes of the variable
|
|
99
|
-
*/
|
|
100
|
-
function getVariableOrigins(node, dfg) {
|
|
101
|
-
// get each variable origin that has already been visited and whose assignment has already been processed
|
|
102
|
-
return (0, dfg_get_origin_1.getOriginInDfg)(dfg, node)
|
|
103
|
-
?.filter(origin => origin.type === 0 /* OriginType.ReadVariableOrigin */)
|
|
104
|
-
.map(entry => dfg.idMap?.get(entry.id))
|
|
105
|
-
.filter(assert_1.isNotUndefined)
|
|
106
|
-
.filter(origin => origin.info.dataFrame?.domain !== undefined)
|
|
107
|
-
.filter(origin => !(0, absint_info_1.hasDataFrameInfoMarker)(origin, absint_info_1.DataFrameInfoMarker.Unassigned)) ?? [];
|
|
108
|
-
}
|
|
85
|
+
exports.DataFrameShapeInferenceVisitor = DataFrameShapeInferenceVisitor;
|
|
109
86
|
//# sourceMappingURL=shape-inference.js.map
|
|
@@ -34,10 +34,10 @@ export declare class BoundedSetDomain<T, Value extends BoundedSetLift<T> = Bound
|
|
|
34
34
|
bottom(): this & BoundedSetDomain<T, BoundedSetBottom>;
|
|
35
35
|
equals(other: this): boolean;
|
|
36
36
|
leq(other: this): boolean;
|
|
37
|
-
join(other: this): this;
|
|
38
37
|
join(other: BoundedSetLift<T> | T[]): this;
|
|
39
|
-
|
|
38
|
+
join(other: this): this;
|
|
40
39
|
meet(other: BoundedSetLift<T> | T[]): this;
|
|
40
|
+
meet(other: this): this;
|
|
41
41
|
/**
|
|
42
42
|
* Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
|
|
43
43
|
*/
|
|
@@ -27,10 +27,10 @@ export declare class IntervalDomain<Value extends IntervalLift = IntervalLift> e
|
|
|
27
27
|
bottom(): this & IntervalDomain<IntervalBottom>;
|
|
28
28
|
equals(other: this): boolean;
|
|
29
29
|
leq(other: this): boolean;
|
|
30
|
-
join(other: this): this;
|
|
31
30
|
join(other: IntervalLift): this;
|
|
32
|
-
|
|
31
|
+
join(other: this): this;
|
|
33
32
|
meet(other: IntervalLift): this;
|
|
33
|
+
meet(other: this): this;
|
|
34
34
|
widen(other: this): this;
|
|
35
35
|
narrow(other: this): this;
|
|
36
36
|
concretize(limit: number): ReadonlySet<number> | typeof Top;
|
|
@@ -19,6 +19,11 @@ type SetRangeTop = typeof SetRangeTop;
|
|
|
19
19
|
type SetRangeBottom = typeof Bottom;
|
|
20
20
|
/** The type of the abstract values of the set range domain that are Top, Bottom, or actual values */
|
|
21
21
|
type SetRangeLift<T> = SetRangeValue<T> | SetRangeTop | SetRangeBottom;
|
|
22
|
+
/** The type of the actual values of the set range domain with a finite range (the range cannot be Top) */
|
|
23
|
+
type SetRangeFinite<T> = {
|
|
24
|
+
readonly min: ReadonlySet<T>;
|
|
25
|
+
readonly range: ReadonlySet<T>;
|
|
26
|
+
};
|
|
22
27
|
/** The type of the actual values of the set range domain as array tuple with a minimum array and range array for better readability (e.g. `[["id","name"], []]`, or `[["id"], ["score"]]`) */
|
|
23
28
|
export type ArrayRangeValue<T> = {
|
|
24
29
|
readonly min: T[];
|
|
@@ -48,11 +53,11 @@ export declare class SetRangeDomain<T, Value extends SetRangeLift<T> = SetRangeL
|
|
|
48
53
|
/**
|
|
49
54
|
* The minimum set (lower bound) of the set range representing all values that must exist (subset of {@link upper}).
|
|
50
55
|
*/
|
|
51
|
-
lower(): SetRangeValue<T>
|
|
56
|
+
lower(): Value extends SetRangeValue<T> ? ReadonlySet<T> : ReadonlySet<T> | typeof Bottom;
|
|
52
57
|
/**
|
|
53
58
|
* The maximum set (upper bound) of the set range representing all values that can possibly exist (union of {@link lower} and range).
|
|
54
59
|
*/
|
|
55
|
-
upper(): SetRangeValue<T>
|
|
60
|
+
upper(): Value extends SetRangeFinite<T> ? ReadonlySet<T> : Value extends SetRangeValue<T> ? ReadonlySet<T> | typeof Top : ReadonlySet<T> | typeof Top | typeof Bottom;
|
|
56
61
|
static top<T>(limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T, SetRangeTop>;
|
|
57
62
|
static bottom<T>(limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T, SetRangeBottom>;
|
|
58
63
|
static abstract<T>(concrete: ReadonlySet<ReadonlySet<T>> | typeof Top, limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T>;
|
|
@@ -60,10 +65,10 @@ export declare class SetRangeDomain<T, Value extends SetRangeLift<T> = SetRangeL
|
|
|
60
65
|
bottom(): this & SetRangeDomain<T, SetRangeBottom>;
|
|
61
66
|
equals(other: this): boolean;
|
|
62
67
|
leq(other: this): boolean;
|
|
63
|
-
join(other: this): this;
|
|
64
68
|
join(other: SetRangeLift<T> | ArrayRangeValue<T>): this;
|
|
65
|
-
|
|
69
|
+
join(other: this): this;
|
|
66
70
|
meet(other: SetRangeLift<T> | ArrayRangeValue<T>): this;
|
|
71
|
+
meet(other: this): this;
|
|
67
72
|
/**
|
|
68
73
|
* Creates the union of this abstract value and another abstract value by creating the union of the minimum and maximum set, respectively.
|
|
69
74
|
*/
|
|
@@ -94,5 +99,6 @@ export declare class SetRangeDomain<T, Value extends SetRangeLift<T> = SetRangeL
|
|
|
94
99
|
isTop(): this is SetRangeDomain<T, SetRangeTop>;
|
|
95
100
|
isBottom(): this is SetRangeDomain<T, SetRangeBottom>;
|
|
96
101
|
isValue(): this is SetRangeDomain<T, SetRangeValue<T>>;
|
|
102
|
+
isFinite(): this is SetRangeDomain<T, SetRangeFinite<T>>;
|
|
97
103
|
}
|
|
98
104
|
export {};
|
|
@@ -61,7 +61,10 @@ class SetRangeDomain extends abstract_domain_1.AbstractDomain {
|
|
|
61
61
|
if (this.value === lattice_1.Bottom) {
|
|
62
62
|
return lattice_1.Bottom;
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
else if (this.value.range == lattice_1.Top) {
|
|
65
|
+
return lattice_1.Top;
|
|
66
|
+
}
|
|
67
|
+
return this.value.min.union(this.value.range);
|
|
65
68
|
}
|
|
66
69
|
static top(limit, setType) {
|
|
67
70
|
return new SetRangeDomain(exports.SetRangeTop, limit, setType);
|
|
@@ -395,6 +398,9 @@ class SetRangeDomain extends abstract_domain_1.AbstractDomain {
|
|
|
395
398
|
isValue() {
|
|
396
399
|
return this.value !== lattice_1.Bottom;
|
|
397
400
|
}
|
|
401
|
+
isFinite() {
|
|
402
|
+
return this.value !== lattice_1.Bottom && this.value.range !== lattice_1.Top;
|
|
403
|
+
}
|
|
398
404
|
}
|
|
399
405
|
exports.SetRangeDomain = SetRangeDomain;
|
|
400
406
|
//# sourceMappingURL=set-range-domain.js.map
|
|
@@ -32,10 +32,10 @@ export declare class SetUpperBoundDomain<T, Value extends SetUpperBoundLift<T> =
|
|
|
32
32
|
bottom(): this & SetUpperBoundDomain<T, SetUpperBoundBottom>;
|
|
33
33
|
equals(other: this): boolean;
|
|
34
34
|
leq(other: this): boolean;
|
|
35
|
-
join(other: this): this;
|
|
36
35
|
join(other: SetUpperBoundLift<T> | T[]): this;
|
|
37
|
-
|
|
36
|
+
join(other: this): this;
|
|
38
37
|
meet(other: SetUpperBoundLift<T> | T[]): this;
|
|
38
|
+
meet(other: this): this;
|
|
39
39
|
/**
|
|
40
40
|
* Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
|
|
41
41
|
*/
|
|
@@ -25,10 +25,10 @@ export declare class SingletonDomain<T, Value extends SingletonLift<T> = Singlet
|
|
|
25
25
|
bottom(): this & SingletonDomain<T, SingletonBottom>;
|
|
26
26
|
equals(other: this): boolean;
|
|
27
27
|
leq(other: this): boolean;
|
|
28
|
-
join(other: this): this;
|
|
29
28
|
join(other: SingletonLift<T>): this;
|
|
30
|
-
|
|
29
|
+
join(other: this): this;
|
|
31
30
|
meet(other: SingletonLift<T>): this;
|
|
31
|
+
meet(other: this): this;
|
|
32
32
|
widen(other: this): this;
|
|
33
33
|
narrow(other: this): this;
|
|
34
34
|
concretize(): ReadonlySet<T> | typeof Top;
|
package/benchmark/slicer.js
CHANGED
|
@@ -26,7 +26,6 @@ const vertex_1 = require("../dataflow/graph/vertex");
|
|
|
26
26
|
const arrays_1 = require("../util/collections/arrays");
|
|
27
27
|
const config_1 = require("../config");
|
|
28
28
|
const extract_cfg_1 = require("../control-flow/extract-cfg");
|
|
29
|
-
const absint_info_1 = require("../abstract-interpretation/data-frame/absint-info");
|
|
30
29
|
const shape_inference_1 = require("../abstract-interpretation/data-frame/shape-inference");
|
|
31
30
|
const lattice_1 = require("../abstract-interpretation/domains/lattice");
|
|
32
31
|
const set_range_domain_1 = require("../abstract-interpretation/domains/set-range-domain");
|
|
@@ -291,7 +290,7 @@ class BenchmarkSlicer {
|
|
|
291
290
|
(0, assert_1.guard)(this.normalizedAst !== undefined, 'normalizedAst should be defined for data frame shape inference');
|
|
292
291
|
(0, assert_1.guard)(this.dataflow !== undefined, 'dataflow should be defined for data frame shape inference');
|
|
293
292
|
(0, assert_1.guard)(this.controlFlow !== undefined, 'controlFlow should be defined for data frame shape inference');
|
|
294
|
-
(0, assert_1.guard)(this.
|
|
293
|
+
(0, assert_1.guard)(this.context !== undefined, 'context should be defined for data frame shape inference');
|
|
295
294
|
const ast = this.normalizedAst;
|
|
296
295
|
const dfg = this.dataflow.graph;
|
|
297
296
|
const cfinfo = this.controlFlow;
|
|
@@ -308,7 +307,9 @@ class BenchmarkSlicer {
|
|
|
308
307
|
sizeOfInfo: 0,
|
|
309
308
|
perNodeStats: new Map()
|
|
310
309
|
};
|
|
311
|
-
const
|
|
310
|
+
const inference = new shape_inference_1.DataFrameShapeInferenceVisitor({ controlFlow: cfinfo, dfg, normalizedAst: ast, ctx: this.context });
|
|
311
|
+
this.measureSimpleStep('infer data frame shapes', () => inference.start());
|
|
312
|
+
const result = inference.getEndState();
|
|
312
313
|
stats.numberOfResultConstraints = result.value.size;
|
|
313
314
|
for (const value of result.value.values()) {
|
|
314
315
|
if (value.isTop()) {
|
|
@@ -321,23 +322,21 @@ class BenchmarkSlicer {
|
|
|
321
322
|
stats.numberOfResultingValues++;
|
|
322
323
|
}
|
|
323
324
|
}
|
|
324
|
-
(0, visitor_1.visitAst)(this.normalizedAst.ast.files.map(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
stats.sizeOfInfo += (0, size_of_1.safeSizeOf)([node.info.dataFrame]);
|
|
329
|
-
const expression = (0, absint_info_1.hasDataFrameExpressionInfo)(node) ? node.info.dataFrame : undefined;
|
|
330
|
-
const value = node.info.dataFrame.domain?.get(node.info.id);
|
|
325
|
+
(0, visitor_1.visitAst)(this.normalizedAst.ast.files.map(file => file.root), node => {
|
|
326
|
+
const operations = inference.getAbstractOperations(node.info.id);
|
|
327
|
+
const value = inference.getAbstractValue(node.info.id);
|
|
331
328
|
// Only store per-node information for nodes representing expressions or nodes with abstract values
|
|
332
|
-
if (
|
|
329
|
+
if (operations === undefined && value === undefined) {
|
|
333
330
|
stats.numberOfEmptyNodes++;
|
|
334
331
|
return;
|
|
335
332
|
}
|
|
333
|
+
const state = inference.getAbstractState(node.info.id);
|
|
334
|
+
stats.sizeOfInfo += (0, size_of_1.safeSizeOf)([state]);
|
|
336
335
|
const nodeStats = {
|
|
337
|
-
numberOfEntries:
|
|
336
|
+
numberOfEntries: state?.value.size ?? 0
|
|
338
337
|
};
|
|
339
|
-
if (
|
|
340
|
-
nodeStats.mappedOperations =
|
|
338
|
+
if (operations !== undefined) {
|
|
339
|
+
nodeStats.mappedOperations = operations.map(op => op.operation);
|
|
341
340
|
stats.numberOfOperationNodes++;
|
|
342
341
|
if (value !== undefined) {
|
|
343
342
|
nodeStats.inferredColNames = this.getInferredNumber(value.colnames);
|