Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockBasedOnArrayMapRector\Fixture;

final class OverrideBareMixed
{
/**
* @param mixed $items
*/
public function run(array $items): void
{
array_map(fn (string $item) => trim($item), $items);
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockBasedOnArrayMapRector\Fixture;

final class OverrideBareMixed
{
/**
* @param string[] $items
*/
public function run(array $items): void
{
array_map(fn (string $item) => trim($item), $items);
}
}

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

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockBasedOnArrayMapRector\Fixture;

final class OverrideDummyArray
{
/**
* @param array $items
*/
public function run(array $items): void
{
array_map(fn (string $item) => trim($item), $items);
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockBasedOnArrayMapRector\Fixture;

final class OverrideDummyArray
{
/**
* @param string[] $items
*/
public function run(array $items): void
{
array_map(fn (string $item) => trim($item), $items);
}
}

?>
5 changes: 2 additions & 3 deletions rules/TypeDeclarationDocblocks/NodeDocblockTypeDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
Expand All @@ -33,7 +32,7 @@ public function __construct(
public function decorateGenericIterableParamType(
Type $type,
PhpDocInfo $phpDocInfo,
ClassMethod $classMethod,
FunctionLike $functionLike,
Param $param,
string $parameterName
): bool {
Expand All @@ -49,7 +48,7 @@ public function decorateGenericIterableParamType(
return false;
}

$this->phpDocTypeChanger->changeParamTypeNode($classMethod, $phpDocInfo, $param, $parameterName, $typeNode);
$this->phpDocTypeChanger->changeParamTypeNode($functionLike, $phpDocInfo, $param, $parameterName, $typeNode);

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,19 @@

namespace Rector\TypeDeclarationDocblocks\Rector\ClassMethod;

use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
use Rector\Rector\AbstractRector;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\TypeDeclarationDocblocks\NodeDocblockTypeDecorator;
use Rector\TypeDeclarationDocblocks\NodeFinder\ArrayMapClosureExprFinder;
use Rector\TypeDeclarationDocblocks\TagNodeAnalyzer\UsefulArrayTagNodeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

Expand All @@ -31,8 +29,8 @@ public function __construct(
private readonly ArrayMapClosureExprFinder $arrayMapClosureExprFinder,
private readonly StaticTypeMapper $staticTypeMapper,
private readonly PhpDocInfoFactory $phpDocInfoFactory,
private readonly DocBlockUpdater $docBlockUpdater,
private readonly PhpDocTypeChanger $phpDocTypeChanger,
private readonly UsefulArrayTagNodeAnalyzer $usefulArrayTagNodeAnalyzer,
private readonly NodeDocblockTypeDecorator $nodeDocblockTypeDecorator
) {

}
Expand Down Expand Up @@ -112,21 +110,24 @@ public function refactor(Node $node): ?Node
continue;
}

$paramType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($paramTypeNode);
$arrayParamType = new ArrayType(new MixedType(), $paramType);

if ($this->isAlreadyNonMixedParamType($functionPhpDocInfo, $paramName)) {
if ($this->usefulArrayTagNodeAnalyzer->isUsefulArrayTag(
$functionPhpDocInfo->getParamTagValueByName($paramName)
)) {
continue;
}

$this->phpDocTypeChanger->changeParamType(
$node,
$functionPhpDocInfo,
$paramType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($paramTypeNode);
$arrayParamType = new ArrayType(new MixedType(), $paramType);

if ($this->nodeDocblockTypeDecorator->decorateGenericIterableParamType(
$arrayParamType,
$functionPhpDocInfo,
$node,
$param,
$paramName
);
$hasChanged = true;
)) {
$hasChanged = true;
}
}

}
Expand All @@ -135,8 +136,6 @@ public function refactor(Node $node): ?Node
return null;
}

$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);

return $node;
}

Expand All @@ -148,30 +147,4 @@ private function isArrayParam(Param $param): bool

return $this->isName($param->type, 'array');
}

private function isMixedArrayType(Type $type): bool
{
if (! $type instanceof ArrayType) {
return false;
}

if (! $type->getItemType() instanceof MixedType) {
return false;
}

return $type->getKeyType() instanceof MixedType;
}

private function isAlreadyNonMixedParamType(
PhpDocInfo $functionPhpDocInfo,
string $paramName
): bool {
$currentParamType = $functionPhpDocInfo->getParamType($paramName);
if ($currentParamType instanceof MixedType) {
return false;
}

// has useful param type already?
return ! $this->isMixedArrayType($currentParamType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function changeReturnTypeNode(
}

public function changeParamTypeNode(
ClassMethod $classMethod,
FunctionLike $functionLike,
PhpDocInfo $phpDocInfo,
Param $param,
string $paramName,
Expand All @@ -129,7 +129,7 @@ public function changeParamTypeNode(
$phpDocInfo->addTagValueNode($paramTagValueNode);
}

$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($classMethod);
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($functionLike);
}

public function changeReturnType(FunctionLike $functionLike, PhpDocInfo $phpDocInfo, Type $newType): bool
Expand Down