Skip to content

Commit

Permalink
Merge pull request #374 from GautierDele/5.x
Browse files Browse the repository at this point in the history
✨ method parameter default value rendering
  • Loading branch information
jaapio authored Nov 4, 2024
2 parents c29b3d1 + 1ed543b commit 6fc32d3
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/DocBlock/Tags/Factory/MethodFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function (MethodTagValueParameterNode $param) use ($context) {
),
$param->isReference,
$param->isVariadic,
(string) $param->defaultValue
$param->defaultValue === null ? MethodParameter::NO_DEFAULT_VALUE : (string) $param->defaultValue
);
},
$tagValue->parameters
Expand Down
95 changes: 95 additions & 0 deletions src/DocBlock/Tags/Factory/MethodParameterFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link http://phpdoc.org
*/

namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;

use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use function str_repeat;
use function strlen;

/**
* @internal This class is not part of the BC promise of this library.
*/
final class MethodParameterFactory
{
/**
* Formats the given default value to a string-able mixin
*
* @param mixed $defaultValue
* @return string
*/
public function format($defaultValue): string
{
if (method_exists($this, $method = 'format'.ucfirst(gettype($defaultValue)))) {
return ' = ' . $this->{$method}($defaultValue);
}
return '';
}

private function formatDouble(float $defaultValue): string
{
return var_export($defaultValue, true);
}

/**
* @param mixed $defaultValue
* @return string
*/
private function formatNull($defaultValue): string
{
return 'null';
}

private function formatInteger(int $defaultValue): string
{
return var_export($defaultValue, true);
}

private function formatString(string $defaultValue): string
{
return var_export($defaultValue, true);
}

private function formatBoolean(bool $defaultValue): string
{
return var_export($defaultValue, true);
}

/**
* @param array<array|null|int|float|bool|string|object> $defaultValue
* @return string
*/
private function formatArray(array $defaultValue): string

Check failure on line 72 in src/DocBlock/Tags/Factory/MethodParameterFactory.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.0)

Method phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodParameterFactory::formatArray() has parameter $defaultValue with no value type specified in iterable type array.
{
$formatedValue = '[';

foreach ($defaultValue as $key => $value) {
if (method_exists($this, $method = 'format'.ucfirst(gettype($value)))) {
$formatedValue .= $this->{$method}($value);

if ($key !== array_key_last($defaultValue)) {
$formatedValue .= ',';
}
}
}

$formatedValue .= ']';

return $formatedValue;
}

private function formatObject(object $defaultValue): string
{
return 'new '. get_class($defaultValue). '()';
}
}
5 changes: 1 addition & 4 deletions src/DocBlock/Tags/Method.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,7 @@ public function __toString(): string
{
$arguments = [];
foreach ($this->parameters as $parameter) {
$arguments[] = $parameter->getType() . ' ' .
($parameter->isReference() ? '&' : '') .
($parameter->isVariadic() ? '...' : '') .
'$' . $parameter->getName();
$arguments[] = (string) $parameter;
}

$argumentStr = '(' . implode(', ', $arguments) . ')';
Expand Down
30 changes: 27 additions & 3 deletions src/DocBlock/Tags/MethodParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace phpDocumentor\Reflection\DocBlock\Tags;

use phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodParameterFactory;
use phpDocumentor\Reflection\Type;

final class MethodParameter
Expand All @@ -24,14 +25,22 @@ final class MethodParameter

private string $name;

private ?string $defaultValue = null;
/**
* @var mixed
*/
private $defaultValue;

public const NO_DEFAULT_VALUE = '__NO_VALUE__';

/**
* @param mixed $defaultValue
*/
public function __construct(
string $name,
Type $type,
bool $isReference = false,
bool $isVariadic = false,
?string $defaultValue = null
$defaultValue = self::NO_DEFAULT_VALUE
) {
$this->type = $type;
$this->isReference = $isReference;
Expand Down Expand Up @@ -62,6 +71,21 @@ public function isVariadic(): bool

public function getDefaultValue(): ?string
{
return $this->defaultValue;
if ($this->defaultValue === static::NO_DEFAULT_VALUE) {
return null;
}
if (is_array($this->defaultValue)) {
return implode(',', $this->defaultValue);
}
return (string) $this->defaultValue;

Check failure on line 80 in src/DocBlock/Tags/MethodParameter.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.0)

Cannot cast mixed to string.
}

public function __toString(): string
{
return $this->getType() . ' ' .
($this->isReference() ? '&' : '') .
($this->isVariadic() ? '...' : '') .
'$' . $this->getName() .
($this->defaultValue !== self::NO_DEFAULT_VALUE ? (new MethodParameterFactory)->format($this->defaultValue) : '');
}
}
95 changes: 95 additions & 0 deletions tests/unit/DocBlock/Tags/MethodParameterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link http://phpdoc.org
*/

namespace phpDocumentor\Reflection\DocBlock\Tags;

use Mockery as m;
use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\Types\Array_;
use phpDocumentor\Reflection\Types\Boolean;
use phpDocumentor\Reflection\Types\Float_;
use phpDocumentor\Reflection\Types\Integer;
use phpDocumentor\Reflection\Types\Nullable;
use phpDocumentor\Reflection\Types\Object_;
use phpDocumentor\Reflection\Types\String_;
use PHPUnit\Framework\TestCase;

/**
* @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Method
* @covers ::<private>
*/
class MethodParameterTest extends TestCase
{
/**
* Call Mockery::close after each test.
*/
public function tearDown(): void
{
m::close();
}

public function collectionDefaultValuesProvider(): array
{
return [
[new String_(), '1', '\'1\''],
[new Integer(), 1, '1'],
[new Boolean(), true, 'true'],
[new Float_(), 1.23, '1.23'],
[new Array_(), [1, '2', true], '[1,\'2\',true]'],
[new Array_(), [[1, 2], '2', true], '[[1,2],\'2\',true]'],
[new Nullable(new Float_()), null, 'null'],
[new Nullable(new Float_()), 1.23, '1.23'],
[new Object_(new Fqsen('\\stdClass')), new \stdClass(), 'new stdClass()'],
];
}

/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\MethodParameter::__construct
* @uses \phpDocumentor\Reflection\DocBlock\Tags\MethodParameter::getDefaultValue()
* @uses \phpDocumentor\Reflection\DocBlock\Tags\MethodParameter::__toString
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
*
* @dataProvider collectionDefaultValuesProvider
* @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render
* @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName
*/
public function testIfTagCanBeRenderedUsingMethodParameterWithDefaultValue(Type $type, $defaultValue, string $defaultValueStr): void
{
$fixture = new MethodParameter('argument', $type, false, false, $defaultValue);

$this->assertSame(
sprintf('%s $argument = %s', $type, $defaultValueStr),
(string) $fixture
);
}

/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\MethodParameter::__construct
* @uses \phpDocumentor\Reflection\DocBlock\Tags\MethodParameter::getDefaultValue()
* @uses \phpDocumentor\Reflection\DocBlock\Tags\MethodParameter::__toString
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
*
* @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::render
* @covers \phpDocumentor\Reflection\DocBlock\Tags\BaseTag::getName
*/
public function testIfTagCanBeRenderedUsingMethodParameterWithNoDefaultValue(): void
{
$fixture = new MethodParameter('argument', new Float_());

$this->assertSame(
'float $argument',
(string) $fixture
);
}
}

0 comments on commit 6fc32d3

Please sign in to comment.