Skip to content

Conversation

@TomasVotruba
Copy link
Member

@TomasVotruba TomasVotruba commented Dec 7, 2025

At the moment, there is no way to handle file-level operations, like adding declare(...) to a file. We hack around this using beforeTraverse(), which is internal part of php-parser and should be avoided.

This PR adds a FileNode to fix that. It allows to make changes directly in refactor() method as it should be 👍

final class DeclareStrictRector extends AbstractRector
{
    public function getNodeTypes(): array
    {
        return [FileNode::class];
    }

   /**
     * @param FileNode $node
     */
    public function refactor(Node $node): ?FileNode
    {
        if ($this->declareStrictTypeFinder->hasDeclareStrictTypes($node)) {
            return null;
        }

        $declaresStrictType = $this->nodeFactory->createDeclaresStrictType();
        $node->stmts = array_merge([$declaresStrictType, new Nop()], $node->stmts);

        return $node;
    }
}

It also opens-up possibility to have a single place to manage use statements (now handled by couple meta services). Next step will be marking beforeTraverse() and afterTraverse() final in AbstractRector, to keep BC promise only for RectorInterface (as it should be from the start).


This PR keeps BC as much as possible and adds reporting about deprecation to in custom rules.

Screenshot From 2025-12-22 11-12-19

Use of FileWithoutNamespace::class node: https://github.com/search?q=%22FileWithoutNamespace%3A%3Aclass%22+NOT+is%3Afork&type=code

Todo

  • add BC layer to make FileWithoutNamespace still work
  • add warning about it's use in getNodeTypes() and explain upgrade path

Related package PRs

@TomasVotruba TomasVotruba changed the title tv rector avoid before traverser Introduce FileNode to handle file-level changes Dec 7, 2025
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch 2 times, most recently from 3af10dd to 4263eff Compare December 7, 2025 11:59
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch 11 times, most recently from 6d9c96d to 652b580 Compare December 8, 2025 23:33
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch 5 times, most recently from ec1edaa to a4b2b44 Compare December 22, 2025 10:09
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch from a4b2b44 to 4af1f44 Compare December 22, 2025 10:24
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch from 41954f4 to 3fc5f1e Compare December 22, 2025 10:29
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch from 3fc5f1e to e53b2fa Compare December 22, 2025 13:04
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch 2 times, most recently from 083efb3 to cbc1c5e Compare December 22, 2025 13:32
@TomasVotruba TomasVotruba force-pushed the tv-rector-avoid-before-traverser branch from 6208ebe to ff771b0 Compare December 22, 2025 15:19
@TomasVotruba
Copy link
Member Author

Let's ship it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants