Skip to content

Commit 71280b6

Browse files
committed
Updated Rector to commit e29863909630baae19805dc2d784a34b8f8e2ab7
rectorphp/rector-src@e298639 [type-declarations] Add TypedPropertyFromDocblockSetUpDefinedRector (#7135)
1 parent 19bd64f commit 71280b6

File tree

5 files changed

+169
-2
lines changed

5 files changed

+169
-2
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
declare (strict_types=1);
4+
namespace Rector\TypeDeclaration\Rector\Class_;
5+
6+
use PhpParser\Node;
7+
use PhpParser\Node\Stmt\Class_;
8+
use PhpParser\Node\Stmt\ClassMethod;
9+
use PhpParser\Node\Stmt\Property;
10+
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
11+
use PHPStan\Type\MixedType;
12+
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
13+
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
14+
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
15+
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
16+
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
17+
use Rector\Rector\AbstractRector;
18+
use Rector\StaticTypeMapper\StaticTypeMapper;
19+
use Rector\TypeDeclaration\AlreadyAssignDetector\ConstructorAssignDetector;
20+
use Rector\ValueObject\MethodName;
21+
use Rector\ValueObject\PhpVersionFeature;
22+
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
23+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
24+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
25+
/**
26+
* @see \Rector\Tests\TypeDeclaration\Rector\Class_\TypedPropertyFromDocblockSetUpDefinedRector\TypedPropertyFromDocblockSetUpDefinedRectorTest
27+
*/
28+
final class TypedPropertyFromDocblockSetUpDefinedRector extends AbstractRector implements MinPhpVersionInterface
29+
{
30+
/**
31+
* @readonly
32+
*/
33+
private TestsNodeAnalyzer $testsNodeAnalyzer;
34+
/**
35+
* @readonly
36+
*/
37+
private ConstructorAssignDetector $constructorAssignDetector;
38+
/**
39+
* @readonly
40+
*/
41+
private PhpDocInfoFactory $phpDocInfoFactory;
42+
/**
43+
* @readonly
44+
*/
45+
private StaticTypeMapper $staticTypeMapper;
46+
/**
47+
* @readonly
48+
*/
49+
private DocBlockUpdater $docBlockUpdater;
50+
public function __construct(TestsNodeAnalyzer $testsNodeAnalyzer, ConstructorAssignDetector $constructorAssignDetector, PhpDocInfoFactory $phpDocInfoFactory, StaticTypeMapper $staticTypeMapper, DocBlockUpdater $docBlockUpdater)
51+
{
52+
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
53+
$this->constructorAssignDetector = $constructorAssignDetector;
54+
$this->phpDocInfoFactory = $phpDocInfoFactory;
55+
$this->staticTypeMapper = $staticTypeMapper;
56+
$this->docBlockUpdater = $docBlockUpdater;
57+
}
58+
public function getRuleDefinition() : RuleDefinition
59+
{
60+
return new RuleDefinition('Add property type in PHPUnit test from docblock, if defined in setUp() method', [new CodeSample(<<<'CODE_SAMPLE'
61+
use PHPUnit\Framework\TestCase;
62+
63+
class SomeClass extends TestCase
64+
{
65+
/**
66+
* @var \Doctrine\ORM\EntityManagerInterface
67+
*/
68+
private $doctrine;
69+
70+
protected function setUp(): void
71+
{
72+
$this->doctrine = $this->container('doctrine.orm.entity_manager');
73+
}
74+
}
75+
CODE_SAMPLE
76+
, <<<'CODE_SAMPLE'
77+
use PHPUnit\Framework\TestCase;
78+
79+
class SomeClass extends TestCase
80+
{
81+
private \Doctrine\ORM\EntityManagerInterface $doctrine;
82+
83+
protected function setUp(): void
84+
{
85+
$this->doctrine = $this->container('doctrine.orm.entity_manager');
86+
}
87+
}
88+
CODE_SAMPLE
89+
)]);
90+
}
91+
/**
92+
* @return array<class-string<Node>>
93+
*/
94+
public function getNodeTypes() : array
95+
{
96+
return [Class_::class];
97+
}
98+
/**
99+
* @param Class_ $node
100+
*/
101+
public function refactor(Node $node) : ?Node
102+
{
103+
if (!$this->testsNodeAnalyzer->isInTestClass($node)) {
104+
return null;
105+
}
106+
// nothing useful here
107+
$setUpClassMethod = $node->getMethod(MethodName::SET_UP);
108+
if (!$setUpClassMethod instanceof ClassMethod) {
109+
return null;
110+
}
111+
$hasChanged = \false;
112+
foreach ($node->getProperties() as $property) {
113+
// already known type
114+
if ($property->type instanceof Node) {
115+
continue;
116+
}
117+
// some magic might be going on
118+
if ($property->isStatic()) {
119+
continue;
120+
}
121+
if (!$property->isPrivate()) {
122+
continue;
123+
}
124+
// exactly one property
125+
if (\count($property->props) !== 1) {
126+
continue;
127+
}
128+
$propertyName = $property->props[0]->name->toString();
129+
if (!$this->constructorAssignDetector->isPropertyAssigned($node, $propertyName)) {
130+
continue;
131+
}
132+
$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNode($property);
133+
if (!$propertyPhpDocInfo instanceof PhpDocInfo) {
134+
continue;
135+
}
136+
$varType = $propertyPhpDocInfo->getVarType();
137+
if ($varType instanceof MixedType) {
138+
continue;
139+
}
140+
$nativePropertyTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($varType, TypeKind::PROPERTY);
141+
if (!$nativePropertyTypeNode instanceof Node) {
142+
continue;
143+
}
144+
// remove var tag
145+
$this->removeVarTag($propertyPhpDocInfo, $property);
146+
$property->type = $nativePropertyTypeNode;
147+
$hasChanged = \true;
148+
}
149+
if ($hasChanged) {
150+
return $node;
151+
}
152+
return null;
153+
}
154+
public function provideMinPhpVersion() : int
155+
{
156+
return PhpVersionFeature::TYPED_PROPERTIES;
157+
}
158+
private function removeVarTag(PhpDocInfo $propertyPhpDocInfo, Property $property) : void
159+
{
160+
$propertyPhpDocInfo->removeByType(VarTagValueNode::class);
161+
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($property);
162+
}
163+
}

src/Application/VersionResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ final class VersionResolver
1919
* @api
2020
* @var string
2121
*/
22-
public const PACKAGE_VERSION = '90542ed2eb7790116a8f491164551962c1ed8522';
22+
public const PACKAGE_VERSION = 'e29863909630baae19805dc2d784a34b8f8e2ab7';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2025-08-11 12:56:16';
27+
public const RELEASE_DATE = '2025-08-11 12:34:04';
2828
/**
2929
* @var int
3030
*/

src/Config/Level/TypeDeclarationLevel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Rector\TypeDeclaration\Rector\Class_\PropertyTypeFromStrictSetterGetterRector;
1313
use Rector\TypeDeclaration\Rector\Class_\ReturnTypeFromStrictTernaryRector;
1414
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector;
15+
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromDocblockSetUpDefinedRector;
1516
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromJMSSerializerAttributeTypeRector;
1617
use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector;
1718
use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeBasedOnPHPUnitDataProviderRector;
@@ -126,5 +127,6 @@ final class TypeDeclarationLevel
126127
TypedPropertyFromJMSSerializerAttributeTypeRector::class,
127128
// possibly based on docblocks, but also helpful, intentionally last
128129
AddArrayFunctionClosureParamTypeRector::class,
130+
TypedPropertyFromDocblockSetUpDefinedRector::class,
129131
];
130132
}

