Skip to content

Commit dd7d554

Browse files
[TypeDeclaration] Skip Valid type from return doc and typed param on AddMethodCallBasedStrictParamTypeRector (#7172)
* [TypeDeclaration] Skip Valid type from return doc and typed param on AddMethodCallBasedStrictParamTypeRector * [ci-review] Rector Rectify --------- Co-authored-by: GitHub Action <actions@github.com>
1 parent a6a8752 commit dd7d554

File tree

7 files changed

+111
-11
lines changed

7 files changed

+111
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\FixtureIntersection;
4+
5+
use Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Source\ConnectionInterface;
6+
use Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Source\ConnectionResolverInterface;
7+
use Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Source\SqlServerConnection;
8+
9+
final class SkipValidTypeFromReturnDoc
10+
{
11+
public function __invoke(ConnectionResolverInterface $resolver): void
12+
{
13+
$connection = $resolver->connection();
14+
15+
if (
16+
$connection instanceof SqlServerConnection
17+
|| ! method_exists($connection, 'getSchemaState')
18+
) {
19+
return;
20+
}
21+
22+
$this->ensureCleanDatabase($connection);
23+
}
24+
25+
private function ensureCleanDatabase(ConnectionInterface $connection): void
26+
{
27+
}
28+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Source;
6+
7+
interface ConnectionInterface
8+
{
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Source;
6+
7+
interface ConnectionResolverInterface
8+
{
9+
/**
10+
* @param string|null $name
11+
* @return ConnectionInterface
12+
*/
13+
public function connection($name = null);
14+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Source;
6+
7+
class SqlServerConnection extends ConnectionInterface
8+
{
9+
}

rules/TypeDeclaration/NodeAnalyzer/CallTypesResolver.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ private function resolveStrictArgValueType(Arg $arg): Type
6060
// "self" in another object is not correct, this make it independent
6161
$argValueType = $this->correctSelfType($argValueType);
6262

63+
$type = $this->nodeTypeResolver->getType($arg->value);
64+
if (! $type->equals($argValueType) && $this->typeComparator->isSubtype($type, $argValueType)) {
65+
return $type;
66+
}
67+
6368
if (! $argValueType instanceof ObjectType) {
6469
return $argValueType;
6570
}
@@ -69,11 +74,6 @@ private function resolveStrictArgValueType(Arg $arg): Type
6974
return new MixedType();
7075
}
7176

72-
$type = $this->nodeTypeResolver->getType($arg->value);
73-
if (! $type->equals($argValueType) && $this->typeComparator->isSubtype($type, $argValueType)) {
74-
return $type;
75-
}
76-
7777
return $argValueType;
7878
}
7979

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\NodeTypeResolver\NodeTypeCorrector;
6+
7+
use PHPStan\Type\Accessory\NonEmptyArrayType;
8+
use PHPStan\Type\ArrayType;
9+
use PHPStan\Type\IntersectionType;
10+
use PHPStan\Type\MixedType;
11+
use PHPStan\Type\Type;
12+
13+
final class AccessoryNonEmptyArrayTypeCorrector
14+
{
15+
public function correct(Type $mainType): Type
16+
{
17+
if (! $mainType instanceof IntersectionType) {
18+
return $mainType;
19+
}
20+
21+
if (! $mainType->isArray()->yes()) {
22+
return $mainType;
23+
}
24+
25+
foreach ($mainType->getTypes() as $type) {
26+
if ($type instanceof NonEmptyArrayType) {
27+
return new ArrayType(new MixedType(), new MixedType());
28+
}
29+
}
30+
31+
return $mainType;
32+
}
33+
}

src/NodeTypeResolver/NodeTypeResolver.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
use Rector\NodeTypeResolver\Contract\NodeTypeResolverAwareInterface;
5252
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
5353
use Rector\NodeTypeResolver\Node\AttributeKey;
54+
use Rector\NodeTypeResolver\NodeTypeCorrector\AccessoryNonEmptyArrayTypeCorrector;
5455
use Rector\NodeTypeResolver\NodeTypeCorrector\AccessoryNonEmptyStringTypeCorrector;
5556
use Rector\NodeTypeResolver\NodeTypeCorrector\GenericClassStringTypeCorrector;
5657
use Rector\NodeTypeResolver\PHPStan\ObjectWithoutClassTypeWithParentTypes;
@@ -79,6 +80,7 @@ public function __construct(
7980
private readonly GenericClassStringTypeCorrector $genericClassStringTypeCorrector,
8081
private readonly ReflectionProvider $reflectionProvider,
8182
private readonly AccessoryNonEmptyStringTypeCorrector $accessoryNonEmptyStringTypeCorrector,
83+
private readonly AccessoryNonEmptyArrayTypeCorrector $accessoryNonEmptyArrayTypeCorrector,
8284
private readonly RenamedClassesDataCollector $renamedClassesDataCollector,
8385
private readonly NodeNameResolver $nodeNameResolver,
8486
iterable $nodeTypeResolvers
@@ -195,8 +197,7 @@ public function getType(Node $node): Type
195197
$type = $this->resolveByNodeTypeResolvers($node);
196198

197199
if ($type instanceof Type) {
198-
$type = $this->accessoryNonEmptyStringTypeCorrector->correct($type);
199-
$type = $this->genericClassStringTypeCorrector->correct($type);
200+
$type = $this->correctType($type);
200201

201202
if ($type instanceof ObjectType) {
202203
$scope = $node->getAttribute(AttributeKey::SCOPE);
@@ -231,9 +232,7 @@ public function getType(Node $node): Type
231232
return new MixedType();
232233
}
233234

234-
$type = $scope->getType($node);
235-
$type = $this->accessoryNonEmptyStringTypeCorrector->correct($type);
236-
$type = $this->genericClassStringTypeCorrector->correct($type);
235+
$type = $this->correctType($scope->getType($node));
237236

238237
// hot fix for phpstan not resolving chain method calls
239238
if (! $node instanceof MethodCall) {
@@ -256,6 +255,14 @@ public function isNullableType(Node $node): bool
256255
return TypeCombinator::containsNull($nodeType);
257256
}
258257

258+
private function correctType(Type $type): Type
259+
{
260+
$type = $this->accessoryNonEmptyStringTypeCorrector->correct($type);
261+
$type = $this->genericClassStringTypeCorrector->correct($type);
262+
263+
return $this->accessoryNonEmptyArrayTypeCorrector->correct($type);
264+
}
265+
259266
public function getNativeType(Expr $expr): Type
260267
{
261268
$scope = $expr->getAttribute(AttributeKey::SCOPE);
@@ -281,7 +288,7 @@ public function getNativeType(Expr $expr): Type
281288
return new ObjectWithoutClassType();
282289
}
283290

284-
return $this->accessoryNonEmptyStringTypeCorrector->correct($type);
291+
return $this->correctType($type);
285292
}
286293

287294
return $this->resolveNativeUnionType($type);

0 commit comments

Comments
 (0)