Permalink
Browse files

bug #27837 [PropertyInfo] Fix dock block lookup fallback loop (DerMan…

…oMann)

This PR was submitted for the 4.1 branch but it was squashed and merged into the 3.4 branch instead (closes #27837).

Discussion
----------

[PropertyInfo] Fix dock block lookup fallback loop

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

`getDocBlock()` in `PhpDocExtractor` implements a fallback loop when trying to lookup a dock block for a property (property, accessor method, mutator method). This relies on the individual lookups to return `null`.

Unfortunately, phpDocumentor will throw an `InvalidArgumentException` exception in case there is no dock block.

Currently the try/catch is wrapping the whole loop which means if the first lookup fails the loop is ended instead of moving on to the next one.

This PR moves the try/catch to each individual call of `$this->docBlockFactory->create()`.

Commits
-------

b1a6120 [PropertyInfo] Fix dock block lookup fallback loop
  • Loading branch information...
nicolas-grekas committed Jul 7, 2018
2 parents f435044 + b1a6120 commit 9a6fe4727322ad0cf821df6abac9456f5fbedd68
@@ -169,25 +169,21 @@ private function getDocBlock($class, $property)
$ucFirstProperty = ucfirst($property);
try {
switch (true) {
case $docBlock = $this->getDocBlockFromProperty($class, $property):
$data = array($docBlock, self::PROPERTY, null);
break;
switch (true) {
case $docBlock = $this->getDocBlockFromProperty($class, $property):
$data = array($docBlock, self::PROPERTY, null);
break;
case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR):
$data = array($docBlock, self::ACCESSOR, null);
break;
case list($docBlock) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::ACCESSOR):
$data = array($docBlock, self::ACCESSOR, null);
break;
case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR):
$data = array($docBlock, self::MUTATOR, $prefix);
break;
case list($docBlock, $prefix) = $this->getDocBlockFromMethod($class, $ucFirstProperty, self::MUTATOR):
$data = array($docBlock, self::MUTATOR, $prefix);
break;
default:
$data = array(null, null, null);
}
} catch (\InvalidArgumentException $e) {
$data = array(null, null, null);
default:
$data = array(null, null, null);
}
return $this->docBlocks[$propertyHash] = $data;
@@ -210,7 +206,11 @@ private function getDocBlockFromProperty($class, $property)
return;
}
return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass()));
try {
return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass()));
} catch (\InvalidArgumentException $e) {
return null;
}
}
/**
@@ -251,6 +251,10 @@ private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
return;
}
return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix);
try {
return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix);
} catch (\InvalidArgumentException $e) {
return null;
}
}
}
@@ -184,6 +184,29 @@ public function testReturnNullOnEmptyDocBlock()
{
$this->assertNull($this->extractor->getShortDescription(EmptyDocBlock::class, 'foo'));
}
public function dockBlockFallbackTypesProvider()
{
return array(
'pub' => array(
'pub', array(new Type(Type::BUILTIN_TYPE_STRING)),
),
'protAcc' => array(
'protAcc', array(new Type(Type::BUILTIN_TYPE_INT)),
),
'protMut' => array(
'protMut', array(new Type(Type::BUILTIN_TYPE_BOOL)),
),
);
}
/**
* @dataProvider dockBlockFallbackTypesProvider
*/
public function testDocBlockFallback($property, $types)
{
$this->assertEquals($types, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\DockBlockFallback', $property));
}
}
class EmptyDocBlock
@@ -0,0 +1,64 @@
<?php
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/**
* PhpDocExtractor should fallback from property -> accessor -> mutator when looking up dockblocks.
*
* @author Martin Rademacher <mano@radebatz.net>
*/
class DockBlockFallback
{
/** @var string $pub */
public $pub = 'pub';
protected $protAcc;
protected $protMut;
public function getPub()
{
return $this->pub;
}
public function setPub($pub)
{
$this->pub = $pub;
}
/**
* @return int
*/
public function getProtAcc()
{
return $this->protAcc;
}
public function setProt($protAcc)
{
$this->protAcc = $protAcc;
}
public function getProtMut()
{
return $this->protMut;
}
/**
* @param bool $protMut
*/
public function setProtMut($protMut)
{
$this->protMut = $protMut;
}
}

0 comments on commit 9a6fe47

Please sign in to comment.