From 69bb0d11f657312bf13c74bedb0b3bec5e48d839 Mon Sep 17 00:00:00 2001 From: Michael Kopinsky Date: Tue, 19 Nov 2024 19:43:23 -0500 Subject: [PATCH] Add PHPStan, fix phpstan errors --- composer.json | 3 ++- phpstan.neon | 5 +++++ src/Matchers/BaseMatch.php | 5 +---- src/Matchers/Bruteforce.php | 7 ++++--- src/Matchers/DateMatch.php | 7 ++++--- src/Matchers/DictionaryMatch.php | 7 ++----- src/Matchers/L33tMatch.php | 5 +++-- src/Matchers/RepeatMatch.php | 7 ++++--- src/Matchers/ReverseDictionaryMatch.php | 5 +++-- src/Matchers/SequenceMatch.php | 8 ++++---- src/Matchers/SpatialMatch.php | 9 +++++---- src/Matchers/YearMatch.php | 8 +++++--- test/Matchers/MockMatch.php | 5 +---- 13 files changed, 43 insertions(+), 38 deletions(-) create mode 100644 phpstan.neon diff --git a/composer.json b/composer.json index 2c40aaa..ae9c8a9 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "require-dev": { "phpunit/phpunit": "^8.5", "php-coveralls/php-coveralls": "*", - "squizlabs/php_codesniffer": "3.*" + "squizlabs/php_codesniffer": "3.*", + "phpstan/phpstan": "^2.0" }, "suggest": { "ext-gmp": "Required for optimized binomial calculations (also requires PHP >= 7.3)" diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..ac41719 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 0 + paths: + - src + - test diff --git a/src/Matchers/BaseMatch.php b/src/Matchers/BaseMatch.php index 527dbc5..97f77d3 100644 --- a/src/Matchers/BaseMatch.php +++ b/src/Matchers/BaseMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Math\Binomial; use ZxcvbnPhp\Scorer; @@ -48,10 +47,8 @@ public function __construct(string $password, int $begin, int $end, string $toke * * @param bool $isSoleMatch * Whether this is the only match in the password - * @return array - * Associative array with warning (string) and suggestions (array of strings) + * @return array{'warning': string, "suggestions": string[]} */ - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] abstract public function getFeedback(bool $isSoleMatch): array; /** diff --git a/src/Matchers/Bruteforce.php b/src/Matchers/Bruteforce.php index cba7bcc..8e99092 100644 --- a/src/Matchers/Bruteforce.php +++ b/src/Matchers/Bruteforce.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Scorer; /** @@ -13,7 +12,7 @@ * * Intentionally not named with Match suffix to prevent autoloading from Matcher. */ -class Bruteforce extends BaseMatch +final class Bruteforce extends BaseMatch { public const BRUTEFORCE_CARDINALITY = 10; @@ -32,7 +31,9 @@ public static function match(string $password, array $userInputs = []): array } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/src/Matchers/DateMatch.php b/src/Matchers/DateMatch.php index f3fdcd9..c67bffe 100644 --- a/src/Matchers/DateMatch.php +++ b/src/Matchers/DateMatch.php @@ -4,10 +4,9 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; -class DateMatch extends BaseMatch +final class DateMatch extends BaseMatch { public const NUM_YEARS = 119; // Years match against 1900 - 2019 public const NUM_MONTHS = 12; @@ -108,7 +107,9 @@ public static function match(string $password, array $userInputs = []): array return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/src/Matchers/DictionaryMatch.php b/src/Matchers/DictionaryMatch.php index b936681..2d44960 100644 --- a/src/Matchers/DictionaryMatch.php +++ b/src/Matchers/DictionaryMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Math\Binomial; @@ -63,7 +62,7 @@ public static function match(string $password, array $userInputs = [], array $ra $results = static::dictionaryMatch($password, $dict); foreach ($results as $result) { $result['dictionary_name'] = $name; - $matches[] = new static($password, $result['begin'], $result['end'], $result['token'], $result); + $matches[] = new DictionaryMatch($password, $result['begin'], $result['end'], $result['token'], $result); } } Matcher::usortStable($matches, [Matcher::class, 'compareMatches']); @@ -88,10 +87,8 @@ public function __construct(string $password, int $begin, int $end, string $toke } /** - * @param bool $isSoleMatch - * @return array + * @return array{'warning': string, "suggestions": string[]} */ - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] public function getFeedback(bool $isSoleMatch): array { $startUpper = '/^[A-Z][^A-Z]+$/u'; diff --git a/src/Matchers/L33tMatch.php b/src/Matchers/L33tMatch.php index 6b6288b..9163706 100644 --- a/src/Matchers/L33tMatch.php +++ b/src/Matchers/L33tMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Math\Binomial; @@ -98,7 +97,9 @@ public function __construct(string $password, int $begin, int $end, string $toke } } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $feedback = parent::getFeedback($isSoleMatch); diff --git a/src/Matchers/RepeatMatch.php b/src/Matchers/RepeatMatch.php index 3f38da2..fe44a03 100644 --- a/src/Matchers/RepeatMatch.php +++ b/src/Matchers/RepeatMatch.php @@ -4,11 +4,10 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Scorer; -class RepeatMatch extends BaseMatch +final class RepeatMatch extends BaseMatch { public const GREEDY_MATCH = '/(.+)\1+/u'; public const LAZY_MATCH = '/(.+?)\1+/u'; @@ -85,7 +84,9 @@ public static function match(string $password, array $userInputs = []): array return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $warning = mb_strlen($this->repeatedChar) == 1 diff --git a/src/Matchers/ReverseDictionaryMatch.php b/src/Matchers/ReverseDictionaryMatch.php index c7b86b6..4f38ecd 100644 --- a/src/Matchers/ReverseDictionaryMatch.php +++ b/src/Matchers/ReverseDictionaryMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; class ReverseDictionaryMatch extends DictionaryMatch @@ -42,7 +41,9 @@ protected function getRawGuesses(): float return parent::getRawGuesses() * 2; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $feedback = parent::getFeedback($isSoleMatch); diff --git a/src/Matchers/SequenceMatch.php b/src/Matchers/SequenceMatch.php index 1350f2a..59531cf 100644 --- a/src/Matchers/SequenceMatch.php +++ b/src/Matchers/SequenceMatch.php @@ -4,9 +4,7 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; - -class SequenceMatch extends BaseMatch +final class SequenceMatch extends BaseMatch { public const MAX_DELTA = 5; @@ -87,7 +85,9 @@ public static function findSequenceMatch(string $password, int $begin, int $end, } } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/src/Matchers/SpatialMatch.php b/src/Matchers/SpatialMatch.php index 6de328b..32297e6 100644 --- a/src/Matchers/SpatialMatch.php +++ b/src/Matchers/SpatialMatch.php @@ -4,11 +4,10 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Math\Binomial; -class SpatialMatch extends BaseMatch +final class SpatialMatch extends BaseMatch { public const SHIFTED_CHARACTERS = '~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?'; @@ -58,7 +57,9 @@ public static function match(string $password, array $userInputs = [], array $gr return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $warning = $this->turns == 1 @@ -93,7 +94,7 @@ public function __construct(string $password, int $begin, int $end, string $toke /** * Match spatial patterns in a adjacency graph. * @param string $password - * @param array $graph + * @param array $graph * @param string $graphName * @return array */ diff --git a/src/Matchers/YearMatch.php b/src/Matchers/YearMatch.php index 9deeea6..ebabf6b 100644 --- a/src/Matchers/YearMatch.php +++ b/src/Matchers/YearMatch.php @@ -4,10 +4,9 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; -class YearMatch extends BaseMatch +final class YearMatch extends BaseMatch { public const NUM_YEARS = 119; @@ -32,7 +31,10 @@ public static function match(string $password, array $userInputs = []): array return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/test/Matchers/MockMatch.php b/test/Matchers/MockMatch.php index cf5d10b..869b7e6 100644 --- a/test/Matchers/MockMatch.php +++ b/test/Matchers/MockMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Test\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matchers\BaseMatch; class MockMatch extends BaseMatch @@ -22,10 +21,8 @@ public function __construct(int $begin, int $end, float $guesses) * Get feedback to a user based on the match. * @param bool $isSoleMatch * Whether this is the only match in the password - * @return array - * Associative array with warning (string) and suggestions (array of strings) + * @return array{'warning': string, "suggestions": string[]} */ - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] public function getFeedback(bool $isSoleMatch): array { return [