Skip to content

Commit 6275905

Browse files
committed
[TypeInfo] Fix promoted property with @var tag
1 parent e7af9b8 commit 6275905

File tree

3 files changed

+30
-23
lines changed

3 files changed

+30
-23
lines changed

src/Symfony/Component/TypeInfo/Tests/Fixtures/DummyWithPhpDoc.php

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ final class DummyWithPhpDoc
1414
*/
1515
public function __construct(
1616
public mixed $promoted,
17+
/**
18+
* @var string
19+
*/
20+
public mixed $promotedVar,
1721
) {
1822
}
1923

src/Symfony/Component/TypeInfo/Tests/TypeResolver/PhpDocAwareReflectionTypeResolverTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public function testReadPhpDoc()
2929

3030
$this->assertEquals(Type::array(Type::object(Dummy::class)), $resolver->resolve($reflection->getProperty('arrayOfDummies')));
3131
$this->assertEquals(Type::bool(), $resolver->resolve($reflection->getProperty('promoted')));
32+
$this->assertEquals(Type::string(), $resolver->resolve($reflection->getProperty('promotedVar')));
3233
$this->assertEquals(Type::object(Dummy::class), $resolver->resolve($reflection->getMethod('getNextDummy')));
3334
$this->assertEquals(Type::object(Dummy::class), $resolver->resolve($reflection->getMethod('getNextDummy')->getParameters()[0]));
3435
}

src/Symfony/Component/TypeInfo/TypeResolver/PhpDocAwareReflectionTypeResolver.php

+25-23
Original file line numberDiff line numberDiff line change
@@ -64,36 +64,38 @@ public function resolve(mixed $subject, ?TypeContext $typeContext = null): Type
6464
throw new UnsupportedException(\sprintf('Expected subject to be a "ReflectionProperty", a "ReflectionParameter" or a "ReflectionFunctionAbstract", "%s" given.', get_debug_type($subject)), $subject);
6565
}
6666

67-
$docComment = match (true) {
68-
$subject instanceof \ReflectionProperty => $subject->isPromoted() ? $subject->getDeclaringClass()?->getConstructor()?->getDocComment() : $subject->getDocComment(),
69-
$subject instanceof \ReflectionParameter => $subject->getDeclaringFunction()->getDocComment(),
70-
$subject instanceof \ReflectionFunctionAbstract => $subject->getDocComment(),
67+
$typeContext ??= $this->typeContextFactory->createFromReflection($subject);
68+
69+
$docComments = match (true) {
70+
$subject instanceof \ReflectionProperty => $subject->isPromoted()
71+
? ['@var' => $subject->getDocComment(), '@param' => $subject->getDeclaringClass()?->getConstructor()?->getDocComment()]
72+
: ['@var' => $subject->getDocComment()],
73+
$subject instanceof \ReflectionParameter => ['@param' => $subject->getDeclaringFunction()->getDocComment()],
74+
$subject instanceof \ReflectionFunctionAbstract => ['@return' => $subject->getDocComment()],
7175
};
7276

73-
if (!$docComment) {
74-
return $this->reflectionTypeResolver->resolve($subject);
75-
}
77+
foreach ($docComments as $tagName => $docComment) {
78+
if (!$docComment) {
79+
continue;
80+
}
7681

77-
$typeContext ??= $this->typeContextFactory->createFromReflection($subject);
82+
$tokens = new TokenIterator($this->lexer->tokenize($docComment));
83+
$docNode = $this->phpDocParser->parse($tokens);
7884

79-
$tagName = match (true) {
80-
$subject instanceof \ReflectionProperty => $subject->isPromoted() ? '@param' : '@var',
81-
$subject instanceof \ReflectionParameter => '@param',
82-
$subject instanceof \ReflectionFunctionAbstract => '@return',
83-
};
85+
foreach ($docNode->getTagsByName($tagName) as $tag) {
86+
$tagValue = $tag->value;
8487

85-
$tokens = new TokenIterator($this->lexer->tokenize($docComment));
86-
$docNode = $this->phpDocParser->parse($tokens);
88+
if ('@var' === $tagName && $tagValue instanceof VarTagValueNode) {
89+
return $this->stringTypeResolver->resolve((string) $tagValue, $typeContext);
90+
}
8791

88-
foreach ($docNode->getTagsByName($tagName) as $tag) {
89-
$tagValue = $tag->value;
92+
if ('@param' === $tagName && $tagValue instanceof ParamTagValueNode && '$'.$subject->getName() === $tagValue->parameterName) {
93+
return $this->stringTypeResolver->resolve((string) $tagValue, $typeContext);
94+
}
9095

91-
if (
92-
$tagValue instanceof VarTagValueNode
93-
|| $tagValue instanceof ParamTagValueNode && $tagName && '$'.$subject->getName() === $tagValue->parameterName
94-
|| $tagValue instanceof ReturnTagValueNode
95-
) {
96-
return $this->stringTypeResolver->resolve((string) $tagValue, $typeContext);
96+
if ('@return' === $tagName && $tagValue instanceof ReturnTagValueNode) {
97+
return $this->stringTypeResolver->resolve((string) $tagValue, $typeContext);
98+
}
9799
}
98100
}
99101

0 commit comments

Comments
 (0)