Skip to content

Drop support for PHPCS < 4.0#2009

Merged
jrfnl merged 24 commits intodevelopfrom
feature/drop-support-phpcs-3
Nov 30, 2025
Merged

Drop support for PHPCS < 4.0#2009
jrfnl merged 24 commits intodevelopfrom
feature/drop-support-phpcs-3

Conversation

@jrfnl
Copy link
Member

@jrfnl jrfnl commented Nov 30, 2025

Context

PHP 8.5 contains various new syntaxes for which support will only be added to PHP_CodeSniffer 4.0. To detect these with PHPCompatibility, we need to drop support for PHPCS 3.x.

Note: this PR is a best effort to remove PHPCS 3.x specific code, but there may well be additional simplifications which can be made.

Also see:

Changes

Composer: drop support for PHPCS < 4.0

4.x does not retokenize static to T_STRING after instanceof

Classes/NewLateStaticBinding: remove PHPCS 3.x compat code

The static keyword is generally tokenized as T_STATIC. However, in PHPCS 3.x, there was one exception - when static was used in an instanceof static expression, the static keyword was tokenized as T_STRING.

As of PHPCS 4.0, this exception has been removed and static in instanceof static will now also be tokenized as T_STATIC.

This commit removes the code handling the PHPCS 3.x exception.

More tokens are parenthesis owners in PHPCS 4.x

As of PHPCS 4.0, T_USE (for closures), T_ISSET, T_UNSET, T_EMPTY, T_EVAL, T_EXIT are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.

FunctionDeclarations/NewTrailingComma: more tokens are parenthesis owners

FunctionUse/ArgumentFunctionsReportCurrentValue: more tokens are parenthesis owners

LanguageConstructs/NewEmptyNonVariable: more tokens are parenthesis owners

Syntax/NewFirstClassCallables: more tokens are parenthesis owners

Syntax/NewFunctionCallTrailingComma: more tokens are parenthesis owners

Variables/ForbiddenThisUseContexts: more tokens are parenthesis owners

Namespaces names are now tokenized as per PHP 8.0+

As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a T_STRING token is a namespaced name, as if it were, it would be tokenized differently.

This also means we can remove some code which is no longer needed as, for instance, a namespace relative name namespace\something will no longer use the T_NAMESPACE token.

AbstractFunctionCallParameterSniff: minor simplification

MiscHelper::isUseOfGlobalConstant(): minor simplification

TokenGroup::isNumber(): minor simplification

FunctionUse/ArgumentFunctionsReportCurrentValue: minor simplification

FunctionUse/ArgumentFunctionsUsage: minor simplification

FunctionUse/NewFunctions: minor simplification

FunctionUse/RemovedFunctions: minor simplification

InitialValue/NewConstantScalarExpressions: minor simplification

Keywords/ForbiddenNames: minor simplification

Numbers/RemovedHexadecimalNumericStrings: minor simplification

ParameterValues/NewPasswordAlgoConstantValues: minor simplification

Variables/RemovedIndirectModificationOfGlobals: minor simplification

Variables/RemovedImplodeFlexibleParamOrder: minor simplification

T_EXIT now includes the namespace separator (where applicable)

ParameterValues/NewExitAsFunctionCall: minor simplification

As of PHPCS 4.0, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check for a T_NS_SEPARATOR token for a fully qualified call to exit/die, as that will be tokenized as part of the T_EXIT token as of PHPCS 4.0.

Various sniffs: minor simplification

As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check for T_NS_SEPARATOR or T_NAMESPACE tokens when examining names.

The Collections::namespacedNameTokens() token array contains the PHPCS cross-version compatible tokens, while the Collections::nameTokens() token array contains only the tokens we need to take into account for PHPCS 4.x.

Various documentation updates for PHPCS < 4 version drop

jrfnl added 24 commits November 30, 2025 12:27
The `static` keyword is generally tokenized as `T_STATIC`. However, in PHPCS 3.x, there was one exception - when `static` was used in an `instanceof static` expression, the `static` keyword was tokenized as `T_STRING`.

As of PHPCS 4.0, this exception has been removed and `static` in `instanceof static` will now also be tokenized as `T_STATIC`.

This commit removes the code handling the PHPCS 3.x exception.
…ners

As of PHPCS 4.0, `T_USE` (for closures), `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT` are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.
…nthesis owners

As of PHPCS 4.0, `T_USE` (for closures), `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT` are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.
…wners

As of PHPCS 4.0, `T_USE` (for closures), `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT` are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.
As of PHPCS 4.0, `T_USE` (for closures), `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT` are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.
As of PHPCS 4.0, `T_USE` (for closures), `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT` are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.
As of PHPCS 4.0, `T_USE` (for closures), `T_ISSET`, `T_UNSET`, `T_EMPTY`, `T_EVAL`, `T_EXIT` are parenthesis owners, so we don't need to token walk to search for the parenthesis opener/closer anymore, we can just access the token stream array indexes directly.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to skip over a `T_NS_SEPARATOR` token for a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaces names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaces names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaces names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This means we can remove some code which is no longer needed as, for instance, a namespace relative name `namespace\something` will no longer use the `T_NAMESPACE` token.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to skip over a `T_NS_SEPARATOR` token for a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check if a `T_STRING` token is a namespaced name, as if it were, it would be tokenized differently.
As of PHPCS 4.0, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check for a `T_NS_SEPARATOR` token for a fully qualified call to exit/die, as that will be tokenized as part of the `T_EXIT` token as of PHPCS 4.0.
As of PHPCS, namespaced names use the tokenization as per PHP 8.0. This also means that we no longer need to check for `T_NS_SEPARATOR` or `T_NAMESPACE` tokens when examining names.

The `Collections::namespacedNameTokens()` token array contains the PHPCS cross-version compatible tokens, while the `Collections::nameTokens()` token array contains only the tokens we need to take into account for PHPCS 4.x.
@jrfnl jrfnl added this to the 10.0.0-alpha3 milestone Nov 30, 2025
@jrfnl jrfnl requested a review from wimg November 30, 2025 11:41
@jrfnl jrfnl force-pushed the feature/drop-support-phpcs-3 branch from fd41bc6 to fea212a Compare November 30, 2025 11:41
@jrfnl
Copy link
Member Author

jrfnl commented Nov 30, 2025

Note: this PR needs an update of the branch protection. I'll sort that out after it has been approved.

@wimg wimg enabled auto-merge November 30, 2025 12:23
@jrfnl jrfnl disabled auto-merge November 30, 2025 12:37
@jrfnl jrfnl merged commit 8333daf into develop Nov 30, 2025
46 checks passed
@jrfnl jrfnl deleted the feature/drop-support-phpcs-3 branch November 30, 2025 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: breaking change Type: meta Repo strategy/structure related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants