/**
  * @param OrType $type
  *
  * @return LogicalAnd|Closure|null
  */
 public function visitOrType(OrType $type)
 {
     $this->typeCheck->visitOrType(func_get_args());
     $expressions = array();
     $containsClosure = false;
     foreach ($type->types() as $subType) {
         $expression = $subType->accept($this);
         if (null === $expression) {
             return null;
         }
         $expressions[] = $expression;
         $containsClosure |= $expression instanceof Closure;
     }
     if (!$containsClosure) {
         $expression = null;
         foreach ($expressions as $subExpression) {
             if ($expression) {
                 $expression->add($subExpression);
             } else {
                 $expression = new LogicalOr($subExpression);
             }
         }
         return $expression;
     }
     $closure = new Closure();
     $closure->addParameter(new Parameter(new Identifier('value')));
     $numExpressions = count($expressions);
     $lastExpressionIndex = $numExpressions - 1;
     for ($i = 0; $i < $lastExpressionIndex; $i++) {
         if ($expressions[$i] instanceof Closure) {
             $checkVariable = new Variable(new Identifier('check'));
             $closure->statementBlock()->add(new ExpressionStatement(new Assign($checkVariable, $expressions[$i])));
             $condition = new Call($checkVariable);
             $condition->add(new Variable(new Identifier('value')));
         } else {
             $condition = $expressions[$i];
         }
         $ifStatement = new IfStatement($condition);
         $ifStatement->trueBranch()->add(new ReturnStatement(new Literal(true)));
         $closure->statementBlock()->add($ifStatement);
     }
     if ($expressions[$lastExpressionIndex] instanceof Closure) {
         foreach ($expressions[$lastExpressionIndex]->statementBlock()->children() as $statement) {
             $closure->statementBlock()->add($statement);
         }
     } else {
         $closure->statementBlock()->add(new ReturnStatement($expressions[$lastExpressionIndex]));
     }
     return $closure;
 }
 /**
  * Visit an or type.
  *
  * @param OrType $type The type.
  *
  * @return mixed The result of visitation.
  */
 public function visitOrType(OrType $type)
 {
     $subTypes = array();
     foreach ($type->types() as $subType) {
         $subTypes[] = $subType->accept($this);
     }
     return implode('|', $subTypes);
 }