You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
At this time, it has not yet been decided what the minimum supported PHP version will be for PHPCS 5.0, though it will be PHP 7.2 or higher (as PHP 7.2 is the new minimum supported PHP version for PHCPS 4.0).
PHP 7.2 allows for:
Adding parameter type declarations, with the exception of union/intersection/DNF/mixed types.
Adding return type declarations, with the exception of union/intersection/DNF/mixed types.
Null/true/false as in union types or as stand-alone types (PHP 8.0/8/2)
Parameter type declarations in PHP are contravariant, which means that overloaded methods in child classes can widen the type.
Return type declarations in PHP are covariant, which means that overloaded methods in child classes can make the type more narrow.
Full support for contravariance and covariance was only added in PHP 7.4.
Proposal
I propose to add return type declarations to the public/protected methods in PHPCS 5.0 as per the list below - providing the minimum PHP version will allow for it (to be decided and discussed in a separate issue).
If any of the signature changes can not be made yet due to the minimum PHP version not allowing for it (yet), those changes (and only those) will move to the first major release which has the required minimum PHP version.
Detailed proposal
Notes about the detailed proposal:
Signatures of private methods methods are excluded from the below list as they don't affect the public API, but these will be updated too.
Methods for which no legal return type can be added, have been left out of the list.
Methods which will need to be updated by extension and do not deviate from the change to the "parent" method, are not listed repetitively.
The return types have largely been based on the currently documented types, which may not be correct (in which case the type will be changed to the real type).
The list is based on the current state of the codebase and is subject to change.
In PHP_CodeSniffer\Config:
public function __get(...): mixed (* PHP 8.0+)
public function __set(...): void
public function __isset(...): bool
public function __unset(...): void
public function getSettings(): array
public function setSettings(...): void
public function setCommandLineValues(...): void
public function restoreDefaults(): void
public function processShortArgument(...): void
public function processLongArgument(...): void
public function processUnknownArgument(...): void
public function processFilePath(...): void
public function printUsage(): void
public function printPHPCSUsage(): void
public function printPHPCBFUsage(): void
public static function getConfigData(...): ?string
public static function getExecutablePath(...): ?string
public function findPrevious(...): int|false (* PHP 8.0+)
public function findNext(...): int|false (* PHP 8.0+)
public function findStartOfStatement(...): int
public function findEndOfStatement(...): int
public function findFirstOnLine(...): int|false (* PHP 8.0+)
public function hasCondition(...): bool
public function getCondition(...): int|false (* PHP 8.0+)
public function findExtendedClassName(...): string|false (* PHP 8.0+)
public function findImplementedInterfaceNames(...): array|false (* PHP 8.0+)
In PHP_CodeSniffer\Files\DummyFile:
public function setErrorCounts(...): void
In PHP_CodeSniffer\Files\FileList:
public function addFile(...): void
public function rewind(): void
public function current(): \PHP_CodeSniffer\Files\File
public function key(): ?string
public function next(): void
public function valid(): bool
public function count(): int
In PHP_CodeSniffer\Filters\Filter:
public function accept(): bool
public function getChildren(): \RecursiveIterator
protected function shouldProcessFile(...): bool
protected function shouldIgnorePath(...): bool
In PHP_CodeSniffer\Filters\ExactMatch:
abstract protected function getDisallowedFiles(): array
abstract protected function getAllowedFiles(): array
In PHP_CodeSniffer\Filters\Git*:
protected function exec(...): array
In PHP_CodeSniffer\Generators\Generator:
protected function getTitle(...): string
public function generate(): void
abstract protected function processSniff(...): void
In PHP_CodeSniffer\Generators\*:
All methods will get the void return type.
In PHP_CodeSniffer\Reports\Report:
public function generateFileReport(...): bool
public function generate(...): void
In PHP_CodeSniffer\Sniffs\Sniff:
public function register(): array
Note: the public function process(...) method will not get a return type as int|void is an illegal type, even in PHP 8.0+ and ?int is incompatible with a child class having a void return type. Classes implementing the interface can still add a return type if the type returned from their implementation is consistently void or int.
In PHP_CodeSniffer\Sniffs\AbstractArraySniff:
public function process(...): void
abstract protected function processSingleLineArray(...): void
abstract protected function processMultiLineArray(...): void
In PHP_CodeSniffer\Sniffs\AbstractPatternSniff:
final public function process(...): void
protected function processPattern(...): array|false (* PHP 8.0+)
protected function prepareError(...): string
abstract protected function getPatterns(): array
protected function registerSupplementary(): array
protected function processSupplementary(...): void
In PHP_CodeSniffer\Sniffs\AbstractScopeSniff:
abstract protected function processTokenWithinScope(...): ?int
abstract protected function processTokenOutsideScope(...): ?int
In PHP_CodeSniffer\Sniffs\DeprecatedSniff:
public function getDeprecationVersion(): string
public function getRemovalVersion(): string
public function getDeprecationMessage(): string
In PHP_CodeSniffer\Tokenizers\Tokenizer:
protected function isMinifiedContent(...): bool
public function getTokens(): array
abstract protected function tokenize(...): array
abstract protected function processAdditional(): void
public function replaceTabsInToken(...): void
In PHP_CodeSniffer\Tokenizers\Comment:
public function tokenizeString(...): array
In PHP_CodeSniffer\Tokenizers\PHP:
public static function standardiseToken(...): array
public static function resolveSimpleToken(...): array
In PHP_CodeSniffer\Util\Cache:
public static function load(...): void
public static function save(): void
public static function get(...): mixed (* PHP 8.0+)
public static function set(...): void
public static function getSize(): int
In PHP_CodeSniffer\Util\Common:
public static function isPharFile(...): bool
public static function isReadable(...): bool
public static function realpath(...): string|false (* PHP 8.0+)
public static function stripBasepath(...): string
public static function detectLineEndings(...): string
public static function isStdinATTY(): bool
public static function escapeshellcmd(...): string
public static function prepareForOutput(...): string
public static function isCamelCaps(...): bool
public static function isUnderscoreName(...): bool
public static function suggestType(...): string
public static function getSniffCode(...): string
public static function cleanSniffClass(...): string
In PHP_CodeSniffer\Util\Standards:
public static function getInstalledStandardPaths(): array
public static function getInstalledStandardDetails(...): array
public static function getInstalledStandards(...): array
public static function isInstalledStandard(...): bool
public static function getInstalledStandardPath(...): ?string
public static function printInstalledStandards(): void
In PHP_CodeSniffer\Util\Timing:
public static function startTiming(): void
public static function getDuration(): float
public static function getHumanReadableDuration(...): string
public static function printRunTime(...): void
In PHP_CodeSniffer\Util\Tokens:
public static function tokenName(...): string
public static function getHighestWeightedToken(...): int|false (* PHP 8.0+)
In PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest:
protected function getTestFiles(...): array
protected function shouldSkipTest(): bool
public function setCliValues(...): void
protected function getErrorList(): array
protected function getWarningList(): array
[*] The above list may still receive some updates over time. If/when updates are made, a comment will be left in the thread detailing the updates which were made.
New methods
Any new methods being introduced to PHPCS during the lifetime of the 4.x major should be considered outside the scope of this issue and can get a return type declaration at their introduction, providing the minimum PHP version allows for it.
New methods which need a type not yet supported via the current minimum PHP version should be added to the list above.
BC considerations
As return types are covariant, adding these type declarations in PHPCS 5.0 constitutes a backward compatibility break as the method signature of overloaded/implemented methods MUST be updated to include a compatible return type declaration.
Suggested Migration Path for External Standards
During the lifetime of PHPCS 4.x, external standards are encouraged to:
Add return type declarations to their code, in line with the above proposal
Add strict_types=1 declarations to their files.
Use tooling like PHPStan and/or Psalm to find further type juggling issues.
None of this can/will be enforced, but external standards using the lifetime of PHPCS 4.x to action the above will be better prepared for supporting PHPCS 5.x when the time comes.
This sounds great! You mentioned private methods, what about final classes and methods? Should they benefit from return type declarations on 3.x already?
This sounds great! You mentioned private methods, what about final classes and methods? Should they benefit from return type declarations on 3.x already?
@greg0ire 3.x has a PHP 5.4 minimum, so that's a no-go. As for 4.x, I'd have to see, though there's enough to do for 4.0 already, so I think it might be better to leave it till 5.0.
Setting the scene
At this time, it has not yet been decided what the minimum supported PHP version will be for PHPCS 5.0, though it will be PHP 7.2 or higher (as PHP 7.2 is the new minimum supported PHP version for PHCPS 4.0).
PHP 7.2 allows for:
PHP 7.2 does not support:
Parameter type declarations in PHP are contravariant, which means that overloaded methods in child classes can widen the type.
Return type declarations in PHP are covariant, which means that overloaded methods in child classes can make the type more narrow.
Full support for contravariance and covariance was only added in PHP 7.4.
Proposal
I propose to add return type declarations to the public/protected methods in PHPCS 5.0 as per the list below - providing the minimum PHP version will allow for it (to be decided and discussed in a separate issue).
If any of the signature changes can not be made yet due to the minimum PHP version not allowing for it (yet), those changes (and only those) will move to the first major release which has the required minimum PHP version.
Detailed proposal
Notes about the detailed proposal:
private
methods methods are excluded from the below list as they don't affect the public API, but these will be updated too.In
PHP_CodeSniffer\Config
:public function __get(...): mixed
(* PHP 8.0+)public function __set(...): void
public function __isset(...): bool
public function __unset(...): void
public function getSettings(): array
public function setSettings(...): void
public function setCommandLineValues(...): void
public function restoreDefaults(): void
public function processShortArgument(...): void
public function processLongArgument(...): void
public function processUnknownArgument(...): void
public function processFilePath(...): void
public function printUsage(): void
public function printPHPCSUsage(): void
public function printPHPCBFUsage(): void
public static function getConfigData(...): ?string
public static function getExecutablePath(...): ?string
public function setConfigData(...): bool
public static function getAllConfigData(): array
public function printConfigData(...): void
In
PHP_CodeSniffer\Fixer
:public function startFile(...): void
public function fixFile(): bool
public function generateDiff(...): string
public function getFixCount(): int
public function getContents(): string
public function getTokenContent(...): string
public function endChangeset(): ?
(under discussion, see Ensure that Fixer::endChangeset() returns the real outcome #375)public function rollbackChangeset(): void
public function replaceToken(...): bool
public function revertToken(...): bool
public function substrToken(...): bool
public function addNewline(...): bool
public function addNewlineBefore(...): bool
public function addContent(...): bool
public function addContentBefore(...): bool
public function changeCodeBlockIndent(...): void
In
PHP_CodeSniffer\Reporter
:public function printReports(): bool
public function printReport(...): void
public function cacheFileReport(...): void
public function prepareFileReport(...): array
In
PHP_CodeSniffer\Ruleset
:public function explain(): void
public function hasSniffDeprecations(): bool
public function showSniffDeprecations(): void
public function processRuleset(...): array
public function registerSniffs(...): void
public function populateTokenListeners(): void
public function setSniffProperty(...): void
public function getIgnorePatterns(...): array
public function getIncludePatterns(...): array
In
PHP_CodeSniffer\Runner
:public function runPHPCS(): int
public function runPHPCBF(): int
public function checkRequirements(): void
public function init(): void
public function handleErrors(...): bool
public function processFile(...): void
public function printProgress(...): void
In
PHP_CodeSniffer\Files\File
:public function setContent(): void
public function reloadContent(): void
public function disableCaching(): void
public function process(): void
public function parse(): void
public function getTokens(): array
public function cleanUp(): void
public function addError(...): bool
public function addWarning(...): bool
public function addErrorOnLine(...): bool
public function addWarningOnLine(...): bool
public function addFixableError(...): bool
public function addFixableWarning(...): bool
protected function addMessage(...): bool
public function recordMetric(...): bool
public function getErrorCount(): int
public function getWarningCount(): int
public function getFixableCount(): int
public function getFixedCount(): int
public function getIgnoredLines(): array
public function getErrors(): array
public function getWarnings(): array
public function getMetrics(): array
public function getListenerTimes(): array
public function getFilename(): string
public function getDeclarationName(...): ?string
public function getMethodParameters(...): array
public function getMethodProperties(...): array
public function getMemberProperties(...): array
public function getClassProperties(...): array
public function isReference(...): bool
public function getTokensAsString(...): string
public function findPrevious(...): int|false
(* PHP 8.0+)public function findNext(...): int|false
(* PHP 8.0+)public function findStartOfStatement(...): int
public function findEndOfStatement(...): int
public function findFirstOnLine(...): int|false
(* PHP 8.0+)public function hasCondition(...): bool
public function getCondition(...): int|false
(* PHP 8.0+)public function findExtendedClassName(...): string|false
(* PHP 8.0+)public function findImplementedInterfaceNames(...): array|false
(* PHP 8.0+)In
PHP_CodeSniffer\Files\DummyFile
:public function setErrorCounts(...): void
In
PHP_CodeSniffer\Files\FileList
:public function addFile(...): void
public function rewind(): void
public function current(): \PHP_CodeSniffer\Files\File
public function key(): ?string
public function next(): void
public function valid(): bool
public function count(): int
In
PHP_CodeSniffer\Filters\Filter
:public function accept(): bool
public function getChildren(): \RecursiveIterator
protected function shouldProcessFile(...): bool
protected function shouldIgnorePath(...): bool
In
PHP_CodeSniffer\Filters\ExactMatch
:abstract protected function getDisallowedFiles(): array
abstract protected function getAllowedFiles(): array
In
PHP_CodeSniffer\Filters\Git*
:protected function exec(...): array
In
PHP_CodeSniffer\Generators\Generator
:protected function getTitle(...): string
public function generate(): void
abstract protected function processSniff(...): void
In
PHP_CodeSniffer\Generators\*
:All methods will get the
void
return type.In
PHP_CodeSniffer\Reports\Report
:public function generateFileReport(...): bool
public function generate(...): void
In
PHP_CodeSniffer\Sniffs\Sniff
:public function register(): array
Note: the
public function process(...)
method will not get a return type asint|void
is an illegal type, even in PHP 8.0+ and?int
is incompatible with a child class having avoid
return type.Classes implementing the interface can still add a return type if the type returned from their implementation is consistently
void
orint
.In
PHP_CodeSniffer\Sniffs\AbstractArraySniff
:public function process(...): void
abstract protected function processSingleLineArray(...): void
abstract protected function processMultiLineArray(...): void
In
PHP_CodeSniffer\Sniffs\AbstractPatternSniff
:final public function process(...): void
protected function processPattern(...): array|false
(* PHP 8.0+)protected function prepareError(...): string
abstract protected function getPatterns(): array
protected function registerSupplementary(): array
protected function processSupplementary(...): void
In
PHP_CodeSniffer\Sniffs\AbstractScopeSniff
:abstract protected function processTokenWithinScope(...): ?int
abstract protected function processTokenOutsideScope(...): ?int
In
PHP_CodeSniffer\Sniffs\DeprecatedSniff
:public function getDeprecationVersion(): string
public function getRemovalVersion(): string
public function getDeprecationMessage(): string
In
PHP_CodeSniffer\Tokenizers\Tokenizer
:protected function isMinifiedContent(...): bool
public function getTokens(): array
abstract protected function tokenize(...): array
abstract protected function processAdditional(): void
public function replaceTabsInToken(...): void
In
PHP_CodeSniffer\Tokenizers\Comment
:public function tokenizeString(...): array
In
PHP_CodeSniffer\Tokenizers\PHP
:public static function standardiseToken(...): array
public static function resolveSimpleToken(...): array
In
PHP_CodeSniffer\Util\Cache
:public static function load(...): void
public static function save(): void
public static function get(...): mixed
(* PHP 8.0+)public static function set(...): void
public static function getSize(): int
In
PHP_CodeSniffer\Util\Common
:public static function isPharFile(...): bool
public static function isReadable(...): bool
public static function realpath(...): string|false
(* PHP 8.0+)public static function stripBasepath(...): string
public static function detectLineEndings(...): string
public static function isStdinATTY(): bool
public static function escapeshellcmd(...): string
public static function prepareForOutput(...): string
public static function isCamelCaps(...): bool
public static function isUnderscoreName(...): bool
public static function suggestType(...): string
public static function getSniffCode(...): string
public static function cleanSniffClass(...): string
In
PHP_CodeSniffer\Util\Standards
:public static function getInstalledStandardPaths(): array
public static function getInstalledStandardDetails(...): array
public static function getInstalledStandards(...): array
public static function isInstalledStandard(...): bool
public static function getInstalledStandardPath(...): ?string
public static function printInstalledStandards(): void
In
PHP_CodeSniffer\Util\Timing
:public static function startTiming(): void
public static function getDuration(): float
public static function getHumanReadableDuration(...): string
public static function printRunTime(...): void
In
PHP_CodeSniffer\Util\Tokens
:public static function tokenName(...): string
public static function getHighestWeightedToken(...): int|false
(* PHP 8.0+)In
PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest
:protected function getTestFiles(...): array
protected function shouldSkipTest(): bool
public function setCliValues(...): void
protected function getErrorList(): array
protected function getWarningList(): array
[*] The above list may still receive some updates over time. If/when updates are made, a comment will be left in the thread detailing the updates which were made.
New methods
Any new methods being introduced to PHPCS during the lifetime of the 4.x major should be considered outside the scope of this issue and can get a return type declaration at their introduction, providing the minimum PHP version allows for it.
New methods which need a type not yet supported via the current minimum PHP version should be added to the list above.
BC considerations
As return types are covariant, adding these type declarations in PHPCS 5.0 constitutes a backward compatibility break as the method signature of overloaded/implemented methods MUST be updated to include a compatible return type declaration.
Suggested Migration Path for External Standards
During the lifetime of PHPCS 4.x, external standards are encouraged to:
strict_types=1
declarations to their files.None of this can/will be enforced, but external standards using the lifetime of PHPCS 4.x to action the above will be better prepared for supporting PHPCS 5.x when the time comes.
Opinions ?
/cc @asispts @dingo-d @fredden @GaryJones @greg0ire @kukulich @michalbundyra @Ocramius @sirbrillig @stronk7 @weierophinney @wimg
The text was updated successfully, but these errors were encountered: