src/FunctionGenerator.php
<?php declare(strict_types=1);
/**
* Created by Vitaly Iegorov <egorov@samsonos.com>.
* on 03.09.16 at 11:30
*/
namespace samsonframework\generator;
/**
* Function generation class.
*
* @author Vitaly Egorov <egorov@samsonos.com>
*/
class FunctionGenerator extends AbstractGenerator
{
use CodeTrait;
/** @var string Function name */
protected $name;
/** @var array Collection of function arguments */
protected $arguments = [];
/** @var array Collection of function arguments descriptions */
protected $argumentDescriptions = [];
/** @var array Collection of function arguments default values */
protected $argumentDefaults = [];
/** @var string Return type hint */
protected $returnType;
/** @var CommentsGenerator */
protected $commentGenerator;
/**
* FunctionGenerator constructor.
*
* @param string $name Function name
* @param AbstractGenerator $parent Parent Generator
*/
public function __construct(string $name, AbstractGenerator $parent = null)
{
$this->name = $name;
$this->commentGenerator = (new CommentsGenerator($this))
->setIndentation($this->indentation);
parent::__construct($parent);
}
/**
* Set function argument.
*
* @param string $name Argument name
* @param string|null $type Argument type
* @param string $description Argument description
* @param mixed $defaultValue Argument default value
*
* @return FunctionGenerator
*/
public function defArgument(
string $name,
string $type = null,
string $description = null,
$defaultValue = null
): FunctionGenerator
{
$this->arguments[$name] = $type;
$this->argumentDescriptions[$name] = $description;
$this->argumentDefaults[$name] = $defaultValue;
$this->commentGenerator->defParam($name, $type, $description);
return $this;
}
/**
* @inheritdoc
*/
public function setIndentation(int $indentation): AbstractGenerator
{
// Set comments indentation
$this->commentGenerator->setIndentation($indentation);
return parent::setIndentation($indentation);
}
/**
* Set function description comment.
*
* @param array $description Function description
*
* @return FunctionGenerator
*/
public function defDescription(array $description): FunctionGenerator
{
// Append description lines
foreach ($description as $line) {
$this->commentGenerator->defLine($line);
}
// Add one empty line at the end
$this->commentGenerator->defLine('');
return $this;
}
/**
* Set return value type
*
* @param string|null $type Return type hint
*
* @param string $description Return type description
*
* @return FunctionGenerator
*/
public function defReturnType(string $type, string $description = ''): FunctionGenerator
{
// Add comment return type
$this->commentGenerator->defReturn($type, $description);
// Set method definition return type, mixed return types are not supported yet
$this->returnType = strpos($type, '|') !== false ? '' : $type;
return $this;
}
/**
* {@inheritdoc}
*/
public function code(): string
{
$formattedCode[] =
$this->indentation($this->indentation) . $this->buildDefinition()
. '(' . $this->buildArguments($this->arguments, $this->argumentDefaults) . ')'
. ($this->returnType ? ' : ' . $this->returnType : '');
// Prepend inner indentation to code
$innerIndentation = $this->indentation(1);
$formattedCode[] = '{';
foreach ($this->code as $codeLine) {
$formattedCode[] = $innerIndentation . $codeLine;
}
$formattedCode[] = '}';
// Generate function comments
$this->commentGenerator->end();
// Get function comments code
$comments = $this->getNestedCode(CommentsGenerator::class);
return "\n\n" . ($comments !== '' ? $comments . "\n" : '') . implode("\n" . $this->indentation($this->indentation), $formattedCode);
}
/**
* Build function definition.
*
* @return string Function definition
*/
protected function buildDefinition()
{
return 'function ' . $this->name;
}
/**
* {@inheritdoc}
*/
public function defComment(): CommentsGenerator
{
return $this->commentGenerator;
}
}