Skip to content

Commit fe1581c

Browse files
Merge branch '7.2' into 7.3
* 7.2: [VarExporter] Fix support for hooks and asymmetric visibility [TypeInfo] Fix promoted property with `@var` tag fix(process): use a pipe for stderr in pty mode to avoid mixed output between stdout and stderr [Cache] fix data collector
2 parents 28931da + 1ee1937 commit fe1581c

File tree

3 files changed

+36
-23
lines changed

3 files changed

+36
-23
lines changed

Tests/Fixtures/DummyWithPhpDoc.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,18 @@ final class DummyWithPhpDoc
2929

3030
/**
3131
* @param bool $promoted
32+
* @param bool $promotedVarAndParam
3233
*/
3334
public function __construct(
3435
public mixed $promoted,
36+
/**
37+
* @var string
38+
*/
39+
public mixed $promotedVar,
40+
/**
41+
* @var string
42+
*/
43+
public mixed $promotedVarAndParam,
3544
) {
3645
}
3746

Tests/TypeResolver/PhpDocAwareReflectionTypeResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public static function readPhpDocDataProvider(): iterable
4141

4242
yield [Type::array(Type::object(Dummy::class)), $reflection->getProperty('arrayOfDummies')];
4343
yield [Type::bool(), $reflection->getProperty('promoted')];
44+
yield [Type::string(), $reflection->getProperty('promotedVar')];
45+
yield [Type::string(), $reflection->getProperty('promotedVarAndParam')];
4446
yield [Type::object(Dummy::class), $reflection->getMethod('getNextDummy')];
4547
yield [Type::object(Dummy::class), $reflection->getMethod('getNextDummy')->getParameters()[0]];
4648
yield [Type::int(), $reflection->getProperty('aliasedInt')];

TypeResolver/PhpDocAwareReflectionTypeResolver.php

Lines changed: 25 additions & 23 deletions
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)