diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index ff82dca..b2660c2 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -4,9 +4,8 @@ on: pull_request: paths: &paths - 'src/**' - - 'config/**' - '.github/workflows/static.yml' - - 'psalm*.xml' + - 'phpstan.neon' - 'composer.json' push: branches: ['master'] @@ -20,10 +19,10 @@ concurrency: cancel-in-progress: true jobs: - psalm: - uses: yiisoft/actions/.github/workflows/psalm.yml@master + phpstan: + uses: yiisoft/actions/.github/workflows/phpstan.yml@master with: os: >- ['ubuntu-latest'] php: >- - ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b052b..2877323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 1.1.1 under development - Enh #61: Explicitly import constants in "use" section (@mspirkov) +- Chg #70: Replace Psalm with PHPStan (@vjik) ## 1.1.0 November 21, 2025 diff --git a/README.md b/README.md index 21134a1..706d860 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ [![Code Coverage](https://codecov.io/gh/yiisoft/json/branch/master/graph/badge.svg)](https://codecov.io/gh/yiisoft/json) [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2Fjson%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/json/master) [![Static analysis](https://github.com/yiisoft/json/actions/workflows/static.yml/badge.svg?branch=master)](https://github.com/yiisoft/json/actions/workflows/static.yml?query=branch%3Amaster) -[![type-coverage](https://shepherd.dev/github/yiisoft/json/coverage.svg)](https://shepherd.dev/github/yiisoft/json) The package provides methods to encode and decode JSON. diff --git a/composer.json b/composer.json index ae5e237..eece5cc 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "friendsofphp/php-cs-fixer": "^3.93", + "phpstan/phpstan": "^2.3", "phpunit/phpunit": "^9.6.22", "rector/rector": "^2.8.1", "shipmonk/composer-dependency-analyser": "^1.8", @@ -67,6 +68,7 @@ "scripts": { "cs-fix": "php-cs-fixer fix", "dependency-analyser": "composer-dependency-analyser", + "phpstan": "phpstan", "rector": "rector", "test": "phpunit --testdox --no-interaction", "test-watch": "phpunit-watcher watch" diff --git a/docs/internals.md b/docs/internals.md index b77907c..4ae9aeb 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -19,10 +19,10 @@ The package tests are checked with [Infection](https://infection.github.io/) mut ## Static analysis -The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis: +The code is statically analyzed with [PHPStan](https://phpstan.org/). To run static analysis: ```shell -./vendor/bin/psalm +./vendor/bin/phpstan ``` ## Code style diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..5287436 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,11 @@ +parameters: + level: max + paths: + - src + ignoreErrors: + # `UnitEnum` is not available in PHP 8.0 and earlier + - + identifier: class.notFound + message: '#^Class UnitEnum not found\.$#' + path: src/Json.php + reportUnmatched: false diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index 590dd10..0000000 --- a/psalm.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - diff --git a/src/Json.php b/src/Json.php index 86de110..c54db88 100644 --- a/src/Json.php +++ b/src/Json.php @@ -44,9 +44,7 @@ final class Json * @param int $options The encoding options. For more details please refer to * {@see https://www.php.net/manual/en/function.json-encode.php}. * Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR`. - * @param int $depth The maximum depth. - * - * @psalm-param int<1, 2147483647> $depth + * @param int<1, 2147483647> $depth The maximum depth. * * @throws JsonException if there is any encoding error. * @@ -64,7 +62,7 @@ public static function encode( } /** - * @var string We use flag `JSON_THROW_ON_ERROR`, so `json_encode` never returns `false`. + * @var non-empty-string We use flag `JSON_THROW_ON_ERROR`, so `json_encode` never returns `false`. */ return json_encode($value, JSON_THROW_ON_ERROR | $options, $depth); } @@ -94,11 +92,9 @@ public static function htmlEncode($value): string * * @param string $json The JSON string to be decoded. * @param bool $asArray Whether to return objects in terms of associative arrays. - * @param int $depth The recursion depth. + * @param int<1, 2147483647> $depth The recursion depth. * @param int $options The decode options. * - * @psalm-param int<1, 2147483647> $depth - * * @throws JsonException If there is any decoding error. * * @return mixed The PHP data. @@ -118,9 +114,9 @@ public static function decode( /** * Pre-processes the array before sending it to `json_encode()`. * - * @param array $data The array to be processed. + * @param array $data The array to be processed. * - * @return array The processed array. + * @return array The processed array. */ private static function processArray(array $data): array { @@ -158,7 +154,6 @@ private static function processObject(object $data) return $data; } - /** @psalm-suppress UndefinedClass Required for PHP 8.0 and earlier */ if ($data instanceof DateTimeInterface || $data instanceof UnitEnum ) { diff --git a/tools/psalm/composer.json b/tools/psalm/composer.json deleted file mode 100644 index 107bf54..0000000 --- a/tools/psalm/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require-dev": { - "vimeo/psalm": "^4.30 || ^5.26.1 || ^6.5" - } -}