fix resolving parent/self/static type annotations
This commit is contained in:
parent
08c789c97b
commit
e9f2ece991
@ -142,11 +142,31 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
|
||||
break;
|
||||
}
|
||||
|
||||
$parentClass = null;
|
||||
$types = [];
|
||||
/** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */
|
||||
foreach ($docBlock->getTagsByName($tag) as $tag) {
|
||||
if ($tag && !$tag instanceof InvalidTag && null !== $tag->getType()) {
|
||||
$types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType()));
|
||||
foreach ($this->phpDocTypeHelper->getTypes($tag->getType()) as $type) {
|
||||
switch ($type->getClassName()) {
|
||||
case 'self':
|
||||
case 'static':
|
||||
$resolvedClass = $class;
|
||||
break;
|
||||
|
||||
case 'parent':
|
||||
if (false !== $resolvedClass = $parentClass ?? $parentClass = get_parent_class($class)) {
|
||||
break;
|
||||
}
|
||||
// no break
|
||||
|
||||
default:
|
||||
$types[] = $type;
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $type->isNullable(), $resolvedClass, $type->isCollection(), $type->getCollectionKeyType(), $type->getCollectionValueType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ use phpDocumentor\Reflection\Types\Collection;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsedInTrait;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsingTrait;
|
||||
use Symfony\Component\PropertyInfo\Type;
|
||||
@ -120,6 +121,7 @@ class PhpDocExtractorTest extends TestCase
|
||||
['staticGetter', null, null, null],
|
||||
['staticSetter', null, null, null],
|
||||
['emptyVar', null, $this->isPhpDocumentorV5() ? 'This should not be removed.' : null, null],
|
||||
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], null, null],
|
||||
];
|
||||
}
|
||||
|
||||
@ -293,6 +295,38 @@ class PhpDocExtractorTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider propertiesStaticTypeProvider
|
||||
*/
|
||||
public function testPropertiesStaticType(string $class, string $property, Type $type)
|
||||
{
|
||||
$this->assertEquals([$type], $this->extractor->getTypes($class, $property));
|
||||
}
|
||||
|
||||
public function propertiesStaticTypeProvider(): array
|
||||
{
|
||||
return [
|
||||
[ParentDummy::class, 'propertyTypeStatic', new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)],
|
||||
[Dummy::class, 'propertyTypeStatic', new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider propertiesParentTypeProvider
|
||||
*/
|
||||
public function testPropertiesParentType(string $class, string $property, ?array $types)
|
||||
{
|
||||
$this->assertEquals($types, $this->extractor->getTypes($class, $property));
|
||||
}
|
||||
|
||||
public function propertiesParentTypeProvider(): array
|
||||
{
|
||||
return [
|
||||
[ParentDummy::class, 'parentAnnotationNoParent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'parent')]],
|
||||
[Dummy::class, 'parentAnnotation', [new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)]],
|
||||
];
|
||||
}
|
||||
|
||||
protected function isPhpDocumentorV5()
|
||||
{
|
||||
if (class_exists(InvalidTag::class)) {
|
||||
|
@ -20,6 +20,8 @@ use Symfony\Component\PropertyInfo\Tests\Fixtures\NotInstantiable;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php74Dummy;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy;
|
||||
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php7ParentDummy;
|
||||
use Symfony\Component\PropertyInfo\Type;
|
||||
|
||||
/**
|
||||
@ -57,12 +59,15 @@ class ReflectionExtractorTest extends TestCase
|
||||
'iteratorCollection',
|
||||
'iteratorCollectionWithKey',
|
||||
'nestedIterators',
|
||||
'parentAnnotation',
|
||||
'foo',
|
||||
'foo2',
|
||||
'foo3',
|
||||
'foo4',
|
||||
'foo5',
|
||||
'files',
|
||||
'propertyTypeStatic',
|
||||
'parentAnnotationNoParent',
|
||||
'a',
|
||||
'DOB',
|
||||
'Id',
|
||||
@ -105,12 +110,15 @@ class ReflectionExtractorTest extends TestCase
|
||||
'iteratorCollection',
|
||||
'iteratorCollectionWithKey',
|
||||
'nestedIterators',
|
||||
'parentAnnotation',
|
||||
'foo',
|
||||
'foo2',
|
||||
'foo3',
|
||||
'foo4',
|
||||
'foo5',
|
||||
'files',
|
||||
'propertyTypeStatic',
|
||||
'parentAnnotationNoParent',
|
||||
'date',
|
||||
'c',
|
||||
'd',
|
||||
@ -143,12 +151,15 @@ class ReflectionExtractorTest extends TestCase
|
||||
'iteratorCollection',
|
||||
'iteratorCollectionWithKey',
|
||||
'nestedIterators',
|
||||
'parentAnnotation',
|
||||
'foo',
|
||||
'foo2',
|
||||
'foo3',
|
||||
'foo4',
|
||||
'foo5',
|
||||
'files',
|
||||
'propertyTypeStatic',
|
||||
'parentAnnotationNoParent',
|
||||
],
|
||||
$noPrefixExtractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy')
|
||||
);
|
||||
@ -184,20 +195,21 @@ class ReflectionExtractorTest extends TestCase
|
||||
/**
|
||||
* @dataProvider php7TypesProvider
|
||||
*/
|
||||
public function testExtractPhp7Type($property, array $type = null)
|
||||
public function testExtractPhp7Type(string $class, string $property, array $type = null)
|
||||
{
|
||||
$this->assertEquals($type, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy', $property, []));
|
||||
$this->assertEquals($type, $this->extractor->getTypes($class, $property, []));
|
||||
}
|
||||
|
||||
public function php7TypesProvider()
|
||||
{
|
||||
return [
|
||||
['foo', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]],
|
||||
['bar', [new Type(Type::BUILTIN_TYPE_INT)]],
|
||||
['baz', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
|
||||
['buz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy')]],
|
||||
['biz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'stdClass')]],
|
||||
['donotexist', null],
|
||||
[Php7Dummy::class, 'foo', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]],
|
||||
[Php7Dummy::class, 'bar', [new Type(Type::BUILTIN_TYPE_INT)]],
|
||||
[Php7Dummy::class, 'baz', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
|
||||
[Php7Dummy::class, 'buz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy')]],
|
||||
[Php7Dummy::class, 'biz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Php7ParentDummy::class)]],
|
||||
[Php7Dummy::class, 'donotexist', null],
|
||||
[Php7ParentDummy::class, 'parent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, \stdClass::class)]],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,11 @@ class Dummy extends ParentDummy
|
||||
*/
|
||||
public $nestedIterators;
|
||||
|
||||
/**
|
||||
* @var parent
|
||||
*/
|
||||
public $parentAnnotation;
|
||||
|
||||
public static function getStatic()
|
||||
{
|
||||
}
|
||||
|
@ -48,6 +48,16 @@ class ParentDummy
|
||||
*/
|
||||
public $files;
|
||||
|
||||
/**
|
||||
* @var static
|
||||
*/
|
||||
public $propertyTypeStatic;
|
||||
|
||||
/**
|
||||
* @var parent
|
||||
*/
|
||||
public $parentAnnotationNoParent;
|
||||
|
||||
/**
|
||||
* @return bool|null
|
||||
*/
|
||||
|
@ -14,7 +14,7 @@ namespace Symfony\Component\PropertyInfo\Tests\Fixtures;
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class Php7Dummy extends \stdClass
|
||||
class Php7Dummy extends Php7ParentDummy
|
||||
{
|
||||
public function getFoo(): array
|
||||
{
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
class Php7ParentDummy extends \stdClass
|
||||
{
|
||||
public function getParent(): parent
|
||||
{
|
||||
}
|
||||
}
|
@ -160,6 +160,10 @@ final class PhpDocTypeHelper
|
||||
return [$docType, null];
|
||||
}
|
||||
|
||||
if (\in_array($docType, ['parent', 'self', 'static'], true)) {
|
||||
return ['object', $docType];
|
||||
}
|
||||
|
||||
return ['object', substr($docType, 1)];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user