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;
    }
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;
    }
@param OrType $type

@return LogicalAnd|Closure|null