/** * @param ParameterList $parameterList * * @return mixed */ public function visitParameterList(ParameterList $parameterList) { $this->typeCheck->visitParameterList(func_get_args()); $parameters = array(); foreach ($parameterList->parameters() as $parameter) { $parameters[] = $parameter->accept($this); } return new ParameterList($parameters, $parameterList->isVariableLength()); }
/** * @param RuntimeConfiguration $configuration * @param ClassDefinition|null $classDefinition * @param MethodDefinition $methodDefinition * @param ParameterList $documentedParameterList * @param ParameterList $nativeParameterList * * @return ParameterList */ public function merge(RuntimeConfiguration $configuration, ClassDefinition $classDefinition = null, MethodDefinition $methodDefinition, ParameterList $documentedParameterList, ParameterList $nativeParameterList) { $this->typeCheck->merge(func_get_args()); $documentedParameters = $documentedParameterList->parameters(); $nativeParameters = $nativeParameterList->parameters(); $parameters = array(); foreach ($nativeParameters as $index => $nativeParameter) { if (array_key_exists($index, $documentedParameters)) { $parameters[] = $this->mergeParameter($configuration, $classDefinition, $methodDefinition, $documentedParameters[$index], $nativeParameter); } else { $this->handleError(new UndocumentedParameter($classDefinition, $methodDefinition, $nativeParameter->name())); $parameters[] = $nativeParameter; } } $documentedParameterCount = count($documentedParameters); $nativeParameterCount = count($nativeParameters); $isVariableLength = false; if ($documentedParameterList->isVariableLength()) { if ($documentedParameterCount > $nativeParameterCount + 1) { $this->handleError(new DocumentedParameterUndefined($classDefinition, $methodDefinition, $documentedParameters[$nativeParameterCount + 1]->name())); } elseif ($documentedParameterCount === $nativeParameterCount) { $this->handleError(new DefinedParameterVariableLength($classDefinition, $methodDefinition, $nativeParameters[$nativeParameterCount - 1]->name())); } elseif ($documentedParameterCount === $nativeParameterCount + 1) { $isVariableLength = true; $parameters[] = $documentedParameters[$nativeParameterCount]; } } elseif ($documentedParameterCount > $nativeParameterCount) { for ($i = $nativeParameterCount; $i < $documentedParameterCount; $i++) { $this->handleError(new DocumentedParameterUndefined($classDefinition, $methodDefinition, $documentedParameters[$i]->name())); } } return new ParameterList($parameters, $isVariableLength); }
/** * @param ParameterList $parameterList * * @return array<integer,IStatement> */ public function visitParameterList(ParameterList $parameterList) { $this->typeCheck->visitParameterList(func_get_args()); $expressions = array(); $parameters = $parameterList->parameters(); $parameterCount = count($parameters); $argumentsVariable = new Variable(new Identifier('arguments')); // empty parameter list if ($parameterCount < 1) { $zeroLiteral = new Literal(0); $countCall = new Call(QualifiedIdentifier::fromString('\\count')); $countCall->add($argumentsVariable); $newExceptionCall = new Call(QualifiedIdentifier::fromString($this->validatorNamespace()->joinAtoms('Exception', 'UnexpectedArgumentException')->string())); $newExceptionCall->add($zeroLiteral); $newExceptionCall->add(new Subscript($argumentsVariable, $zeroLiteral)); $ifStatement = new IfStatement(new Greater($countCall, $zeroLiteral)); $ifStatement->trueBranch()->add(new ThrowStatement(new NewOperator($newExceptionCall))); $expressions[] = $ifStatement; return $this->wrapExpressions($expressions); } $argumentCountVariable = new Variable(new Identifier('argumentCount')); $argumentCountCall = new Call(QualifiedIdentifier::fromString('\\count')); $argumentCountCall->add($argumentsVariable); $expressions[] = new Assign($argumentCountVariable, $argumentCountCall); // missing parameter checks $requiredParameterCount = count($parameterList->requiredParameters()); $lastRequiredParameterIndex = $requiredParameterCount - 1; $missingParametersStatement = null; if ($requiredParameterCount > 0) { $missingParametersStatement = new IfStatement(new Less($argumentCountVariable, new Literal($requiredParameterCount))); for ($i = 0; $i < $lastRequiredParameterIndex; $i++) { $newExceptionCall = new Call(QualifiedIdentifier::fromString($this->validatorNamespace()->joinAtoms('Exception', 'MissingArgumentException')->string())); $newExceptionCall->add(new Literal($parameters[$i]->name())); $newExceptionCall->add(new Literal($i)); $newExceptionCall->add(new Literal($this->renderTypeName($parameters[$i]->type()))); $ifStatement = new IfStatement(new Less($argumentCountVariable, new Literal($i + 1))); $ifStatement->trueBranch()->add(new ThrowStatement(new NewOperator($newExceptionCall))); $missingParametersStatement->trueBranch()->add($ifStatement); } $newExceptionCall = new Call(QualifiedIdentifier::fromString($this->validatorNamespace()->joinAtoms('Exception', 'MissingArgumentException')->string())); $newExceptionCall->add(new Literal($parameters[$lastRequiredParameterIndex]->name())); $newExceptionCall->add(new Literal($lastRequiredParameterIndex)); $newExceptionCall->add(new Literal($this->renderTypeName($parameters[$lastRequiredParameterIndex]->type()))); $missingParametersStatement->trueBranch()->add(new ThrowStatement(new NewOperator($newExceptionCall))); } // unexpected arguments check if (!$parameterList->isVariableLength()) { $parameterCountLiteral = new Literal($parameterCount); $newExceptionCall = new Call(QualifiedIdentifier::fromString($this->validatorNamespace()->joinAtoms('Exception', 'UnexpectedArgumentException')->string())); $newExceptionCall->add($parameterCountLiteral); $newExceptionCall->add(new Subscript($argumentsVariable, $parameterCountLiteral)); $tooManyParametersStatement = new IfStatement(new Greater($argumentCountVariable, $parameterCountLiteral)); $tooManyParametersStatement->trueBranch()->add(new ThrowStatement(new NewOperator($newExceptionCall))); if ($missingParametersStatement) { $missingParametersStatement->setFalseBranch($tooManyParametersStatement); } else { $expressions[] = $tooManyParametersStatement; } } if ($missingParametersStatement) { $expressions[] = $missingParametersStatement; } // type checks foreach ($parameters as $index => $parameter) { $isVariableLength = $parameterList->isVariableLength() && $index === $parameterCount - 1; $indexLiteral = new Literal($index); $oldArgumentExpression = $this->argumentExpression; $oldIndexExpression = $this->indexExpression; if (!$isVariableLength) { $this->indexExpression = $indexLiteral; $this->argumentExpression = new Subscript($argumentsVariable, $this->indexExpression); } $parameterExpressions = $parameter->accept($this); if (count($parameterExpressions) < 1) { $this->argumentExpression = $oldArgumentExpression; $this->indexExpression = $oldIndexExpression; continue; } array_unshift($parameterExpressions, new ExpressionStatement(new Assign(new Variable(new Identifier('value')), $this->argumentExpression))); $parameterExpressions = $this->wrapExpressions($parameterExpressions); // wrap variable length in loop if ($isVariableLength) { $closure = new Closure(); $closure->addParameter(new ParameterASTNode(new Identifier('argument'))); $closure->addParameter(new ParameterASTNode(new Identifier('index'))); foreach ($parameterExpressions as $expression) { $closure->statementBlock()->add($expression); } $checkVariable = new Variable(new Identifier('check')); $indexVariable = new Variable(new Identifier('index')); $checkCall = new Call($checkVariable); $checkCall->add(new Subscript($argumentsVariable, $indexVariable)); $checkCall->add($indexVariable); $loopContents = new StatementBlock(); $loopContents->add(new ExpressionStatement($checkCall)); $parameterExpressions = array(new ExpressionStatement(new Assign($checkVariable, $closure)), new ForStatement(new Assign($indexVariable, $indexLiteral), new Less($indexVariable, $argumentCountVariable), new PostfixIncrement($indexVariable), $loopContents)); } // wrap optional in if statement if ($parameter->isOptional()) { $if = new IfStatement(new Greater($argumentCountVariable, $indexLiteral)); foreach ($parameterExpressions as $expression) { $if->trueBranch()->add($expression); } $parameterExpressions = array($if); } foreach ($parameterExpressions as $expression) { $expressions[] = $expression; } $this->argumentExpression = $oldArgumentExpression; $this->indexExpression = $oldIndexExpression; } return $this->wrapExpressions($expressions); }