Author: Elliot Levin (elliotlevin@hotmail.com)
Inheritance: extends ExpressionWalker
 public function testExpressionWalkerWorks()
 {
     $expression = O\Expression::variable(O\Expression::value('foo'));
     $expressionWalker = new O\DynamicExpressionWalker([O\ValueExpression::getType() => function (O\ValueExpression $expression) {
         return O\Expression::value('bar');
     }]);
     $newExpression = $expressionWalker->walk($expression);
     $this->assertNotEquals($expression, $newExpression);
     $this->assertSame($newExpression->getName()->getValue(), 'bar');
 }
Beispiel #2
0
 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));
     }
 }
 protected function parseQueryExpression(callable $queryFunction, O\IEvaluationContext &$evaluationContext = null)
 {
     $reflection = $this->functionInterpreter->getReflection($queryFunction);
     $evaluationContext = $reflection->asEvaluationContext();
     $function = $this->functionInterpreter->getStructure($reflection);
     $expressions = $function->getBodyExpressions();
     $this->assertCount(1, $expressions);
     //Resolve the parameter variable with the queryable value and $this
     $parameterName = $reflection->getSignature()->getParameterExpressions()[0]->getName();
     $expression = $expressions[0];
     foreach ([$parameterName => $this->queryable, 'this' => $this] as $variable => $value) {
         $variableReplacer = new O\DynamicExpressionWalker([O\VariableExpression::getType() => function (O\VariableExpression $expression) use($variable, &$value) {
             if ($expression->getName() instanceof O\ValueExpression && $expression->getName()->getValue() === $variable) {
                 return O\Expression::value($value);
             } else {
                 return $expression;
             }
         }, O\ClosureExpression::getType() => function ($closure) {
             return $closure;
         }]);
         $expression = $variableReplacer->walk($expression);
     }
     if ($expression instanceof O\ReturnExpression) {
         return $expression->getValue();
     } else {
         return $expression;
     }
 }
 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;
 }