[TypeDeclaration] Skip use return docblock on typed intersection type (#1728)

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Abdul Malik Ikhsan 2022-01-26 18:11:28 +07:00 committed by GitHub
parent 64d76cd11e
commit a26c59a7e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 22 deletions

View File

@ -6,28 +6,23 @@ namespace Rector\NodeTypeResolver\NodeTypeCorrector;
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\Type;
final class AccessoryNonEmptyStringTypeCorrector
{
/**
* @var array<class-string<Type>>
*/
private const INTERSECTION_DISALLOWED_TYPES = [
AccessoryNonEmptyStringType::class,
ObjectWithoutClassType::class,
];
public function correct(Type $mainType): Type | IntersectionType
{
if (! $mainType instanceof IntersectionType) {
return $mainType;
}
if (! $mainType->isSubTypeOf(new AccessoryNonEmptyStringType())->yes()) {
return $mainType;
}
$clearIntersectionedTypes = [];
foreach ($mainType->getTypes() as $intersectionedType) {
if (in_array($intersectionedType::class, self::INTERSECTION_DISALLOWED_TYPES, true)) {
if ($intersectionedType instanceof AccessoryNonEmptyStringType) {
continue;
}
@ -38,12 +33,6 @@ final class AccessoryNonEmptyStringTypeCorrector
return $clearIntersectionedTypes[0];
}
$countIntersectionTypes = count($mainType->getTypes());
$countClearIntersectionedTypes = count($clearIntersectionedTypes);
if ($countIntersectionTypes === $countClearIntersectionedTypes) {
return $mainType;
}
return new IntersectionType($clearIntersectionedTypes);
}
}

View File

@ -85,7 +85,7 @@ final class IntersectionTypeMapper implements TypeMapperInterface
}
$resolvedTypeName = (string) $resolvedType;
if ($resolvedTypeName === 'string') {
if (in_array($resolvedTypeName, ['string', 'object'], true)) {
return $resolvedType;
}

View File

@ -0,0 +1,23 @@
<?php
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\FixtureForPhp81;
use Exception;
final class SkipObjectIntersectionTypeWithReturnDoc
{
/**
* @template T
* @psalm-param class-string<T> $className
* @return string
*/
protected function getObject(string $className): object {
$object = new $className();
if (!$object instanceof $className) {
throw new Exception();
}
return $object;
}
}

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\Php81\Rector\ClassConst;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassConst;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
@ -60,9 +61,9 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$parentClass = $this->betterNodeFinder->findParentType($node, Node\Stmt\Class_::class);
$parentClass = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $parentClass instanceof Node\Stmt\Class_) {
if (! $parentClass instanceof Class_) {
return null;
}

View File

@ -6,6 +6,7 @@ namespace Rector\TypeDeclaration;
use PhpParser\Node\ComplexType;
use PhpParser\Node\Identifier;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\UnionType;
@ -19,7 +20,7 @@ final class PhpParserTypeAnalyzer
}
public function isCovariantSubtypeOf(
Name | NullableType | UnionType | Identifier $possibleSubtype,
Name | NullableType | UnionType | Identifier | IntersectionType $possibleSubtype,
Name | NullableType | UnionType | Identifier | ComplexType $possibleParentType
): bool {
// skip until PHP 8 is out
@ -45,7 +46,7 @@ final class PhpParserTypeAnalyzer
}
private function isUnionType(
Identifier|Name|NullableType|UnionType $possibleSubtype,
Identifier|Name|NullableType|UnionType|IntersectionType $possibleSubtype,
ComplexType|Identifier|Name $possibleParentType
): bool {
if ($possibleSubtype instanceof UnionType) {

View File

@ -6,6 +6,7 @@ namespace Rector\TypeDeclaration\Rector\FunctionLike;
use PhpParser\Node;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Class_;
@ -202,7 +203,7 @@ CODE_SAMPLE
private function addReturnType(
ClassMethod | Function_ $functionLike,
Name|NullableType|\PhpParser\Node\UnionType $inferredReturnNode
Name|NullableType|\PhpParser\Node\UnionType|IntersectionType $inferredReturnNode
): void {
if ($functionLike->returnType === null) {
$functionLike->returnType = $inferredReturnNode;