Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
136f0c8
refactor(env): remove unused working dir ref
MaxAtoms Nov 17, 2025
8737bb5
feat(analyzer): add environment context
MaxAtoms Nov 17, 2025
880fcb2
feat(analyzer): add built-in env
MaxAtoms Nov 17, 2025
f5c30e5
feat(dataflow): use built-in env from context
MaxAtoms Nov 18, 2025
b12af76
Merge remote-tracking branch 'origin/main' into 2027-env-into-ctx
MaxAtoms Nov 18, 2025
d133410
refactor(dataflow): update documentation
MaxAtoms Nov 19, 2025
d04f153
feat(analyzer): add read-only env context
MaxAtoms Nov 20, 2025
cf9f6ef
feat(analyzer): add getters for child envs
MaxAtoms Nov 20, 2025
cc708bb
Merge remote-tracking branch 'origin/main' into 2027-env-into-ctx
MaxAtoms Nov 20, 2025
02a4fbe
Merge branch 'main' into 2027-env-into-ctx
EagleoutIce Nov 24, 2025
8258d47
docs(analyzer): add env ctx to analyzer wiki
MaxAtoms Nov 24, 2025
fb201de
feat-fix(analyzer): create empty built-in env only once
MaxAtoms Nov 24, 2025
4a6e13a
wip(environment): always use built-in env from analyzer
MaxAtoms Nov 24, 2025
4dc16d5
feat(analyzer): provide getter for empty built-in env
MaxAtoms Nov 24, 2025
b36e1ff
wip(environment): fix access to env in static slicer
MaxAtoms Nov 24, 2025
8d85e5d
wip(environment): pass down env
MaxAtoms Nov 24, 2025
74b4e6f
wip(environment): remove env from dataflow graph
MaxAtoms Nov 25, 2025
f4dbf8c
wip(environment): fix references to clean env
MaxAtoms Nov 25, 2025
9838800
fixup! wip(environment): fix references to clean env
MaxAtoms Nov 25, 2025
7d5306c
wip(environment): clean-up
MaxAtoms Nov 25, 2025
b0a6841
Merge remote-tracking branch 'origin/main' into 2027-env-into-ctx
MaxAtoms Nov 25, 2025
f62e4cd
refactor: fix method order
MaxAtoms Nov 25, 2025
b0dd2a7
tests-fix: remove tmp describe.only
MaxAtoms Nov 25, 2025
640a931
feat(analyzer): calculate fingerprint of clean env only once
MaxAtoms Nov 25, 2025
a5201e5
Merge remote-tracking branch 'origin/main' into 2027-env-into-ctx
MaxAtoms Nov 27, 2025
9b2ce21
lint-fix: indentation
MaxAtoms Nov 27, 2025
7e02ee0
Merge branch 'main' into 2027-env-into-ctx
EagleoutIce Dec 1, 2025
c26ef1c
docs-fix(analyzer): use new ctx methods
MaxAtoms Dec 1, 2025
b6b8165
refactor(dataflow): use contextFromInput
MaxAtoms Dec 1, 2025
3d40666
refactor(analyzer): use config as default
MaxAtoms Dec 1, 2025
cc26437
refactor(df-graph): add default cleanEnv
MaxAtoms Dec 1, 2025
c150603
refactor(linter): consolidate params
MaxAtoms Dec 1, 2025
c1016e3
refactor: nits
MaxAtoms Dec 1, 2025
2f612fa
test-fix(slicing): only use analyzer results
MaxAtoms Dec 1, 2025
3353158
refactor(slicing): make ctx optional
MaxAtoms Dec 1, 2025
fea85c5
refactor(df-graph): introduce addVertex delegate
MaxAtoms Dec 1, 2025
6f20325
refactor(analyzer): rename env ctx methods
MaxAtoms Dec 1, 2025
b1e0e41
refactor(analyzer): return built-in env as readonly
MaxAtoms Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions src/abstract-interpretation/data-frame/absint-visitor.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import { type CfgBasicBlockVertex, type CfgSimpleVertex, type ControlFlowInformation , CfgVertexType, getVertexRootId, isMarkerVertex } from '../../control-flow/control-flow-graph';
import { type SemanticCfgGuidedVisitorConfiguration , SemanticCfgGuidedVisitor } from '../../control-flow/semantic-cfg-guided-visitor';
import {
type CfgBasicBlockVertex,
type CfgSimpleVertex,
CfgVertexType,
type ControlFlowInformation,
getVertexRootId,
isMarkerVertex
} from '../../control-flow/control-flow-graph';
import {
SemanticCfgGuidedVisitor,
type SemanticCfgGuidedVisitorConfiguration
} from '../../control-flow/semantic-cfg-guided-visitor';
import type { DataflowGraph } from '../../dataflow/graph/graph';
import type { DataflowGraphVertexFunctionCall, DataflowGraphVertexVariableDefinition } from '../../dataflow/graph/vertex';
import type { NoInfo, RNode } from '../../r-bridge/lang-4.x/ast/model/model';
import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import { isNotUndefined } from '../../util/assert';
import { DataFrameInfoMarker, hasDataFrameAssignmentInfo, hasDataFrameExpressionInfo, hasDataFrameInfoMarker, type AbstractInterpretationInfo } from './absint-info';
import {
type AbstractInterpretationInfo,
DataFrameInfoMarker,
hasDataFrameAssignmentInfo,
hasDataFrameExpressionInfo,
hasDataFrameInfoMarker
} from './absint-info';
import { DataFrameDomain, DataFrameStateDomain } from './dataframe-domain';
import { mapDataFrameAccess } from './mappers/access-mapper';
import { isAssignmentTarget, mapDataFrameVariableAssignment } from './mappers/assignment-mapper';
Expand Down Expand Up @@ -100,7 +116,7 @@ export class DataFrameShapeInferenceVisitor<
const sourceNode = this.getNormalizedAst(source);

