Skip to content

[dx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel(), introduce ruleWithConfigurationPhpVersionBound() - #8405

Merged
TomasVotruba merged 9 commits into
mainfrom
deprecate-php-set-constants
Aug 29, 2026
Merged

[dx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel(), introduce ruleWithConfigurationPhpVersionBound()#8405
TomasVotruba merged 9 commits into
mainfrom
deprecate-php-set-constants

Conversation

@TomasVotruba

@TomasVotruba TomasVotruba commented Aug 29, 2026

Copy link
Copy Markdown
Member

The per-version PHP set constants SetList::PHP_52SetList::PHP_86 are superseded by withPhpSets() and withPhpLevel(), which resolve the target PHP version automatically. The runtime PhpVersionedFilter already gates every rule by its MinPhpVersionInterface, so the cumulative per-version set selection is redundant.

Changes

  • All 17 SetList::PHP_* constants marked @deprecated, pointing to withPhpSets() / withPhpLevel(). The constants and their config/set/php*.php files stay in place, so this is backward compatible.
  • New config/set/php-version-based.php lists every PHP version rule directly - one rules() call with // PHP x.x comment separators, modeled on rector-symfony composer-based.php. withPhpSets() and withPhpLevel() now load this single set; each rule self-gates by PHP version at runtime.
  • New RectorConfig::ruleWithConfigurationPhpVersionBound($rectorClass, $configuration, $phpVersion), the PHP-version analog of ruleWithConfigurationComposerVersionBound(). Configured rules that span versions (RenameFunctionRector, RemoveFuncCallArgRector, RenameCastRector) register each version's configuration only when the target PHP version is high enough. An explicitly picked withPhpSets(phpXX: true) version is the target, otherwise the project composer.json PHP version.
  • PhpLevelSetResolver removed - the runtime filter does the version gating.
  • PhpVersionedFilter: an explicitly picked withPhpSets(phpXX: true) version now caps all rules at that ceiling (previously only polyfilled rules; the rest were capped by file selection), preserving behavior.

Note

withPhpLevel() uses rule position as its level knob. Collapsing to one set dedups rules that were listed in multiple version files (149 -> 141) and groups configured rules at the end, so a given level number can map to a slightly different rule than before. The runtime filter still prevents any rule above the project PHP version from applying.

@TomasVotruba
TomasVotruba force-pushed the deprecate-php-set-constants branch from 2aacc52 to e936ba0 Compare August 29, 2026 17:49
…evel()

The per-version PHP set constants are superseded by withPhpSets() and
withPhpLevel(), which resolve the target PHP version automatically. Mark
them @deprecated to steer users toward the version-driven API.

Internal resolution (PhpLevelSetResolver, config/set/level, their tests)
still fetches the constants until the single version-driven set replaces
them, so those paths are excluded from the deprecation check.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
… PhpLevelSetResolver

withPhpSets() and withPhpLevel() now load one config/set/php-version-based.php
set that lists every PHP version rule. The runtime PhpVersionedFilter already
gates each rule by MinPhpVersionInterface, so cumulative per-version file
selection is redundant - PhpLevelSetResolver is removed.

An explicitly picked withPhpSets(phpXX: true) version still caps the set: the
ceiling now applies to all rules in PhpVersionedFilter (previously only to
polyfilled ones, the rest were capped by file selection), preserving behavior.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
…rationPhpVersionBound()

The single set now enumerates every PHP version rule in one rules() call with
per-version comment separators, mirroring rector-symfony composer-based.php.

Configured rules that span multiple versions (RenameFunctionRector,
RemoveFuncCallArgRector, RenameCastRector) are registered via the new
RectorConfig::ruleWithConfigurationPhpVersionBound(), which applies a
configuration only when the target PHP version is high enough - mirroring
ruleWithConfigurationComposerVersionBound() for package versions. An explicitly
picked withPhpSets(phpXX) version is the target, otherwise the project
composer.json PHP version is used.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
@TomasVotruba
TomasVotruba force-pushed the deprecate-php-set-constants branch from 6a792b5 to 97661ab Compare August 29, 2026 20:09
@TomasVotruba TomasVotruba changed the title Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel() [dyx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel() Aug 29, 2026
@TomasVotruba TomasVotruba changed the title [dyx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel() [dx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel() Aug 29, 2026
@TomasVotruba
TomasVotruba marked this pull request as ready for review August 29, 2026 20:25
@TomasVotruba
TomasVotruba force-pushed the deprecate-php-set-constants branch from 1f4b1c8 to 130af89 Compare August 29, 2026 20:29
addPhpLevelSets() takes the picked PHP version again (nullable): an explicit
withPhpSets(phpXX) version acts as a ceiling, null keeps composer.json gating
and polyfill package support.

Also fix SetList::PHP_VERSION_BASED_SET path depth - it sits three levels deep
in src/Set/ValueObject, so it needs ../../../ to reach config/set.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
Restore the original non-nullable int signature. The picked-version ceiling is
set in the explicit-pick branch only, so the no-arg case keeps composer.json
gating and polyfill package support.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
…lSets() version arg

withSets() emits an E_USER_DEPRECATED notice when a SetList::PHP_* set file is
passed, pointing to withPhpSets()/withPhpLevel(). Detected by file path, so the
deprecated constants are not referenced internally.

addPhpLevelSets() keeps the non-nullable picked version and stores it; an
explicit withPhpSets(phpXX) version acts as a ceiling via isPhpSetsVersionPicked,
while the composer.json fallback does not, preserving polyfill package support.
Storing the version also keeps the argument used, so it is not stripped as dead.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
@TomasVotruba
TomasVotruba force-pushed the deprecate-php-set-constants branch from 8c4cd3b to 33fa2f9 Compare August 29, 2026 20:58
Replace the trigger_error() deprecation with a SymfonyStyle ->warning() via a
new Notifier::notifyDeprecatedPhpSet(), matching the other withSets/withPhpSets
notifications. Drop the console-output unit test, in line with the untested
Notifier notifications.

Claude-Session: https://claude.ai/code/session_014Q25TQ4b7b13UQQXScu3Fg
@TomasVotruba TomasVotruba changed the title [dx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel() [dx] Deprecate SetList::PHP_* constants in favor of withPhpSets()/withPhpLevel(), introduce ruleWithConfigurationPhpVersionBound() Aug 29, 2026
@TomasVotruba
TomasVotruba merged commit cdfd2b5 into main Aug 29, 2026
44 checks passed
@TomasVotruba
TomasVotruba deleted the deprecate-php-set-constants branch August 29, 2026 21:08
@TomasVotruba

TomasVotruba commented Aug 29, 2026

Copy link
Copy Markdown
Member Author

/cc @calebdw I came up with this one today :) the PHP rules are resolve by php-version, not by sets anymore.
This will make config design so much simpler. Thanks for inspiration

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