Skip to content

Commit 430ec79

Browse files
LastDragon-runicolas-grekas
authored andcommitted
[PropertyInfo] Fixed promoted property type detection for PhpStanExtractor
1 parent 43a1fa1 commit 430ec79

File tree

3 files changed

+37
-13
lines changed

3 files changed

+37
-13
lines changed

src/Symfony/Component/PropertyInfo/Extractor/PhpStanExtractor.php

+20-12
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,7 @@ private function getDocBlockFromConstructor(string $class, string $property): ?P
183183
return null;
184184
}
185185

186-
$tokens = new TokenIterator($this->lexer->tokenize($rawDocNode));
187-
$phpDocNode = $this->phpDocParser->parse($tokens);
188-
$tokens->consumeTokenType(Lexer::TOKEN_END);
186+
$phpDocNode = $this->getPhpDocNode($rawDocNode);
189187

190188
return $this->filterDocBlockParams($phpDocNode, $property);
191189
}
@@ -239,24 +237,27 @@ private function getDocBlockFromProperty(string $class, string $property): ?arra
239237
return null;
240238
}
241239

240+
// Type can be inside property docblock as `@var`
241+
$rawDocNode = $reflectionProperty->getDocComment();
242+
$phpDocNode = $rawDocNode ? $this->getPhpDocNode($rawDocNode) : null;
242243
$source = self::PROPERTY;
243244

244-
if ($reflectionProperty->isPromoted()) {
245+
if (!$phpDocNode?->getTagsByName('@var')) {
246+
$phpDocNode = null;
247+
}
248+
249+
// or in the constructor as `@param` for promoted properties
250+
if (!$phpDocNode && $reflectionProperty->isPromoted()) {
245251
$constructor = new \ReflectionMethod($class, '__construct');
246252
$rawDocNode = $constructor->getDocComment();
253+
$phpDocNode = $rawDocNode ? $this->getPhpDocNode($rawDocNode) : null;
247254
$source = self::MUTATOR;
248-
} else {
249-
$rawDocNode = $reflectionProperty->getDocComment();
250255
}
251256

252-
if (!$rawDocNode) {
257+
if (!$phpDocNode) {
253258
return null;
254259
}
255260

256-
$tokens = new TokenIterator($this->lexer->tokenize($rawDocNode));
257-
$phpDocNode = $this->phpDocParser->parse($tokens);
258-
$tokens->consumeTokenType(Lexer::TOKEN_END);
259-
260261
return [$phpDocNode, $source, $reflectionProperty->class];
261262
}
262263

@@ -296,10 +297,17 @@ private function getDocBlockFromMethod(string $class, string $ucFirstProperty, i
296297
return null;
297298
}
298299

300+
$phpDocNode = $this->getPhpDocNode($rawDocNode);
301+
302+
return [$phpDocNode, $prefix, $reflectionMethod->class];
303+
}
304+
305+
private function getPhpDocNode(string $rawDocNode): PhpDocNode
306+
{
299307
$tokens = new TokenIterator($this->lexer->tokenize($rawDocNode));
300308
$phpDocNode = $this->phpDocParser->parse($tokens);
301309
$tokens->consumeTokenType(Lexer::TOKEN_END);
302310

303-
return [$phpDocNode, $prefix, $reflectionMethod->class];
311+
return $phpDocNode;
304312
}
305313
}

src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ public function testExtractPhp80Type(string $class, $property, array $type = nul
474474
public static function php80TypesProvider()
475475
{
476476
return [
477+
[Php80Dummy::class, 'promotedWithDocCommentAndType', [new Type(Type::BUILTIN_TYPE_INT)]],
478+
[Php80Dummy::class, 'promotedWithDocComment', [new Type(Type::BUILTIN_TYPE_STRING)]],
477479
[Php80Dummy::class, 'promotedAndMutated', [new Type(Type::BUILTIN_TYPE_STRING)]],
478480
[Php80Dummy::class, 'promoted', null],
479481
[Php80Dummy::class, 'collection', [new Type(Type::BUILTIN_TYPE_ARRAY, collection: true, collectionValueType: new Type(Type::BUILTIN_TYPE_STRING))]],

src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php80Dummy.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,23 @@ class Php80Dummy
1717

1818
/**
1919
* @param string $promotedAndMutated
20+
* @param string $promotedWithDocComment
21+
* @param string $promotedWithDocCommentAndType
2022
* @param array<string> $collection
2123
*/
22-
public function __construct(private mixed $promoted, private mixed $promotedAndMutated, private array $collection)
24+
public function __construct(
25+
private mixed $promoted,
26+
private mixed $promotedAndMutated,
27+
/**
28+
* Comment without @var.
29+
*/
30+
private mixed $promotedWithDocComment,
31+
/**
32+
* @var int
33+
*/
34+
private mixed $promotedWithDocCommentAndType,
35+
private array $collection,
36+
)
2337
{
2438
}
2539

0 commit comments

Comments
 (0)