vendor/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,6 +2712,7 @@
27122712
'Rector\\TypeDeclaration\\Rector\\Class_\\PropertyTypeFromStrictSetterGetterRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php',
27132713
'Rector\\TypeDeclaration\\Rector\\Class_\\ReturnTypeFromStrictTernaryRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/ReturnTypeFromStrictTernaryRector.php',
27142714
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromCreateMockAssignRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php',
2715+
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromDocblockSetUpDefinedRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromDocblockSetUpDefinedRector.php',
27152716
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromJMSSerializerAttributeTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromJMSSerializerAttributeTypeRector.php',
27162717
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureNeverReturnTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/Closure/AddClosureNeverReturnTypeRector.php',
27172718
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureVoidReturnTypeWhereNoReturnRector' => $baseDir . '/rules/TypeDeclaration/Rector/Closure/AddClosureVoidReturnTypeWhereNoReturnRector.php',

vendor/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,6 +2948,7 @@ class ComposerStaticInit637fffe8153e0b8c33fed1ed89863932
29482948
'Rector\\TypeDeclaration\\Rector\\Class_\\PropertyTypeFromStrictSetterGetterRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php',
29492949
'Rector\\TypeDeclaration\\Rector\\Class_\\ReturnTypeFromStrictTernaryRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/ReturnTypeFromStrictTernaryRector.php',
29502950
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromCreateMockAssignRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php',
2951+
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromDocblockSetUpDefinedRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromDocblockSetUpDefinedRector.php',
29512952
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromJMSSerializerAttributeTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromJMSSerializerAttributeTypeRector.php',
29522953
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureNeverReturnTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Closure/AddClosureNeverReturnTypeRector.php',
29532954
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureVoidReturnTypeWhereNoReturnRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Closure/AddClosureVoidReturnTypeWhereNoReturnRector.php',

0 commit comments

Comments
 (0)