[PropertyInfo] fix resolving parent|self type hints

This commit is contained in:
Nicolas Grekas 2018-05-16 15:47:24 +02:00
parent 10a2d39365
commit 88a3b90860
6 changed files with 48 additions and 10 deletions

View File

@ -176,7 +176,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
if (!$reflectionType = $reflectionParameter->getType()) {
return;
}
$type = $this->extractFromReflectionType($reflectionType);
$type = $this->extractFromReflectionType($reflectionType, $reflectionMethod);
// HHVM reports variadics with "array" but not builtin type hints
if (!$reflectionType->isBuiltin() && Type::BUILTIN_TYPE_ARRAY === $type->getBuiltinType()) {
@ -188,7 +188,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
} elseif (Type::BUILTIN_TYPE_CALLABLE === $info[1]) {
$type = new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull());
} else {
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $info[1]);
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $this->resolveTypeName($info[1], $reflectionMethod));
}
} else {
return;
@ -217,7 +217,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
}
if ($this->supportsParameterType && $reflectionType = $reflectionMethod->getReturnType()) {
return array($this->extractFromReflectionType($reflectionType));
return array($this->extractFromReflectionType($reflectionType, $reflectionMethod));
}
if (\in_array($prefix, array('is', 'can'))) {
@ -228,11 +228,9 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
/**
* Extracts data from the PHP 7 reflection type.
*
* @param \ReflectionType $reflectionType
*
* @return Type
*/
private function extractFromReflectionType(\ReflectionType $reflectionType)
private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod)
{
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : $reflectionType->__toString();
$nullable = $reflectionType->allowsNull();
@ -244,12 +242,24 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
} elseif ($reflectionType->isBuiltin()) {
$type = new Type($phpTypeOrClass, $nullable);
} else {
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $phpTypeOrClass);
$type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod));
}
return $type;
}
private function resolveTypeName($name, \ReflectionMethod $reflectionMethod)
{
if ('self' === $lcName = strtolower($name)) {
return $reflectionMethod->getDeclaringClass()->name;
}
if ('parent' === $lcName && $parent = $reflectionMethod->getDeclaringClass()->getParentClass()) {
return $parent->name;
}
return $name;
}
/**
* Does the class have the given public property?
*

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\PropertyInfo\Tests\PhpDocExtractors;
namespace Symfony\Component\PropertyInfo\Tests\PhpDocExtractor;
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;

View File

@ -52,6 +52,8 @@ class ReflectionExtractorTest extends TestCase
'DOB',
'Id',
'123',
'self',
'realParent',
'c',
'd',
'e',
@ -135,6 +137,8 @@ class ReflectionExtractorTest extends TestCase
array('donotexist', null),
array('staticGetter', null),
array('staticSetter', null),
array('self', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy'))),
array('realParent', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy'))),
);
}
@ -153,6 +157,8 @@ class ReflectionExtractorTest extends TestCase
array('foo', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true))),
array('bar', array(new Type(Type::BUILTIN_TYPE_INT))),
array('baz', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING)))),
array('buz', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy'))),
array('biz', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'stdClass'))),
array('donotexist', null),
);
}

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\PropertyInfo\Tests\Extractors;
namespace Symfony\Component\PropertyInfo\Tests\Extractor;
use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;

View File

@ -127,4 +127,18 @@ class Dummy extends ParentDummy
public function get123()
{
}
/**
* @param self $self
*/
public function setSelf(self $self)
{
}
/**
* @param parent $realParent
*/
public function setRealParent(parent $realParent)
{
}
}

View File

@ -14,7 +14,7 @@ namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class Php7Dummy
class Php7Dummy extends \stdClass
{
public function getFoo(): array
{
@ -27,4 +27,12 @@ class Php7Dummy
public function addBaz(string $baz)
{
}
public function getBuz(): self
{
}
public function getBiz(): parent
{
}
}