🫙

Rectorを使って返す型にvoidを付ける

2025/02/24に公開

はじめに

返す値がない時にvoidを指定するが、
未指定のメソッドに対して1つ1つ手作業でつけるのはたいへん面倒なので一括でつけるルールがRectorにあるか調べたら...

あった!!、まさかの2つ!!

  • AddVoidReturnTypeWhereNoReturnRector
  • AddTestsVoidReturnTypeWhereNoReturnRector

そこでこの記事で2つを試してみることにした。

環境

  • PHP 8.4.4

ルール

まずは2つのルールの違いを調べる。

AddTestsVoidReturnTypeWhereNoReturnRectorを使うのはテストクラスとテストクラス以外のクラスが同じディレクトリ(tests配下)に共存している場合にテストクラスのみに対象を絞りたい時に使うのかな?

今回はAddVoidReturnTypeWhereNoReturnRectorを使えばvoidを付ける目的は達成できるから使うのは1つで問題はなさそう。

試す

以降は実際にRectorを使って修正するまでを試してみる。

インストール

READMEに書かれている手順でインストールする。

composer require rector/rector --dev

インストール後に下記のコマンドを実行してバージョンを確認してみる。

vendor/bin/rector --version

% ./vendor/bin/rector --version
Rector 2.0.9

この記事を書いている時点でのバージョンは2.0.9です。

Rectorの初期化

まずは設定ファイルのrector.phpを作るためにvendor/bin/rectorコマンドを実行する。
実行すると、rector.phpがないと言われるので、yesと入力し作成する。

% ./vendor/bin/rector

 No "rector.php" config found. Should we generate it for you? [yes]:
 > yes


 [OK] The config is added now. Re-run command to make Rector do the work!

作成したrector.phpをつぎのように書き換える。

<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector;

return RectorConfig::configure()
    ->withPaths([
        __DIR__ . '/src',
        __DIR__ . '/tests',
    ])
    ->withRules([
        AddVoidReturnTypeWhereNoReturnRector::class,
    ]);

実行

適当に用意した下記のサンプルコードに対して実行してみます。

src/A.php
<?php

class A {
    public function test()
    {
        return;
    }
}
tests/ATest.php
<?php

class ATest extends \PHPUnit\Framework\TestCase
{
    public function test()
    {
        $this->assertSame(1, 1);
    }
}

実行は下記のコマンドを使う。

vendor/bin/rector process --dry-run

まずは--dry-runを付けることで修正されるか確認してみる。
検査対象のディレクトリはrector.phpに書いたので省略する。

% vendor/bin/rector process --dry-run
 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
2 files with changes
====================

1) src/A.php:0

    ---------- begin diff ----------
@@ @@
 <?php

 class A {
-    public function test()
+    public function test(): void
     {
         return;
     }
    ----------- end diff -----------

Applied rules:
 * AddVoidReturnTypeWhereNoReturnRector


2) tests/ATest.php:1

    ---------- begin diff ----------
@@ @@

 class ATest extends \PHPUnit\Framework\TestCase
 {
-    public function test()
+    public function test(): void
     {
         $this->assertSame(1, 1);
     }
    ----------- end diff -----------

Applied rules:
 * AddVoidReturnTypeWhereNoReturnRector

 [OK] 2 files would have been changed (dry-run) by Rector

想定通りの結果なら--dry-runなしで実行し、修正を適用する。

% vendor/bin/rector process
 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
2 files with changes
====================

1) src/A.php:0

    ---------- begin diff ----------
@@ @@
 <?php

 class A {
-    public function test()
+    public function test(): void
     {
         return;
     }
    ----------- end diff -----------

Applied rules:
 * AddVoidReturnTypeWhereNoReturnRector


2) tests/ATest.php:1

    ---------- begin diff ----------
@@ @@

 class ATest extends \PHPUnit\Framework\TestCase
 {
-    public function test()
+    public function test(): void
     {
         $this->assertSame(1, 1);
     }
    ----------- end diff -----------

Applied rules:
 * AddVoidReturnTypeWhereNoReturnRector

 [OK] 2 files have been changed by Rector

修正が適用されていればvendor/bin/rector processを再度実行すると対象は無しになっています。

% vendor/bin/rector process
 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 [OK] Rector is done!

これで大丈夫です、修正済み、メソッドにvoidが付いていますね。

まとめ

Rectorを使えば1つ1つ手作業を行う必要もなく一括で対応することができます。
今回はvoidを付けるを試しましたが別のルールではPHPDocの内容をもとに引数の型や返す型を設定もできるので活用してみるもの良いかもしれないです。

GitHubで編集を提案

Discussion