diff --git a/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php b/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php index c7a1b9885e5c..a6b94bcdee85 100644 --- a/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php +++ b/packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php @@ -18,7 +18,9 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\Type\ArrayType; +use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\MixedType; +use PHPStan\Type\NeverType; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; use Rector\BetterPhpDocParser\Annotation\AnnotationNaming; @@ -245,6 +247,15 @@ public function changeVarTag(Node $node, Type $newType): void return; } + // prevent existing type override by mixed + if (! $currentVarType instanceof MixedType) { + if ($newType instanceof ConstantArrayType) { + if ($newType->getItemType() instanceof NeverType) { + return; + } + } + } + $this->removeTagFromNode($node, 'var', true); $this->addTypeSpecificTag($node, 'var', $newType); diff --git a/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/CompleteVarDocTypePropertyRectorTest.php b/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/CompleteVarDocTypePropertyRectorTest.php index f517fdcfae3f..1dfa134f7262 100644 --- a/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/CompleteVarDocTypePropertyRectorTest.php +++ b/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/CompleteVarDocTypePropertyRectorTest.php @@ -27,6 +27,7 @@ public function provideDataForTest(): Iterator yield [__DIR__ . '/Fixture/typed_array.php.inc']; yield [__DIR__ . '/Fixture/typed_array_nested.php.inc']; yield [__DIR__ . '/Fixture/symfony_console_command.php.inc']; + yield [__DIR__ . '/Fixture/skip_more_specific.php.inc']; } protected function getRectorClass(): string diff --git a/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/skip_more_specific.php.inc b/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/skip_more_specific.php.inc new file mode 100644 index 000000000000..f1af735a5a01 --- /dev/null +++ b/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/skip_more_specific.php.inc @@ -0,0 +1,31 @@ +getLabel()] = $service; + } + /** + * find registered SomeService. + * + * @return SomeService[] + */ + public static function getRegisteredSomeServices() + { + return self::$registry; + } +} diff --git a/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Source/SomeService.php b/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Source/SomeService.php new file mode 100644 index 000000000000..4e14fecc3314 --- /dev/null +++ b/packages/TypeDeclaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Source/SomeService.php @@ -0,0 +1,8 @@ +