From 6711777263f2dc4e301af092d619f56dc50ea912 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 29 Sep 2025 19:54:27 +0200 Subject: [PATCH 1/2] generalize non empty string --- rector.php | 1 + rules/Privatization/TypeManipulator/TypeNormalizer.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rector.php b/rector.php index adc0b834fb9..b24f7fe82f0 100644 --- a/rector.php +++ b/rector.php @@ -13,6 +13,7 @@ codeQuality: true, codingStyle: true, typeDeclarations: true, + typeDeclarationDocblocks: true, privatization: true, naming: true, instanceOf: true, diff --git a/rules/Privatization/TypeManipulator/TypeNormalizer.php b/rules/Privatization/TypeManipulator/TypeNormalizer.php index e29c0c16df5..b1b47fcec2d 100644 --- a/rules/Privatization/TypeManipulator/TypeNormalizer.php +++ b/rules/Privatization/TypeManipulator/TypeNormalizer.php @@ -5,6 +5,7 @@ namespace Rector\Privatization\TypeManipulator; use PHPStan\Type\Accessory\AccessoryLiteralStringType; +use PHPStan\Type\Accessory\AccessoryNonEmptyStringType; use PHPStan\Type\Accessory\AccessoryNonFalsyStringType; use PHPStan\Type\ArrayType; use PHPStan\Type\BooleanType; @@ -57,7 +58,7 @@ public function generalizeConstantBoolTypes(Type $type): Type public function generalizeConstantTypes(Type $type): Type { return TypeTraverser::map($type, function (Type $type, callable $traverseCallback): Type { - if ($type instanceof AccessoryNonFalsyStringType || $type instanceof AccessoryLiteralStringType) { + if ($type instanceof AccessoryNonFalsyStringType || $type instanceof AccessoryLiteralStringType || $type instanceof AccessoryNonEmptyStringType) { return new StringType(); } From fcede0a34a4b602ffefd90eaa1c5babcee63d4c2 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 29 Sep 2025 19:54:54 +0200 Subject: [PATCH 2/2] [tests] add known iterable types --- rector.php | 2 +- .../ShortNameResolver/ShortNameResolverTest.php | 3 +++ rules-tests/Naming/Naming/PropertyNamingTest.php | 3 +++ .../PhpDocInfo/PhpDocInfoPrinter/DoctrineTest.php | 3 +++ .../StaticDoctrineAnnotationParser/ArrayParserTest.php | 3 +++ .../StaticDoctrineAnnotationParserTest.php | 3 +++ tests/FileSystem/FilePathHelperTest.php | 3 +++ .../ExpectedNameResolver/InflectorSingularResolverTest.php | 3 +++ .../ParamTypeResolver/ParamTypeResolverTest.php | 3 +++ .../PropertyTypeResolver/PropertyTypeResolverTest.php | 3 +++ .../VariableTypeResolver/VariableTypeResolverTest.php | 3 +++ .../StaticTypeMapper/StaticTypeMapperTest.php | 6 ++++++ .../TypeMapper/ArrayTypeMapperTest.php | 6 ++++++ .../AnnotationToAttributeMapperTest.php | 3 +++ tests/PhpAttribute/UseAliasNameMatcherTest.php | 3 +++ tests/PhpParser/Printer/BetterStandardPrinterTest.php | 3 +++ tests/Set/SetManager/SetManagerTest.php | 3 +++ tests/Skipper/FileSystem/FnMatchPathNormalizerTest.php | 3 +++ tests/Skipper/Skipper/SkipperTest.php | 6 ++++++ tests/Util/Reflection/PrivatesAccessorTest.php | 3 +++ tests/Validation/RectorAssertTest.php | 3 +++ 21 files changed, 70 insertions(+), 1 deletion(-) diff --git a/rector.php b/rector.php index b24f7fe82f0..d8bdd5c82e5 100644 --- a/rector.php +++ b/rector.php @@ -13,7 +13,7 @@ codeQuality: true, codingStyle: true, typeDeclarations: true, - typeDeclarationDocblocks: true, + // typeDeclarationDocblocks: true, privatization: true, naming: true, instanceOf: true, diff --git a/rules-tests/CodingStyle/ClassNameImport/ShortNameResolver/ShortNameResolverTest.php b/rules-tests/CodingStyle/ClassNameImport/ShortNameResolver/ShortNameResolverTest.php index 7f74c6535e7..d1e105b9fe9 100644 --- a/rules-tests/CodingStyle/ClassNameImport/ShortNameResolver/ShortNameResolverTest.php +++ b/rules-tests/CodingStyle/ClassNameImport/ShortNameResolver/ShortNameResolverTest.php @@ -37,6 +37,9 @@ public function test(string $filePath, array $expectedShortNames): void $this->assertSame($expectedShortNames, $shortNames); } + /** + * @return Iterator, mixed>> + */ public static function provideData(): Iterator { yield [__DIR__ . '/Fixture/various_imports.php.inc', [ diff --git a/rules-tests/Naming/Naming/PropertyNamingTest.php b/rules-tests/Naming/Naming/PropertyNamingTest.php index c03028e3da8..0d0d1b92ec6 100644 --- a/rules-tests/Naming/Naming/PropertyNamingTest.php +++ b/rules-tests/Naming/Naming/PropertyNamingTest.php @@ -57,6 +57,9 @@ public function testPropertyName(string $objectName, string $expectedVariableNam $this->assertSame($expectedVariableName, $variableName); } + /** + * @return Iterator> + */ public static function provideDataPropertyName(): Iterator { yield ['SomeVariable', 'someVariable']; diff --git a/tests/BetterPhpDocParser/PhpDocInfo/PhpDocInfoPrinter/DoctrineTest.php b/tests/BetterPhpDocParser/PhpDocInfo/PhpDocInfoPrinter/DoctrineTest.php index ec6a6a2551f..aacecb90d2a 100644 --- a/tests/BetterPhpDocParser/PhpDocInfo/PhpDocInfoPrinter/DoctrineTest.php +++ b/tests/BetterPhpDocParser/PhpDocInfo/PhpDocInfoPrinter/DoctrineTest.php @@ -26,6 +26,9 @@ public function testClass(string $docFilePath, string $className): void $this->assertSame($docComment, $printedPhpDocInfo); } + /** + * @return Iterator, mixed>> + */ public static function provideDataClass(): Iterator { yield [__DIR__ . '/Source/Doctrine/index_in_table.txt', IndexInTable::class]; diff --git a/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/ArrayParserTest.php b/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/ArrayParserTest.php index 21b82e50c8a..bb3cbe47a77 100644 --- a/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/ArrayParserTest.php +++ b/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/ArrayParserTest.php @@ -41,6 +41,9 @@ public function test(string $docContent, array $expectedArrayItemNodes): void $this->assertEquals($expectedArrayItemNodes, $arrayItemNodes); } + /** + * @return Iterator|string)>> + */ public static function provideData(): Iterator { yield ['{key: "value"}', [new ArrayItemNode(new StringNode('value'), 'key')]]; diff --git a/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/StaticDoctrineAnnotationParserTest.php b/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/StaticDoctrineAnnotationParserTest.php index a0772f6f583..fd7c40b3f7c 100644 --- a/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/StaticDoctrineAnnotationParserTest.php +++ b/tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/StaticDoctrineAnnotationParserTest.php @@ -43,6 +43,9 @@ public function test(string $docContent, CurlyListNode | array $expectedValue): $this->assertEquals($expectedValue, $value); } + /** + * @return Iterator, mixed>> + */ public static function provideData(): Iterator { $curlyListNode = new CurlyListNode([ diff --git a/tests/FileSystem/FilePathHelperTest.php b/tests/FileSystem/FilePathHelperTest.php index 6b519429f3c..1fc3431a7de 100644 --- a/tests/FileSystem/FilePathHelperTest.php +++ b/tests/FileSystem/FilePathHelperTest.php @@ -26,6 +26,9 @@ public function test(string $inputPath, string $expectedNormalizedPath): void $this->assertSame($expectedNormalizedPath, $normalizedPath); } + /** + * @return Iterator> + */ public static function provideData(): Iterator { // based on Linux diff --git a/tests/Naming/ExpectedNameResolver/InflectorSingularResolverTest.php b/tests/Naming/ExpectedNameResolver/InflectorSingularResolverTest.php index 8326dfabed2..b3410dff31e 100644 --- a/tests/Naming/ExpectedNameResolver/InflectorSingularResolverTest.php +++ b/tests/Naming/ExpectedNameResolver/InflectorSingularResolverTest.php @@ -27,6 +27,9 @@ public function testResolveForForeach(string $currentName, string $expectedSingu $this->assertSame($expectedSingularName, $singularValue); } + /** + * @return Iterator> + */ public static function provideData(): Iterator { yield ['psr4NamespacesToPaths', 'psr4NamespaceToPath']; diff --git a/tests/NodeTypeResolver/PerNodeTypeResolver/ParamTypeResolver/ParamTypeResolverTest.php b/tests/NodeTypeResolver/PerNodeTypeResolver/ParamTypeResolver/ParamTypeResolverTest.php index 66cef73a2b8..7eb73a23fbe 100644 --- a/tests/NodeTypeResolver/PerNodeTypeResolver/ParamTypeResolver/ParamTypeResolverTest.php +++ b/tests/NodeTypeResolver/PerNodeTypeResolver/ParamTypeResolver/ParamTypeResolverTest.php @@ -25,6 +25,9 @@ public function test(string $file, int $nodePosition, string $expectedType): voi $this->assertSame($resolvedType::class, $expectedType); } + /** + * @return Iterator, mixed>> + */ public static function provideData(): Iterator { yield [__DIR__ . '/Source/MethodParamTypeHint.php', 0, FullyQualifiedObjectType::class]; diff --git a/tests/NodeTypeResolver/PerNodeTypeResolver/PropertyTypeResolver/PropertyTypeResolverTest.php b/tests/NodeTypeResolver/PerNodeTypeResolver/PropertyTypeResolver/PropertyTypeResolverTest.php index 607e93889cf..55a3072d36c 100644 --- a/tests/NodeTypeResolver/PerNodeTypeResolver/PropertyTypeResolver/PropertyTypeResolverTest.php +++ b/tests/NodeTypeResolver/PerNodeTypeResolver/PropertyTypeResolver/PropertyTypeResolverTest.php @@ -41,6 +41,9 @@ public function test(string $file, int $nodePosition, Type $expectedType): void $this->assertSame($expectedTypeAsString, $resolvedTypeAsString); } + /** + * @return Iterator> + */ public static function provideData(): Iterator { yield [__DIR__ . '/Source/MethodParamDocBlock.php', 0, new ObjectType(Html::class)]; diff --git a/tests/NodeTypeResolver/PerNodeTypeResolver/VariableTypeResolver/VariableTypeResolverTest.php b/tests/NodeTypeResolver/PerNodeTypeResolver/VariableTypeResolver/VariableTypeResolverTest.php index b2b24215b7b..1d9e6ff5356 100644 --- a/tests/NodeTypeResolver/PerNodeTypeResolver/VariableTypeResolver/VariableTypeResolverTest.php +++ b/tests/NodeTypeResolver/PerNodeTypeResolver/VariableTypeResolver/VariableTypeResolverTest.php @@ -29,6 +29,9 @@ public function test(string $file, int $nodePosition, TypeWithClassName $expecte $this->assertSame($expectedTypeWithClassName->getClassName(), $resolvedType->getClassName()); } + /** + * @return Iterator> + */ public static function provideData(): Iterator { $anotherTypeObjectType = new ObjectType(AnotherType::class); diff --git a/tests/NodeTypeResolver/StaticTypeMapper/StaticTypeMapperTest.php b/tests/NodeTypeResolver/StaticTypeMapper/StaticTypeMapperTest.php index f42e35b53af..9b48149da29 100644 --- a/tests/NodeTypeResolver/StaticTypeMapper/StaticTypeMapperTest.php +++ b/tests/NodeTypeResolver/StaticTypeMapper/StaticTypeMapperTest.php @@ -44,6 +44,9 @@ public function testMapPHPStanPhpDocTypeNodeToPHPStanType(TypeNode $typeNode, st $this->assertInstanceOf($expectedType, $phpStanType); } + /** + * @return Iterator, mixed>> + */ public static function provideData(): Iterator { $genericTypeNode = new GenericTypeNode(new IdentifierTypeNode('Traversable'), []); @@ -85,6 +88,9 @@ public function testMapPhpParserNodePHPStanType(Node $node, string $expectedType $this->assertInstanceOf($expectedType, $phpStanType); } + /** + * @return Iterator|Identifier)>> + */ public static function provideDataForMapPhpParserNodePHPStanType(): Iterator { yield [new Identifier('iterable'), IterableType::class]; diff --git a/tests/PHPStanStaticTypeMapper/TypeMapper/ArrayTypeMapperTest.php b/tests/PHPStanStaticTypeMapper/TypeMapper/ArrayTypeMapperTest.php index 7273088aa2e..32226689504 100644 --- a/tests/PHPStanStaticTypeMapper/TypeMapper/ArrayTypeMapperTest.php +++ b/tests/PHPStanStaticTypeMapper/TypeMapper/ArrayTypeMapperTest.php @@ -53,6 +53,9 @@ public static function provideDataWithoutKeys(): Iterator yield [$arrayType, 'string[]']; } + /** + * @return Iterator> + */ public static function provideDataUnionedWithoutKeys(): Iterator { $stringAndIntegerUnionType = new UnionType([new StringType(), new IntegerType()]); @@ -66,6 +69,9 @@ public static function provideDataUnionedWithoutKeys(): Iterator yield [$evenMoreNestedUnionArrayType, 'string[][][]|int[][][]']; } + /** + * @return Iterator> + */ public static function provideDataWithKeys(): Iterator { $arrayMixedToStringType = new ArrayType(new MixedType(), new StringType()); diff --git a/tests/PhpAttribute/AnnotationToAttributeMapper/AnnotationToAttributeMapperTest.php b/tests/PhpAttribute/AnnotationToAttributeMapper/AnnotationToAttributeMapperTest.php index fdd202455e0..387002ee8fc 100644 --- a/tests/PhpAttribute/AnnotationToAttributeMapper/AnnotationToAttributeMapperTest.php +++ b/tests/PhpAttribute/AnnotationToAttributeMapper/AnnotationToAttributeMapperTest.php @@ -42,6 +42,9 @@ public function test(mixed $input, string $expectedTypeClass): void } } + /** + * @return Iterator, mixed>> + */ public static function provideData(): Iterator { yield [false, ConstFetch::class]; diff --git a/tests/PhpAttribute/UseAliasNameMatcherTest.php b/tests/PhpAttribute/UseAliasNameMatcherTest.php index d503e83ad2b..cdf15e3f348 100644 --- a/tests/PhpAttribute/UseAliasNameMatcherTest.php +++ b/tests/PhpAttribute/UseAliasNameMatcherTest.php @@ -56,6 +56,9 @@ public function test( $this->assertSame($expectedAttributeUseImportName, $useAliasMetadata->getUseImportName()); } + /** + * @return Iterator> + */ public static function provideData(): Iterator { yield [ diff --git a/tests/PhpParser/Printer/BetterStandardPrinterTest.php b/tests/PhpParser/Printer/BetterStandardPrinterTest.php index 23f77522932..4a75bc516a3 100644 --- a/tests/PhpParser/Printer/BetterStandardPrinterTest.php +++ b/tests/PhpParser/Printer/BetterStandardPrinterTest.php @@ -80,6 +80,9 @@ public function testYield(Node $node, string $expectedPrintedNode): void $this->assertSame($expectedPrintedNode, $printedNode); } + /** + * @return Iterator> + */ public static function provideDataForYield(): Iterator { $yield = new Yield_(new String_('value')); diff --git a/tests/Set/SetManager/SetManagerTest.php b/tests/Set/SetManager/SetManagerTest.php index 41b557e5426..9e25d74fc54 100644 --- a/tests/Set/SetManager/SetManagerTest.php +++ b/tests/Set/SetManager/SetManagerTest.php @@ -37,6 +37,9 @@ public function testByVersion(string $projectDirectory, array $expectedSets): vo $this->assertSame($expectedSets, $composerTriggeredSets); } + /** + * @return Iterator<(array>|array>|array>|array)> + */ public static function provideInstalledTwigData(): Iterator { // here we cannot used features coming up in 2.4, as we only have 2.0 diff --git a/tests/Skipper/FileSystem/FnMatchPathNormalizerTest.php b/tests/Skipper/FileSystem/FnMatchPathNormalizerTest.php index 93333115772..1e176a58ae2 100644 --- a/tests/Skipper/FileSystem/FnMatchPathNormalizerTest.php +++ b/tests/Skipper/FileSystem/FnMatchPathNormalizerTest.php @@ -28,6 +28,9 @@ public function testPaths(string $path, string $expectedNormalizedPath): void $this->assertSame($expectedNormalizedPath, $normalizedPath); } + /** + * @return Iterator> + */ public static function providePaths(): Iterator { yield ['path/with/no/asterisk', 'path/with/no/asterisk']; diff --git a/tests/Skipper/Skipper/SkipperTest.php b/tests/Skipper/Skipper/SkipperTest.php index fb532352058..33dda0fd5a8 100644 --- a/tests/Skipper/Skipper/SkipperTest.php +++ b/tests/Skipper/Skipper/SkipperTest.php @@ -86,6 +86,9 @@ public function testSkipElementAndFilePath(string $element, string $filePath, bo $this->assertSame($expectedSkip, $resolvedSkip); } + /** + * @return Iterator, mixed>> + */ public static function provideCheckerAndFile(): Iterator { yield [FifthElement::class, __DIR__ . '/Fixture', true]; @@ -97,6 +100,9 @@ public static function provideCheckerAndFile(): Iterator yield [NotSkippedClass::class, __DIR__ . '/Fixture/someOtherFile', false]; } + /** + * @return Iterator, mixed>> + */ public static function provideDataShouldSkipElement(): Iterator { yield [ThreeMan::class, false]; diff --git a/tests/Util/Reflection/PrivatesAccessorTest.php b/tests/Util/Reflection/PrivatesAccessorTest.php index 4057b453edc..418fa7fbb04 100644 --- a/tests/Util/Reflection/PrivatesAccessorTest.php +++ b/tests/Util/Reflection/PrivatesAccessorTest.php @@ -36,6 +36,9 @@ public function test( $this->assertSame($expectedResult, $result); } + /** + * @return Iterator, mixed>> + */ public static function provideData(): Iterator { yield [SomeClassWithPrivateMethods::class, 'getNumber', [], 5]; diff --git a/tests/Validation/RectorAssertTest.php b/tests/Validation/RectorAssertTest.php index f36987c2c6a..78272b4e867 100644 --- a/tests/Validation/RectorAssertTest.php +++ b/tests/Validation/RectorAssertTest.php @@ -89,6 +89,9 @@ public function testInvalidFunctionName(string $functionName): void RectorAssert::functionName($functionName); } + /** + * @return Iterator> + */ public static function provideDataInvalidFunctionNames(): Iterator { yield ['35'];