Skip to content

Commit

Permalink
Make ReturnNeverTypeRector work with type declaration, add it to PHP …
Browse files Browse the repository at this point in the history
…8.1 set (#3852)
  • Loading branch information
TomasVotruba committed May 14, 2023
1 parent 7a32610 commit 7f49261
Show file tree
Hide file tree
Showing 17 changed files with 57 additions and 313 deletions.
6 changes: 2 additions & 4 deletions build/target-repository/docs/rector_rules_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -9357,10 +9357,8 @@ Add "never" return-type for methods that never return anything
```diff
final class SomeClass
{
+ /**
+ * @return never
+ */
public function run()
- public function run()
+ public function run(): never
{
throw new InvalidException();
}
Expand Down
27 changes: 15 additions & 12 deletions config/set/php81.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(ReturnNeverTypeRector::class);
$rectorConfig->rule(MyCLabsClassToEnumRector::class);
$rectorConfig->rule(MyCLabsMethodCallToEnumConstRector::class);
$rectorConfig->rule(FinalizePublicClassConstantRector::class);
$rectorConfig->rule(ReadOnlyPropertyRector::class);
$rectorConfig->rule(SpatieEnumClassToEnumRector::class);
$rectorConfig->rule(SpatieEnumMethodCallToEnumConstRector::class);
$rectorConfig->rule(Php81ResourceReturnToObjectRector::class);
$rectorConfig->rule(NewInInitializerRector::class);
$rectorConfig->rule(IntersectionTypesRector::class);
$rectorConfig->rule(NullToStrictStringFuncCallArgRector::class);
$rectorConfig->rule(FirstClassCallableRector::class);
$rectorConfig->rules([
ReturnNeverTypeRector::class,
MyCLabsClassToEnumRector::class,
MyCLabsMethodCallToEnumConstRector::class,
FinalizePublicClassConstantRector::class,
ReadOnlyPropertyRector::class,
SpatieEnumClassToEnumRector::class,
SpatieEnumMethodCallToEnumConstRector::class,
Php81ResourceReturnToObjectRector::class,
NewInInitializerRector::class,
IntersectionTypesRector::class,
NullToStrictStringFuncCallArgRector::class,
FirstClassCallableRector::class,
ReturnNeverTypeRector::class,
]);
};
1 change: 0 additions & 1 deletion packages/Testing/PHPUnit/AbstractTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Kernel\RectorKernel;
use Rector\Core\Util\FileHasher;
use Webmozart\Assert\Assert;

abstract class AbstractTestCase extends TestCase
{
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

30 changes: 9 additions & 21 deletions rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
use PhpParser\Node\Stmt\Return_;
use PhpParser\Node\Stmt\Throw_;
use PHPStan\Type\NeverType;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeNestingScope\ValueObject\ControlStructure;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

Expand All @@ -29,12 +28,10 @@
*
* @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector\ReturnNeverTypeRectorTest
*/
final class ReturnNeverTypeRector extends AbstractRector
final class ReturnNeverTypeRector extends AbstractRector implements MinPhpVersionInterface
{
public function __construct(
private readonly ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard,
private readonly PhpDocTypeChanger $phpDocTypeChanger,
private readonly PhpVersionProvider $phpVersionProvider,
) {
}

Expand All @@ -56,10 +53,7 @@ public function run()
<<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @return never
*/
public function run()
public function run(): never
{
throw new InvalidException();
}
Expand All @@ -86,22 +80,16 @@ public function refactor(Node $node): ?Node
return null;
}

if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::NEVER_TYPE)) {
// never-type supported natively
$node->returnType = new Identifier('never');
} else {
// static anlysis based never type
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$hasChanged = $this->phpDocTypeChanger->changeReturnType($phpDocInfo, new NeverType());

if (! $hasChanged) {
return null;
}
}
$node->returnType = new Identifier('never');

return $node;
}

public function provideMinPhpVersion(): int
{
return PhpVersionFeature::NEVER_TYPE;
}

private function shouldSkip(ClassMethod | Function_ | Closure $node): bool
{
$hasReturn = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($node, Return_::class);
Expand Down

0 comments on commit 7f49261

Please sign in to comment.