/** * Visit an and type. * * @param AndType $type The type. * * @return mixed The result of visitation. */ public function visitAndType(AndType $type) { $subTypes = array(); foreach ($type->types() as $subType) { $subTypes[] = $subType->accept($this); } return implode('+', $subTypes); }
/** * @param AndType $type * * @return LogicalAnd|Closure|null */ public function visitAndType(AndType $type) { $this->typeCheck->visitAndType(func_get_args()); $expressions = array(); $containsClosure = false; foreach ($type->types() as $subType) { $expression = $subType->accept($this); if (null !== $expression) { $expressions[] = $expression = $subType->accept($this); $containsClosure |= $expression instanceof Closure; } } $numExpressions = count($expressions); if ($numExpressions < 1) { return null; } if (!$containsClosure) { $expression = null; foreach ($expressions as $subExpression) { if ($expression) { $expression->add($subExpression); } else { $expression = new LogicalAnd($subExpression); } } return $expression; } $closure = new Closure(); $closure->addParameter(new Parameter(new Identifier('value'))); $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(new LogicalNot($condition)); $ifStatement->trueBranch()->add(new ReturnStatement(new Literal(false))); $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; }