Skip to content

Commit

Permalink
[TypeDeclaration] Skip use return docblock on typed intersection type (
Browse files Browse the repository at this point in the history
…#1728)

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Jan 26, 2022
1 parent 64d76cd commit a26c59a
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,23 @@

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;
}

Expand All @@ -38,12 +33,6 @@ public function correct(Type $mainType): Type | IntersectionType
return $clearIntersectionedTypes[0];
}

$countIntersectionTypes = count($mainType->getTypes());
$countClearIntersectionedTypes = count($clearIntersectionedTypes);
if ($countIntersectionTypes === $countClearIntersectionedTypes) {
return $mainType;
}

return new IntersectionType($clearIntersectionedTypes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function mapToPhpParserNode(Type $type, TypeKind $typeKind): ?Node
}

$resolvedTypeName = (string) $resolvedType;
if ($resolvedTypeName === 'string') {
if (in_array($resolvedTypeName, ['string', 'object'], true)) {
return $resolvedType;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;
Expand Down Expand Up @@ -60,9 +61,9 @@ public function getNodeTypes(): array
*/
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;
}

Expand Down
5 changes: 3 additions & 2 deletions rules/TypeDeclaration/PhpParserTypeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PhpParser\Node\ComplexType;
use PhpParser\Node\Identifier;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\UnionType;
Expand All @@ -19,7 +20,7 @@ public function __construct(
}

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
Expand All @@ -45,7 +46,7 @@ public function isCovariantSubtypeOf(
}

private function isUnionType(
Identifier|Name|NullableType|UnionType $possibleSubtype,
Identifier|Name|NullableType|UnionType|IntersectionType $possibleSubtype,
ComplexType|Identifier|Name $possibleParentType
): bool {
if ($possibleSubtype instanceof UnionType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PhpParser\Node;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Class_;
Expand Down Expand Up @@ -202,7 +203,7 @@ private function shouldSkipExistingReturnType(ClassMethod | Function_ $functionL

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;
Expand Down

0 comments on commit a26c59a

Please sign in to comment.