/** * Entry point for the `walkQuery` routine. Execution bounces between here, where the reducer's ->visit() method * is invoked, and `walkQuery` where we send in the scores from the `visit` call. * * @param Query $query * @param AbstractType $currentLevelSchema * @param AbstractQueryVisitor $reducer */ protected function doVisit(Query $query, $currentLevelSchema, $reducer) { if (!$currentLevelSchema instanceof AbstractObjectType || !$currentLevelSchema->hasField($query->getName())) { return; } if ($operationField = $currentLevelSchema->getField($query->getName())) { $coroutine = $this->walkQuery($query, $operationField); if ($results = $coroutine->current()) { $queryCost = 0; while ($results) { // initial values come from advancing the generator via ->current, subsequent values come from ->send() list($queryField, $astField, $childCost) = $results; /** * @var Query|FieldAst $queryField * @var Field $astField */ $cost = $reducer->visit($queryField->getKeyValueArguments(), $astField->getConfig(), $childCost); $queryCost += $cost; $results = $coroutine->send($cost); } } } }