public function interpretSource(O\Expression $expression) { $isQueryScope = false; $queryableQueryResolver = new O\DynamicExpressionWalker([O\TraversalExpression::getType() => function (O\TraversalExpression $expression, O\ExpressionWalker $self) use(&$isQueryScope) { $expression = $expression->updateValue($self->walk($expression->getValue())); if ($isQueryScope) { return $expression; } else { return $self->walk(O\Expression::value($expression->evaluate($this->evaluationContext))); } }, O\ValueExpression::getType() => function (O\ValueExpression $expression) use(&$isQueryScope) { if ($expression->getValue() instanceof IQueryable) { $isQueryScope = true; } return $expression; }]); $expression = $queryableQueryResolver->walk($expression); if ($isQueryScope) { $this->scopeInterpreter->interpretScope($expression); $this->interpretation->interpretQueryScope($this->getId('source-scope'), $this->scopeInterpreter->getInterpretation()); } else { $this->interpretation->interpretArrayOrIterator($this->getId('source-iterator'), $expression->evaluate($this->evaluationContext)); } }
public function tryComputeResults(O\Expression $queryExpression, &$results) { if (isset($this->storage[$queryExpression])) { $results = $this->storage[$queryExpression]; return true; } $foundApplicableResults = false; //Searches the query expression tree and checks if any parent expressions have saved results //If so, the expression tree is updated with a Traversable implementation with the saved results $applicableScopeFinder = function (O\Expression $expression, O\ExpressionWalker $self) use(&$foundApplicableResults) { if (isset($this->storage[$expression])) { $foundApplicableResults = true; return O\Expression::value($this->newTraversable($this->storage[$expression])); } if ($expression instanceof O\ValueExpression) { return $expression; } /** @var $expression O\TraversalExpression */ return $expression->updateValue($self->walk($expression->getValue())); }; $traversalWalker = new O\DynamicExpressionWalker([O\TraversalExpression::getType() => $applicableScopeFinder, O\ValueExpression::getType() => $applicableScopeFinder]); $remainingQueryExpression = $traversalWalker->walk($queryExpression); //If found applicable results, execute the updated expression tree against the Traversable //implementation to compute the result of the query. $results = $foundApplicableResults ? $remainingQueryExpression->evaluate() : null; return $foundApplicableResults; }
protected final function interpretSourceAsScope(O\TraversalExpression $expression) { $this->scopeInterpreter->interpretScope($expression->getValue()); }