diff --git a/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php b/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php index dd0ea4a..fa5154e 100644 --- a/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php +++ b/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php @@ -149,7 +149,7 @@ public function process(File $phpcsFile, $stackPtr): void $j = ($i - 1); while (($j >= 0) && ($tokens[$j]['line'] === $current['line'])) { - if (!\in_array($tokens[$j]['code'], PHP_CodeSniffer_Tokens::$emptyTokens, true)) { + if (!\in_array($tokens[$j]['code'], PHP_CodeSniffer_Tokens::EMPTY_TOKENS, true)) { $hasKeyInLine = true; } diff --git a/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php b/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php index bf09656..8d16a4b 100644 --- a/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php +++ b/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php @@ -177,12 +177,13 @@ public function process(File $phpcsFile, $stackPtr): void private function getUseImport(File $phpcsFile, int $stackPtr) { $importTokens = [ - T_NS_SEPARATOR, + T_NAME_FULLY_QUALIFIED, + T_NAME_QUALIFIED, T_STRING, ]; $start = $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + PHP_CodeSniffer_Tokens::EMPTY_TOKENS, ($stackPtr + 1), null, true @@ -238,7 +239,7 @@ private function checkIsNonImportUse(File $phpcsFile, int $stackPtr): bool $tokens = $phpcsFile->getTokens(); $prev = $phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, + PHP_CodeSniffer_Tokens::EMPTY_TOKENS, ($stackPtr - 1), 0, true, diff --git a/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php b/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php index 28620a2..1c186fa 100644 --- a/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php +++ b/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php @@ -42,11 +42,11 @@ class UnnecessaryNamespaceUsageSniff implements Sniff /** * Tokens used in full class name. * - * @var array */ - private $classNameTokens = [ - T_NS_SEPARATOR, - T_STRING, + private const CLASS_NAME_TOKENS = [ + T_NAME_FULLY_QUALIFIED, + T_NAME_QUALIFIED, + T_NAME_RELATIVE, ]; /** @@ -88,7 +88,9 @@ public function process(File $phpcsFile, $stackPtr): void '@var' => 2, ]; $scanTokens = [ - T_NS_SEPARATOR, + T_NAME_FULLY_QUALIFIED, + T_NAME_QUALIFIED, + T_NAME_RELATIVE, T_DOC_COMMENT_OPEN_TAG, ]; @@ -100,17 +102,13 @@ public function process(File $phpcsFile, $stackPtr): void while (false !== $nsSep) { $classNameEnd = (int) $phpcsFile->findNext( - $this->classNameTokens, + self::CLASS_NAME_TOKENS, $nsSep, null, true ); - if (T_NS_SEPARATOR === $tokens[$nsSep]['code']) { - if (T_STRING === $tokens[($nsSep - 1)]['code']) { - --$nsSep; - } - + if (\in_array($tokens[$nsSep]['code'], self::CLASS_NAME_TOKENS, true)) { $className = $phpcsFile->getTokensAsString( $nsSep, ($classNameEnd - $nsSep) @@ -122,7 +120,6 @@ public function process(File $phpcsFile, $stackPtr): void $className, $namespace, $nsSep, - ($classNameEnd - 1) ); } else { // Doc comment block. @@ -193,8 +190,6 @@ public function process(File $phpcsFile, $stackPtr): void $typeToken, $namespace, $docCommentStringPtr, - $docCommentStringPtr, - true ); } } @@ -223,13 +218,13 @@ protected function getUseStatements(File $phpcsFile, int $start, int $end): arra while (false !== $useTokenPtr) { $classNameStart = (int) $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + PHP_CodeSniffer_Tokens::EMPTY_TOKENS, ($useTokenPtr + 1), $end, true ); $classNameEnd = $phpcsFile->findNext( - $this->classNameTokens, + self::CLASS_NAME_TOKENS, ($classNameStart + 1), $end, true @@ -255,7 +250,7 @@ protected function getUseStatements(File $phpcsFile, int $start, int $end): arra /** @var int $aliasNamePtr */ $aliasNamePtr = $phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, + PHP_CodeSniffer_Tokens::EMPTY_TOKENS, ($useEnd - 1), 0, true @@ -264,8 +259,15 @@ protected function getUseStatements(File $phpcsFile, int $start, int $end): arra $length = ($classNameEnd - $classNameStart); $className = $phpcsFile->getTokensAsString($classNameStart, $length); - $className = $this->getFullyQualifiedClassName($className); - $useStatements[$className] = $tokens[$aliasNamePtr]['content']; + $className = $this->getFullyQualifiedClassName($className); + $tokenContent = $tokens[$aliasNamePtr]['content']; + + if (\str_contains($tokenContent, '\\')) { + $path = \explode('\\', $tokenContent); + $tokenContent = $path[\array_key_last($path)]; + } + + $useStatements[$className] = $tokenContent; $i = ($useEnd + 1); $useTokenPtr = T_COMMA === $tokens[$useEnd]['code'] ? $i : $phpcsFile->findNext(T_USE, $i, $end); @@ -287,7 +289,7 @@ protected function getNamespace(File $phpcsFile, int $start, int $end): string { $namespace = (int) $phpcsFile->findNext(T_NAMESPACE, $start, $end); $namespaceStart = $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + PHP_CodeSniffer_Tokens::EMPTY_TOKENS, ($namespace + 1), $end, true @@ -298,7 +300,7 @@ protected function getNamespace(File $phpcsFile, int $start, int $end): string } $namespaceEnd = (int) $phpcsFile->findNext( - $this->classNameTokens, + self::CLASS_NAME_TOKENS, ($namespaceStart + 1), $end, true @@ -330,18 +332,13 @@ private function getFullyQualifiedClassName(string $className): string * @param string $className class name * @param string $namespace name space * @param int $startPtr start token pointer - * @param int $endPtr end token pointer - * @param bool $isDocBlock true if fixing doc block * * @return void */ - private function checkShorthandPossible(File $phpcsFile, array $useStatements, string $className, string $namespace, int $startPtr, int $endPtr, bool $isDocBlock = false): void + private function checkShorthandPossible(File $phpcsFile, array $useStatements, string $className, string $namespace, int $startPtr): void { - $msg = 'Shorthand possible. Replace "%s" with "%s"'; - $code = 'UnnecessaryNamespaceUsage'; - $fixable = false; - $replaceClassName = false; - $replacement = ''; + $msg = 'Shorthand possible. Replace "%s" with "%s"'; + $code = 'UnnecessaryNamespaceUsage'; $fullClassName = $this->getFullyQualifiedClassName($className); @@ -353,50 +350,37 @@ private function checkShorthandPossible(File $phpcsFile, array $useStatements, s $replacement, ]; - $fixable = $phpcsFile->addFixableWarning( + $phpcsFile->addFixableWarning( $msg, $startPtr, $code, $data ); - - $replaceClassName = true; } elseif ('' !== $namespace && \str_starts_with($fullClassName, $namespace)) { $replacement = \substr($fullClassName, \strlen($namespace)); - $data = [ + $data = [ $className, $replacement, ]; - $fixable = $phpcsFile->addFixableWarning( + + $phpcsFile->addFixableWarning( $msg, $startPtr, $code, $data ); - } - - if (true !== $fixable) { + } else { return; } $phpcsFile->fixer->beginChangeset(); - if (true === $isDocBlock) { - $tokens = $phpcsFile->getTokens(); - $oldContent = $tokens[$startPtr]['content']; - /** @var string $newContent */ - $newContent = \str_replace($className, $replacement, $oldContent); - $phpcsFile->fixer->replaceToken($startPtr, $newContent); - } else { - for ($i = $startPtr; $i < $endPtr; $i++) { - $phpcsFile->fixer->replaceToken($i, ''); - } - - if (true === $replaceClassName) { - $phpcsFile->fixer->replaceToken($endPtr, $replacement); - } - } + $tokens = $phpcsFile->getTokens(); + $oldContent = $tokens[$startPtr]['content']; + /** @var string $newContent */ + $newContent = \str_replace($className, $replacement, $oldContent); + $phpcsFile->fixer->replaceToken($startPtr, $newContent); $phpcsFile->fixer->endChangeset(); } diff --git a/MO4/Tests/AbstractMo4SniffUnitTest.php b/MO4/Tests/AbstractMo4SniffUnitTest.php index 875462a..f51fe26 100644 --- a/MO4/Tests/AbstractMo4SniffUnitTest.php +++ b/MO4/Tests/AbstractMo4SniffUnitTest.php @@ -15,7 +15,7 @@ namespace MO4\Tests; use PHP_CodeSniffer\Exceptions\RuntimeException; -use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; +use PHP_CodeSniffer\Tests\Standards\AbstractSniffTestCase; /** * Abstract class to make the writing of tests more convenient. @@ -34,11 +34,11 @@ * * @link https://github.com/mayflower/mo4-coding-standard */ -abstract class AbstractMo4SniffUnitTest extends AbstractSniffUnitTest +abstract class AbstractMo4SniffUnitTest extends AbstractSniffTestCase { /** * Array or Array containing the test file as key and as value the key-value pairs with line number and number of# - * errors as describe in @see AbstractSniffUnitTest::getErrorList + * errors as describe in @see AbstractSniffTestCase::getErrorList * * When the array is empty, the test will pass. * @@ -48,7 +48,7 @@ abstract class AbstractMo4SniffUnitTest extends AbstractSniffUnitTest /** * Array or Array containing the test file as key and as value the key-value pairs with line number and number of# - * errors as describe in @see AbstractSniffUnitTest::getWarningList + * errors as describe in @see AbstractSniffTestCase::getWarningList * * When the array is empty, the test will pass. * diff --git a/MO4/ruleset.xml b/MO4/ruleset.xml index 6935241..bf96f9a 100644 --- a/MO4/ruleset.xml +++ b/MO4/ruleset.xml @@ -47,9 +47,7 @@ - - - + error diff --git a/composer.json b/composer.json index c59be4e..0d04cad 100644 --- a/composer.json +++ b/composer.json @@ -25,14 +25,15 @@ "require": { "php": "^8.1", "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", - "escapestudios/symfony2-coding-standard": "^3.16.0", - "slevomat/coding-standard": "^8.14", - "squizlabs/php_codesniffer": "^3.8.0" + "escapestudios/symfony2-coding-standard": "dev-phpcs4", + "slevomat/coding-standard": "^8.23", + "squizlabs/php_codesniffer": "^4.0.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.45", "nikic/php-parser": "< 5.0.1", "phan/phan": "^5.4.5", + "phpcsstandards/phpcsdevtools": "^1.2", "phpstan/phpstan": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^9.6.15", @@ -42,6 +43,12 @@ "symfony/polyfill-php83": "^1.32", "vimeo/psalm": "^6.0.0" }, + "repositories": [ + { + "type": "vcs", + "url": "git@github.com:mmoll/Symfony-coding-standard.git" + } + ], "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 6f0aabe..312cde8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,7 +8,7 @@ > - vendor/squizlabs/php_codesniffer/tests/Standards/AllSniffs.php + MO4/Tests diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 364cf04..badc25a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -22,7 +22,7 @@ require_once __DIR__.'/../vendor/squizlabs/php_codesniffer/tests/bootstrap.php'; // Add this Standard. -Config::setConfigData( +(new Config())->setConfigData( 'installed_paths', __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$myStandardName, true