Skip to content

experiment: remove shouldSkipCurrentNode guard - #8589

Closed
TomasVotruba wants to merge 1 commit into
mainfrom
experiment-remove-skip-current-node
Closed

TomasVotruba wants to merge 1 commit into
mainfrom
experiment-remove-skip-current-node

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Experiment: what breaks if we remove the shouldSkipCurrentNode guard?

Removed from RectorRunner::run():

// node already changed by this rule in a previous pass -> hard skip
if ($this->skipper->shouldSkipCurrentNode($rector::class, $node)) {
    return null;
}

Result

ChangeSwitchTernaryTest fails:

ShouldNotHappenException: Scope not available on "PhpParser\Node\Stmt\Expression" node.
Fix scope refresh on changed nodes first   (ScopeFetcher.php:26)

Why

The guard delegates to RectifiedAnalyzer::hasRectified(), which covers two cases:

  1. consecutive CREATED_BY_RULE - same rule re-applies to a node it just created (infinite re-apply loop).
  2. just-reprinted node with overlapping token start and no refreshed scope.

Case 2 is the one that breaks. When a rule reprints a node (switch -> match here), the new Expression node has no scope yet. The guard skips it before refactor(). Without the guard, a rule subscribing to that node runs, calls ScopeFetcher::fetch() on a scopeless node, and throws.

tests/Issues/ChangeSwitchTernary exists precisely to pin this behavior.

Alternatives to handle it differently

  • Refresh scope on reprinted nodes before running rules (so ScopeFetcher never sees a scopeless node) - heavier, defeats the skip's purpose.
  • Split the two concerns into separate explicit checks - clarity only, same work.

Current guard is the cheapest correct approach. Draft - not for merge, demonstrates the finding.

Drops the hard skip that bails out before refactor() when a node was
already rectified by the same rule or just reprinted without a refreshed
scope.

Breaks ChangeSwitchTernaryTest: a rule firing on a freshly reprinted
Expression node hits ScopeFetcher::fetch() on a scopeless node and
throws 'Scope not available'. The guard was the safety net for that
case (and for consecutive CREATED_BY_RULE re-application loops).
@TomasVotruba
TomasVotruba deleted the experiment-remove-skip-current-node branch October 10, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant