From 1572491a8ab32bfe3927302aaa36bd3e4ea9e059 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 13 Feb 2021 14:25:19 +0100 Subject: [PATCH] use the right context for properties defined in traits --- .../Extractor/PhpDocExtractor.php | 12 ++++++- .../Tests/Extractor/PhpDocExtractorTest.php | 20 ++++++++++++ .../Tests/Fixtures/TraitUsage/DummyTrait.php | 32 +++++++++++++++++++ .../Fixtures/TraitUsage/DummyUsedInTrait.php | 16 ++++++++++ .../Fixtures/TraitUsage/DummyUsingTrait.php | 17 ++++++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyTrait.php create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsedInTrait.php create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsingTrait.php diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 176a00a2f8..a701a011c6 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -201,7 +201,17 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property } try { - return $this->docBlockFactory->create($reflectionProperty, $this->createFromReflector($reflectionProperty->getDeclaringClass())); + $reflector = $reflectionProperty->getDeclaringClass(); + + foreach ($reflector->getTraits() as $trait) { + if ($trait->hasProperty($property)) { + $reflector = $trait; + + break; + } + } + + return $this->docBlockFactory->create($reflectionProperty, $this->createFromReflector($reflector)); } catch (\InvalidArgumentException $e) { return null; } catch (\RuntimeException $e) { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index d352fa12b6..bd3d5287c2 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -16,6 +16,9 @@ use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; 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\TraitUsage\DummyUsedInTrait; +use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsingTrait; use Symfony\Component\PropertyInfo\Type; /** @@ -273,6 +276,23 @@ class PhpDocExtractorTest extends TestCase $this->assertEquals($types, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\DockBlockFallback', $property)); } + /** + * @dataProvider propertiesDefinedByTraitsProvider + */ + public function testPropertiesDefinedByTraits(string $property, Type $type) + { + $this->assertEquals([$type], $this->extractor->getTypes(DummyUsingTrait::class, $property)); + } + + public function propertiesDefinedByTraitsProvider(): array + { + return [ + ['propertyInTraitPrimitiveType', new Type(Type::BUILTIN_TYPE_STRING)], + ['propertyInTraitObjectSameNamespace', new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyUsedInTrait::class)], + ['propertyInTraitObjectDifferentNamespace', new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], + ]; + } + protected function isPhpDocumentorV5() { if (class_exists(InvalidTag::class)) { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyTrait.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyTrait.php new file mode 100644 index 0000000000..6284ebf105 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyTrait.php @@ -0,0 +1,32 @@ + + * + * 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\TraitUsage; + +use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; + +trait DummyTrait +{ + /** + * @var string + */ + private $propertyInTraitPrimitiveType; + + /** + * @var DummyUsedInTrait + */ + private $propertyInTraitObjectSameNamespace; + + /** + * @var Dummy + */ + private $propertyInTraitObjectDifferentNamespace; +} diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsedInTrait.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsedInTrait.php new file mode 100644 index 0000000000..b887f6654e --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsedInTrait.php @@ -0,0 +1,16 @@ + + * + * 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\TraitUsage; + +class DummyUsedInTrait +{ +} diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsingTrait.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsingTrait.php new file mode 100644 index 0000000000..bfd75a36f4 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/TraitUsage/DummyUsingTrait.php @@ -0,0 +1,17 @@ + + * + * 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\TraitUsage; + +class DummyUsingTrait +{ + use DummyTrait; +}