final class BackwardSlicer
Restricted visibility: declared "@visibility root". Code outside that scope must not name this declaration.

Walks back from a call to the start of its body, keeping only what its argument depends on.

The walk starts with the names the argument reads and goes back statement by statement. An assignment to one of those names is kept as a step, and the names its right-hand side reads are looked for instead. A branch that assigns none of them is stepped over whole; one that does splits the path into one path per arm, which is what keeps the values an arm assigns together. A loop becomes one path per number of passes, up to the budget's limit. What comes out at the start of the body is the set of paths, each with the steps that lead from there to the call and the names still left to find.

Constants§

public const MAX_PATHS = 24

How many paths are kept apart before the rest are gathered into one.

Methods§

public function __construct(
    SourceTree $tree,
    EvaluationBudget $budget,
    ?FreeNames $names = null,
    ?ModifiedNames $modified = null,
)

Wires the slicer to the source it walks and the budget it spends.

Parameters

Calls 5
public function sliceFromEnd(FunctionLike $body, array<string, true> $needs): list<Arrival>

Every path from the start of a body to its end, with what each still needs.

Parameters

$bodyFunctionLike
$needsarray<string, true>The names read at the end of the body

Returns

list<Arrival>
Test cases 1
Called from 1
Calls 6
public function owningStatement(Node $owner): ?Stmt

The statement an arm or a block belongs to, which is where the walk goes on from.

Parameters

$ownerNode

Returns

?Stmt
Test cases 1
Called from 1
Calls 1
  • method-call Node::getAttribute() line 154
public function leaveClosure(
    Closure|ArrowFunction $closure,
    list<Pending> $paths,
): list<Arrival>

The paths carried out of a closure into the body it is written in.

What the closure takes from outside — its use list, or for an arrow function every name that is not one of its parameters — is looked for where the closure is written. Its parameters, and any name it reads without defining, are its own: a step says so, and the walk does not look for them outside.

Parameters

$closureClosure|ArrowFunction
$pathslist<Pending>

Returns

list<Arrival>
Test cases 1
Called from 1
Calls 8
public function outside(
    Closure|ArrowFunction $closure,
    array<string, true> $needs,
): array<string, true>

The names among those needed that a closure takes from where it is written.

Parameters

$closureClosure|ArrowFunction
$needsarray<string, true>

Returns

array<string, true>
Test cases 1
Called from 1
Calls 4
public function walkList(list<Stmt> $list, int $end, list<Pending> $paths): list<Pending>

The paths walked back over the statements of a list, from the given position to its start.

Parameters

$listlist<Stmt>
$endint
$pathslist<Pending>

Returns

list<Pending>
Test cases 1
Called from 7
Calls 4
public function allDone(list<Pending> $paths): bool
public function walkArms(list<list<Stmt>> $arms, array<string, true> $needs): list<Pending>

Each arm walked back from its end, as paths that start where the branch finishes.

Parameters

$armslist<list<Stmt>>
$needsarray<string, true>

Returns

list<Pending>
Test cases 1
Called from 1
Calls 4
public function branch(Pending $path, list<Pending> $runs): list<Pending>

A path taken on over the runs a branch may have taken.

The runs become one step that holds them as alternatives, rather than one path each. Running the step still runs every arm on its own, so the values an arm assigns stay together; what is saved is walking the rest of the body once per arm, which for a body of ten consecutive conditionals would be a thousand walks.

Parameters

$pathPending
$runslist<Pending>Paths that start where the branch finishes

Returns

list<Pending>
Test cases 1
Called from 2
Calls 3
public function bound(list<Pending> $paths): list<Pending>

The paths with repeats merged and the rest gathered once there are too many to keep apart.

Parameters

$pathslist<Pending>

Returns

list<Pending>
Test cases 1
Called from 1
Calls 5

Private surface 7§

Implementation details, listed for orientation only.

private SourceTree $tree
private EvaluationBudget $budget
private FreeNames $names
private ModifiedNames $modified
private LoopPasses $loops
private BranchArms $arms
private AssignmentSteps $steps

Test cases 93§

Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.

Dedicated tests 19
Other tests reaching this symbol 74

Relations§

Instantiated in 1
Method calls 7
Type declarations 7