Author: Elliot Levin (elliotlevin@hotmail.com)
 /**
  * @param callable $function
  * @param array    $variableTypeMap
  * @param mixed    $expression
  *
  * @return ITypeAnalysis
  */
 protected function getAnalysis(callable $function, array $variableTypeMap = [], &$expression = null)
 {
     $reflection = $this->functionInterpreter->getReflection($function);
     foreach ($reflection->getSignature()->getParameterExpressions() as $parameterExpression) {
         $variableTypeMap[$parameterExpression->getName()] = $this->typeSystem->getTypeFromTypeHint($parameterExpression->getTypeHint());
     }
     $analysisContext = $this->expressionAnalyser->createAnalysisContext($reflection->asEvaluationContext());
     foreach ($variableTypeMap as $variable => $type) {
         $analysisContext->setExpressionType(O\Expression::variable(O\Expression::value($variable)), $type);
     }
     $bodyExpressions = $this->functionInterpreter->getStructure($reflection)->getBodyExpressions();
     foreach ($bodyExpressions as $expression) {
         if ($expression instanceof O\ReturnExpression) {
             return $this->expressionAnalyser->analyse($analysisContext, $expression->getValue());
         } elseif (count($bodyExpressions) === 1) {
             return $this->expressionAnalyser->analyse($analysisContext, $expression);
         } else {
             $this->expressionAnalyser->analyse($analysisContext, $expression);
         }
     }
 }
Beispiel #2
0
 public function visitClosure(O\ClosureExpression $expression)
 {
     $originalContext = $this->analysisContext;
     $this->analysisContext = $originalContext->inNewScope();
     foreach ($expression->getParameters() as $parameter) {
         $this->walk($parameter);
         $typeHintType = $this->typeSystem->getTypeFromTypeHint($parameter->getTypeHint());
         if (!$parameter->hasDefaultValue() || $this->analysis[$parameter->getDefaultValue()]->isEqualTo($typeHintType)) {
             $this->analysisContext->setExpressionType($parameter->asVariable(), $typeHintType);
         } else {
             $this->analysisContext->setExpressionType($parameter->asVariable(), $this->typeSystem->getNativeType(INativeType::TYPE_MIXED));
         }
     }
     foreach ($expression->getUsedVariables() as $usedVariable) {
         $variable = $usedVariable->asVariable();
         //TODO: handle references with used variables. Probably impossible though.
         $this->analysisContext->setExpressionType($variable, $originalContext->getExpressionType($variable));
     }
     $this->walkAll($expression->getBodyExpressions());
     $this->analysis[$expression] = $this->typeSystem->getObjectType('Closure');
     $this->analysisContext = $originalContext;
 }