if(node !== undefined && isAssignmentTarget(targetNode) && sourceNode !== undefined) {
node.info.dataFrame = mapDataFrameVariableAssignment(targetNode, sourceNode, this.config.dfg);
node.info.dataFrame = mapDataFrameVariableAssignment(targetNode, sourceNode, this.config.dfg, this.config.ctx);
this.applyDataFrameAssignment(node);
this.clearUnassignedInfo(targetNode);
}
Expand All @@ -110,7 +126,7 @@ export class DataFrameShapeInferenceVisitor<
const node = this.getNormalizedAst(call.id);

if(node !== undefined) {
node.info.dataFrame = mapDataFrameAccess(node, this.config.dfg);
node.info.dataFrame = mapDataFrameAccess(node, this.config.dfg, this.config.ctx);
this.applyDataFrameExpression(node);
}
}
Expand All @@ -130,7 +146,7 @@ export class DataFrameShapeInferenceVisitor<
const sourceNode = this.getNormalizedAst(source);

if(node !== undefined && targetNode !== undefined && sourceNode !== undefined) {
node.info.dataFrame = mapDataFrameReplacementFunction(node, sourceNode, this.config.dfg);
node.info.dataFrame = mapDataFrameReplacementFunction(node, sourceNode, this.config.dfg, this.config.ctx);
this.applyDataFrameExpression(node);
this.clearUnassignedInfo(targetNode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import type { ResolveInfo } from '../../../dataflow/eval/resolve/alias-tracking'
import type { DataflowGraph } from '../../../dataflow/graph/graph';
import type { RNode } from '../../../r-bridge/lang-4.x/ast/model/model';
import type { RAccess, RIndexAccess, RNamedAccess } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-access';
import { type RFunctionArgument , EmptyArgument } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import { EmptyArgument, type RFunctionArgument } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import type { ParentInformation } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
import { RType } from '../../../r-bridge/lang-4.x/ast/model/type';
import type { DataFrameExpressionInfo, DataFrameOperation } from '../absint-info';
import { resolveIdToArgValue, resolveIdToArgValueSymbolName, unquoteArgument } from '../resolve-args';
import { getArgumentValue, isDataFrameArgument } from './arguments';
import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';

/**
* Special named arguments of index-based access operators
Expand All @@ -22,16 +23,18 @@ const SpecialAccessArgumentsMapper: Record<RIndexAccess['operator'], string[]> =
* Maps a concrete data frame access to abstract data frame operations.
* @param node - The R node of the access
* @param dfg - The data flow graph for resolving the arguments
* @param ctx - The read-only Flowr analyzer context
* @returns Data frame expression info containing the mapped abstract data frame operations, or `undefined` if the node does not represent a data frame access
*/
export function mapDataFrameAccess(
node: RNode<ParentInformation>,
dfg: DataflowGraph
dfg: DataflowGraph,
ctx: ReadOnlyFlowrAnalyzerContext
): DataFrameExpressionInfo | undefined {
if(node.type !== RType.Access) {
return;
}
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias };
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias, ctx };
let operations: DataFrameOperation[] | undefined;

if(isStringBasedAccess(node)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ import type { ParentInformation } from '../../../r-bridge/lang-4.x/ast/model/pro
import { RType } from '../../../r-bridge/lang-4.x/ast/model/type';
import type { DataFrameAssignmentInfo } from '../absint-info';
import { isDataFrameArgument } from './arguments';
import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';

/**
* Maps a concrete data frame assignment to data frame assignment info containing the ids of the identifier and assigned expression.
* We currently do not support function assignments dealing with data frames.
* @param identifier - The R node of the variable identifier
* @param expression - The R node of the assigned expression
* @param dfg - The data flow graph for resolving the arguments
* @param ctx - The analysis context
* @returns Data frame assignment info containing the IDs of the identifier and expression, or `undefined` if the node does not represent a data frame assignment
*/
export function mapDataFrameVariableAssignment(
identifier: RSymbol<ParentInformation> | RString<ParentInformation>,
expression: RNode<ParentInformation>,
dfg: DataflowGraph
dfg: DataflowGraph,
ctx: ReadOnlyFlowrAnalyzerContext
): DataFrameAssignmentInfo | undefined {
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias };
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias, ctx };

if(!isDataFrameArgument(expression, resolveInfo)) {
return;
Expand Down
31 changes: 25 additions & 6 deletions src/abstract-interpretation/data-frame/mappers/function-mapper.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
import { VariableResolve } from '../../../config';
import { VariableResolve } from '../../../config';
import { type ResolveInfo } from '../../../dataflow/eval/resolve/alias-tracking';
import type { DataflowGraph } from '../../../dataflow/graph/graph';
import { toUnnamedArgument } from '../../../dataflow/internal/process/functions/call/argument/make-argument';
import { findSource } from '../../../dataflow/internal/process/functions/call/built-in/built-in-source';
import type { RNode } from '../../../r-bridge/lang-4.x/ast/model/model';
import { type RFunctionArgument , EmptyArgument } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import { EmptyArgument, type RFunctionArgument } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import type { ParentInformation } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
import { RType } from '../../../r-bridge/lang-4.x/ast/model/type';
import { type RParseRequest , requestFromInput } from '../../../r-bridge/retriever';
import { requestFromInput, type RParseRequest } from '../../../r-bridge/retriever';
import { assertUnreachable, isNotUndefined, isUndefined } from '../../../util/assert';
import { readLineByLineSync } from '../../../util/files';
import type { DataFrameExpressionInfo, DataFrameOperation } from '../absint-info';
import { DataFrameDomain } from '../dataframe-domain';
import { resolveIdToArgName, resolveIdToArgValue, resolveIdToArgValueSymbolName, resolveIdToArgVectorLength, unescapeSpecialChars } from '../resolve-args';
import {
resolveIdToArgName,
resolveIdToArgValue,
resolveIdToArgValueSymbolName,
resolveIdToArgVectorLength,
unescapeSpecialChars
} from '../resolve-args';
import type { ConstraintType } from '../semantics';
import { resolveIdToDataFrameShape } from '../shape-inference';
import { type FunctionParameterLocation , escapeRegExp, filterValidNames, getArgumentValue, getEffectiveArgs, getFunctionArgument, getFunctionArguments, getUnresolvedSymbolsInExpression, hasCriticalArgument, isDataFrameArgument, isNamedArgument, isRNull } from './arguments';
import {
escapeRegExp,
filterValidNames,
type FunctionParameterLocation,
getArgumentValue,
getEffectiveArgs,
getFunctionArgument,
getFunctionArguments,
getUnresolvedSymbolsInExpression,
hasCriticalArgument,
isDataFrameArgument,
isNamedArgument,
isRNull
} from './arguments';
import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';

/**
Expand Down Expand Up @@ -602,7 +621,7 @@ export function mapDataFrameFunctionCall<Name extends DataFrameFunction>(
if(node.type !== RType.FunctionCall || !node.named) {
return;
}
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias };
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias, ctx };
let operations: DataFrameOperation[] | undefined;

if(isDataFrameFunction(node.functionName.content)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { resolveIdToArgStringVector, resolveIdToArgValue, resolveIdToArgValueSym
import { ConstraintType } from '../semantics';
import { isStringBasedAccess } from './access-mapper';
import { isDataFrameArgument, isRNull } from './arguments';
import type { ReadOnlyFlowrAnalyzerContext } from '../../../project/context/flowr-analyzer-context';

/** Mapper for mapping the supported data frame replacement functions to mapper functions */
const DataFrameReplacementFunctionMapper = {
Expand Down Expand Up @@ -46,15 +47,17 @@ type DataFrameReplacementFunction = keyof typeof DataFrameReplacementFunctionMap
* Maps a concrete data frame replacement function to abstract data frame operations.
* @param node - The R node of the replacement function
* @param dfg - The data flow graph for resolving the arguments
* @param ctx - The read-only Flowr analysis context
* @returns Data frame expression info containing the mapped abstract data frame operations, or `undefined` if the node does not represent a data frame replacement function
*/
export function mapDataFrameReplacementFunction(
node: RNode<ParentInformation>,
expression: RNode<ParentInformation>,
dfg: DataflowGraph
dfg: DataflowGraph,
ctx: ReadOnlyFlowrAnalyzerContext
): DataFrameExpressionInfo | undefined {
const parent = hasParentReplacement(node, dfg) ? dfg.idMap?.get(node.info.parent) : undefined;
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias };
const resolveInfo = { graph: dfg, idMap: dfg.idMap, full: true, resolve: VariableResolve.Alias, ctx };
let operations: DataFrameOperation[] | undefined;

if(node.type === RType.Access) {
Expand Down
24 changes: 16 additions & 8 deletions src/benchmark/slicer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module
*/

import { type IStoppableStopwatch , Measurements } from './stopwatch';
import { type IStoppableStopwatch, Measurements } from './stopwatch';
import seedrandom from 'seedrandom';
import { log, LogLevel } from '../util/log';
import type { MergeableRecord } from '../util/objects';
Expand All @@ -25,10 +25,18 @@ import type {
} from './stats/stats';
import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { SlicingCriteria } from '../slicing/criterion/parse';
import { type DEFAULT_SLICING_PIPELINE, type TREE_SITTER_SLICING_PIPELINE , createSlicePipeline } from '../core/steps/pipeline/default-pipelines';
import { type RParseRequestFromFile, type RParseRequestFromText , retrieveNumberOfRTokensOfLastParse } from '../r-bridge/retriever';
import {
createSlicePipeline,
type DEFAULT_SLICING_PIPELINE,
type TREE_SITTER_SLICING_PIPELINE
} from '../core/steps/pipeline/default-pipelines';
import {
retrieveNumberOfRTokensOfLastParse,
type RParseRequestFromFile,
type RParseRequestFromText
} from '../r-bridge/retriever';
import type { PipelineStepNames, PipelineStepOutputWithName } from '../core/steps/pipeline/pipeline';
import { type SlicingCriteriaFilter , collectAllSlicingCriteria } from '../slicing/criterion/collect-all';
import { collectAllSlicingCriteria, type SlicingCriteriaFilter } from '../slicing/criterion/collect-all';
import { RType } from '../r-bridge/lang-4.x/ast/model/type';
import { visitAst } from '../r-bridge/lang-4.x/ast/model/processing/visitor';
import { getSizeOfDfGraph, safeSizeOf } from './stats/size-of';
Expand All @@ -39,9 +47,9 @@ import { RShell } from '../r-bridge/shell';
import { TreeSitterType } from '../r-bridge/lang-4.x/tree-sitter/tree-sitter-types';
import { TreeSitterExecutor } from '../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor';
import type { InGraphIdentifierDefinition } from '../dataflow/environments/identifier';
import { type ContainerIndicesCollection , isParentContainerIndex } from '../dataflow/graph/vertex';
import { type ContainerIndicesCollection, isParentContainerIndex } from '../dataflow/graph/vertex';
import { equidistantSampling } from '../util/collections/arrays';
import { type FlowrConfigOptions , getEngineConfig } from '../config';
import { type FlowrConfigOptions, getEngineConfig } from '../config';
import type { ControlFlowInformation } from '../control-flow/control-flow-graph';
import { extractCfg } from '../control-flow/extract-cfg';
import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
Expand All @@ -53,7 +61,7 @@ import type { DataFrameDomain } from '../abstract-interpretation/data-frame/data
import type { PosIntervalDomain } from '../abstract-interpretation/domains/positive-interval-domain';
import { inferDataFrameShapes } from '../abstract-interpretation/data-frame/shape-inference';
import fs from 'fs';
import type { FlowrAnalyzerContext } from '../project/context/flowr-analyzer-context';
import type { FlowrAnalyzerContext, ReadOnlyFlowrAnalyzerContext } from '../project/context/flowr-analyzer-context';
import { contextFromInput } from '../project/context/flowr-analyzer-context';

/**
Expand Down Expand Up @@ -337,7 +345,7 @@ export class BenchmarkSlicer {
};
this.perSliceMeasurements.set(slicingCriteria, stats);

this.executor.updateRequest({ criterion: slicingCriteria });
this.executor.updateRequest({ criterion: slicingCriteria, context: this.context as ReadOnlyFlowrAnalyzerContext });

const totalStopwatch = measurements.start('total');

Expand Down
6 changes: 4 additions & 2 deletions src/control-flow/cfg-dead-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class CfgConditionalDeadCodeRemoval extends SemanticCfgGuidedVisitor {
graph: this.config.dfg,
full: true,
idMap: this.config.normalizedAst.idMap,
resolve: this.config.ctx.config.solver.variables
resolve: this.config.ctx.config.solver.variables,
ctx: this.config.ctx,
}));
if(values === undefined || values.elements.length !== 1 || values.elements[0].type != 'logical' || !isValue(values.elements[0].value)) {
this.unableToCalculateValue(id);
Expand Down Expand Up @@ -101,7 +102,8 @@ class CfgConditionalDeadCodeRemoval extends SemanticCfgGuidedVisitor {
graph: this.config.dfg,
full: true,
idMap: this.config.normalizedAst.idMap,
resolve: this.config.ctx.config.solver.variables
resolve: this.config.ctx.config.solver.variables,
ctx: this.config.ctx,
}));
if(values === undefined || values.elements.length !== 1 || values.elements[0].type != 'logical' || !isValue(values.elements[0].value)) {
return undefined;
Expand Down
12 changes: 7 additions & 5 deletions src/control-flow/useless-loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { resolveIdToValue } from '../dataflow/eval/resolve/alias-tracking';
import { valueSetGuard } from '../dataflow/eval/values/general';
import { isValue } from '../dataflow/eval/values/r-value';
import type { DataflowGraph } from '../dataflow/graph/graph';
import { type DataflowGraphVertexFunctionCall , VertexType } from '../dataflow/graph/vertex';
import { type ControlDependency , happensInEveryBranch } from '../dataflow/info';
import { type DataflowGraphVertexFunctionCall, VertexType } from '../dataflow/graph/vertex';
import { type ControlDependency, happensInEveryBranch } from '../dataflow/info';
import { EmptyArgument } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
import { guard } from '../util/assert';
import type { ControlFlowInformation } from './control-flow-graph';
import { type SemanticCfgGuidedVisitorConfiguration , SemanticCfgGuidedVisitor } from './semantic-cfg-guided-visitor';
import { SemanticCfgGuidedVisitor, type SemanticCfgGuidedVisitorConfiguration } from './semantic-cfg-guided-visitor';
import type { ReadOnlyFlowrAnalyzerContext } from '../project/context/flowr-analyzer-context';


Expand Down Expand Up @@ -48,7 +48,8 @@ export function onlyLoopsOnce(loop: NodeId, dataflow: DataflowGraph, controlflow
const values = valueSetGuard(resolveIdToValue(vectorOfLoop.nodeId, {
graph: dataflow,
idMap: dataflow.idMap,
resolve: ctx.config.solver.variables
resolve: ctx.config.solver.variables,
ctx: ctx
}));
if(values === undefined || values.elements.length !== 1 || values.elements[0].type !== 'vector' || !isValue(values.elements[0].elements)) {
return undefined;
Expand Down Expand Up @@ -93,7 +94,8 @@ class CfgSingleIterationLoopDetector extends SemanticCfgGuidedVisitor {
graph: this.config.dfg,
full: true,
idMap: this.config.normalizedAst.idMap,
resolve: this.config.ctx.config.solver.variables
resolve: this.config.ctx.config.solver.variables,
ctx: this.config.ctx
}));
if(values === undefined || values.elements.length !== 1 || values.elements[0].type != 'logical' || !isValue(values.elements[0].value)) {
return undefined;
Expand Down
7 changes: 5 additions & 2 deletions src/core/steps/all/static-slicing/00-slice.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { internalPrinter, StepOutputFormat } from '../../../print/print';
import { type IPipelineStep , PipelineStepStage } from '../../pipeline-step';
import { type IPipelineStep, PipelineStepStage } from '../../pipeline-step';
import type { DeepReadonly } from 'ts-essentials';
import type { DataflowInformation } from '../../../../dataflow/info';
import type { SlicingCriteria } from '../../../../slicing/criterion/parse';
import type { NormalizedAst } from '../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
import { staticSlice } from '../../../../slicing/static/static-slicer';
import type { ReadOnlyFlowrAnalyzerContext } from '../../../../project/context/flowr-analyzer-context';

export interface SliceRequiredInput {
/** The slicing criterion is only of interest if you actually want to slice the R code */
Expand All @@ -13,6 +14,8 @@ export interface SliceRequiredInput {
readonly threshold?: number
/** The direction to slice in. Defaults to backward slicing if unset. */
readonly direction?: SliceDirection
/** The context of the analysis */
readonly context: ReadOnlyFlowrAnalyzerContext
}

export enum SliceDirection {
Expand All @@ -22,7 +25,7 @@ export enum SliceDirection {

function processor(results: { dataflow?: DataflowInformation, normalize?: NormalizedAst }, input: Partial<SliceRequiredInput>) {
const direction = input.direction ?? SliceDirection.Backward;
return staticSlice((results.dataflow as DataflowInformation), results.normalize as NormalizedAst, input.criterion as SlicingCriteria, direction, input.threshold);
return staticSlice(input.context as ReadOnlyFlowrAnalyzerContext, (results.dataflow as DataflowInformation), results.normalize as NormalizedAst, input.criterion as SlicingCriteria, direction, input.threshold);
}

export const STATIC_SLICE = {
Expand Down
Loading
Loading