From ce264e3ad64b0c1d39afdbc73fc3f02c9a4b01b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 00:11:18 +0000 Subject: [PATCH 01/13] Update build-cs --- build-cs/composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build-cs/composer.lock b/build-cs/composer.lock index b52da6f8..d8730d8a 100644 --- a/build-cs/composer.lock +++ b/build-cs/composer.lock @@ -9,16 +9,16 @@ "packages-dev": [ { "name": "consistence-community/coding-standard", - "version": "3.11.2", + "version": "3.11.3", "source": { "type": "git", "url": "https://github.com/consistence-community/coding-standard.git", - "reference": "adb4be482e76990552bf624309d2acc8754ba1bd" + "reference": "f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consistence-community/coding-standard/zipball/adb4be482e76990552bf624309d2acc8754ba1bd", - "reference": "adb4be482e76990552bf624309d2acc8754ba1bd", + "url": "https://api.github.com/repos/consistence-community/coding-standard/zipball/f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1", + "reference": "f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1", "shasum": "" }, "require": { @@ -70,9 +70,9 @@ ], "support": { "issues": "https://github.com/consistence-community/coding-standard/issues", - "source": "https://github.com/consistence-community/coding-standard/tree/3.11.2" + "source": "https://github.com/consistence-community/coding-standard/tree/3.11.3" }, - "time": "2022-06-21T08:36:36+00:00" + "time": "2023-03-27T14:55:41+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", @@ -199,16 +199,16 @@ }, { "name": "slevomat/coding-standard", - "version": "8.9.0", + "version": "8.9.1", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "8f11e0f5ff984d6862bb9d83aa513dc05a1773ef" + "reference": "3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/8f11e0f5ff984d6862bb9d83aa513dc05a1773ef", - "reference": "8f11e0f5ff984d6862bb9d83aa513dc05a1773ef", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2", + "reference": "3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2", "shasum": "" }, "require": { @@ -248,7 +248,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.9.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.9.1" }, "funding": [ { @@ -260,7 +260,7 @@ "type": "tidelift" } ], - "time": "2023-03-25T15:52:37+00:00" + "time": "2023-03-27T11:00:16+00:00" }, { "name": "squizlabs/php_codesniffer", From 35fda6c8ceaac95b64b13559c15da11882ad7000 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 00:36:39 +0000 Subject: [PATCH 02/13] Update dependency slevomat/coding-standard to v8.10.0 --- build-cs/composer.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/build-cs/composer.lock b/build-cs/composer.lock index d8730d8a..2eafc159 100644 --- a/build-cs/composer.lock +++ b/build-cs/composer.lock @@ -154,16 +154,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.16.1", + "version": "1.18.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571" + "reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e27e92d939e2e3636f0a1f0afaba59692c0bf571", - "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/22dcdfd725ddf99583bfe398fc624ad6c5004a0f", + "reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f", "shasum": "" }, "require": { @@ -193,38 +193,38 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.16.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.18.1" }, - "time": "2023-02-07T18:11:17+00:00" + "time": "2023-04-07T11:51:11+00:00" }, { "name": "slevomat/coding-standard", - "version": "8.9.1", + "version": "8.10.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2" + "reference": "c4e213e6e57f741451a08e68ef838802eec92287" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2", - "reference": "3d4fe0c803ae15829ef72d90d3d4eee3dd9f79b2", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/c4e213e6e57f741451a08e68ef838802eec92287", + "reference": "c4e213e6e57f741451a08e68ef838802eec92287", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": ">=1.16.0 <1.17.0", + "phpstan/phpdoc-parser": ">=1.18.0 <1.19.0", "squizlabs/php_codesniffer": "^3.7.1" }, "require-dev": { "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.10.8", + "phpstan/phpstan": "1.4.10|1.10.11", "phpstan/phpstan-deprecation-rules": "1.1.3", - "phpstan/phpstan-phpunit": "1.0.0|1.3.10", - "phpstan/phpstan-strict-rules": "1.5.0", - "phpunit/phpunit": "7.5.20|8.5.21|9.6.5" + "phpstan/phpstan-phpunit": "1.0.0|1.3.11", + "phpstan/phpstan-strict-rules": "1.5.1", + "phpunit/phpunit": "7.5.20|8.5.21|9.6.6|10.0.19" }, "type": "phpcodesniffer-standard", "extra": { @@ -248,7 +248,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.9.1" + "source": "https://github.com/slevomat/coding-standard/tree/8.10.0" }, "funding": [ { @@ -260,7 +260,7 @@ "type": "tidelift" } ], - "time": "2023-03-27T11:00:16+00:00" + "time": "2023-04-10T07:39:29+00:00" }, { "name": "squizlabs/php_codesniffer", From 1b9b85fe937333254e53bb873ecd3f868afd83db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 02:18:09 +0000 Subject: [PATCH 03/13] Update dependency slevomat/coding-standard to v8.11.0 --- build-cs/composer.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/build-cs/composer.lock b/build-cs/composer.lock index 2eafc159..0cea3f9e 100644 --- a/build-cs/composer.lock +++ b/build-cs/composer.lock @@ -154,16 +154,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.18.1", + "version": "1.20.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f" + "reference": "90490bd8fd8530a272043c4950c180b6d0cf5f81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/22dcdfd725ddf99583bfe398fc624ad6c5004a0f", - "reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/90490bd8fd8530a272043c4950c180b6d0cf5f81", + "reference": "90490bd8fd8530a272043c4950c180b6d0cf5f81", "shasum": "" }, "require": { @@ -193,38 +193,38 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.18.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.2" }, - "time": "2023-04-07T11:51:11+00:00" + "time": "2023-04-22T12:59:35+00:00" }, { "name": "slevomat/coding-standard", - "version": "8.10.0", + "version": "8.11.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "c4e213e6e57f741451a08e68ef838802eec92287" + "reference": "91428d5bcf7db93a842bcf97f465edf62527f3ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/c4e213e6e57f741451a08e68ef838802eec92287", - "reference": "c4e213e6e57f741451a08e68ef838802eec92287", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/91428d5bcf7db93a842bcf97f465edf62527f3ea", + "reference": "91428d5bcf7db93a842bcf97f465edf62527f3ea", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": ">=1.18.0 <1.19.0", + "phpstan/phpdoc-parser": ">=1.20.0 <1.21.0", "squizlabs/php_codesniffer": "^3.7.1" }, "require-dev": { "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.10.11", + "phpstan/phpstan": "1.10.14", "phpstan/phpstan-deprecation-rules": "1.1.3", - "phpstan/phpstan-phpunit": "1.0.0|1.3.11", + "phpstan/phpstan-phpunit": "1.3.11", "phpstan/phpstan-strict-rules": "1.5.1", - "phpunit/phpunit": "7.5.20|8.5.21|9.6.6|10.0.19" + "phpunit/phpunit": "7.5.20|8.5.21|9.6.6|10.1.1" }, "type": "phpcodesniffer-standard", "extra": { @@ -248,7 +248,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.10.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.11.0" }, "funding": [ { @@ -260,7 +260,7 @@ "type": "tidelift" } ], - "time": "2023-04-10T07:39:29+00:00" + "time": "2023-04-21T15:51:44+00:00" }, { "name": "squizlabs/php_codesniffer", From fa91928228e1d487888aac7431d8806fcdfa81c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 02:43:20 +0000 Subject: [PATCH 04/13] Update dependency slevomat/coding-standard to v8.11.1 --- build-cs/composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build-cs/composer.lock b/build-cs/composer.lock index 0cea3f9e..dab6b094 100644 --- a/build-cs/composer.lock +++ b/build-cs/composer.lock @@ -154,16 +154,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.20.2", + "version": "1.20.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "90490bd8fd8530a272043c4950c180b6d0cf5f81" + "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/90490bd8fd8530a272043c4950c180b6d0cf5f81", - "reference": "90490bd8fd8530a272043c4950c180b6d0cf5f81", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", + "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", "shasum": "" }, "require": { @@ -193,22 +193,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.2" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4" }, - "time": "2023-04-22T12:59:35+00:00" + "time": "2023-05-02T09:19:37+00:00" }, { "name": "slevomat/coding-standard", - "version": "8.11.0", + "version": "8.11.1", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "91428d5bcf7db93a842bcf97f465edf62527f3ea" + "reference": "af87461316b257e46e15bb041dca6fca3796d822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/91428d5bcf7db93a842bcf97f465edf62527f3ea", - "reference": "91428d5bcf7db93a842bcf97f465edf62527f3ea", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/af87461316b257e46e15bb041dca6fca3796d822", + "reference": "af87461316b257e46e15bb041dca6fca3796d822", "shasum": "" }, "require": { @@ -248,7 +248,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.11.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.11.1" }, "funding": [ { @@ -260,7 +260,7 @@ "type": "tidelift" } ], - "time": "2023-04-21T15:51:44+00:00" + "time": "2023-04-24T08:19:01+00:00" }, { "name": "squizlabs/php_codesniffer", From a1891b44eb815e5ef1011faed44ce9dcc15ed630 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 00:57:30 +0000 Subject: [PATCH 05/13] Update dependency slevomat/coding-standard to v8.12.0 --- build-cs/composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build-cs/composer.lock b/build-cs/composer.lock index dab6b094..db122416 100644 --- a/build-cs/composer.lock +++ b/build-cs/composer.lock @@ -199,16 +199,16 @@ }, { "name": "slevomat/coding-standard", - "version": "8.11.1", + "version": "8.12.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "af87461316b257e46e15bb041dca6fca3796d822" + "reference": "cc04334ed0ce5a251389112fbd2dbe1dbc931ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/af87461316b257e46e15bb041dca6fca3796d822", - "reference": "af87461316b257e46e15bb041dca6fca3796d822", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/cc04334ed0ce5a251389112fbd2dbe1dbc931ae8", + "reference": "cc04334ed0ce5a251389112fbd2dbe1dbc931ae8", "shasum": "" }, "require": { @@ -220,11 +220,11 @@ "require-dev": { "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.10.14", + "phpstan/phpstan": "1.10.15", "phpstan/phpstan-deprecation-rules": "1.1.3", "phpstan/phpstan-phpunit": "1.3.11", "phpstan/phpstan-strict-rules": "1.5.1", - "phpunit/phpunit": "7.5.20|8.5.21|9.6.6|10.1.1" + "phpunit/phpunit": "7.5.20|8.5.21|9.6.8|10.1.3" }, "type": "phpcodesniffer-standard", "extra": { @@ -248,7 +248,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.11.1" + "source": "https://github.com/slevomat/coding-standard/tree/8.12.0" }, "funding": [ { @@ -260,7 +260,7 @@ "type": "tidelift" } ], - "time": "2023-04-24T08:19:01+00:00" + "time": "2023-05-14T20:06:01+00:00" }, { "name": "squizlabs/php_codesniffer", From 5c143aa605bbf392a90630773618eeaeeac7a49b Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 25 May 2023 15:27:48 +0200 Subject: [PATCH 06/13] Next-gen coding standard workflow --- .gitattributes | 1 - .github/renovate.json | 5 - .github/workflows/build.yml | 14 +- .gitignore | 1 + Makefile | 10 +- build-cs/.gitignore | 1 - build-cs/composer.json | 13 -- build-cs/composer.lock | 331 ------------------------------------ phpcs.xml | 111 ------------ 9 files changed, 21 insertions(+), 466 deletions(-) delete mode 100644 build-cs/.gitignore delete mode 100644 build-cs/composer.json delete mode 100644 build-cs/composer.lock delete mode 100644 phpcs.xml diff --git a/.gitattributes b/.gitattributes index 48387724..45a67c45 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,6 +6,5 @@ tmp export-ignore .gitattributes export-ignore .gitignore export-ignore Makefile export-ignore -phpcs.xml export-ignore phpstan.neon export-ignore phpunit.xml export-ignore diff --git a/.github/renovate.json b/.github/renovate.json index b775cc18..d3f5961e 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -10,11 +10,6 @@ "enabled": true, "groupName": "root-composer" }, - { - "matchPaths": ["build-cs/**"], - "enabled": true, - "groupName": "build-cs" - }, { "matchPaths": [".github/**"], "enabled": true, diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ba258b6c..0bb37b0d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: "Lint" run: "make lint" - coding-standards: + coding-standard: name: "Coding Standard" runs-on: "ubuntu-latest" @@ -55,11 +55,17 @@ jobs: - name: "Checkout" uses: actions/checkout@v3 + - name: "Checkout build-cs" + uses: actions/checkout@v3 + with: + repository: "phpstan/build-cs" + path: "build-cs" + - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: coverage: "none" - php-version: "8.0" + php-version: "8.2" - name: "Validate Composer" run: "composer validate" @@ -67,6 +73,10 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" + - name: "Install build-cs dependencies" + working-directory: "build-cs" + run: "composer install --no-interaction --no-progress" + - name: "Lint" run: "make lint" diff --git a/.gitignore b/.gitignore index 2db21315..7de9f3c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /tests/tmp +/build-cs /vendor /composer.lock .phpunit.result.cache diff --git a/Makefile b/Makefile index fe917d3b..a175843c 100644 --- a/Makefile +++ b/Makefile @@ -10,13 +10,19 @@ lint: php vendor/bin/parallel-lint --colors \ src tests +.PHONY: cs-install +cs-install: + git clone https://github.com/phpstan/build-cs.git || true + git -C build-cs fetch origin && git -C build-cs reset --hard origin/main + composer install --working-dir build-cs + .PHONY: cs cs: - composer install --working-dir build-cs && php build-cs/vendor/bin/phpcs + php build-cs/vendor/bin/phpcs --standard=build-cs/phpcs.xml src tests .PHONY: cs-fix cs-fix: - php build-cs/vendor/bin/phpcbf + php build-cs/vendor/bin/phpcbf --standard=build-cs/phpcs.xml src tests .PHONY: phpstan phpstan: diff --git a/build-cs/.gitignore b/build-cs/.gitignore deleted file mode 100644 index 61ead866..00000000 --- a/build-cs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/vendor diff --git a/build-cs/composer.json b/build-cs/composer.json deleted file mode 100644 index 16a240bc..00000000 --- a/build-cs/composer.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "require-dev": { - "consistence-community/coding-standard": "^3.11.0", - "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", - "slevomat/coding-standard": "^8.8.0", - "squizlabs/php_codesniffer": "^3.5.3" - }, - "config": { - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } - } -} diff --git a/build-cs/composer.lock b/build-cs/composer.lock deleted file mode 100644 index db122416..00000000 --- a/build-cs/composer.lock +++ /dev/null @@ -1,331 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "e69c1916405a7e3c8001c1b609a0ee61", - "packages": [], - "packages-dev": [ - { - "name": "consistence-community/coding-standard", - "version": "3.11.3", - "source": { - "type": "git", - "url": "https://github.com/consistence-community/coding-standard.git", - "reference": "f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/consistence-community/coding-standard/zipball/f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1", - "reference": "f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1", - "shasum": "" - }, - "require": { - "php": "~8.0", - "slevomat/coding-standard": "~8.0", - "squizlabs/php_codesniffer": "~3.7.0" - }, - "replace": { - "consistence/coding-standard": "3.10.*" - }, - "require-dev": { - "phing/phing": "2.17.0", - "php-parallel-lint/php-parallel-lint": "1.3.1", - "phpunit/phpunit": "9.5.10" - }, - "type": "library", - "autoload": { - "psr-4": { - "Consistence\\": [ - "Consistence" - ] - }, - "classmap": [ - "Consistence" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "VaĊĦek Purchart", - "email": "me@vasekpurchart.cz", - "homepage": "http://vasekpurchart.cz" - } - ], - "description": "Consistence - Coding Standard - PHP Code Sniffer rules", - "keywords": [ - "Coding Standard", - "PHPCodeSniffer", - "codesniffer", - "coding", - "cs", - "phpcs", - "ruleset", - "sniffer", - "standard" - ], - "support": { - "issues": "https://github.com/consistence-community/coding-standard/issues", - "source": "https://github.com/consistence-community/coding-standard/tree/3.11.3" - }, - "time": "2023-03-27T14:55:41+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "4be43904336affa5c2f70744a348312336afd0da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", - "reference": "4be43904336affa5c2f70744a348312336afd0da", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "ext-json": "*", - "ext-zip": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0", - "yoast/phpunit-polyfills": "^1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/composer-installer/issues", - "source": "https://github.com/PHPCSStandards/composer-installer" - }, - "time": "2023-01-05T11:28:13+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.20.4", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", - "reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4" - }, - "time": "2023-05-02T09:19:37+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "8.12.0", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "cc04334ed0ce5a251389112fbd2dbe1dbc931ae8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/cc04334ed0ce5a251389112fbd2dbe1dbc931ae8", - "reference": "cc04334ed0ce5a251389112fbd2dbe1dbc931ae8", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": ">=1.20.0 <1.21.0", - "squizlabs/php_codesniffer": "^3.7.1" - }, - "require-dev": { - "phing/phing": "2.17.4", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.10.15", - "phpstan/phpstan-deprecation-rules": "1.1.3", - "phpstan/phpstan-phpunit": "1.3.11", - "phpstan/phpstan-strict-rules": "1.5.1", - "phpunit/phpunit": "7.5.20|8.5.21|9.6.8|10.1.3" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "8.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "keywords": [ - "dev", - "phpcs" - ], - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.12.0" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2023-05-14T20:06:01+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2023-02-22T23:07:41+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" -} diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 95032a6e..00000000 --- a/phpcs.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - src - tests - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10 - - - - - - 10 - - - - - - - - 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tests/*/data - From cca41e8ff93430a443e622a0c15c9f1f01aaac69 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 12:05:21 +0200 Subject: [PATCH 07/13] Require PHPStan 1.11 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9cf4e652..83dbeb9e 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ ], "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.11" }, "require-dev": { "nikic/php-parser": "^4.13.0", From bd3aa8b9744ed1fd5cd33b1b52bbde56667ad7a3 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 12:06:36 +0200 Subject: [PATCH 08/13] Modernized rules with generics and RuleErrorBuilder --- phpstan-baseline.neon | 478 ------------------ phpstan.neon | 1 - .../BooleanInBooleanAndRule.php | 9 +- .../BooleanInBooleanNotRule.php | 12 +- .../BooleanInBooleanOrRule.php | 9 +- .../BooleanInElseIfConditionRule.php | 12 +- .../BooleanInIfConditionRule.php | 12 +- .../BooleanInTernaryOperatorRule.php | 12 +- src/Rules/Cast/UselessCastRule.php | 8 +- .../RequireParentConstructCallRule.php | 20 +- .../DisallowedBacktickRule.php | 12 +- .../DisallowedEmptyRule.php | 11 +- .../DisallowedImplicitArrayCreationRule.php | 14 +- .../DisallowedShortTernaryRule.php | 4 +- .../OverwriteVariablesWithForLoopInitRule.php | 11 +- .../OverwriteVariablesWithForeachRule.php | 16 +- .../WrongCaseOfInheritedMethodRule.php | 11 +- ...ndInArithmeticIncrementOrDecrementRule.php | 8 +- .../OperandsInArithmeticAdditionRule.php | 15 +- .../OperandsInArithmeticDivisionRule.php | 15 +- ...OperandsInArithmeticExponentiationRule.php | 15 +- .../OperandsInArithmeticModuloRule.php | 15 +- ...OperandsInArithmeticMultiplicationRule.php | 15 +- .../OperandsInArithmeticSubtractionRule.php | 15 +- ...DynamicCallOnStaticMethodsCallableRule.php | 13 +- .../DynamicCallOnStaticMethodsRule.php | 20 +- .../StrictCalls/StrictFunctionCallsRule.php | 24 +- .../VariableMethodCallRule.php | 14 +- .../VariableMethodCallableRule.php | 5 +- .../VariablePropertyFetchRule.php | 14 +- .../VariableStaticMethodCallRule.php | 14 +- .../VariableStaticMethodCallableRule.php | 5 +- .../VariableStaticPropertyFetchRule.php | 14 +- .../VariableVariablesRule.php | 13 +- .../BooleanInBooleanNotRuleTest.php | 3 + .../BooleanInElseIfConditionRuleTest.php | 3 + .../BooleanInIfConditionRuleTest.php | 3 + .../BooleanInTernaryOperatorRuleTest.php | 3 + tests/Rules/Cast/UselessCastRuleTest.php | 3 + .../RequireParentConstructCallRuleTest.php | 3 + .../DisallowedBacktickRuleTest.php | 3 + .../DisallowedEmptyRuleTest.php | 3 + ...isallowedImplicitArrayCreationRuleTest.php | 3 + .../OverwriteVariablesWithForeachRuleTest.php | 3 + .../WrongCaseOfInheritedMethodRuleTest.php | 3 + ...ArithmeticIncrementOrDecrementRuleTest.php | 7 + ...erandInArithmeticPostDecrementRuleTest.php | 3 + ...erandInArithmeticPostIncrementRuleTest.php | 3 + ...perandInArithmeticPreDecrementRuleTest.php | 3 + ...perandInArithmeticPreIncrementRuleTest.php | 3 + .../OperandsInArithmeticAdditionRuleTest.php | 3 + .../OperandsInArithmeticDivisionRuleTest.php | 3 + ...andsInArithmeticExponentiationRuleTest.php | 3 + .../OperandsInArithmeticModuloRuleTest.php | 3 + ...andsInArithmeticMultiplicationRuleTest.php | 3 + ...perandsInArithmeticSubtractionRuleTest.php | 3 + .../DynamicCallOnStaticMethodsRuleTest.php | 3 + .../StrictFunctionCallsRuleTest.php | 3 + .../VariableMethodCallRuleTest.php | 3 + .../VariablePropertyFetchRuleTest.php | 3 + .../VariableStaticMethodCallRuleTest.php | 3 + .../VariableStaticPropertyFetchRuleTest.php | 3 + .../VariableVariablesRuleTest.php | 3 + 63 files changed, 310 insertions(+), 667 deletions(-) delete mode 100644 phpstan-baseline.neon diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon deleted file mode 100644 index 84faab10..00000000 --- a/phpstan-baseline.neon +++ /dev/null @@ -1,478 +0,0 @@ - - -parameters: - ignoreErrors: - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInBooleanNotRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BooleanNot\\) of method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInBooleanNotRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInElseIfConditionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Stmt\\\\ElseIf_\\) of method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInElseIfConditionRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInIfConditionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInIfConditionRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Stmt\\\\If_\\) of method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInIfConditionRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInIfConditionRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInTernaryOperatorRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\Ternary\\) of method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInTernaryOperatorRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Cast\\\\UselessCastRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Cast/UselessCastRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\Cast\\) of method PHPStan\\\\Rules\\\\Cast\\\\UselessCastRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Cast/UselessCastRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Classes\\\\RequireParentConstructCallRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Classes/RequireParentConstructCallRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Stmt\\\\ClassMethod\\) of method PHPStan\\\\Rules\\\\Classes\\\\RequireParentConstructCallRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Classes/RequireParentConstructCallRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedBacktickRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/DisallowedConstructs/DisallowedBacktickRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\Empty_\\) of method PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedBacktickRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/DisallowedConstructs/DisallowedBacktickRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedEmptyRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/DisallowedConstructs/DisallowedEmptyRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\Empty_\\) of method PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedEmptyRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/DisallowedConstructs/DisallowedEmptyRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedImplicitArrayCreationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\Assign\\) of method PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedImplicitArrayCreationRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\ForeachLoop\\\\OverwriteVariablesWithForeachRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Stmt\\\\Foreach_\\) of method PHPStan\\\\Rules\\\\ForeachLoop\\\\OverwriteVariablesWithForeachRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticAdditionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticAdditionRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticDivisionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticDivisionRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticExponentiationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticExponentiationRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticModuloRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticModuloRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticMultiplicationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticSubtractionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticSubtractionRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\StrictCalls\\\\DynamicCallOnStaticMethodsRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\MethodCall\\) of method PHPStan\\\\Rules\\\\StrictCalls\\\\DynamicCallOnStaticMethodsRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\StrictCalls\\\\StrictFunctionCallsRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/StrictCalls/StrictFunctionCallsRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\FuncCall\\) of method PHPStan\\\\Rules\\\\StrictCalls\\\\StrictFunctionCallsRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/StrictCalls/StrictFunctionCallsRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableMethodCallRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/VariableVariables/VariableMethodCallRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\MethodCall\\) of method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableMethodCallRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/VariableVariables/VariableMethodCallRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariablePropertyFetchRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/VariableVariables/VariablePropertyFetchRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\PropertyFetch\\) of method PHPStan\\\\Rules\\\\VariableVariables\\\\VariablePropertyFetchRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/VariableVariables/VariablePropertyFetchRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticMethodCallRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/VariableVariables/VariableStaticMethodCallRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\StaticCall\\) of method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticMethodCallRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/VariableVariables/VariableStaticMethodCallRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticPropertyFetchRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\StaticPropertyFetch\\) of method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticPropertyFetchRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableVariablesRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" - count: 1 - path: src/Rules/VariableVariables/VariableVariablesRule.php - - - - message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\Variable\\) of method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableVariablesRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/VariableVariables/VariableVariablesRule.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInBooleanNotRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInBooleanNotRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInElseIfConditionRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInElseIfConditionRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInIfConditionRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInIfConditionRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInTernaryOperatorRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\BooleansInConditions\\\\BooleanInTernaryOperatorRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Cast\\\\UselessCastRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Cast/UselessCastRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Cast\\\\UselessCastRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Cast/UselessCastRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Classes\\\\RequireParentConstructCallRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Classes/RequireParentConstructCallRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Classes\\\\RequireParentConstructCallRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Classes/RequireParentConstructCallRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedBacktickRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/DisallowedConstructs/DisallowedBacktickRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedBacktickRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/DisallowedConstructs/DisallowedBacktickRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedEmptyRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/DisallowedConstructs/DisallowedEmptyRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedEmptyRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/DisallowedConstructs/DisallowedEmptyRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedImplicitArrayCreationRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\DisallowedConstructs\\\\DisallowedImplicitArrayCreationRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\ForeachLoop\\\\OverwriteVariablesWithForeachRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/ForeachLoop/OverwriteVariablesWithForeachRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\ForeachLoop\\\\OverwriteVariablesWithForeachRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/ForeachLoop/OverwriteVariablesWithForeachRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Methods\\\\WrongCaseOfInheritedMethodRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Methods/WrongCaseOfInheritedMethodRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Methods\\\\WrongCaseOfInheritedMethodRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Methods/WrongCaseOfInheritedMethodRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticIncrementOrDecrementRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticIncrementOrDecrementRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticIncrementOrDecrementRuleTest\\:\\:createRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticPostDecrementRuleTest\\:\\:createRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticPostIncrementRuleTest\\:\\:createRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticPreDecrementRuleTest\\:\\:createRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandInArithmeticPreIncrementRuleTest\\:\\:createRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticAdditionRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticAdditionRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticDivisionRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticDivisionRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticExponentiationRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticExponentiationRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticModuloRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticModuloRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticMultiplicationRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticMultiplicationRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticSubtractionRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticSubtractionRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\StrictCalls\\\\DynamicCallOnStaticMethodsRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/StrictCalls/DynamicCallOnStaticMethodsRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\StrictCalls\\\\DynamicCallOnStaticMethodsRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/StrictCalls/DynamicCallOnStaticMethodsRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\StrictCalls\\\\StrictFunctionCallsRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\StrictCalls\\\\StrictFunctionCallsRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableMethodCallRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/VariableVariables/VariableMethodCallRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableMethodCallRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/VariableVariables/VariableMethodCallRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariablePropertyFetchRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\VariableVariables\\\\VariablePropertyFetchRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticMethodCallRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/VariableVariables/VariableStaticMethodCallRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticMethodCallRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/VariableVariables/VariableStaticMethodCallRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticPropertyFetchRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/VariableVariables/VariableStaticPropertyFetchRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableStaticPropertyFetchRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/VariableVariables/VariableStaticPropertyFetchRuleTest.php - - - - message: "#^Class PHPStan\\\\Rules\\\\VariableVariables\\\\VariableVariablesRuleTest extends generic class PHPStan\\\\Testing\\\\RuleTestCase but does not specify its types\\: TRule$#" - count: 1 - path: tests/Rules/VariableVariables/VariableVariablesRuleTest.php - - - - message: "#^Method PHPStan\\\\Rules\\\\VariableVariables\\\\VariableVariablesRuleTest\\:\\:getRule\\(\\) return type with generic interface PHPStan\\\\Rules\\\\Rule does not specify its types\\: TNodeType$#" - count: 1 - path: tests/Rules/VariableVariables/VariableVariablesRuleTest.php diff --git a/phpstan.neon b/phpstan.neon index f3caa84a..cc5bc263 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,7 +4,6 @@ includes: - vendor/phpstan/phpstan-phpunit/rules.neon - rules.neon - phar://phpstan.phar/conf/bleedingEdge.neon - - phpstan-baseline.neon parameters: excludePaths: diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php index 53140ccf..1e3309a5 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php @@ -6,6 +6,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Node\BooleanAndNode; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; @@ -34,19 +35,19 @@ public function processNode(Node $node, Scope $scope): array $messages = []; if (!$this->helper->passesAsBoolean($scope, $originalNode->left)) { $leftType = $scope->getType($originalNode->left); - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in &&, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightScope = $node->getRightScope(); if (!$this->helper->passesAsBoolean($rightScope, $originalNode->right)) { $rightType = $rightScope->getType($originalNode->right); - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in &&, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php index 0e53c873..9d8a592d 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php @@ -6,9 +6,13 @@ use PhpParser\Node\Expr\BooleanNot; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class BooleanInBooleanNotRule implements Rule { @@ -25,10 +29,6 @@ public function getNodeType(): string return BooleanNot::class; } - /** - * @param BooleanNot $node - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($this->helper->passesAsBoolean($scope, $node->expr)) { @@ -38,10 +38,10 @@ public function processNode(Node $node, Scope $scope): array $expressionType = $scope->getType($node->expr); return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in a negated boolean, %s given.', $expressionType->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php index bf98c5cd..c98da42c 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php @@ -6,6 +6,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Node\BooleanOrNode; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; @@ -34,19 +35,19 @@ public function processNode(Node $node, Scope $scope): array $messages = []; if (!$this->helper->passesAsBoolean($scope, $originalNode->left)) { $leftType = $scope->getType($originalNode->left); - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in ||, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightScope = $node->getRightScope(); if (!$this->helper->passesAsBoolean($rightScope, $originalNode->right)) { $rightType = $rightScope->getType($originalNode->right); - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in ||, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php index 8dfe3dac..ae94956e 100644 --- a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php +++ b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php @@ -6,9 +6,13 @@ use PhpParser\Node\Stmt\ElseIf_; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class BooleanInElseIfConditionRule implements Rule { @@ -25,10 +29,6 @@ public function getNodeType(): string return ElseIf_::class; } - /** - * @param ElseIf_ $node - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($this->helper->passesAsBoolean($scope, $node->cond)) { @@ -38,10 +38,10 @@ public function processNode(Node $node, Scope $scope): array $conditionExpressionType = $scope->getType($node->cond); return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in an elseif condition, %s given.', $conditionExpressionType->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php index 7b1cbfb8..fe858f92 100644 --- a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php +++ b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php @@ -6,9 +6,13 @@ use PhpParser\Node\Stmt\If_; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class BooleanInIfConditionRule implements Rule { @@ -25,10 +29,6 @@ public function getNodeType(): string return If_::class; } - /** - * @param If_ $node - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($this->helper->passesAsBoolean($scope, $node->cond)) { @@ -38,10 +38,10 @@ public function processNode(Node $node, Scope $scope): array $conditionExpressionType = $scope->getType($node->cond); return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in an if condition, %s given.', $conditionExpressionType->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php index 5d389b7a..5c04c283 100644 --- a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php +++ b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php @@ -6,9 +6,13 @@ use PhpParser\Node\Expr\Ternary; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class BooleanInTernaryOperatorRule implements Rule { @@ -25,10 +29,6 @@ public function getNodeType(): string return Ternary::class; } - /** - * @param Ternary $node - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node->if === null) { @@ -42,10 +42,10 @@ public function processNode(Node $node, Scope $scope): array $conditionExpressionType = $scope->getType($node->cond); return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in a ternary operator condition, %s given.', $conditionExpressionType->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/Cast/UselessCastRule.php b/src/Rules/Cast/UselessCastRule.php index c156a09a..1bb526f0 100644 --- a/src/Rules/Cast/UselessCastRule.php +++ b/src/Rules/Cast/UselessCastRule.php @@ -6,13 +6,15 @@ use PhpParser\Node\Expr\Cast; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\ErrorType; use PHPStan\Type\GeneralizePrecision; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class UselessCastRule implements Rule { @@ -29,10 +31,6 @@ public function getNodeType(): string return Cast::class; } - /** - * @param Cast $node - * @return RuleError[] errors - */ public function processNode(Node $node, Scope $scope): array { $castType = $scope->getType($node); diff --git a/src/Rules/Classes/RequireParentConstructCallRule.php b/src/Rules/Classes/RequireParentConstructCallRule.php index c07e04e4..fae97f32 100644 --- a/src/Rules/Classes/RequireParentConstructCallRule.php +++ b/src/Rules/Classes/RequireParentConstructCallRule.php @@ -10,10 +10,14 @@ use PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass; use PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnum; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\ShouldNotHappenException; use function property_exists; use function sprintf; +/** + * @implements Rule + */ class RequireParentConstructCallRule implements Rule { @@ -22,10 +26,6 @@ public function getNodeType(): string return ClassMethod::class; } - /** - * @param ClassMethod $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if (!$scope->isInClass()) { @@ -52,30 +52,30 @@ public function processNode(Node $node, Scope $scope): array if ($this->callsParentConstruct($node)) { if ($classReflection->getParentClass() === false) { return [ - sprintf( + RuleErrorBuilder::message(sprintf( '%s::__construct() calls parent constructor but does not extend any class.', $classReflection->getName() - ), + ))->build(), ]; } if ($this->getParentConstructorClass($classReflection) === false) { return [ - sprintf( + RuleErrorBuilder::message(sprintf( '%s::__construct() calls parent constructor but parent does not have one.', $classReflection->getName() - ), + ))->build(), ]; } } else { $parentClass = $this->getParentConstructorClass($classReflection); if ($parentClass !== false) { return [ - sprintf( + RuleErrorBuilder::message(sprintf( '%s::__construct() does not call parent constructor from %s.', $classReflection->getName(), $parentClass->getName() - ), + ))->build(), ]; } } diff --git a/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php b/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php index aab3824d..d2b4bc66 100644 --- a/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php @@ -3,11 +3,14 @@ namespace PHPStan\Rules\DisallowedConstructs; use PhpParser\Node; -use PhpParser\Node\Expr\Empty_; use PhpParser\Node\Expr\ShellExec; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; +/** + * @implements Rule + */ class DisallowedBacktickRule implements Rule { @@ -16,14 +19,11 @@ public function getNodeType(): string return ShellExec::class; } - /** - * @param Empty_ $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { return [ - 'Backtick operator is not allowed. Use shell_exec() instead.', + RuleErrorBuilder::message('Backtick operator is not allowed. Use shell_exec() instead.') + ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php b/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php index 9a867cd5..4e0be7b2 100644 --- a/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php @@ -6,7 +6,11 @@ use PhpParser\Node\Expr\Empty_; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; +/** + * @implements Rule + */ class DisallowedEmptyRule implements Rule { @@ -15,14 +19,11 @@ public function getNodeType(): string return Empty_::class; } - /** - * @param Empty_ $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { return [ - 'Construct empty() is not allowed. Use more strict comparison.', + RuleErrorBuilder::message('Construct empty() is not allowed. Use more strict comparison.') + ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php b/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php index 322d0dac..f775dc47 100644 --- a/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php @@ -8,9 +8,13 @@ use PhpParser\Node\Expr\Variable; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use function is_string; use function sprintf; +/** + * @implements Rule + */ class DisallowedImplicitArrayCreationRule implements Rule { @@ -19,10 +23,6 @@ public function getNodeType(): string return Assign::class; } - /** - * @param Assign $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if (!$node->var instanceof ArrayDimFetch) { @@ -45,13 +45,15 @@ public function processNode(Node $node, Scope $scope): array $certainty = $scope->hasVariableType($node->name); if ($certainty->no()) { return [ - sprintf('Implicit array creation is not allowed - variable $%s does not exist.', $node->name), + RuleErrorBuilder::message(sprintf('Implicit array creation is not allowed - variable $%s does not exist.', $node->name)) + ->build(), ]; } if ($certainty->maybe()) { return [ - sprintf('Implicit array creation is not allowed - variable $%s might not exist.', $node->name), + RuleErrorBuilder::message(sprintf('Implicit array creation is not allowed - variable $%s might not exist.', $node->name)) + ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php b/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php index 59db24ac..349f6ca2 100644 --- a/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr\Ternary; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; /** * @implements Rule @@ -25,7 +26,8 @@ public function processNode(Node $node, Scope $scope): array } return [ - 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + RuleErrorBuilder::message('Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.') + ->build(), ]; } diff --git a/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php b/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php index ca8f631c..89861a99 100644 --- a/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php +++ b/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php @@ -8,6 +8,8 @@ use PhpParser\Node\Stmt\For_; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use function is_string; use function sprintf; @@ -22,10 +24,6 @@ public function getNodeType(): string return For_::class; } - /** - * @param For_ $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { $errors = []; @@ -43,7 +41,7 @@ public function processNode(Node $node, Scope $scope): array } /** - * @return string[] + * @return list */ private function checkValueVar(Scope $scope, Expr $expr): array { @@ -53,7 +51,8 @@ private function checkValueVar(Scope $scope, Expr $expr): array && is_string($expr->name) && $scope->hasVariableType($expr->name)->yes() ) { - $errors[] = sprintf('For loop initial assignment overwrites variable $%s.', $expr->name); + $errors[] = RuleErrorBuilder::message(sprintf('For loop initial assignment overwrites variable $%s.', $expr->name)) + ->build(); } if ( diff --git a/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php b/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php index dbf16d25..e3932121 100644 --- a/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php +++ b/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php @@ -7,21 +7,21 @@ use PhpParser\Node\Stmt\Foreach_; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use function is_string; use function sprintf; +/** + * @implements Rule + */ class OverwriteVariablesWithForeachRule implements Rule { public function getNodeType(): string { - return Node\Stmt\Foreach_::class; + return Foreach_::class; } - /** - * @param Foreach_ $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { $errors = []; @@ -30,7 +30,8 @@ public function processNode(Node $node, Scope $scope): array && is_string($node->keyVar->name) && $scope->hasVariableType($node->keyVar->name)->yes() ) { - $errors[] = sprintf('Foreach overwrites $%s with its key variable.', $node->keyVar->name); + $errors[] = RuleErrorBuilder::message(sprintf('Foreach overwrites $%s with its key variable.', $node->keyVar->name)) + ->build(); } foreach ($this->checkValueVar($scope, $node->valueVar) as $error) { @@ -51,7 +52,8 @@ private function checkValueVar(Scope $scope, Expr $expr): array && is_string($expr->name) && $scope->hasVariableType($expr->name)->yes() ) { - $errors[] = sprintf('Foreach overwrites $%s with its value variable.', $expr->name); + $errors[] = RuleErrorBuilder::message(sprintf('Foreach overwrites $%s with its value variable.', $expr->name)) + ->build(); } if ( diff --git a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php index be62e245..bb8fc5cc 100644 --- a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php +++ b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php @@ -7,6 +7,8 @@ use PHPStan\Node\InClassMethodNode; use PHPStan\Reflection\ClassReflection; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use function sprintf; /** @@ -50,9 +52,6 @@ public function processNode( continue; } - /** @var string $interfaceMessage */ - $interfaceMessage = $interfaceMessage; - $messages[] = $interfaceMessage; } @@ -63,7 +62,7 @@ private function findMethod( ClassReflection $declaringClass, ClassReflection $classReflection, string $methodName - ): ?string + ): ?RuleError { if (!$classReflection->hasNativeMethod($methodName)) { return null; @@ -74,14 +73,14 @@ private function findMethod( return null; } - return sprintf( + return RuleErrorBuilder::message(sprintf( 'Method %s::%s() does not match %s method name: %s::%s().', $declaringClass->getDisplayName(), $methodName, $classReflection->isInterface() ? 'interface' : 'parent', $classReflection->getDisplayName(), $parentMethod->getName() - ); + ))->build(); } } diff --git a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php index 13364758..56b590d9 100644 --- a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php @@ -9,6 +9,7 @@ use PhpParser\Node\Expr\PreInc; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; @@ -28,8 +29,7 @@ public function __construct(OperatorRuleHelper $helper) } /** - * @param PreInc|PreDec|PostInc|PostDec $node - * @return string[] errors + * @param TNodeType $node */ public function processNode(Node $node, Scope $scope): array { @@ -42,11 +42,11 @@ public function processNode(Node $node, Scope $scope): array || ($node instanceof PreDec || $node instanceof PostDec) && !$this->helper->isValidForDecrement($scope, $node->var) ) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %s, %s given.', $this->describeOperation(), $varType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php index ba29b5a7..2dbf3efc 100644 --- a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php @@ -8,10 +8,14 @@ use PhpParser\Node\Expr\BinaryOp\Plus as BinaryOpPlus; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function count; use function sprintf; +/** + * @implements Rule + */ class OperandsInArithmeticAdditionRule implements Rule { @@ -32,9 +36,6 @@ public function getNodeType(): string return Expr::class; } - /** - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node instanceof BinaryOpPlus) { @@ -55,16 +56,16 @@ public function processNode(Node $node, Scope $scope): array $messages = []; if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in +, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in +, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php index 663ff36e..423455f3 100644 --- a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php @@ -8,9 +8,13 @@ use PhpParser\Node\Expr\BinaryOp\Div as BinaryOpDiv; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class OperandsInArithmeticDivisionRule implements Rule { @@ -31,9 +35,6 @@ public function getNodeType(): string return Expr::class; } - /** - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node instanceof BinaryOpDiv) { @@ -49,18 +50,18 @@ public function processNode(Node $node, Scope $scope): array $messages = []; $leftType = $scope->getType($left); if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in /, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightType = $scope->getType($right); if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in /, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php index 40f7ae7e..b2b67f3d 100644 --- a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php @@ -8,9 +8,13 @@ use PhpParser\Node\Expr\BinaryOp\Pow as BinaryOpPow; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class OperandsInArithmeticExponentiationRule implements Rule { @@ -31,9 +35,6 @@ public function getNodeType(): string return Expr::class; } - /** - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node instanceof BinaryOpPow) { @@ -49,18 +50,18 @@ public function processNode(Node $node, Scope $scope): array $messages = []; $leftType = $scope->getType($left); if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in **, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightType = $scope->getType($right); if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in **, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticModuloRule.php b/src/Rules/Operators/OperandsInArithmeticModuloRule.php index 38e0d38d..1932945d 100644 --- a/src/Rules/Operators/OperandsInArithmeticModuloRule.php +++ b/src/Rules/Operators/OperandsInArithmeticModuloRule.php @@ -8,9 +8,13 @@ use PhpParser\Node\Expr\BinaryOp\Mod as BinaryOpMod; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class OperandsInArithmeticModuloRule implements Rule { @@ -31,9 +35,6 @@ public function getNodeType(): string return Expr::class; } - /** - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node instanceof BinaryOpMod) { @@ -49,18 +50,18 @@ public function processNode(Node $node, Scope $scope): array $messages = []; $leftType = $scope->getType($left); if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %%, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightType = $scope->getType($right); if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %%, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php index f1e4c064..1c99f70f 100644 --- a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php @@ -8,9 +8,13 @@ use PhpParser\Node\Expr\BinaryOp\Mul as BinaryOpMul; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class OperandsInArithmeticMultiplicationRule implements Rule { @@ -31,9 +35,6 @@ public function getNodeType(): string return Expr::class; } - /** - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node instanceof BinaryOpMul) { @@ -49,18 +50,18 @@ public function processNode(Node $node, Scope $scope): array $messages = []; $leftType = $scope->getType($left); if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in *, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightType = $scope->getType($right); if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in *, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php index 5333c2a1..4ac61d53 100644 --- a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php @@ -8,9 +8,13 @@ use PhpParser\Node\Expr\BinaryOp\Minus as BinaryOpMinus; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class OperandsInArithmeticSubtractionRule implements Rule { @@ -31,9 +35,6 @@ public function getNodeType(): string return Expr::class; } - /** - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if ($node instanceof BinaryOpMinus) { @@ -49,18 +50,18 @@ public function processNode(Node $node, Scope $scope): array $messages = []; $leftType = $scope->getType($left); if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in -, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } $rightType = $scope->getType($right); if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { - $messages[] = sprintf( + $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in -, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ); + ))->build(); } return $messages; diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php index 95e27fec..73ea10a4 100644 --- a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php +++ b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php @@ -6,6 +6,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Node\MethodCallableNode; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Rules\RuleLevelHelper; use PHPStan\Type\ErrorType; use PHPStan\Type\Type; @@ -52,11 +53,13 @@ static function (Type $type) use ($name): bool { $methodReflection = $type->getMethod($name, $scope); if ($methodReflection->isStatic()) { - return [sprintf( - 'Dynamic call to static method %s::%s().', - $methodReflection->getDeclaringClass()->getDisplayName(), - $methodReflection->getName() - )]; + return [ + RuleErrorBuilder::message(sprintf( + 'Dynamic call to static method %s::%s().', + $methodReflection->getDeclaringClass()->getDisplayName(), + $methodReflection->getName() + ))->build(), + ]; } return []; diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php index 5319c3a8..269f6132 100644 --- a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php +++ b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\PHPStanTestCase; use PHPStan\Testing\TypeInferenceTestCase; @@ -14,6 +15,9 @@ use function in_array; use function sprintf; +/** + * @implements Rule + */ class DynamicCallOnStaticMethodsRule implements Rule { @@ -30,10 +34,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @param MethodCall $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if (!$node->name instanceof Node\Identifier) { @@ -64,11 +64,13 @@ static function (Type $type) use ($name): bool { return []; } - return [sprintf( - 'Dynamic call to static method %s::%s().', - $methodReflection->getDeclaringClass()->getDisplayName(), - $methodReflection->getName() - )]; + return [ + RuleErrorBuilder::message(sprintf( + 'Dynamic call to static method %s::%s().', + $methodReflection->getDeclaringClass()->getDisplayName(), + $methodReflection->getName() + ))->build(), + ]; } return []; diff --git a/src/Rules/StrictCalls/StrictFunctionCallsRule.php b/src/Rules/StrictCalls/StrictFunctionCallsRule.php index b27c25fe..04508699 100644 --- a/src/Rules/StrictCalls/StrictFunctionCallsRule.php +++ b/src/Rules/StrictCalls/StrictFunctionCallsRule.php @@ -8,11 +8,15 @@ use PHPStan\Analyser\Scope; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\Constant\ConstantBooleanType; use function array_key_exists; use function sprintf; use function strtolower; +/** + * @implements Rule + */ class StrictFunctionCallsRule implements Rule { @@ -37,10 +41,6 @@ public function getNodeType(): string return FuncCall::class; } - /** - * @param FuncCall $node - * @return string[] errors - */ public function processNode(Node $node, Scope $scope): array { if (!$node->name instanceof Name) { @@ -62,13 +62,25 @@ public function processNode(Node $node, Scope $scope): array $argumentPosition = $this->functionArguments[$functionName]; if (!array_key_exists($argumentPosition, $node->getArgs())) { - return [sprintf('Call to function %s() requires parameter #%d to be set.', $functionName, $argumentPosition + 1)]; + return [ + RuleErrorBuilder::message(sprintf( + 'Call to function %s() requires parameter #%d to be set.', + $functionName, + $argumentPosition + 1 + ))->build(), + ]; } $argumentType = $scope->getType($node->getArgs()[$argumentPosition]->value); $trueType = new ConstantBooleanType(true); if (!$trueType->isSuperTypeOf($argumentType)->yes()) { - return [sprintf('Call to function %s() requires parameter #%d to be true.', $functionName, $argumentPosition + 1)]; + return [ + RuleErrorBuilder::message(sprintf( + 'Call to function %s() requires parameter #%d to be true.', + $functionName, + $argumentPosition + 1 + ))->build(), + ]; } return []; diff --git a/src/Rules/VariableVariables/VariableMethodCallRule.php b/src/Rules/VariableVariables/VariableMethodCallRule.php index 4221cfa8..6d18a2eb 100644 --- a/src/Rules/VariableVariables/VariableMethodCallRule.php +++ b/src/Rules/VariableVariables/VariableMethodCallRule.php @@ -6,21 +6,21 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class VariableMethodCallRule implements Rule { public function getNodeType(): string { - return Node\Expr\MethodCall::class; + return MethodCall::class; } - /** - * @param MethodCall $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if ($node->name instanceof Node\Identifier) { @@ -28,10 +28,10 @@ public function processNode(Node $node, Scope $scope): array } return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Variable method call on %s.', $scope->getType($node->var)->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableMethodCallableRule.php b/src/Rules/VariableVariables/VariableMethodCallableRule.php index f293b562..be904f95 100644 --- a/src/Rules/VariableVariables/VariableMethodCallableRule.php +++ b/src/Rules/VariableVariables/VariableMethodCallableRule.php @@ -6,6 +6,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Node\MethodCallableNode; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; @@ -27,10 +28,10 @@ public function processNode(Node $node, Scope $scope): array } return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Variable method call on %s.', $scope->getType($node->getVar())->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/VariableVariables/VariablePropertyFetchRule.php b/src/Rules/VariableVariables/VariablePropertyFetchRule.php index 1b7fe52d..0b2e9b7b 100644 --- a/src/Rules/VariableVariables/VariablePropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariablePropertyFetchRule.php @@ -8,9 +8,13 @@ use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class VariablePropertyFetchRule implements Rule { @@ -31,13 +35,9 @@ public function __construct(ReflectionProvider $reflectionProvider, array $unive public function getNodeType(): string { - return Node\Expr\PropertyFetch::class; + return PropertyFetch::class; } - /** - * @param PropertyFetch $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if ($node->name instanceof Node\Identifier) { @@ -56,10 +56,10 @@ public function processNode(Node $node, Scope $scope): array } return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Variable property access on %s.', $fetchedOnType->describe(VerbosityLevel::typeOnly()) - ), + ))->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php index 0d6b8202..5250dd6e 100644 --- a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php +++ b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php @@ -6,21 +6,21 @@ use PhpParser\Node\Expr\StaticCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class VariableStaticMethodCallRule implements Rule { public function getNodeType(): string { - return Node\Expr\StaticCall::class; + return StaticCall::class; } - /** - * @param StaticCall $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if ($node->name instanceof Node\Identifier) { @@ -34,10 +34,10 @@ public function processNode(Node $node, Scope $scope): array } return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Variable static method call on %s.', $methodCalledOn - ), + ))->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php index 8ede1f00..1dc6280a 100644 --- a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php +++ b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php @@ -6,6 +6,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Node\StaticMethodCallableNode; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; @@ -33,10 +34,10 @@ public function processNode(Node $node, Scope $scope): array } return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Variable static method call on %s.', $methodCalledOn - ), + ))->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php index 4b410a7f..72d937ef 100644 --- a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php @@ -6,21 +6,21 @@ use PhpParser\Node\Expr\StaticPropertyFetch; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; use function sprintf; +/** + * @implements Rule + */ class VariableStaticPropertyFetchRule implements Rule { public function getNodeType(): string { - return Node\Expr\StaticPropertyFetch::class; + return StaticPropertyFetch::class; } - /** - * @param StaticPropertyFetch $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if ($node->name instanceof Node\Identifier) { @@ -34,10 +34,10 @@ public function processNode(Node $node, Scope $scope): array } return [ - sprintf( + RuleErrorBuilder::message(sprintf( 'Variable static property access on %s.', $propertyAccessedOn - ), + ))->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableVariablesRule.php b/src/Rules/VariableVariables/VariableVariablesRule.php index 9768f21b..fee986a7 100644 --- a/src/Rules/VariableVariables/VariableVariablesRule.php +++ b/src/Rules/VariableVariables/VariableVariablesRule.php @@ -6,20 +6,20 @@ use PhpParser\Node\Expr\Variable; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; use function is_string; +/** + * @implements Rule + */ class VariableVariablesRule implements Rule { public function getNodeType(): string { - return Node\Expr\Variable::class; + return Variable::class; } - /** - * @param Variable $node - * @return string[] - */ public function processNode(Node $node, Scope $scope): array { if (is_string($node->name)) { @@ -27,7 +27,8 @@ public function processNode(Node $node, Scope $scope): array } return [ - 'Variable variables are not allowed.', + RuleErrorBuilder::message('Variable variables are not allowed.') + ->build(), ]; } diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php index 33dd205c..1d5e017d 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class BooleanInBooleanNotRuleTest extends RuleTestCase { diff --git a/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php index b2df79fc..43cd364b 100644 --- a/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class BooleanInElseIfConditionRuleTest extends RuleTestCase { diff --git a/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php index 196af111..59324856 100644 --- a/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class BooleanInIfConditionRuleTest extends RuleTestCase { diff --git a/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php index 76bd4ad0..a7149e00 100644 --- a/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class BooleanInTernaryOperatorRuleTest extends RuleTestCase { diff --git a/tests/Rules/Cast/UselessCastRuleTest.php b/tests/Rules/Cast/UselessCastRuleTest.php index c1affdde..0d26a4ec 100644 --- a/tests/Rules/Cast/UselessCastRuleTest.php +++ b/tests/Rules/Cast/UselessCastRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class UselessCastRuleTest extends RuleTestCase { diff --git a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php index caeee5c8..38fdc5c7 100644 --- a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php +++ b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Testing\RuleTestCase; use const PHP_VERSION_ID; +/** + * @extends RuleTestCase + */ class RequireParentConstructCallRuleTest extends RuleTestCase { diff --git a/tests/Rules/DisallowedConstructs/DisallowedBacktickRuleTest.php b/tests/Rules/DisallowedConstructs/DisallowedBacktickRuleTest.php index 1b697e0a..e370f3e7 100644 --- a/tests/Rules/DisallowedConstructs/DisallowedBacktickRuleTest.php +++ b/tests/Rules/DisallowedConstructs/DisallowedBacktickRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class DisallowedBacktickRuleTest extends RuleTestCase { diff --git a/tests/Rules/DisallowedConstructs/DisallowedEmptyRuleTest.php b/tests/Rules/DisallowedConstructs/DisallowedEmptyRuleTest.php index 5ffc7f67..172093ba 100644 --- a/tests/Rules/DisallowedConstructs/DisallowedEmptyRuleTest.php +++ b/tests/Rules/DisallowedConstructs/DisallowedEmptyRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class DisallowedEmptyRuleTest extends RuleTestCase { diff --git a/tests/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRuleTest.php b/tests/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRuleTest.php index 6092a5f4..69c25a7a 100644 --- a/tests/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRuleTest.php +++ b/tests/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class DisallowedImplicitArrayCreationRuleTest extends RuleTestCase { diff --git a/tests/Rules/ForeachLoop/OverwriteVariablesWithForeachRuleTest.php b/tests/Rules/ForeachLoop/OverwriteVariablesWithForeachRuleTest.php index 5d483d55..031aa148 100644 --- a/tests/Rules/ForeachLoop/OverwriteVariablesWithForeachRuleTest.php +++ b/tests/Rules/ForeachLoop/OverwriteVariablesWithForeachRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class OverwriteVariablesWithForeachRuleTest extends RuleTestCase { diff --git a/tests/Rules/Methods/WrongCaseOfInheritedMethodRuleTest.php b/tests/Rules/Methods/WrongCaseOfInheritedMethodRuleTest.php index b2425faf..d4235b6b 100644 --- a/tests/Rules/Methods/WrongCaseOfInheritedMethodRuleTest.php +++ b/tests/Rules/Methods/WrongCaseOfInheritedMethodRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class WrongCaseOfInheritedMethodRuleTest extends RuleTestCase { diff --git a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php index 02e38f43..b737cc30 100644 --- a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php @@ -6,6 +6,10 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @template T of Rule + * @extends RuleTestCase + */ abstract class OperandInArithmeticIncrementOrDecrementRuleTest extends RuleTestCase { @@ -23,6 +27,9 @@ public function testRule(): void $this->analyse([__DIR__ . '/data/increment-decrement.php'], $this->getExpectedErrors()); } + /** + * @return T + */ abstract protected function createRule(OperatorRuleHelper $helper): Rule; /** diff --git a/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php index 0a441d8a..2572c751 100644 --- a/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php @@ -4,6 +4,9 @@ use PHPStan\Rules\Rule; +/** + * @extends OperandInArithmeticIncrementOrDecrementRuleTest + */ class OperandInArithmeticPostDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest { diff --git a/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php index 0b18f3a9..4a7ad751 100644 --- a/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php @@ -4,6 +4,9 @@ use PHPStan\Rules\Rule; +/** + * @extends OperandInArithmeticIncrementOrDecrementRuleTest + */ class OperandInArithmeticPostIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest { diff --git a/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php index 2e695f89..bcc9e64a 100644 --- a/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php @@ -4,6 +4,9 @@ use PHPStan\Rules\Rule; +/** + * @extends OperandInArithmeticIncrementOrDecrementRuleTest + */ class OperandInArithmeticPreDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest { diff --git a/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php index 47449369..d733207e 100644 --- a/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php @@ -4,6 +4,9 @@ use PHPStan\Rules\Rule; +/** + * @extends OperandInArithmeticIncrementOrDecrementRuleTest + */ class OperandInArithmeticPreIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest { diff --git a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php index 892db77f..0d25e12c 100644 --- a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php @@ -8,6 +8,9 @@ use function array_merge; use const PHP_VERSION_ID; +/** + * @extends RuleTestCase + */ class OperandsInArithmeticAdditionRuleTest extends RuleTestCase { diff --git a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php index 0571e38d..74e21357 100644 --- a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class OperandsInArithmeticDivisionRuleTest extends RuleTestCase { diff --git a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php index 56492a36..2ae96a42 100644 --- a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class OperandsInArithmeticExponentiationRuleTest extends RuleTestCase { diff --git a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php index 953732ca..e58e489e 100644 --- a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class OperandsInArithmeticModuloRuleTest extends RuleTestCase { diff --git a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php index a0015d27..51c6a8c3 100644 --- a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class OperandsInArithmeticMultiplicationRuleTest extends RuleTestCase { diff --git a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php index cbe8e08d..3b7cf00f 100644 --- a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class OperandsInArithmeticSubtractionRuleTest extends RuleTestCase { diff --git a/tests/Rules/StrictCalls/DynamicCallOnStaticMethodsRuleTest.php b/tests/Rules/StrictCalls/DynamicCallOnStaticMethodsRuleTest.php index a35919a2..a009b1e4 100644 --- a/tests/Rules/StrictCalls/DynamicCallOnStaticMethodsRuleTest.php +++ b/tests/Rules/StrictCalls/DynamicCallOnStaticMethodsRuleTest.php @@ -6,6 +6,9 @@ use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class DynamicCallOnStaticMethodsRuleTest extends RuleTestCase { diff --git a/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php b/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php index 8a1ce29c..fa08fe7a 100644 --- a/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php +++ b/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class StrictFunctionCallsRuleTest extends RuleTestCase { diff --git a/tests/Rules/VariableVariables/VariableMethodCallRuleTest.php b/tests/Rules/VariableVariables/VariableMethodCallRuleTest.php index 150df3fb..36304bbb 100644 --- a/tests/Rules/VariableVariables/VariableMethodCallRuleTest.php +++ b/tests/Rules/VariableVariables/VariableMethodCallRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class VariableMethodCallRuleTest extends RuleTestCase { diff --git a/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php b/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php index 2cf7e17d..9126d836 100644 --- a/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php +++ b/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class VariablePropertyFetchRuleTest extends RuleTestCase { diff --git a/tests/Rules/VariableVariables/VariableStaticMethodCallRuleTest.php b/tests/Rules/VariableVariables/VariableStaticMethodCallRuleTest.php index d55bd585..35796bf3 100644 --- a/tests/Rules/VariableVariables/VariableStaticMethodCallRuleTest.php +++ b/tests/Rules/VariableVariables/VariableStaticMethodCallRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class VariableStaticMethodCallRuleTest extends RuleTestCase { diff --git a/tests/Rules/VariableVariables/VariableStaticPropertyFetchRuleTest.php b/tests/Rules/VariableVariables/VariableStaticPropertyFetchRuleTest.php index 7fe3dde0..91a8f71d 100644 --- a/tests/Rules/VariableVariables/VariableStaticPropertyFetchRuleTest.php +++ b/tests/Rules/VariableVariables/VariableStaticPropertyFetchRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class VariableStaticPropertyFetchRuleTest extends RuleTestCase { diff --git a/tests/Rules/VariableVariables/VariableVariablesRuleTest.php b/tests/Rules/VariableVariables/VariableVariablesRuleTest.php index 1b9fdef6..fcc73913 100644 --- a/tests/Rules/VariableVariables/VariableVariablesRuleTest.php +++ b/tests/Rules/VariableVariables/VariableVariablesRuleTest.php @@ -5,6 +5,9 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class VariableVariablesRuleTest extends RuleTestCase { From 872bc91400552a0aa55e6a297261d24eb4d46ebb Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 9 Jun 2023 16:03:40 +0200 Subject: [PATCH 09/13] Removed some errors from RequireParentConstructCallRule - already reported by PHPStan core --- .../RequireParentConstructCallRule.php | 38 ++++++------------- .../RequireParentConstructCallRuleTest.php | 11 +----- 2 files changed, 12 insertions(+), 37 deletions(-) diff --git a/src/Rules/Classes/RequireParentConstructCallRule.php b/src/Rules/Classes/RequireParentConstructCallRule.php index fae97f32..b533fe53 100644 --- a/src/Rules/Classes/RequireParentConstructCallRule.php +++ b/src/Rules/Classes/RequireParentConstructCallRule.php @@ -50,34 +50,18 @@ public function processNode(Node $node, Scope $scope): array } if ($this->callsParentConstruct($node)) { - if ($classReflection->getParentClass() === false) { - return [ - RuleErrorBuilder::message(sprintf( - '%s::__construct() calls parent constructor but does not extend any class.', - $classReflection->getName() - ))->build(), - ]; - } + return []; + } - if ($this->getParentConstructorClass($classReflection) === false) { - return [ - RuleErrorBuilder::message(sprintf( - '%s::__construct() calls parent constructor but parent does not have one.', - $classReflection->getName() - ))->build(), - ]; - } - } else { - $parentClass = $this->getParentConstructorClass($classReflection); - if ($parentClass !== false) { - return [ - RuleErrorBuilder::message(sprintf( - '%s::__construct() does not call parent constructor from %s.', - $classReflection->getName(), - $parentClass->getName() - ))->build(), - ]; - } + $parentClass = $this->getParentConstructorClass($classReflection); + if ($parentClass !== false) { + return [ + RuleErrorBuilder::message(sprintf( + '%s::__construct() does not call parent constructor from %s.', + $classReflection->getName(), + $parentClass->getName() + ))->build(), + ]; } return []; diff --git a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php index 38fdc5c7..e8d63620 100644 --- a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php +++ b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php @@ -20,10 +20,6 @@ protected function getRule(): Rule public function testCallToParentConstructor(): void { $this->analyse([__DIR__ . '/data/call-to-parent-constructor.php'], [ - [ - 'IpsumCallToParentConstructor::__construct() calls parent constructor but parent does not have one.', - 31, - ], [ 'BCallToParentConstructor::__construct() does not call parent constructor from ACallToParentConstructor.', 51, @@ -53,12 +49,7 @@ public function testCallsParentButHasNotParent(): void if (PHP_VERSION_ID >= 70400) { self::markTestSkipped('This test does not support PHP 7.4 or higher.'); } - $this->analyse([__DIR__ . '/data/call-to-parent-constructor-php-lt-74.php'], [ - [ - 'CCallToParentConstructor::__construct() calls parent constructor but does not extend any class.', - 6, - ], - ]); + $this->analyse([__DIR__ . '/data/call-to-parent-constructor-php-lt-74.php'], []); } } From 477f53a560823cef4751429d91d62630ce265992 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 14:09:30 +0200 Subject: [PATCH 10/13] Error identifiers --- .../BooleansInConditions/BooleanInBooleanAndRule.php | 4 ++-- .../BooleansInConditions/BooleanInBooleanNotRule.php | 2 +- src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php | 4 ++-- .../BooleansInConditions/BooleanInElseIfConditionRule.php | 2 +- .../BooleansInConditions/BooleanInIfConditionRule.php | 2 +- .../BooleansInConditions/BooleanInTernaryOperatorRule.php | 2 +- src/Rules/Cast/UselessCastRule.php | 2 +- src/Rules/Classes/RequireParentConstructCallRule.php | 2 +- src/Rules/DisallowedConstructs/DisallowedBacktickRule.php | 1 + src/Rules/DisallowedConstructs/DisallowedEmptyRule.php | 1 + .../DisallowedImplicitArrayCreationRule.php | 2 ++ .../DisallowedLooseComparisonRule.php | 8 ++++++-- .../DisallowedConstructs/DisallowedShortTernaryRule.php | 1 + .../ForLoop/OverwriteVariablesWithForLoopInitRule.php | 5 +++-- .../ForeachLoop/OverwriteVariablesWithForeachRule.php | 5 ++++- src/Rules/Functions/ClosureUsesThisRule.php | 1 + src/Rules/Methods/WrongCaseOfInheritedMethodRule.php | 6 +++--- .../OperandInArithmeticIncrementOrDecrementRule.php | 7 ++++++- .../Operators/OperandInArithmeticPostDecrementRule.php | 5 +++++ .../Operators/OperandInArithmeticPostIncrementRule.php | 5 +++++ .../Operators/OperandInArithmeticPreDecrementRule.php | 5 +++++ .../Operators/OperandInArithmeticPreIncrementRule.php | 5 +++++ src/Rules/Operators/OperandsInArithmeticAdditionRule.php | 4 ++-- src/Rules/Operators/OperandsInArithmeticDivisionRule.php | 4 ++-- .../Operators/OperandsInArithmeticExponentiationRule.php | 4 ++-- src/Rules/Operators/OperandsInArithmeticModuloRule.php | 4 ++-- .../Operators/OperandsInArithmeticMultiplicationRule.php | 4 ++-- .../Operators/OperandsInArithmeticSubtractionRule.php | 4 ++-- .../DynamicCallOnStaticMethodsCallableRule.php | 2 +- src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php | 2 +- src/Rules/StrictCalls/StrictFunctionCallsRule.php | 4 ++-- .../MatchingTypeInSwitchCaseConditionRule.php | 5 ++++- src/Rules/VariableVariables/VariableMethodCallRule.php | 2 +- .../VariableVariables/VariableMethodCallableRule.php | 2 +- src/Rules/VariableVariables/VariablePropertyFetchRule.php | 2 +- .../VariableVariables/VariableStaticMethodCallRule.php | 2 +- .../VariableStaticMethodCallableRule.php | 2 +- .../VariableVariables/VariableStaticPropertyFetchRule.php | 2 +- src/Rules/VariableVariables/VariableVariablesRule.php | 1 + 39 files changed, 85 insertions(+), 42 deletions(-) diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php index 1e3309a5..a266d851 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php @@ -38,7 +38,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in &&, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('booleanAnd.leftNotBoolean')->build(); } $rightScope = $node->getRightScope(); @@ -47,7 +47,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in &&, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('booleanAnd.rightNotBoolean')->build(); } return $messages; diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php index 9d8a592d..6fcdd06c 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php @@ -41,7 +41,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in a negated boolean, %s given.', $expressionType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('booleanNot.exprNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php index c98da42c..144bda22 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php @@ -38,7 +38,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in ||, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('booleanOr.leftNotBoolean')->build(); } $rightScope = $node->getRightScope(); @@ -47,7 +47,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in ||, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('booleanOr.rightNotBoolean')->build(); } return $messages; diff --git a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php index ae94956e..2501b828 100644 --- a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php +++ b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php @@ -41,7 +41,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in an elseif condition, %s given.', $conditionExpressionType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('elseif.condNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php index fe858f92..5adb10ed 100644 --- a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php +++ b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php @@ -41,7 +41,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in an if condition, %s given.', $conditionExpressionType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('if.condNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php index 5c04c283..e1ac9ccb 100644 --- a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php +++ b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php @@ -45,7 +45,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in a ternary operator condition, %s given.', $conditionExpressionType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('ternary.condNotBoolean')->build(), ]; } diff --git a/src/Rules/Cast/UselessCastRule.php b/src/Rules/Cast/UselessCastRule.php index 1bb526f0..adc20e14 100644 --- a/src/Rules/Cast/UselessCastRule.php +++ b/src/Rules/Cast/UselessCastRule.php @@ -62,7 +62,7 @@ public function processNode(Node $node, Scope $scope): array 'Casting to %s something that\'s already %s.', $castType->describe(VerbosityLevel::typeOnly()), $expressionType->describe(VerbosityLevel::typeOnly()) - )))->build(), + )))->identifier('cast.useless')->build(), ]; } diff --git a/src/Rules/Classes/RequireParentConstructCallRule.php b/src/Rules/Classes/RequireParentConstructCallRule.php index b533fe53..76d3d16c 100644 --- a/src/Rules/Classes/RequireParentConstructCallRule.php +++ b/src/Rules/Classes/RequireParentConstructCallRule.php @@ -60,7 +60,7 @@ public function processNode(Node $node, Scope $scope): array '%s::__construct() does not call parent constructor from %s.', $classReflection->getName(), $parentClass->getName() - ))->build(), + ))->identifier('constructor.missingParentCall')->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php b/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php index d2b4bc66..76e401ce 100644 --- a/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php @@ -23,6 +23,7 @@ public function processNode(Node $node, Scope $scope): array { return [ RuleErrorBuilder::message('Backtick operator is not allowed. Use shell_exec() instead.') + ->identifier('backtick.notAllowed') ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php b/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php index 4e0be7b2..d19f5ea2 100644 --- a/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php @@ -23,6 +23,7 @@ public function processNode(Node $node, Scope $scope): array { return [ RuleErrorBuilder::message('Construct empty() is not allowed. Use more strict comparison.') + ->identifier('empty.notAllowed') ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php b/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php index f775dc47..cee777ce 100644 --- a/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php @@ -46,6 +46,7 @@ public function processNode(Node $node, Scope $scope): array if ($certainty->no()) { return [ RuleErrorBuilder::message(sprintf('Implicit array creation is not allowed - variable $%s does not exist.', $node->name)) + ->identifier('variable.implicitArray') ->build(), ]; } @@ -53,6 +54,7 @@ public function processNode(Node $node, Scope $scope): array if ($certainty->maybe()) { return [ RuleErrorBuilder::message(sprintf('Implicit array creation is not allowed - variable $%s might not exist.', $node->name)) + ->identifier('variable.implicitArray') ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php b/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php index a1425c76..9b709be9 100644 --- a/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php @@ -27,14 +27,18 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message( 'Loose comparison via "==" is not allowed.' - )->tip('Use strict comparison via "===" instead.')->build(), + )->tip('Use strict comparison via "===" instead.') + ->identifier('equal.notAllowed') + ->build(), ]; } if ($node instanceof NotEqual) { return [ RuleErrorBuilder::message( 'Loose comparison via "!=" is not allowed.' - )->tip('Use strict comparison via "!==" instead.')->build(), + )->tip('Use strict comparison via "!==" instead.') + ->identifier('notEqual.notAllowed') + ->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php b/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php index 349f6ca2..fac42790 100644 --- a/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php @@ -27,6 +27,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message('Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.') + ->identifier('ternary.shortNotAllowed') ->build(), ]; } diff --git a/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php b/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php index 89861a99..f710474e 100644 --- a/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php +++ b/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php @@ -7,8 +7,8 @@ use PhpParser\Node\Expr\Assign; use PhpParser\Node\Stmt\For_; use PHPStan\Analyser\Scope; +use PHPStan\Rules\IdentifierRuleError; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; use PHPStan\Rules\RuleErrorBuilder; use function is_string; use function sprintf; @@ -41,7 +41,7 @@ public function processNode(Node $node, Scope $scope): array } /** - * @return list + * @return list */ private function checkValueVar(Scope $scope, Expr $expr): array { @@ -52,6 +52,7 @@ private function checkValueVar(Scope $scope, Expr $expr): array && $scope->hasVariableType($expr->name)->yes() ) { $errors[] = RuleErrorBuilder::message(sprintf('For loop initial assignment overwrites variable $%s.', $expr->name)) + ->identifier('for.variableOverwrite') ->build(); } diff --git a/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php b/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php index e3932121..0cf620c3 100644 --- a/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php +++ b/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr; use PhpParser\Node\Stmt\Foreach_; use PHPStan\Analyser\Scope; +use PHPStan\Rules\IdentifierRuleError; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use function is_string; @@ -31,6 +32,7 @@ public function processNode(Node $node, Scope $scope): array && $scope->hasVariableType($node->keyVar->name)->yes() ) { $errors[] = RuleErrorBuilder::message(sprintf('Foreach overwrites $%s with its key variable.', $node->keyVar->name)) + ->identifier('foreach.keyOverwrite') ->build(); } @@ -42,7 +44,7 @@ public function processNode(Node $node, Scope $scope): array } /** - * @return string[] + * @return list */ private function checkValueVar(Scope $scope, Expr $expr): array { @@ -53,6 +55,7 @@ private function checkValueVar(Scope $scope, Expr $expr): array && $scope->hasVariableType($expr->name)->yes() ) { $errors[] = RuleErrorBuilder::message(sprintf('Foreach overwrites $%s with its value variable.', $expr->name)) + ->identifier('foreach.valueOverwrite') ->build(); } diff --git a/src/Rules/Functions/ClosureUsesThisRule.php b/src/Rules/Functions/ClosureUsesThisRule.php index fbce62f9..d2cb4a45 100644 --- a/src/Rules/Functions/ClosureUsesThisRule.php +++ b/src/Rules/Functions/ClosureUsesThisRule.php @@ -43,6 +43,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf('Anonymous function uses $this assigned to variable $%s. Use $this directly in the function body.', $closureUse->var->name)) ->line($closureUse->getLine()) + ->identifier('closure.useThis') ->build(); } return $messages; diff --git a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php index bb8fc5cc..1cca26ed 100644 --- a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php +++ b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php @@ -6,8 +6,8 @@ use PHPStan\Analyser\Scope; use PHPStan\Node\InClassMethodNode; use PHPStan\Reflection\ClassReflection; +use PHPStan\Rules\IdentifierRuleError; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; use PHPStan\Rules\RuleErrorBuilder; use function sprintf; @@ -62,7 +62,7 @@ private function findMethod( ClassReflection $declaringClass, ClassReflection $classReflection, string $methodName - ): ?RuleError + ): ?IdentifierRuleError { if (!$classReflection->hasNativeMethod($methodName)) { return null; @@ -80,7 +80,7 @@ private function findMethod( $classReflection->isInterface() ? 'interface' : 'parent', $classReflection->getDisplayName(), $parentMethod->getName() - ))->build(); + ))->identifier('method.nameCase')->build(); } } diff --git a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php index 56b590d9..af82a08c 100644 --- a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php @@ -46,7 +46,7 @@ public function processNode(Node $node, Scope $scope): array 'Only numeric types are allowed in %s, %s given.', $this->describeOperation(), $varType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier(sprintf('%s.nonNumeric', $this->getIdentifier()))->build(); } return $messages; @@ -54,4 +54,9 @@ public function processNode(Node $node, Scope $scope): array abstract protected function describeOperation(): string; + /** + * @return 'preInc'|'postInc'|'preDec'|'postDec' + */ + abstract protected function getIdentifier(): string; + } diff --git a/src/Rules/Operators/OperandInArithmeticPostDecrementRule.php b/src/Rules/Operators/OperandInArithmeticPostDecrementRule.php index 88298ec9..d0e08099 100644 --- a/src/Rules/Operators/OperandInArithmeticPostDecrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticPostDecrementRule.php @@ -20,4 +20,9 @@ protected function describeOperation(): string return 'post-decrement'; } + protected function getIdentifier(): string + { + return 'postDec'; + } + } diff --git a/src/Rules/Operators/OperandInArithmeticPostIncrementRule.php b/src/Rules/Operators/OperandInArithmeticPostIncrementRule.php index e9367dcb..400d8288 100644 --- a/src/Rules/Operators/OperandInArithmeticPostIncrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticPostIncrementRule.php @@ -20,4 +20,9 @@ protected function describeOperation(): string return 'post-increment'; } + protected function getIdentifier(): string + { + return 'postInc'; + } + } diff --git a/src/Rules/Operators/OperandInArithmeticPreDecrementRule.php b/src/Rules/Operators/OperandInArithmeticPreDecrementRule.php index 643f8d31..9d583560 100644 --- a/src/Rules/Operators/OperandInArithmeticPreDecrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticPreDecrementRule.php @@ -20,4 +20,9 @@ protected function describeOperation(): string return 'pre-decrement'; } + protected function getIdentifier(): string + { + return 'preDec'; + } + } diff --git a/src/Rules/Operators/OperandInArithmeticPreIncrementRule.php b/src/Rules/Operators/OperandInArithmeticPreIncrementRule.php index 3ad29af7..d5d81f2a 100644 --- a/src/Rules/Operators/OperandInArithmeticPreIncrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticPreIncrementRule.php @@ -20,4 +20,9 @@ protected function describeOperation(): string return 'pre-increment'; } + protected function getIdentifier(): string + { + return 'preInc'; + } + } diff --git a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php index 2dbf3efc..246b609d 100644 --- a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php @@ -59,13 +59,13 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in +, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('plus.leftNonNumeric')->build(); } if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in +, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('plus.rightNonNumeric')->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php index 423455f3..8a146ded 100644 --- a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php @@ -53,7 +53,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in /, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('div.leftNonNumeric')->build(); } $rightType = $scope->getType($right); @@ -61,7 +61,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in /, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('div.rightNonNumeric')->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php index b2b67f3d..fe809ef7 100644 --- a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php @@ -53,7 +53,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in **, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('pow.leftNonNumeric')->build(); } $rightType = $scope->getType($right); @@ -61,7 +61,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in **, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('pow.rightNonNumeric')->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticModuloRule.php b/src/Rules/Operators/OperandsInArithmeticModuloRule.php index 1932945d..4aad3661 100644 --- a/src/Rules/Operators/OperandsInArithmeticModuloRule.php +++ b/src/Rules/Operators/OperandsInArithmeticModuloRule.php @@ -53,7 +53,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %%, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('mod.leftNonNumeric')->build(); } $rightType = $scope->getType($right); @@ -61,7 +61,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %%, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('mod.rightNonNumeric')->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php index 1c99f70f..f662bdce 100644 --- a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php @@ -53,7 +53,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in *, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('mul.leftNonNumeric')->build(); } $rightType = $scope->getType($right); @@ -61,7 +61,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in *, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('mul.rightNonNumeric')->build(); } return $messages; diff --git a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php index 4ac61d53..9bec287d 100644 --- a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php @@ -53,7 +53,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in -, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('minus.leftNonNumeric')->build(); } $rightType = $scope->getType($right); @@ -61,7 +61,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in -, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) - ))->build(); + ))->identifier('minus.rightNonNumeric')->build(); } return $messages; diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php index 73ea10a4..d14b5678 100644 --- a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php +++ b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php @@ -58,7 +58,7 @@ static function (Type $type) use ($name): bool { 'Dynamic call to static method %s::%s().', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName() - ))->build(), + ))->identifier('staticMethod.dynamicCall')->build(), ]; } diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php index 269f6132..44b180c0 100644 --- a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php +++ b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php @@ -69,7 +69,7 @@ static function (Type $type) use ($name): bool { 'Dynamic call to static method %s::%s().', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName() - ))->build(), + ))->identifier('staticMethod.dynamicCall')->build(), ]; } diff --git a/src/Rules/StrictCalls/StrictFunctionCallsRule.php b/src/Rules/StrictCalls/StrictFunctionCallsRule.php index 04508699..2b6cd899 100644 --- a/src/Rules/StrictCalls/StrictFunctionCallsRule.php +++ b/src/Rules/StrictCalls/StrictFunctionCallsRule.php @@ -67,7 +67,7 @@ public function processNode(Node $node, Scope $scope): array 'Call to function %s() requires parameter #%d to be set.', $functionName, $argumentPosition + 1 - ))->build(), + ))->identifier('function.strict')->build(), ]; } @@ -79,7 +79,7 @@ public function processNode(Node $node, Scope $scope): array 'Call to function %s() requires parameter #%d to be true.', $functionName, $argumentPosition + 1 - ))->build(), + ))->identifier('function.strict')->build(), ]; } diff --git a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php index bb4bebbf..e52195a1 100644 --- a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php +++ b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php @@ -49,7 +49,10 @@ public function processNode(Node $node, Scope $scope): array $conditionType->describe(VerbosityLevel::value()), $this->printer->prettyPrintExpr($case->cond), $caseType->describe(VerbosityLevel::typeOnly()) - ))->line($case->getLine())->build(); + )) + ->line($case->getLine()) + ->identifier('switch.type') + ->build(); } return $messages; diff --git a/src/Rules/VariableVariables/VariableMethodCallRule.php b/src/Rules/VariableVariables/VariableMethodCallRule.php index 6d18a2eb..f92f84c1 100644 --- a/src/Rules/VariableVariables/VariableMethodCallRule.php +++ b/src/Rules/VariableVariables/VariableMethodCallRule.php @@ -31,7 +31,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Variable method call on %s.', $scope->getType($node->var)->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('method.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableMethodCallableRule.php b/src/Rules/VariableVariables/VariableMethodCallableRule.php index be904f95..6a5fd518 100644 --- a/src/Rules/VariableVariables/VariableMethodCallableRule.php +++ b/src/Rules/VariableVariables/VariableMethodCallableRule.php @@ -31,7 +31,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Variable method call on %s.', $scope->getType($node->getVar())->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('method.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariablePropertyFetchRule.php b/src/Rules/VariableVariables/VariablePropertyFetchRule.php index 0b2e9b7b..73ff0888 100644 --- a/src/Rules/VariableVariables/VariablePropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariablePropertyFetchRule.php @@ -59,7 +59,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Variable property access on %s.', $fetchedOnType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('property.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php index 5250dd6e..eb3a770c 100644 --- a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php +++ b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php @@ -37,7 +37,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Variable static method call on %s.', $methodCalledOn - ))->build(), + ))->identifier('staticMethod.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php index 1dc6280a..f765da66 100644 --- a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php +++ b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php @@ -37,7 +37,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Variable static method call on %s.', $methodCalledOn - ))->build(), + ))->identifier('staticMethod.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php index 72d937ef..f27c7792 100644 --- a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php @@ -37,7 +37,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Variable static property access on %s.', $propertyAccessedOn - ))->build(), + ))->identifier('staticProperty.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableVariablesRule.php b/src/Rules/VariableVariables/VariableVariablesRule.php index fee986a7..f78e4ef4 100644 --- a/src/Rules/VariableVariables/VariableVariablesRule.php +++ b/src/Rules/VariableVariables/VariableVariablesRule.php @@ -28,6 +28,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message('Variable variables are not allowed.') + ->identifier('variable.dynamicName') ->build(), ]; } From 88e714c05658eb18a45ab6a6f4d17a29d44cc065 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 9 Jun 2023 17:56:41 +0200 Subject: [PATCH 11/13] BooleanInBooleanAndRule, BooleanInBooleanOrRule - different identifier and description for logical operators --- rules.neon | 4 ++++ .../BooleanInBooleanAndRule.php | 18 +++++++++++++----- .../BooleanInBooleanOrRule.php | 18 +++++++++++++----- .../BooleanInBooleanAndRuleTest.php | 15 ++++++++++++--- .../BooleanInBooleanOrRuleTest.php | 11 ++++++++++- .../BooleansInConditions/data/conditions.php | 5 +++++ 6 files changed, 57 insertions(+), 14 deletions(-) diff --git a/rules.neon b/rules.neon index 46632c0c..9f2c6e4c 100644 --- a/rules.neon +++ b/rules.neon @@ -142,12 +142,16 @@ services: - class: PHPStan\Rules\BooleansInConditions\BooleanInBooleanAndRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\BooleansInConditions\BooleanInBooleanNotRule - class: PHPStan\Rules\BooleansInConditions\BooleanInBooleanOrRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\BooleansInConditions\BooleanInElseIfConditionRule diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php index a266d851..aebe8add 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php @@ -19,9 +19,13 @@ class BooleanInBooleanAndRule implements Rule /** @var BooleanRuleHelper */ private $helper; - public function __construct(BooleanRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(BooleanRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -33,21 +37,25 @@ public function processNode(Node $node, Scope $scope): array { $originalNode = $node->getOriginalNode(); $messages = []; + $nodeText = $this->bleedingEdge ? $originalNode->getOperatorSigil() : '&&'; + $identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanAnd ? 'booleanAnd' : 'logicalAnd'; if (!$this->helper->passesAsBoolean($scope, $originalNode->left)) { $leftType = $scope->getType($originalNode->left); $messages[] = RuleErrorBuilder::message(sprintf( - 'Only booleans are allowed in &&, %s given on the left side.', + 'Only booleans are allowed in %s, %s given on the left side.', + $nodeText, $leftType->describe(VerbosityLevel::typeOnly()) - ))->identifier('booleanAnd.leftNotBoolean')->build(); + ))->identifier(sprintf('%s.leftNotBoolean', $identifierType))->build(); } $rightScope = $node->getRightScope(); if (!$this->helper->passesAsBoolean($rightScope, $originalNode->right)) { $rightType = $rightScope->getType($originalNode->right); $messages[] = RuleErrorBuilder::message(sprintf( - 'Only booleans are allowed in &&, %s given on the right side.', + 'Only booleans are allowed in %s, %s given on the right side.', + $nodeText, $rightType->describe(VerbosityLevel::typeOnly()) - ))->identifier('booleanAnd.rightNotBoolean')->build(); + ))->identifier(sprintf('%s.rightNotBoolean', $identifierType))->build(); } return $messages; diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php index 144bda22..e03911cf 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php @@ -19,9 +19,13 @@ class BooleanInBooleanOrRule implements Rule /** @var BooleanRuleHelper */ private $helper; - public function __construct(BooleanRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(BooleanRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -33,21 +37,25 @@ public function processNode(Node $node, Scope $scope): array { $originalNode = $node->getOriginalNode(); $messages = []; + $nodeText = $this->bleedingEdge ? $originalNode->getOperatorSigil() : '||'; + $identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanOr ? 'booleanOr' : 'logicalOr'; if (!$this->helper->passesAsBoolean($scope, $originalNode->left)) { $leftType = $scope->getType($originalNode->left); $messages[] = RuleErrorBuilder::message(sprintf( - 'Only booleans are allowed in ||, %s given on the left side.', + 'Only booleans are allowed in %s, %s given on the left side.', + $nodeText, $leftType->describe(VerbosityLevel::typeOnly()) - ))->identifier('booleanOr.leftNotBoolean')->build(); + ))->identifier(sprintf('%s.leftNotBoolean', $identifierType))->build(); } $rightScope = $node->getRightScope(); if (!$this->helper->passesAsBoolean($rightScope, $originalNode->right)) { $rightType = $rightScope->getType($originalNode->right); $messages[] = RuleErrorBuilder::message(sprintf( - 'Only booleans are allowed in ||, %s given on the right side.', + 'Only booleans are allowed in %s, %s given on the right side.', + $nodeText, $rightType->describe(VerbosityLevel::typeOnly()) - ))->identifier('booleanOr.rightNotBoolean')->build(); + ))->identifier(sprintf('%s.rightNotBoolean', $identifierType))->build(); } return $messages; diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php index c9244204..c0f448dd 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php @@ -17,7 +17,8 @@ protected function getRule(): Rule return new BooleanInBooleanAndRule( new BooleanRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -44,6 +45,14 @@ public function testRule(): void 'Only booleans are allowed in &&, mixed given on the right side.', 19, ], + [ + 'Only booleans are allowed in and, mixed given on the right side.', + 47, + ], + [ + 'Only booleans are allowed in and, mixed given on the left side.', + 48, + ], ]); } @@ -61,11 +70,11 @@ public function testLogicalAnd(): void { $this->analyse([__DIR__ . '/data/logical-and.php'], [ [ - 'Only booleans are allowed in &&, string|false given on the left side.', + 'Only booleans are allowed in and, string|false given on the left side.', 14, ], [ - 'Only booleans are allowed in &&, mixed given on the right side.', + 'Only booleans are allowed in and, mixed given on the right side.', 14, ], ]); diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php index 1a4fafb0..c9d7ed45 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php @@ -17,7 +17,8 @@ protected function getRule(): Rule return new BooleanInBooleanOrRule( new BooleanRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -40,6 +41,14 @@ public function testRule(): void 'Only booleans are allowed in ||, mixed given on the right side.', 29, ], + [ + 'Only booleans are allowed in or, mixed given on the right side.', + 49, + ], + [ + 'Only booleans are allowed in or, mixed given on the left side.', + 50, + ], ]); } diff --git a/tests/Rules/BooleansInConditions/data/conditions.php b/tests/Rules/BooleansInConditions/data/conditions.php index 3af62400..968867ff 100644 --- a/tests/Rules/BooleansInConditions/data/conditions.php +++ b/tests/Rules/BooleansInConditions/data/conditions.php @@ -43,3 +43,8 @@ $bool ? 1 : 2; $string ? 1 : 2; $string ?: null; + +$bool and $explicitMixed; +$explicitMixed and $bool; +$bool or $explicitMixed; +$explicitMixed or $bool; From b7edb14296bae350401afef889c0243958174975 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 9 Jun 2023 18:01:59 +0200 Subject: [PATCH 12/13] Rename abstract OperandInArithmeticIncrementOrDecrementRuleTest --- ...> OperandInArithmeticIncrementOrDecrementRuleTestCase.php} | 2 +- .../Operators/OperandInArithmeticPostDecrementRuleTest.php | 4 ++-- .../Operators/OperandInArithmeticPostIncrementRuleTest.php | 4 ++-- .../Operators/OperandInArithmeticPreDecrementRuleTest.php | 4 ++-- .../Operators/OperandInArithmeticPreIncrementRuleTest.php | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) rename tests/Rules/Operators/{OperandInArithmeticIncrementOrDecrementRuleTest.php => OperandInArithmeticIncrementOrDecrementRuleTestCase.php} (89%) diff --git a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php similarity index 89% rename from tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php rename to tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php index b737cc30..0efa83a7 100644 --- a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php @@ -10,7 +10,7 @@ * @template T of Rule * @extends RuleTestCase */ -abstract class OperandInArithmeticIncrementOrDecrementRuleTest extends RuleTestCase +abstract class OperandInArithmeticIncrementOrDecrementRuleTestCase extends RuleTestCase { protected function getRule(): Rule diff --git a/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php index 2572c751..c4ea1569 100644 --- a/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php @@ -5,9 +5,9 @@ use PHPStan\Rules\Rule; /** - * @extends OperandInArithmeticIncrementOrDecrementRuleTest + * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase */ -class OperandInArithmeticPostDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest +class OperandInArithmeticPostDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTestCase { protected function createRule(OperatorRuleHelper $helper): Rule diff --git a/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php index 4a7ad751..94357e60 100644 --- a/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php @@ -5,9 +5,9 @@ use PHPStan\Rules\Rule; /** - * @extends OperandInArithmeticIncrementOrDecrementRuleTest + * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase */ -class OperandInArithmeticPostIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest +class OperandInArithmeticPostIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTestCase { protected function createRule(OperatorRuleHelper $helper): Rule diff --git a/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php index bcc9e64a..2bb021a9 100644 --- a/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php @@ -5,9 +5,9 @@ use PHPStan\Rules\Rule; /** - * @extends OperandInArithmeticIncrementOrDecrementRuleTest + * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase */ -class OperandInArithmeticPreDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest +class OperandInArithmeticPreDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTestCase { protected function createRule(OperatorRuleHelper $helper): Rule diff --git a/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php b/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php index d733207e..2ffe1bb6 100644 --- a/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php +++ b/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php @@ -5,9 +5,9 @@ use PHPStan\Rules\Rule; /** - * @extends OperandInArithmeticIncrementOrDecrementRuleTest + * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase */ -class OperandInArithmeticPreIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest +class OperandInArithmeticPreIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTestCase { protected function createRule(OperatorRuleHelper $helper): Rule From 00a51cb57dbb80bfdb4c6333130529b2b46e761b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on=20Gersen?= Date: Thu, 3 Aug 2023 08:10:45 +0200 Subject: [PATCH 13/13] Add rule to disallow casting potential null values --- README.md | 3 + rules.neon | 9 ++ src/Rules/Cast/NullCastRule.php | 80 +++++++++++++++++ tests/Rules/Cast/NullCastRuleTest.php | 87 +++++++++++++++++++ .../Rules/Cast/data/null-cast-not-phpdoc.php | 20 +++++ tests/Rules/Cast/data/null-cast.php | 19 ++++ 6 files changed, 218 insertions(+) create mode 100644 src/Rules/Cast/NullCastRule.php create mode 100644 tests/Rules/Cast/NullCastRuleTest.php create mode 100644 tests/Rules/Cast/data/null-cast-not-phpdoc.php create mode 100644 tests/Rules/Cast/data/null-cast.php diff --git a/README.md b/README.md index 246c0c84..9dee7781 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ * Require calling parent constructor * Disallow usage of backtick operator (`` $ls = `ls -la` ``) * Closure should use `$this` directly instead of using `$this` variable indirectly +* Report useless casts +* Disallow explicit casting of potential `null` values (with [https://phpstan.org/blog/what-is-bleeding-edge](bleeding edge) enabled) Additional rules are coming in subsequent releases! @@ -65,6 +67,7 @@ parameters: disallowedLooseComparison: false booleansInConditions: false uselessCast: false + nullCast: false requireParentConstructorCall: false disallowedConstructs: false overwriteVariablesWithLoop: false diff --git a/rules.neon b/rules.neon index 9f2c6e4c..ba0c7d07 100644 --- a/rules.neon +++ b/rules.neon @@ -20,6 +20,7 @@ parameters: disallowedLooseComparison: [%strictRules.allRules%, %featureToggles.bleedingEdge%] booleansInConditions: %strictRules.allRules% uselessCast: %strictRules.allRules% + nullCast: [%strictRules.allRules%, %featureToggles.bleedingEdge%] requireParentConstructorCall: %strictRules.allRules% disallowedConstructs: %strictRules.allRules% overwriteVariablesWithLoop: %strictRules.allRules% @@ -36,6 +37,7 @@ parametersSchema: disallowedLooseComparison: anyOf(bool(), arrayOf(bool())), booleansInConditions: anyOf(bool(), arrayOf(bool())) uselessCast: anyOf(bool(), arrayOf(bool())) + nullCast: anyOf(bool(), arrayOf(bool())) requireParentConstructorCall: anyOf(bool(), arrayOf(bool())) disallowedConstructs: anyOf(bool(), arrayOf(bool())) overwriteVariablesWithLoop: anyOf(bool(), arrayOf(bool())) @@ -64,6 +66,8 @@ conditionalTags: phpstan.rules.rule: %strictRules.booleansInConditions% PHPStan\Rules\Cast\UselessCastRule: phpstan.rules.rule: %strictRules.uselessCast% + PHPStan\Rules\Cast\NullCastRule: + phpstan.rules.rule: %strictRules.nullCast% PHPStan\Rules\Classes\RequireParentConstructCallRule: phpstan.rules.rule: %strictRules.requireParentConstructorCall% PHPStan\Rules\DisallowedConstructs\DisallowedBacktickRule: @@ -167,6 +171,11 @@ services: arguments: treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% + - + class: PHPStan\Rules\Cast\NullCastRule + arguments: + treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% + - class: PHPStan\Rules\Classes\RequireParentConstructCallRule diff --git a/src/Rules/Cast/NullCastRule.php b/src/Rules/Cast/NullCastRule.php new file mode 100644 index 00000000..17b5859e --- /dev/null +++ b/src/Rules/Cast/NullCastRule.php @@ -0,0 +1,80 @@ + + */ +class NullCastRule implements Rule +{ + + /** @var bool */ + private $treatPhpDocTypesAsCertain; + + public function __construct(bool $treatPhpDocTypesAsCertain) + { + $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; + } + + public function getNodeType(): string + { + return Cast::class; + } + + public function processNode(Node $node, Scope $scope): array + { + $castType = $scope->getType($node); + if ($castType instanceof ErrorType) { + return []; + } + $castType = $castType->generalize(GeneralizePrecision::lessSpecific()); + + if ($this->treatPhpDocTypesAsCertain) { + $expressionType = $scope->getType($node->expr); + } else { + $expressionType = $scope->getNativeType($node->expr); + } + + // This is handled by PhpStan at level 9 + if ($expressionType->isSuperTypeOf(new MixedType())->yes()) { + return []; + } + + if (!$expressionType->isNull()->no()) { + $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $node): RuleErrorBuilder { + if (!$this->treatPhpDocTypesAsCertain) { + return $ruleErrorBuilder; + } + + $expressionTypeWithoutPhpDoc = $scope->getNativeType($node->expr); + if (!(new NullType())->isSuperTypeOf($expressionTypeWithoutPhpDoc)->no()) { + return $ruleErrorBuilder; + } + + return $ruleErrorBuilder->tip('Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.'); + }; + return [ + $addTip(RuleErrorBuilder::message(sprintf( + 'Only non-null values should be cast to %s, %s given.', + $castType->describe(VerbosityLevel::typeOnly()), + $expressionType->describe(VerbosityLevel::typeOnly()) + )))->identifier('cast.null')->build(), + ]; + } + + return []; + } + +} diff --git a/tests/Rules/Cast/NullCastRuleTest.php b/tests/Rules/Cast/NullCastRuleTest.php new file mode 100644 index 00000000..a8d1caf9 --- /dev/null +++ b/tests/Rules/Cast/NullCastRuleTest.php @@ -0,0 +1,87 @@ + + */ +class NullCastRuleTest extends RuleTestCase +{ + + /** @var bool */ + private $treatPhpDocTypesAsCertain; + + protected function getRule(): Rule + { + return new NullCastRule($this->treatPhpDocTypesAsCertain); + } + + protected function shouldTreatPhpDocTypesAsCertain(): bool + { + return $this->treatPhpDocTypesAsCertain; + } + + public function testNullCast(): void + { + require_once __DIR__ . '/data/null-cast.php'; + $this->treatPhpDocTypesAsCertain = true; + $this->analyse( + [__DIR__ . '/data/null-cast.php'], + [ + [ + 'Only non-null values should be cast to int, int|null given.', + 6, + ], + [ + 'Only non-null values should be cast to int, string|null given.', + 8, + ], + [ + 'Only non-null values should be cast to float, int|null given.', + 9, + ], + [ + 'Only non-null values should be cast to float, string|null given.', + 11, + ], + [ + 'Only non-null values should be cast to string, string|null given.', + 12, + ], + [ + 'Only non-null values should be cast to stdClass, string|null given.', + 13, + ], + [ + 'Only non-null values should be cast to stdClass, null given.', + 15, + ], + [ + 'Only non-null values should be cast to array, null given.', + 17, + ], + ] + ); + } + + public function testDoNotReportPhpDoc(): void + { + $this->treatPhpDocTypesAsCertain = false; + $this->analyse([__DIR__ . '/data/null-cast-not-phpdoc.php'], []); + } + + public function testReportPhpDoc(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/null-cast-not-phpdoc.php'], [ + [ + 'Only non-null values should be cast to int, int|null given.', + 17, + ], + ]); + } + +} diff --git a/tests/Rules/Cast/data/null-cast-not-phpdoc.php b/tests/Rules/Cast/data/null-cast-not-phpdoc.php new file mode 100644 index 00000000..42f2bf22 --- /dev/null +++ b/tests/Rules/Cast/data/null-cast-not-phpdoc.php @@ -0,0 +1,20 @@ += 8.0 + +namespace NullCast; + +function foo(?int $a, string $b, ?string $c, mixed $d) { + (int)$a; + (int)$b; + (int)$c; + (float)$a; + (float)$b; + (float)$c; + (string)$c; + (object)$c; + (object)'null'; + (object)null; + (array)'null'; + (array)null; + (int)$d; +}