Rector Documentation

repository·main·Indexed 27 days ago

https://github.com/rectorphp/rector

Rector is a tool for instant PHP upgrades and automated refactoring, supporting PHP versions from 5.3 to 8.5 and major frameworks like Symfony, PHPUnit, and Doctrine. It provides capabilities for continuous code quality improvement, custom rule creation via the `custom-rule` command, and CI integration for GitHub Actions and GitLab CI. The tool operates on an Abstract Syntax Tree (AST) and includes commands for processing code, listing active rules, and debugging AST nodes.

Tokens
2.8K
Snippets
9
Records
21
Agent score
95%

What's inside Rector

  1. Upgrade requirements for Rector 2.0

    main

    When upgrading to Rector 2.0, ensure your environment meets the following requirements:

    • PHP Version: Requires PHP 7.4 or newer.
    • PHP-Parser: Rector now uses PHP-Parser 5.
    • PHPStan: Rector now uses PHPStan 2.
  2. Migrate from FileWithoutNamespace to FileNode (Rector 2.3+)

    main

    In Rector 2.3, FileWithoutNamespace is deprecated and replaced by FileNode. FileNode represents both namespaced and non-namespaced files. Additionally, beforeTraverse() is now @final; instead of using beforeTraverse(), you should include FileNode::class in your getNodeTypes() array to perform file-level operations.

    use Rector\PhpParser\Node\FileNode;
    use Rector\Rector\AbstractRector;
    
    final class SomeRector extends AbstractRector
    {
        public function getNodeTypes(): array
        {
            return [FileNode::class];
        }
    
        /**
         * @param FileNode $node
         */
        public function refactor(Node $node): ?Node
        {
            foreach ($node->stmts as $stmt) {
                // ...
            }
    
            return $node;
        }
    }
  3. Configure Rector in rector.php

    main

    To use Rector, create a rector.php file in your project root. You can register individual rules using withRules() and apply predefined rule sets using withPreparedSets() (e.g., deadCode or codeQuality).

    use Rector\Config\RectorConfig;
    use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;
    
    return RectorConfig::configure()
        // register single rule
        ->withRules([
            TypedPropertyFromStrictConstructorRector::class
        ])
        // here we can define, what prepared sets of rules will be applied
        ->withPreparedSets(
            deadCode: true,
            codeQuality: true
        );
  4. Handle namespaced and non-namespaced files with FileNode

    main

    When using FileNode to modify file contents, you can handle both namespaced and non-namespaced files by hooking into both FileNode::class and PhpParser\Node\Stmt\Namespace_::class. Use isNamespaced() to determine if the file has a namespace to avoid redundant processing.

    use Rector\PhpParser\Node\FileNode;
    use Rector\Rector\AbstractRector;
    use PhpParser\Node\Stmt\Namespace_;
    
    final class SomeRector extends AbstractRector
    {
        public function getNodeTypes(): array
        {
            return [FileNode::class, Namespace_::class];
        }
    
        /**
         * @param FileNode|Namespace_ $node
         */
        public function refactor(Node $node): ?Node
        {
            if ($node instanceof FileNode && $node->isNamespaced()) {
                // handled in the Namespace_ node
                return null;
            }
    
            foreach ($node->stmts as $stmt) {
                // modify stmts in desired way here
            }
    
            return $node;
        }
    }
  5. Remove getRuleDefinition() from custom rules (Rector 2.0+)

    main
    The getRuleDefinition() method has been removed from AbstractRector in Rector 2.0. Custom rules no longer require this method for documentation. If you need to document your rule, use a standard PHP docblock above the class.
  6. Remove SetListInterface from custom sets (Rector 2.0+)

    main

    The SetListInterface was removed in Rector 2.0. If you have custom rule sets, simply remove the implementation of the interface from your class.

    // Before
    use Rector\Set\Contract\SetListInterface;
    final class YourSetList implements SetListInterface
    
    // After
    final class YourSetList
  7. Debug AST nodes with print_node()

    main

    Rector provides a print_node() helper function to pretty-print AST nodes as PHP code, which is useful for debugging custom rules.

    use PhpParser\Node\Scalar\String_;
    $node = new String_('hello world!');
    
    // prints node to string as PHP code displays it
    print_node($node);
  8. Replace AbstractScopeAwareRector with AbstractRector (Rector 2.0+)

    main

    In Rector 2.0, Rector\Rector\AbstractScopeAwareRector has been removed. Custom rules should now extend AbstractRector. To access the Scope object, use Rector\PHPStan\ScopeFetcher::fetch($node) inside the refactor() method.

    use Rector\Rector\AbstractRector;
    use Rector\PHPStan\ScopeFetcher;
    
    final class SimpleRector extends AbstractRector
    {
        public function refactor(Node $node): ?Node
        {
            if (...) {
                // this allow to fetch scope only when needed
                $scope = ScopeFetcher::fetch($node);
            }
    
            // ...
        }
    }
  9. Run Rector dry run or apply changes

    main
    Run Rector against a directory. Use the --dry-run flag to see a diff of what would change without actually modifying files. To apply the changes to your code, run the command without the --dry-run flag.