From f89f5e3eb7f741818e43ad4a605f51e58ceed6f6 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Mon, 22 Aug 2022 03:17:42 +0200 Subject: [PATCH 1/5] copypaste some stuff --- .../AlphabeticallySortedUsesSniff.php | 79 ++++++++++++++++++- .../AlphabeticallySortedUsesSniffTest.php | 2 +- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php index d6bbd0436..16394ce3b 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php @@ -4,6 +4,7 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\Sniff; +use PHP_CodeSniffer\Util\Common; use SlevomatCodingStandard\Helpers\CommentHelper; use SlevomatCodingStandard\Helpers\NamespaceHelper; use SlevomatCodingStandard\Helpers\StringHelper; @@ -22,6 +23,9 @@ use function sprintf; use function strcasecmp; use function strcmp; +use function strcoll; +use function strlen; +use function substr; use function uasort; use const T_OPEN_TAG; use const T_SEMICOLON; @@ -32,11 +36,18 @@ class AlphabeticallySortedUsesSniff implements Sniff public const CODE_INCORRECT_ORDER = 'IncorrectlyOrderedUses'; + private const SUPPORTED_ORDERING_METHODS = [ + 'dictionary', + 'caseInsensitive', + 'caseSensitive', + 'locale', + ]; + /** @var bool */ public $psr12Compatible = true; - /** @var bool */ - public $caseSensitive = false; + /** @var string */ + public $order = 'caseInsensitive'; /** * @return array @@ -54,6 +65,19 @@ public function register(): array */ public function process(File $phpcsFile, $openTagPointer): void { + if (!in_array($this->order, self::SUPPORTED_ORDERING_METHODS, true)) { + $error = sprintf( + "'%s' is not a valid order for %s! Pick one of: %s", + $this->order, + Common::getSniffCode(self::class), + implode(', ', self::SUPPORTED_ORDERING_METHODS) + ); + + $phpcsFile->addError($error, $openTagPointer, 'InvalidOrder'); + + return; + } + if (TokenHelper::findPrevious($phpcsFile, T_OPEN_TAG, $openTagPointer - 1) !== null) { return; } @@ -201,11 +225,58 @@ private function compareUseStatements(UseStatement $a, UseStatement $b): int private function compare(string $a, string $b): int { - if ($this->caseSensitive) { - return strcmp($a, $b); + switch ($this->order) { + case 'caseSensitive': + return strcmp($a, $b); + case 'locale': + return strcoll($a, $b); + case 'dictionary': + return $this->dictionaryCompare($a, $b); } + // default is 'caseInsensitive' return strcasecmp($a, $b); } + /** + * Lexicographical namespace string compare. + * + * Example: + * + * use Doctrine\ORM\Query; + * use Doctrine\ORM\Query\Expr; + * use Doctrine\ORM\QueryBuilder; + * + * @param string $a first namespace string + * @param string $b second namespace string + */ + private function dictionaryCompare(string $a, string $b): int + { + $min = min(strlen($a), strlen($b)); + + for ($i = 0; $i < $min; $i++) { + if ($a[$i] === $b[$i]) { + continue; + } + + if ($a[$i] === NamespaceHelper::NAMESPACE_SEPARATOR) { + return -1; + } + + if ($b[$i] === NamespaceHelper::NAMESPACE_SEPARATOR) { + return 1; + } + + if ($a[$i] < $b[$i]) { + return -1; + } + + if ($a[$i] > $b[$i]) { + return 1; + } + } + + return strcmp(substr($a, $min), substr($b, $min)); + } + } diff --git a/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php b/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php index 4cafae835..158d5b123 100644 --- a/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php +++ b/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php @@ -45,7 +45,7 @@ public function testCorrectOrderOfSimilarNamespacesCaseSensitive(): void { self::assertNoSniffErrorInFile( self::checkFile(__DIR__ . '/data/correctOrderSimilarNamespacesCaseSensitive.php', [ - 'caseSensitive' => true, + 'order' => 'caseSensitive', ]) ); } From 1a713c36dad5347549a84aee143cbb88b79b34f7 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Tue, 23 Aug 2022 03:16:55 +0200 Subject: [PATCH 2/5] yo --- .../Namespaces/AlphabeticallySortedUsesSniff.php | 6 ++++-- .../AlphabeticallySortedUsesSniffTest.php | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php index 16394ce3b..3f0dc409f 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php @@ -36,6 +36,8 @@ class AlphabeticallySortedUsesSniff implements Sniff public const CODE_INCORRECT_ORDER = 'IncorrectlyOrderedUses'; + public const INVALID_ORDER = 'InvalidOrder'; + private const SUPPORTED_ORDERING_METHODS = [ 'dictionary', 'caseInsensitive', @@ -67,13 +69,13 @@ public function process(File $phpcsFile, $openTagPointer): void { if (!in_array($this->order, self::SUPPORTED_ORDERING_METHODS, true)) { $error = sprintf( - "'%s' is not a valid order for %s! Pick one of: %s", + "'%s' is not a valid order for %s. Pick one of: %s", $this->order, Common::getSniffCode(self::class), implode(', ', self::SUPPORTED_ORDERING_METHODS) ); - $phpcsFile->addError($error, $openTagPointer, 'InvalidOrder'); + $phpcsFile->addError($error, $openTagPointer, self::INVALID_ORDER); return; } diff --git a/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php b/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php index 158d5b123..b8d6659ee 100644 --- a/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php +++ b/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php @@ -66,6 +66,19 @@ public function testPatrikOrder(): void self::assertNoSniffErrorInFile($report); } + public function testUnknownOrder(): void + { + self::assertSniffError( + self::checkFile( + __DIR__ . '/data/alphabeticalPatrik.php', + ['order' => 'mySpecialOrder'] + ), + 1, + AlphabeticallySortedUsesSniff::INVALID_ORDER, + "'mySpecialOrder' is not a valid order for SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses. Pick one of: dictionary, caseInsensitive, caseSensitive, locale" + ); + } + public function testFixable(): void { $report = self::checkFile( From 76427157a302c98a5a1ccaabe8c07ce6050c8cf5 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Tue, 23 Aug 2022 23:08:46 +0200 Subject: [PATCH 3/5] lol --- .../Namespaces/AlphabeticallySortedUsesSniff.php | 8 -------- .../AlphabeticallySortedUsesSniffTest.php | 13 +++++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php index 3f0dc409f..cadfdf853 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php @@ -261,14 +261,6 @@ private function dictionaryCompare(string $a, string $b): int continue; } - if ($a[$i] === NamespaceHelper::NAMESPACE_SEPARATOR) { - return -1; - } - - if ($b[$i] === NamespaceHelper::NAMESPACE_SEPARATOR) { - return 1; - } - if ($a[$i] < $b[$i]) { return -1; } diff --git a/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php b/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php index b8d6659ee..d09ef9d73 100644 --- a/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php +++ b/tests/Sniffs/Namespaces/AlphabeticallySortedUsesSniffTest.php @@ -79,6 +79,19 @@ public function testUnknownOrder(): void ); } + public function testDictionaryOrder(): void + { + self::assertSniffError( + self::checkFile( + __DIR__ . '/data/dictionary.php', + ['order' => 'dictionary'] + ), + 17, + AlphabeticallySortedUsesSniff::CODE_INCORRECT_ORDER, + 'Expr' + ); + } + public function testFixable(): void { $report = self::checkFile( From d26f5687687b5e26e94df33cd2884cd1e13612d6 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Tue, 23 Aug 2022 23:09:59 +0200 Subject: [PATCH 4/5] meh --- tests/Sniffs/Namespaces/data/dictionary.php | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/Sniffs/Namespaces/data/dictionary.php diff --git a/tests/Sniffs/Namespaces/data/dictionary.php b/tests/Sniffs/Namespaces/data/dictionary.php new file mode 100644 index 000000000..7bfa24b39 --- /dev/null +++ b/tests/Sniffs/Namespaces/data/dictionary.php @@ -0,0 +1,22 @@ + Date: Tue, 23 Aug 2022 23:15:17 +0200 Subject: [PATCH 5/5] meh --- tests/Sniffs/Namespaces/data/dictionary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Sniffs/Namespaces/data/dictionary.php b/tests/Sniffs/Namespaces/data/dictionary.php index 7bfa24b39..dd16d7d85 100644 --- a/tests/Sniffs/Namespaces/data/dictionary.php +++ b/tests/Sniffs/Namespaces/data/dictionary.php @@ -16,7 +16,7 @@ use MyApp\Validator\ParameterContainer; use Doctrine\ORM\Query\Expr; -class Foo +class Fooo { }