classLoopPasses
final class LoopPasses
Walks back through a loop one pass at a time.
A loop that builds part of a statement produces a different statement for every number of times it runs, so each number of passes is its own path: the statement as it is before the loop, after one pass, after two, up to the budget's limit. When a path could still have gone round again at the limit, it is marked as cut short, because the statements listed are not all of the ones the loop can produce. A foreach over an array written out in full runs exactly as many times as the array has elements, and only that number is taken.
Methods§
public function __construct(
BackwardSlicer $slicer,
FreeNames $names,
ModifiedNames $modified,
EvaluationBudget $budget,
)Wires the loop walk to the slicer it walks bodies with.
Parameters
$slicer | BackwardSlicer | |
$names | FreeNames | |
$modified | ModifiedNames | |
$budget | EvaluationBudget |
Calls 1
public function isLoop(Node $node): boolWhether the node is a loop.
Parameters
$node | Node |
Returns
boolTest cases 1
Called from 2
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\BackwardSlicer::leave() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/BackwardSlicer.php:133
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\BackwardSlicer::over() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/BackwardSlicer.php:297
public function runs(Stmt $loop, array<string, true> $needs): list<Pending>The runs a loop before the point may have made, as paths that start where the loop finishes.
Parameters
$loop | Stmt | |
$needs | array<string, true> |
Returns
list<Pending>Test cases 4
Called from 1
Calls 8
- method-call LoopPasses::writtenPasses() line 73
- static-call Pending::needing() line 75
- method-call LoopPasses::entering() line 77
- method-call LoopPasses::pass() line 80
- function-call
array_mergeline 82 - method-call LoopPasses::continues() line 84
- function-call
array_mapline 92 - method-call Pending::cut() line 92
The paths carried out of the start of a loop body the point is written in.
Parameters
$loop | Stmt | |
$paths | list<Pending> | Paths standing at the start of the pass the point is in |
Returns
list<Arrival>Called from 1
Calls 8
- function-call
array_mapline 104 - method-call LoopPasses::binding() line 104
- method-call LoopPasses::continues() line 106
- method-call Pending::cut() line 108
- function-call
array_mergeline 109 - method-call BackwardSlicer::before() line 109
- method-call LoopPasses::entering() line 109
- method-call LoopPasses::pass() line 113
The paths walked back over one whole pass, from its end to its start.
Parameters
$loop | Stmt | |
$paths | list<Pending> |
Returns
list<Pending>Test cases 1
Called from 2
Calls 6
- method-call LoopPasses::expressions() line 126
- method-call LoopPasses::bodyOf() line 128
- method-call BackwardSlicer::walkList() line 129
- function-call
countline 129 - function-call
array_mapline 131 - method-call LoopPasses::binding() line 131
public function bodyOf(Stmt $loop): list<Stmt>The statements a loop repeats.
Parameters
$loop | Stmt |
Returns
list<Stmt>Test cases 1
Called from 1
Calls 1
- function-call
array_valuesline 143
A path walked back over the start of one pass of a foreach, where its variables are set.
Parameters
$loop | Stmt | |
$path | Pending |
Returns
Test cases 2
Called from 2
Calls 6
- method-call Pending::isDone() line 154
- method-call ModifiedNames::own() line 157
- function-call
array_intersect_keyline 158 - method-call Pending::through() line 162
- new SliceStep line 162
- function-call
array_diff_keyline 162
The paths walked back over what runs before a loop's first pass.
A foreach reads the array it goes over once, before the first pass, whatever the passes then do to the variable holding it; so that is where the array is looked for, and only on a path that needed the loop's variables at all.
Parameters
$loop | Stmt | |
$paths | list<Pending> |
Returns
list<Pending>Test cases 1
Called from 3
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\LoopPasses::runs() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/LoopPasses.php:77
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\LoopPasses::runs() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/LoopPasses.php:82
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\LoopPasses::leaveBody() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/LoopPasses.php:109
Calls 5
- method-call LoopPasses::expressions() line 179
- function-call
array_mapline 185 - method-call LoopPasses::bound() line 186
- new Pending line 187
- method-call FreeNames::read() line 187
public function bound(Foreach_ $loop, Pending $path): boolWhether a path took one of a foreach's passes as a step.
Parameters
$loop | Foreach_ | |
$path | Pending |
Returns
boolTest cases 1
public function expressions(
array<array-key, Expr> $expressions,
list<Pending> $paths,
): list<Pending>The paths walked back over a list of expressions, last first.
Parameters
$expressions | array<array-key, Expr> | |
$paths | list<Pending> |
Returns
list<Pending>Test cases 1
Called from 2
Calls 4
- function-call
array_reverseline 216 - function-call
array_mapline 217 - method-call Pending::isDone() line 218
- method-call AssignmentSteps::over() line 218
public function continues(Stmt $loop, list<Pending> $paths): boolWhether another pass could still change something a path needs.
Parameters
$loop | Stmt | |
$paths | list<Pending> |
Returns
boolCalled from 2
Calls 1
- method-call ModifiedNames::touches() line 234
public function writtenPasses(Stmt $loop): ?intHow many times a foreach over an array written out in full runs, or null when that is not known.
Parameters
$loop | Stmt |
Returns
?intTest cases 1
Called from 1
Calls 1
- function-call
countline 256
Private surface 5§
Implementation details, listed for orientation only.
private BackwardSlicer $slicerprivate FreeNames $namesprivate ModifiedNames $modifiedprivate EvaluationBudget $budgetprivate AssignmentSteps $stepsTest cases 41§
Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.
Dedicated tests 14
LoopPassesTest::testBindingIsAStepOnlyForAPathThatNeedsTheLoopsVariablescallsLoopPassesTest::testBodyOfIsWhatALoopRepeatscallsLoopPassesTest::testBoundSaysWhetherAPathTookOneOfTheLoopsPassescallsLoopPassesTest::testContinuesSaysWhetherAnotherPassCouldChangeWhatIsNeededcallsLoopPassesTest::testEnteringReadsWhatALoopGoesOverBeforeItsFirstPasscallsLoopPassesTest::testExpressionsWalkBackOverAListLastFirstcallsLoopPassesTest::testIsLoopRecognisesEveryKindOfLoopcallsLoopPassesTest::testLeaveBodyFollowsAPointInsideALoopBackThroughEarlierPassescallsLoopPassesTest::testPassWalksBackOverOneWholePasscallsLoopPassesTest::testRunsListTheStatementAfterEachNumberOfPassesUpToTheLimitcallsLoopPassesTest::testRunsOfADoWhileAlwaysIncludeAPasscallsLoopPassesTest::testRunsStopOnceAPassCannotChangeWhatIsNeededcallsLoopPassesTest::testRunsTakeExactlyAsManyPassesAsAWrittenOutArrayHasElementscallsLoopPassesTest::testWrittenPassesCountsOnlyAnArrayWrittenOutInFullcalls
Other tests reaching this symbol 27
CatalogCommandTestcallsCallEvaluatorTestcallsConstantReaderTestcallsCalleeReturnsTestcallsCallersTestcallsDeriverTestcallsEntryBinderTestcallsCallbackEffectsTestcallsPropertyWritesTestcallsBackwardSlicerTestcallsSliceExecutorTestcallsExpressionEvaluatorTestcallsRegistryTestcallsInterpreterTestcallsModelQueriesTestcallsReferenceEvaluatorTestcallsCallContextTestcallsModelContextTestcallsQueryModelInterfaceTestcallsBuilderCallsTestcallsBuilderQueriesTestcallsCallbackModelTestcallsCallModelTestcallsLaravelExtensionTestcallsAnalyzerTestcallsJsonReporterTestcallsTextReporterTestcalls
Relations§
Instantiated in 1
Method calls 4
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\BackwardSlicer::leave() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/BackwardSlicer.php:133
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\BackwardSlicer::leave() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/BackwardSlicer.php:134
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\BackwardSlicer::over() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/BackwardSlicer.php:297
- method-call SqlCatalog\Core\Analysis\Derivation\Slice\BackwardSlicer::over() packages/sql-catalog/src/Core/Analysis/Derivation/Slice/BackwardSlicer.php:298