/** * @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); }