Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\AddReturnDocblockDataProviderRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class AddReturnDocblockDataProviderRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\AddReturnDocblockDataProviderRector\Fixture;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class DataProviderMethod extends TestCase
{
#[DataProvider('provideData')]
public function testSomething()
{
}

public static function provideData()
{
return [
['data1'],
['data2'],
];
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\AddReturnDocblockDataProviderRector\Fixture;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class DataProviderMethod extends TestCase
{
#[DataProvider('provideData')]
public function testSomething()
{
}

/**
* @return string[][]
*/
public static function provideData()
{
return [
['data1'],
['data2'],
];
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\AddReturnDocblockDataProviderRector\Fixture;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class WithIntegers extends TestCase
{
#[DataProvider('provideData')]
public function testSomething()
{
}

public static function provideData()
{
return [
[125, 35],
[1252]
];
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\AddReturnDocblockDataProviderRector\Fixture;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class WithIntegers extends TestCase
{
#[DataProvider('provideData')]
public function testSomething()
{
}

/**
* @return int[][]
*/
public static function provideData()
{
return [
[125, 35],
[1252]
];
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\TypeDeclarationDocblocks\Rector\Class_\AddReturnDocblockDataProviderRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(AddReturnDocblockDataProviderRector::class);
};
6 changes: 3 additions & 3 deletions rules/CodingStyle/Rector/Enum_/EnumCaseToPascalCaseRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ private function convertToPascalCase(string $name): string
fn ($part): string =>
// If part is all uppercase, convert to ucfirst(strtolower())
// If part is already mixed or PascalCase, keep as is except ucfirst
ctype_upper((string) $part)
? ucfirst(strtolower((string) $part))
: ucfirst((string) $part),
ctype_upper($part)
? ucfirst(strtolower($part))
: ucfirst($part),
$parts
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,31 @@ private function shouldSkip(
): bool {
$params = $node->getParams();
$args = $callLike->getArgs();
if ($callLike->isFirstClassCallable()) {
return true;
}

if (
$callLike->isFirstClassCallable()
|| $this->isChainedCall($callLike)
|| $this->isUsingNamedArgs($args)
|| $this->isUsingByRef($params)
|| $this->isNotUsingSameParamsForArgs($params, $args)
|| $this->isDependantMethod($callLike, $params)
|| $this->isUsingThisInNonObjectContext($callLike, $scope)
) {
if ($this->isChainedCall($callLike)) {
return true;
}

return false;
if ($this->isUsingNamedArgs($args)) {
return true;
}

if ($this->isUsingByRef($params)) {
return true;
}

if ($this->isNotUsingSameParamsForArgs($params, $args)) {
return true;
}

if ($this->isDependantMethod($callLike, $params)) {
return true;
}

return $this->isUsingThisInNonObjectContext($callLike, $scope);
}

private function extractCallLike(Closure|ArrowFunction $node): FuncCall|MethodCall|StaticCall|null
Expand All @@ -99,6 +110,7 @@ private function extractCallLike(Closure|ArrowFunction $node): FuncCall|MethodCa
if (count($node->stmts) !== 1 || ! $node->stmts[0] instanceof Return_) {
return null;
}

$callLike = $node->stmts[0]->expr;
} else {
$callLike = $node->expr;
Expand Down Expand Up @@ -198,6 +210,7 @@ private function isUsingByRef(array $params): bool
return true;
}
}

return false;
}

Expand All @@ -211,6 +224,7 @@ private function isUsingNamedArgs(array $args): bool
return true;
}
}

return false;
}

Expand All @@ -220,10 +234,6 @@ private function isChainedCall(FuncCall|MethodCall|StaticCall $callLike): bool
return false;
}

if (! $callLike->var instanceof CallLike) {
return false;
}

return true;
return $callLike->var instanceof CallLike;
}
}
46 changes: 44 additions & 2 deletions rules/Privatization/TypeManipulator/TypeNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,30 @@

namespace Rector\Privatization\TypeManipulator;

use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\MixedType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeTraverser;
use PHPStan\Type\UnionType;

final class TypeNormalizer
{
/**
* Generalize false/true type to bool,
* Generalize false/true constantArrayType to bool,
* as mostly default value but accepts both
*/
public function generalizeConstantBoolTypes(Type $type): Type
{
return TypeTraverser::map($type, static function (Type $type, callable $traverseCallback): BooleanType|Type {
return TypeTraverser::map($type, function (Type $type, callable $traverseCallback): BooleanType|Type {
if ($type instanceof ConstantBooleanType) {
return new BooleanType();
}
Expand All @@ -40,7 +44,45 @@ public function generalizeConstantBoolTypes(Type $type): Type
return new IntegerType();
}

if ($type instanceof ConstantArrayType) {
// is relevant int constantArrayType?
if ($this->isImplicitNumberedListKeyType($type)) {
$keyType = new MixedType();
} else {
$keyType = $traverseCallback($type->getKeyType(), $traverseCallback);
}

// should be string[]
$itemType = $traverseCallback($type->getItemType(), $traverseCallback);
if ($itemType instanceof ConstantStringType) {
$itemType = new StringType();
}

return new ArrayType($keyType, $itemType);
}

return $traverseCallback($type, $traverseCallback);
});
}

private function isImplicitNumberedListKeyType(ConstantArrayType $constantArrayType): bool
{
if (! $constantArrayType->getKeyType() instanceof UnionType) {
return false;
}

foreach ($constantArrayType->getKeyType()->getTypes() as $key => $keyType) {
if ($keyType instanceof ConstantIntegerType) {
if ($keyType->getValue() === $key) {
continue;
}

return false;
}

return false;
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ public function __construct(
) {
}

/**
* @return ClassMethod[]
*/
public function findDataProviderNodesInClass(Class_ $class): array
{
$dataProviderClassMethods = [];

foreach ($class->getMethods() as $classMethod) {
$currentDataProviderNodes = $this->findDataProviderNodes($class, $classMethod);
$dataProviderClassMethods = array_merge(
$dataProviderClassMethods,
$currentDataProviderNodes->getClassMethods()
);
}

return $dataProviderClassMethods;
}

public function findDataProviderNodes(Class_ $class, ClassMethod $classMethod): DataProviderNodes
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($classMethod);
Expand Down
Loading
Loading