From c2c6423fdb6e427725fd9bce533504c1f2c34fed Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Fri, 13 Sep 2024 17:26:02 +0300 Subject: [PATCH 01/14] CORE-2120 Removed the dependency on AbstractFixer because it is internal, some refactoring because of this. Fixed the situation when there was a wrong indent in closures. --- .../SplittingInSeveralLinesFixer.php | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index fd5e7cf..2874ddd 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -12,25 +12,25 @@ use Paysera\PhpCsFixerConfig\Parser\Entity\ItemInterface; use Paysera\PhpCsFixerConfig\Parser\Parser; use Paysera\PhpCsFixerConfig\Parser\Entity\SeparatedItemList; -use PhpCsFixer\AbstractFixer; use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Tokenizer\Tokens; +use PhpCsFixer\WhitespacesFixerConfig; use SplFileInfo; -final class SplittingInSeveralLinesFixer extends AbstractFixer implements WhitespacesAwareFixerInterface +final class SplittingInSeveralLinesFixer implements WhitespacesAwareFixerInterface { private Parser $parser; private ContextualTokenBuilder $contextualTokenBuilder; + private WhitespacesFixerConfig $whitespacesConfig; public function __construct() { - parent::__construct(); - $this->parser = new Parser(new GroupSeparatorHelper()); $this->contextualTokenBuilder = new ContextualTokenBuilder(); + $this->whitespacesConfig = new WhitespacesFixerConfig(' ', "\n"); } public function getDefinition(): FixerDefinitionInterface @@ -95,7 +95,22 @@ public function isCandidate(Tokens $tokens): bool return true; } - protected function applyFix(SplFileInfo $file, Tokens $tokens): void + public function isRisky(): bool + { + return false; + } + + public function supports(SplFileInfo $file): bool + { + return true; + } + + public function setWhitespacesConfig(WhitespacesFixerConfig $config): void + { + $this->whitespacesConfig = $config; + } + + public function fix(SplFileInfo $file, Tokens $tokens): void { $startEndTokens = [ '=' => ';', @@ -110,10 +125,12 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void do { foreach ($startEndTokens as $startValue => $endValue) { if ($token->getContent() === $startValue) { - $groupedItem = $this->parser->parseUntil($token, $endValue); - $this->fixWhitespaceForItem($groupedItem); + if ($token->getContent() === '(' && $token->getNextToken()->getContent() !== 'function') { // closure situation + $groupedItem = $this->parser->parseUntil($token, $endValue); + $this->fixWhitespaceForItem($groupedItem); - $token = $groupedItem->lastToken(); + $token = $groupedItem->lastToken(); + } } } @@ -123,7 +140,7 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void $this->contextualTokenBuilder->overrideTokens($tokens, $firstToken); } - private function fixWhitespaceForItem(ItemInterface $groupedItem) + private function fixWhitespaceForItem(ItemInterface $groupedItem): void { $standardIndent = $this->whitespacesConfig->getIndent(); @@ -159,7 +176,7 @@ private function fixWhitespaceForItem(ItemInterface $groupedItem) } } - private function ensureContentForPrefixWhitespace(ComplexItemList $itemList, string $content) + private function ensureContentForPrefixWhitespace(ComplexItemList $itemList, string $content): void { $prefixWhitespaceItem = $itemList->getFirstPrefixWhitespaceItem(); @@ -202,7 +219,7 @@ private function ensureContentForPrefixWhitespace(ComplexItemList $itemList, str } } - private function ensureContentForPostfixWhitespace(ComplexItemList $itemList, string $content) + private function ensureContentForPostfixWhitespace(ComplexItemList $itemList, string $content): void { $postfixWhitespaceItem = $itemList->getFirstPostfixWhitespaceItem(); @@ -238,7 +255,7 @@ private function ensureContentForPostfixWhitespace(ComplexItemList $itemList, st } } - private function fixSeparators(SeparatedItemList $itemList, string $indent) + private function fixSeparators(SeparatedItemList $itemList, string $indent): void { $separator = $itemList->getSeparator(); @@ -275,7 +292,7 @@ private function isItemListUnsupported(ComplexItemList $itemList): bool ); } - private function fixWhitespaceBefore(ItemInterface $item, ?string $whitespaceBefore, bool $forceWhitespace) + private function fixWhitespaceBefore(ItemInterface $item, ?string $whitespaceBefore, bool $forceWhitespace): void { $firstToken = $item->firstToken(); if ($firstToken->isWhitespace()) { @@ -295,7 +312,7 @@ private function fixWhitespaceAfter(ItemInterface $item, ?string $whitespaceAfte } } - private function replaceWithIfNeeded(ContextualToken $token, string $replacement = null) + private function replaceWithIfNeeded(ContextualToken $token, string $replacement = null): void { if ($replacement === null) { $token->previousToken()->setNextContextualToken($token->getNextToken()); @@ -313,9 +330,9 @@ private function replaceWithIfNeeded(ContextualToken $token, string $replacement private function hasExtraLinesWithCorrectEnding(string $current, string $replacement): bool { return ( - substr($replacement, 0, 1) === "\n" - && substr($current, 0, 1) === "\n" - && substr($current, -strlen($replacement)) === $replacement + str_starts_with($replacement, "\n") + && str_starts_with($current, "\n") + && str_ends_with($current, $replacement) ); } } From 0fcce536446b610a226626ba4216c12bd989f2c9 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Fri, 13 Sep 2024 17:29:04 +0300 Subject: [PATCH 02/14] CORE-2120 wrong config file name in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7105af..e72f809 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ You can look at `.travis.yml` file in this repository for integration with travi Run in project directory by command: `{your-bin-dir}/php-cs-fixer fix /path/to/code --verbose --dry-run --diff` -Use `--config=.php-cs-fixer.php` flag for custom configuration. +Use `--config=php-cs-fixer.php` flag for custom configuration. If `/path/to/code` is not defined `php-cs-fixer` will run files from default `src` directory excluding `Test` folders. From c484878e330fcf89932a4522139d2feb1eecb571 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Tue, 17 Sep 2024 13:36:03 +0300 Subject: [PATCH 03/14] CORE-2120 str_starts_with available only for php 8+. --- .../PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index 2874ddd..19217e9 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -330,9 +330,9 @@ private function replaceWithIfNeeded(ContextualToken $token, string $replacement private function hasExtraLinesWithCorrectEnding(string $current, string $replacement): bool { return ( - str_starts_with($replacement, "\n") - && str_starts_with($current, "\n") - && str_ends_with($current, $replacement) + substr($replacement, 0, 1) === "\n" + && substr($current, 0, 1) === "\n" + && substr($current, -strlen($replacement)) === $replacement ); } } From 2572a2ce24e856c10178d8a1051c2342534724e2 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Wed, 18 Sep 2024 17:49:55 +0300 Subject: [PATCH 04/14] CORE-2120 1. VisibilityPropertiesFixer has been changed to properly detect variables declared in the __constructor.Some other refactoring of fixer. 2.DefaultValuesInConstructorFixer priority changed to work wright with VisibilityPropertiesFixer. 3.SplittingInSeveralLinesFixer was refactored to handle situations with splitting lines in closures and functions parameters, including parameters in __constructor. 4. Some code style changes. --- .../DefaultValuesInConstructorFixer.php | 7 ++ .../PhpBasic/CodeStyle/MethodNamingFixer.php | 59 +++++++------ .../SplittingInSeveralLinesFixer.php | 52 ++++++------ .../Feature/VisibilityPropertiesFixer.php | 83 +++++++++++-------- 4 files changed, 115 insertions(+), 86 deletions(-) diff --git a/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php b/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php index 4db01f6..ed0cfe7 100644 --- a/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php @@ -54,6 +54,12 @@ public function getName(): string return 'Paysera/php_basic_code_style_default_values_in_constructor'; } + public function getPriority(): int + { + // Should run after `VisibilityPropertiesFixer` + return 61; + } + public function isCandidate(Tokens $tokens): bool { return $tokens->isAnyTokenKindsFound([T_CLASS]); @@ -88,6 +94,7 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void $token->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) && !$tokens[$subsequentDeclarativeToken]->isGivenKind(T_STATIC) && !$tokens[$subsequentDeclarativeToken]->isGivenKind(T_FUNCTION) + && !$tokens[$subsequentDeclarativeToken]->isGivenKind(T_READONLY) ) { $propertyNameIndex = $tokens->getNextNonWhitespace($key); $endOfPropertyDeclarationSemicolon = $tokens->getNextTokenOfKind($key, [';']); diff --git a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php index be944c9..435380d 100644 --- a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php @@ -94,36 +94,41 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void $functionTokenIndex = $tokens->getPrevNonWhitespace($key); $visibilityTokenIndex = $functionTokenIndex ? $tokens->getPrevNonWhitespace($functionTokenIndex) : null; - if ($functionTokenIndex && $visibilityTokenIndex) { - if ( - $token->isGivenKind(T_STRING) - && $tokens[$key + 1]->equals('(') - && $tokens[$functionTokenIndex]->isGivenKind(T_FUNCTION) - && $tokens[$visibilityTokenIndex]->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) - ) { - $functionName = $tokens[$key]->getContent(); - $parenthesesEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $key + 1); - $nextIndex = $tokens->getNextMeaningfulToken($parenthesesEndIndex); - - $returnType = null; - if ($tokens[$nextIndex]->isGivenKind(CT::T_TYPE_COLON)) { - $typeIndex = $tokens->getNextMeaningfulToken($nextIndex); - $returnType = $tokens[$typeIndex]->getContent(); - $nextIndex = $tokens->getNextMeaningfulToken($typeIndex); - } - - if (!$tokens[$nextIndex]->equals('{')) { - continue; - } - - $this->fixMethod($tokens, $functionName, $visibilityTokenIndex, $nextIndex, $returnType); + if ( + $functionTokenIndex + && $visibilityTokenIndex + && $token->isGivenKind(T_STRING) + && $tokens[$key + 1]->equals('(') + && $tokens[$functionTokenIndex]->isGivenKind(T_FUNCTION) + && $tokens[$visibilityTokenIndex]->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) + ) { + $functionName = $tokens[$key]->getContent(); + $parenthesesEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $key + 1); + $nextIndex = $tokens->getNextMeaningfulToken($parenthesesEndIndex); + + $returnType = null; + if ($tokens[$nextIndex]->isGivenKind(CT::T_TYPE_COLON)) { + $typeIndex = $tokens->getNextMeaningfulToken($nextIndex); + $returnType = $tokens[$typeIndex]->getContent(); + $nextIndex = $tokens->getNextMeaningfulToken($typeIndex); } + + if (!$tokens[$nextIndex]->equals('{')) { + continue; + } + + $this->fixMethod($tokens, $functionName, $visibilityTokenIndex, $nextIndex, $returnType); } } } - private function fixMethod(Tokens $tokens, $functionName, $visibilityTokenIndex, $curlyBraceStartIndex, $returnType) - { + private function fixMethod( + Tokens $tokens, + $functionName, + $visibilityTokenIndex, + $curlyBraceStartIndex, + $returnType, + ): void { $index = $tokens->getPrevNonWhitespace($visibilityTokenIndex); $docBlockIndex = null; if ($tokens[$index]->isGivenKind(T_DOC_COMMENT)) { @@ -133,7 +138,7 @@ private function fixMethod(Tokens $tokens, $functionName, $visibilityTokenIndex, } $shouldReturnBool = preg_match( - '#^(?:' . implode('|', $this->boolFunctionPrefixes) . ')[A-Z]#', + '#^(' . implode('|', $this->boolFunctionPrefixes) . ')[A-Z]#', $functionName, ); @@ -167,7 +172,7 @@ private function hasFunctionReturnClause(Tokens $tokens, int $curlyBraceStartInd return false; } - private function insertComment(Tokens $tokens, int $insertIndex) + private function insertComment(Tokens $tokens, int $insertIndex): void { $comment = '// TODO: ' . self::BOOL_FUNCTION_COMMENT; if (!$tokens[$tokens->getNextNonWhitespace($insertIndex)]->isGivenKind(T_COMMENT)) { diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index 19217e9..a8d09aa 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -12,25 +12,25 @@ use Paysera\PhpCsFixerConfig\Parser\Entity\ItemInterface; use Paysera\PhpCsFixerConfig\Parser\Parser; use Paysera\PhpCsFixerConfig\Parser\Entity\SeparatedItemList; +use PhpCsFixer\AbstractFixer; use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Tokenizer\Tokens; -use PhpCsFixer\WhitespacesFixerConfig; use SplFileInfo; -final class SplittingInSeveralLinesFixer implements WhitespacesAwareFixerInterface +final class SplittingInSeveralLinesFixer extends AbstractFixer implements WhitespacesAwareFixerInterface { private Parser $parser; private ContextualTokenBuilder $contextualTokenBuilder; - private WhitespacesFixerConfig $whitespacesConfig; public function __construct() { + parent::__construct(); + $this->parser = new Parser(new GroupSeparatorHelper()); $this->contextualTokenBuilder = new ContextualTokenBuilder(); - $this->whitespacesConfig = new WhitespacesFixerConfig(' ', "\n"); } public function getDefinition(): FixerDefinitionInterface @@ -95,22 +95,7 @@ public function isCandidate(Tokens $tokens): bool return true; } - public function isRisky(): bool - { - return false; - } - - public function supports(SplFileInfo $file): bool - { - return true; - } - - public function setWhitespacesConfig(WhitespacesFixerConfig $config): void - { - $this->whitespacesConfig = $config; - } - - public function fix(SplFileInfo $file, Tokens $tokens): void + protected function applyFix(SplFileInfo $file, Tokens $tokens): void { $startEndTokens = [ '=' => ';', @@ -125,12 +110,29 @@ public function fix(SplFileInfo $file, Tokens $tokens): void do { foreach ($startEndTokens as $startValue => $endValue) { if ($token->getContent() === $startValue) { - if ($token->getContent() === '(' && $token->getNextToken()->getContent() !== 'function') { // closure situation - $groupedItem = $this->parser->parseUntil($token, $endValue); - $this->fixWhitespaceForItem($groupedItem); - - $token = $groupedItem->lastToken(); + // closure situation + if ($token->getContent() === '(') { + if ($token->nextNonWhitespaceToken()->getContent() === 'function') { + continue; + } + + if ( + $token + ->previousNonWhitespaceToken() + ->previousNonWhitespaceToken() + ->getContent() === 'function' + ) { + $groupedItem = $this->parser->parseUntil($token, $endValue); + $token = $groupedItem->lastToken(); + + continue; + } } + + $groupedItem = $this->parser->parseUntil($token, $endValue); + $this->fixWhitespaceForItem($groupedItem); + + $token = $groupedItem->lastToken(); } } diff --git a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php index 110e775..df73a0a 100644 --- a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php +++ b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php @@ -23,6 +23,7 @@ final class VisibilityPropertiesFixer extends AbstractFixer implements Whitespac use ConfigurableFixerTrait { configure as public configureConfigurableFixerTrait; } + public const DYNAMIC_PROPERTIES_CONVENTION = 'PhpBasic convention 3.14.1: We avoid dynamic properties'; public const PUBLIC_PROPERTIES_CONVENTION = 'PhpBasic convention 3.14.1: We don’t use public properties'; public const PROTECTED_PROPERTIES_CONVENTION = 'PhpBasic convention 3.14.2: We prefer use private over protected properties'; @@ -128,15 +129,16 @@ public function configure(array $configuration = null): void protected function createConfigurationDefinition(): FixerConfigurationResolver { return - new FixerConfigurationResolver([ - (new FixerOptionBuilder( - 'excluded_parents', - 'Allows to set Parent class names where in children Classes it is allowed to use public or protected properties', - )) - ->setAllowedTypes(['array', 'bool']) - ->getOption(), - ]) - ; + new FixerConfigurationResolver( + [ + (new FixerOptionBuilder( + 'excluded_parents', + 'Allows to set Parent class names where in children Classes it is allowed to use public or protected properties', + )) + ->setAllowedTypes(['array', 'bool']) + ->getOption(), + ], + ); } protected function applyFix(SplFileInfo $file, Tokens $tokens): void @@ -195,7 +197,7 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void ) { $this->insertComment( $tokens, - $tokens->getNextTokenOfKind($key, [';']), + $key, $tokens[$key]->getContent(), self::DYNAMIC_PROPERTIES_CONVENTION, ); @@ -227,8 +229,8 @@ private function validateNotDefinedProperties( int $key, array $propertyVariables, string $propertyName, - string $classNamespace - ) { + string $classNamespace, + ): void { $variable = '$' . $propertyName; if ( !in_array($variable, $propertyVariables, true) @@ -258,30 +260,38 @@ private function isPropertyInAnotherClass(string $variableName, ?string $classNa private function getPropertyVariable(Tokens $tokens, int $key, bool $propertyExclusion): ?string { - $previousTokenIndex = $tokens->getPrevMeaningfulToken($key); - $previousPreviousTokenIndex = $tokens->getPrevMeaningfulToken($previousTokenIndex); - if ( - $tokens[$previousTokenIndex]->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) - || ( - $tokens[$previousTokenIndex]->isGivenKind(T_STATIC) - && $tokens[$previousPreviousTokenIndex]->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) - ) - ) { + /** @var array $previousTokens */ + $index = $key; + + for ($i = 0; $i < 4; $i++) { + $previousTokenIndex = $tokens->getPrevMeaningfulToken($index); + $previousTokens[] = $tokens[$previousTokenIndex]; + $index = $previousTokenIndex; + } + + $visibilityToken = null; + + foreach ($previousTokens as $previousToken) { + if ($previousToken->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE, 10028, 10029, 10030])) { + $visibilityToken = $previousToken; + break; + } + + if ($previousToken->isGivenKind(T_FUNCTION)) { + break; + } + } + + if ($visibilityToken !== null) { if ( - ( - $tokens[$previousTokenIndex]->isGivenKind(T_PUBLIC) - || $tokens[$previousPreviousTokenIndex]->isGivenKind(T_PUBLIC) - ) + $visibilityToken->isGivenKind([T_PUBLIC, 10028]) && !$propertyExclusion ) { $this->insertVariablePropertyWarning($tokens, $key, self::PUBLIC_PROPERTIES_CONVENTION); } if ( - ( - $tokens[$previousTokenIndex]->isGivenKind(T_PROTECTED) - || $tokens[$previousPreviousTokenIndex]->isGivenKind(T_PROTECTED) - ) + $visibilityToken->isGivenKind([T_PROTECTED, 10029]) && !$propertyExclusion ) { $this->insertVariablePropertyWarning($tokens, $key, self::PROTECTED_PROPERTIES_CONVENTION); @@ -293,22 +303,27 @@ private function getPropertyVariable(Tokens $tokens, int $key, bool $propertyExc return null; } - private function insertVariablePropertyWarning(Tokens $tokens, int $key, string $convention) + private function insertVariablePropertyWarning(Tokens $tokens, int $key, string $convention): void { $this->insertComment( $tokens, - $tokens->getNextTokenOfKind($key, [';']), + $key, $tokens[$key]->getContent(), $convention, ); } - private function insertComment(Tokens $tokens, int $insertIndex, string $propertyName, string $convention) + private function insertComment(Tokens $tokens, int $insertIndex, string $propertyName, string $convention): void { $comment = '// TODO: "' . $propertyName . '" - ' . $convention; - if (!$tokens[$tokens->getNextNonWhitespace($insertIndex)]->isGivenKind(T_COMMENT)) { + + do { + $token = $tokens[$insertIndex++]; + } while (!substr_count($token->getContent(), "\n")); + + if (!$tokens[$tokens->getNextNonWhitespace($insertIndex - 3)]->isGivenKind(T_COMMENT)) { $tokens->insertSlices([ - ++$insertIndex => [ + $insertIndex - 1 => [ new Token([T_WHITESPACE, ' ']), new Token([T_COMMENT, $comment]), ], From 27aa5a8402657a0d7068db2e48cbf593e12d0cf2 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Wed, 18 Sep 2024 18:02:47 +0300 Subject: [PATCH 05/14] CORE-2120 1. Minimum PHP version has been changed to 8.1. 2. friendsofphp/php-cs-fixer` minor update to version 3.64.0 3. Dependencies update (phpunit) 4. Modified the `download-phar.sh` script to download the latest PHAR file. 5. VisibilityPropertiesFixer has been changed to properly detect variables declared in the __constructor.Some other refactoring of fixer. 6.DefaultValuesInConstructorFixer priority changed to work wright with VisibilityPropertiesFixer. 7.SplittingInSeveralLinesFixer was refactored to handle situations with splitting lines in closures and functions parameters, including parameters in __constructor. 8. Some code style changes. 9. Some PHP 8 functions used instead of old functions (str_starts_with, str_contains). --- CHANGELOG.md | 18 ++++++++++++++++++ composer.json | 6 +++--- download-phar.sh | 2 +- paysera-php-cs-fixer | Bin 3197245 -> 3229161 bytes src/Fixer/IgnorableFixerDecorator.php | 2 +- .../PhpBasic/CodeStyle/MethodNamingFixer.php | 7 +++---- .../SplittingInSeveralLinesFixer.php | 6 +++--- 7 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee522e5..297fe9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,24 @@ Semantic Versioning is maintained only for the following: The fixers themselves can change their behavior on any update. New fixers could be added with minor releases, this would require changes in configuration if migration mode is used. +## 3.0.1 + +### Changed +- Minimum PHP version has been changed to 8.1. + +- friendsofphp/php-cs-fixer` minor update to version 3.64.0 + +- Dependencies update (phpunit) + +- Modified the `download-phar.sh` script to download the latest PHAR file. + +- VisibilityPropertiesFixer has been changed to properly detect variables declared in the __constructor.Some other refactoring of fixer. + +- DefaultValuesInConstructorFixer priority changed to work wright with VisibilityPropertiesFixer. + +- SplittingInSeveralLinesFixer was refactored to handle situations with splitting lines in closures and functions parameters, including parameters in __constructor. + + ## 3.0.0 ### Changed diff --git a/composer.json b/composer.json index 29aa65a..e3f4356 100644 --- a/composer.json +++ b/composer.json @@ -3,12 +3,12 @@ "description": "PHP CS Fixer config for Paysera conventions", "type": "library", "require": { - "php": ">=7.4", + "php": "^8.1", "doctrine/inflector": "^1.0 || ^2.0" }, "require-dev": { - "phpunit/phpunit": "^6.0 || ^7.0 || ^8.0 || ^9.0", - "friendsofphp/php-cs-fixer": "3.60.0", + "phpunit/phpunit": "^9.3.0", + "friendsofphp/php-cs-fixer": "3.64.0", "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2" }, "autoload": { diff --git a/download-phar.sh b/download-phar.sh index 7a19100..56dcf56 100644 --- a/download-phar.sh +++ b/download-phar.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -curl -L https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v3.60.0/php-cs-fixer.phar -o paysera-php-cs-fixer +curl -L https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v3.64.0/php-cs-fixer.phar -o paysera-php-cs-fixer chmod +x paysera-php-cs-fixer diff --git a/paysera-php-cs-fixer b/paysera-php-cs-fixer index df1a6a2d2dc9cb4624995f31b66a77ad0a11f501..d071fa55254133a98b0d25ada192ece10420ef95 100755 GIT binary patch delta 40489 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 delta 17581 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 diff --git a/src/Fixer/IgnorableFixerDecorator.php b/src/Fixer/IgnorableFixerDecorator.php index 34cce92..320b2ee 100644 --- a/src/Fixer/IgnorableFixerDecorator.php +++ b/src/Fixer/IgnorableFixerDecorator.php @@ -67,7 +67,7 @@ public function fix(SplFileInfo $file, Tokens $tokens): void { $ignoreNotice = self::IGNORE_ANNOTATION . ' ' . $this->getName(); $contents = $tokens->generateCode(); - if (strpos($contents, $ignoreNotice) !== false) { + if (str_contains($contents, $ignoreNotice)) { return; } diff --git a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php index 435380d..31c8493 100644 --- a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php @@ -17,10 +17,9 @@ final class MethodNamingFixer extends AbstractFixer { public const BOOL_FUNCTION_COMMENT = 'Question-type functions always return boolean (https://bit.ly/psg-methods)'; - private array $boolFunctionPrefixes; - - public function __construct() - { + public function __construct( + private array $boolFunctionPrefixes = [], + ) { parent::__construct(); $this->boolFunctionPrefixes = [ diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index a8d09aa..cec4b48 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -332,9 +332,9 @@ private function replaceWithIfNeeded(ContextualToken $token, string $replacement private function hasExtraLinesWithCorrectEnding(string $current, string $replacement): bool { return ( - substr($replacement, 0, 1) === "\n" - && substr($current, 0, 1) === "\n" - && substr($current, -strlen($replacement)) === $replacement + str_starts_with($replacement, "\n") + && str_starts_with($current, "\n") + && str_ends_with($current, $replacement) ); } } From 8370ad5bf23738d1b2cb14aa535a76c6629e93e4 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Mon, 30 Sep 2024 17:56:23 +0300 Subject: [PATCH 06/14] CORE-2120 empty lines not needed in changelog list --- CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 297fe9a..b359ca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,20 +15,13 @@ New fixers could be added with minor releases, this would require changes in con ### Changed - Minimum PHP version has been changed to 8.1. - - friendsofphp/php-cs-fixer` minor update to version 3.64.0 - - Dependencies update (phpunit) - - Modified the `download-phar.sh` script to download the latest PHAR file. - - VisibilityPropertiesFixer has been changed to properly detect variables declared in the __constructor.Some other refactoring of fixer. - - DefaultValuesInConstructorFixer priority changed to work wright with VisibilityPropertiesFixer. - - SplittingInSeveralLinesFixer was refactored to handle situations with splitting lines in closures and functions parameters, including parameters in __constructor. - ## 3.0.0 ### Changed From 31dd5cf46cb3ca05a7b96d757910d45e8cb66a74 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Tue, 1 Oct 2024 14:09:56 +0300 Subject: [PATCH 07/14] CORE-2120 Support PHP 7.4; Refactor code style Added PHP 7.4 support in composer.json and improved compatibility. Refactored code to replace PHP 8 string functions with older equivalents and restructured some methods for better maintainability. --- composer.json | 2 +- src/Fixer/IgnorableFixerDecorator.php | 2 +- .../CodeStyle/DefaultValuesInConstructorFixer.php | 11 ++++++++--- src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php | 8 ++++---- .../CodeStyle/SplittingInSeveralLinesFixer.php | 6 +++--- .../PhpBasic/Feature/VisibilityPropertiesFixer.php | 2 +- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index e3f4356..15b14cc 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "PHP CS Fixer config for Paysera conventions", "type": "library", "require": { - "php": "^8.1", + "php": "^7.4 || ^8.1", "doctrine/inflector": "^1.0 || ^2.0" }, "require-dev": { diff --git a/src/Fixer/IgnorableFixerDecorator.php b/src/Fixer/IgnorableFixerDecorator.php index 320b2ee..34cce92 100644 --- a/src/Fixer/IgnorableFixerDecorator.php +++ b/src/Fixer/IgnorableFixerDecorator.php @@ -67,7 +67,7 @@ public function fix(SplFileInfo $file, Tokens $tokens): void { $ignoreNotice = self::IGNORE_ANNOTATION . ' ' . $this->getName(); $contents = $tokens->generateCode(); - if (str_contains($contents, $ignoreNotice)) { + if (strpos($contents, $ignoreNotice) !== false) { return; } diff --git a/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php b/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php index ed0cfe7..7280611 100644 --- a/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php @@ -90,11 +90,16 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void $parentConstructNeeded = true; } $subsequentDeclarativeToken = $tokens->getNextMeaningfulToken($key); + + // PHP 7.4 support + $tokenKinds = [T_STATIC, T_FUNCTION]; + if (defined('T_READONLY')) { + $tokenKinds[] = T_READONLY; + } + if ( $token->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) - && !$tokens[$subsequentDeclarativeToken]->isGivenKind(T_STATIC) - && !$tokens[$subsequentDeclarativeToken]->isGivenKind(T_FUNCTION) - && !$tokens[$subsequentDeclarativeToken]->isGivenKind(T_READONLY) + && !$tokens[$subsequentDeclarativeToken]->isGivenKind($tokenKinds) ) { $propertyNameIndex = $tokens->getNextNonWhitespace($key); $endOfPropertyDeclarationSemicolon = $tokens->getNextTokenOfKind($key, [';']); diff --git a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php index 31c8493..3b81ff4 100644 --- a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php @@ -17,9 +17,9 @@ final class MethodNamingFixer extends AbstractFixer { public const BOOL_FUNCTION_COMMENT = 'Question-type functions always return boolean (https://bit.ly/psg-methods)'; - public function __construct( - private array $boolFunctionPrefixes = [], - ) { + private array $boolFunctionPrefixes; + + public function __construct() { parent::__construct(); $this->boolFunctionPrefixes = [ @@ -126,7 +126,7 @@ private function fixMethod( $functionName, $visibilityTokenIndex, $curlyBraceStartIndex, - $returnType, + $returnType ): void { $index = $tokens->getPrevNonWhitespace($visibilityTokenIndex); $docBlockIndex = null; diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index cec4b48..a8d09aa 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -332,9 +332,9 @@ private function replaceWithIfNeeded(ContextualToken $token, string $replacement private function hasExtraLinesWithCorrectEnding(string $current, string $replacement): bool { return ( - str_starts_with($replacement, "\n") - && str_starts_with($current, "\n") - && str_ends_with($current, $replacement) + substr($replacement, 0, 1) === "\n" + && substr($current, 0, 1) === "\n" + && substr($current, -strlen($replacement)) === $replacement ); } } diff --git a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php index df73a0a..adce499 100644 --- a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php +++ b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php @@ -229,7 +229,7 @@ private function validateNotDefinedProperties( int $key, array $propertyVariables, string $propertyName, - string $classNamespace, + string $classNamespace ): void { $variable = '$' . $propertyName; if ( From d6a19acb72e9ff8911522f909f1805de9624dde8 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Tue, 1 Oct 2024 14:16:55 +0300 Subject: [PATCH 08/14] CORE-2120 Refactor visibility token extraction into a separate method Extracted the visibility token logic from the main method into a dedicated private method `getVisibilityToken`. This improves code readability and reusability by encapsulating the visibility token extraction in a single location. --- .../Feature/VisibilityPropertiesFixer.php | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php index adce499..58b11a0 100644 --- a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php +++ b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php @@ -269,18 +269,7 @@ private function getPropertyVariable(Tokens $tokens, int $key, bool $propertyExc $index = $previousTokenIndex; } - $visibilityToken = null; - - foreach ($previousTokens as $previousToken) { - if ($previousToken->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE, 10028, 10029, 10030])) { - $visibilityToken = $previousToken; - break; - } - - if ($previousToken->isGivenKind(T_FUNCTION)) { - break; - } - } + $visibilityToken = $this->getVisibilityToken($previousTokens); if ($visibilityToken !== null) { if ( @@ -330,4 +319,26 @@ private function insertComment(Tokens $tokens, int $insertIndex, string $propert ]); } } + + /** + * @param array $previousTokens + * @return Token|null + */ + private function getVisibilityToken(array $previousTokens): ?Token + { + $visibilityToken = null; + + foreach ($previousTokens as $previousToken) { + if ($previousToken->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE, 10028, 10029, 10030])) { + $visibilityToken = $previousToken; + break; + } + + if ($previousToken->isGivenKind(T_FUNCTION)) { + break; + } + } + + return $visibilityToken; + } } From 8f6081561b59b42d74720b69c4024032b4f1fb2f Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Tue, 1 Oct 2024 14:24:19 +0300 Subject: [PATCH 09/14] CORE-2120 --- .../PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php b/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php index 7280611..d541f97 100644 --- a/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/DefaultValuesInConstructorFixer.php @@ -91,7 +91,7 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void } $subsequentDeclarativeToken = $tokens->getNextMeaningfulToken($key); - // PHP 7.4 support + // @TODO: PHP 7.4 support, drop condition when there will be no PHP 7.4 support. $tokenKinds = [T_STATIC, T_FUNCTION]; if (defined('T_READONLY')) { $tokenKinds[] = T_READONLY; From 1c9009961f8c5256be47264638f0326fc2e9fefa Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Tue, 1 Oct 2024 14:27:34 +0300 Subject: [PATCH 10/14] CORE-2120 CHANGELOG.md fixed --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b359ca2..23c1ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ New fixers could be added with minor releases, this would require changes in con ## 3.0.1 ### Changed -- Minimum PHP version has been changed to 8.1. - friendsofphp/php-cs-fixer` minor update to version 3.64.0 - Dependencies update (phpunit) - Modified the `download-phar.sh` script to download the latest PHAR file. From 5271a90d7822991d4262a439009e5a8a51785472 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Wed, 2 Oct 2024 16:20:22 +0300 Subject: [PATCH 11/14] CORE-2120 Simplify function logic and improve code readability. Refactor `getVisibilityToken` to return early, removing unnecessary variable. Extract closure and function parameter processing logic in `SplittingInSeveralLinesFixer` to a separate method for better modularity. --- .../PhpBasic/CodeStyle/MethodNamingFixer.php | 11 +++-- .../SplittingInSeveralLinesFixer.php | 48 +++++++++++-------- .../Feature/VisibilityPropertiesFixer.php | 9 ++-- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php index 3b81ff4..34c4d55 100644 --- a/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/MethodNamingFixer.php @@ -19,7 +19,8 @@ final class MethodNamingFixer extends AbstractFixer private array $boolFunctionPrefixes; - public function __construct() { + public function __construct() + { parent::__construct(); $this->boolFunctionPrefixes = [ @@ -93,10 +94,12 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void $functionTokenIndex = $tokens->getPrevNonWhitespace($key); $visibilityTokenIndex = $functionTokenIndex ? $tokens->getPrevNonWhitespace($functionTokenIndex) : null; + if ($functionTokenIndex === null || $visibilityTokenIndex === null) { + continue; + } + if ( - $functionTokenIndex - && $visibilityTokenIndex - && $token->isGivenKind(T_STRING) + $token->isGivenKind(T_STRING) && $tokens[$key + 1]->equals('(') && $tokens[$functionTokenIndex]->isGivenKind(T_FUNCTION) && $tokens[$visibilityTokenIndex]->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE]) diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index a8d09aa..fd23504 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -110,29 +110,15 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void do { foreach ($startEndTokens as $startValue => $endValue) { if ($token->getContent() === $startValue) { - // closure situation - if ($token->getContent() === '(') { - if ($token->nextNonWhitespaceToken()->getContent() === 'function') { - continue; - } - - if ( - $token - ->previousNonWhitespaceToken() - ->previousNonWhitespaceToken() - ->getContent() === 'function' - ) { - $groupedItem = $this->parser->parseUntil($token, $endValue); - $token = $groupedItem->lastToken(); - - continue; - } - } + $processResult = $this->processForClosureAndFunctionParameters($token, $endValue); + $token = $processResult ?? $token; - $groupedItem = $this->parser->parseUntil($token, $endValue); - $this->fixWhitespaceForItem($groupedItem); + if ($processResult === null) { + $groupedItem = $this->parser->parseUntil($token, $endValue); + $this->fixWhitespaceForItem($groupedItem); - $token = $groupedItem->lastToken(); + $token = $groupedItem->lastToken(); + } } } @@ -337,4 +323,24 @@ private function hasExtraLinesWithCorrectEnding(string $current, string $replace && substr($current, -strlen($replacement)) === $replacement ); } + + private function processForClosureAndFunctionParameters(ContextualToken $token, string $endValue): ?ContextualToken + { + if ($token->getContent() === '(') { + if ($token->nextNonWhitespaceToken()->getContent() === 'function') { + return null; + } + + if ( + $token + ->previousNonWhitespaceToken() + ->previousNonWhitespaceToken() + ->getContent() === 'function' + ) { + return $this->parser->parseUntil($token, $endValue)->lastToken(); + } + } + + return null; + } } diff --git a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php index 58b11a0..edd9da8 100644 --- a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php +++ b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php @@ -326,19 +326,16 @@ private function insertComment(Tokens $tokens, int $insertIndex, string $propert */ private function getVisibilityToken(array $previousTokens): ?Token { - $visibilityToken = null; - foreach ($previousTokens as $previousToken) { if ($previousToken->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE, 10028, 10029, 10030])) { - $visibilityToken = $previousToken; - break; + return $previousToken; } if ($previousToken->isGivenKind(T_FUNCTION)) { - break; + return null; } } - return $visibilityToken; + return null; } } From 2f6877e850c62cd1b2d676b818421cc1f59a0961 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Wed, 2 Oct 2024 16:42:32 +0300 Subject: [PATCH 12/14] CORE-2120 --- src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php index fd23504..967f97a 100644 --- a/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php +++ b/src/Fixer/PhpBasic/CodeStyle/SplittingInSeveralLinesFixer.php @@ -328,7 +328,7 @@ private function processForClosureAndFunctionParameters(ContextualToken $token, { if ($token->getContent() === '(') { if ($token->nextNonWhitespaceToken()->getContent() === 'function') { - return null; + return $token; } if ( From 8628d502396f9bf80973b3f5d82bb3c9236dfc25 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Wed, 2 Oct 2024 17:09:13 +0300 Subject: [PATCH 13/14] CORE-2120 --- src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php index edd9da8..cc73b6b 100644 --- a/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php +++ b/src/Fixer/PhpBasic/Feature/VisibilityPropertiesFixer.php @@ -321,7 +321,7 @@ private function insertComment(Tokens $tokens, int $insertIndex, string $propert } /** - * @param array $previousTokens + * @param Token[] $previousTokens * @return Token|null */ private function getVisibilityToken(array $previousTokens): ?Token From f9f72da262a2606e2fcde113893037d21fac18b9 Mon Sep 17 00:00:00 2001 From: Viktor Kulahin Date: Thu, 3 Oct 2024 10:58:32 +0300 Subject: [PATCH 14/14] CORE-2120 Update PHP version constraints in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 15b14cc..9434b4d 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "PHP CS Fixer config for Paysera conventions", "type": "library", "require": { - "php": "^7.4 || ^8.1", + "php": ">=7.4 <8.0 || >=8.1", "doctrine/inflector": "^1.0 || ^2.0" }, "require-dev": {