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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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/55] 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 aeaa0229d0a25051f0aad40164571f7beaf58924 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 02:11:02 +0000 Subject: [PATCH 13/55] Update actions/checkout action to v4 --- .github/workflows/build.yml | 10 +++++----- .github/workflows/create-tag.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0bb37b0d..c137cf58 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: "shivammathur/setup-php@v2" @@ -53,10 +53,10 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Checkout build-cs" - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: "phpstan/build-cs" path: "build-cs" @@ -103,7 +103,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: "shivammathur/setup-php@v2" @@ -146,7 +146,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/.github/workflows/create-tag.yml b/.github/workflows/create-tag.yml index 8452d986..a8535014 100644 --- a/.github/workflows/create-tag.yml +++ b/.github/workflows/create-tag.yml @@ -21,7 +21,7 @@ jobs: runs-on: "ubuntu-latest" steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.PHPSTAN_BOT_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 92b72547..e4a8ac62 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Generate changelog id: changelog From 50aab8dc2b2d68f43e2231133322221e697d4dd3 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Oct 2023 15:27:36 +0100 Subject: [PATCH 14/55] Open 1.6.x-dev --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c137cf58..3204f0b8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: pull_request: push: branches: - - "1.5.x" + - "1.6.x" jobs: lint: From 1b125fb195e726c88dc0cf29d83272d5f4747c8d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:27:48 +0000 Subject: [PATCH 15/55] Update dessant/lock-threads action to v5 --- .github/workflows/lock-closed-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml index 4c7990df..c2b017b9 100644 --- a/.github/workflows/lock-closed-issues.yml +++ b/.github/workflows/lock-closed-issues.yml @@ -8,7 +8,7 @@ jobs: lock: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v4 + - uses: dessant/lock-threads@v5 with: github-token: ${{ github.token }} issue-inactive-days: '31' From 2090cfca49793b876887695f3293062070abc83c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:27:45 +0000 Subject: [PATCH 16/55] Update metcalfc/changelog-generator action to v4.2.0 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e4a8ac62..2fb750a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Generate changelog id: changelog - uses: metcalfc/changelog-generator@v4.1.0 + uses: metcalfc/changelog-generator@v4.2.0 with: myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }} From 5981dc4b8dcc011cd1ca82b925c071f1e5190853 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 01:27:09 +0000 Subject: [PATCH 17/55] Update cbrgm/mastodon-github-action action to v2 --- .github/workflows/release-toot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-toot.yml b/.github/workflows/release-toot.yml index 6a1c8156..1ba4fd77 100644 --- a/.github/workflows/release-toot.yml +++ b/.github/workflows/release-toot.yml @@ -10,7 +10,7 @@ jobs: toot: runs-on: ubuntu-latest steps: - - uses: cbrgm/mastodon-github-action@v1 + - uses: cbrgm/mastodon-github-action@v2 if: ${{ !github.event.repository.private }} with: # GitHub event payload From 2bc39672669f0493b3b3833f13273cbedaaa121b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 22:26:40 +0000 Subject: [PATCH 18/55] Update metcalfc/changelog-generator action to v4.3.1 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2fb750a4..b1a669a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Generate changelog id: changelog - uses: metcalfc/changelog-generator@v4.2.0 + uses: metcalfc/changelog-generator@v4.3.1 with: myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }} From 3d334752d850a010738d37498cce439b6fb76ff3 Mon Sep 17 00:00:00 2001 From: Brad <28307684+mad-briller@users.noreply.github.com> Date: Mon, 26 Feb 2024 13:18:36 +0000 Subject: [PATCH 19/55] Fix UselessCastRuleTest. --- tests/Rules/Cast/UselessCastRuleTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Rules/Cast/UselessCastRuleTest.php b/tests/Rules/Cast/UselessCastRuleTest.php index 0d26a4ec..c5a151ea 100644 --- a/tests/Rules/Cast/UselessCastRuleTest.php +++ b/tests/Rules/Cast/UselessCastRuleTest.php @@ -47,6 +47,11 @@ public function testUselessCast(): void 'Casting to float something that\'s already float.', 27, ], + [ + 'Casting to string something that\'s already string.', + 39, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], [ 'Casting to string something that\'s already string.', 46, From d0dc2f0a6caf4ca2fcb837fb071e7452759a4847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Mirtes?= Date: Sun, 24 Mar 2024 09:12:48 +0100 Subject: [PATCH 20/55] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 246c0c84..74ac8d54 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ parameters: noVariableVariables: false ``` +Aside from introducing new custom rules, phpstan-strict-rules also [change the default values of some configuration parameters](https://github.com/phpstan/phpstan-strict-rules/blob/1.6.x/rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). + ## Enabling rules one-by-one If you don't want to start using all the available strict rules at once but only one or two, you can! @@ -96,3 +98,5 @@ parameters: allRules: false booleansInConditions: true ``` + +Even with `strictRules.allRules` set to `false`, part of this package is still in effect. That's because phpstan-strict-rules also [change the default values of some configuration parameters](https://github.com/phpstan/phpstan-strict-rules/blob/1.6.x/rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). From b5233d58637aadee4428961365196b205b557844 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 3 Apr 2024 14:37:23 +0200 Subject: [PATCH 21/55] Fix build --- tests/Levels/data/arithmeticOperators.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/Levels/data/arithmeticOperators.php b/tests/Levels/data/arithmeticOperators.php index 785ed151..e1ba49ae 100644 --- a/tests/Levels/data/arithmeticOperators.php +++ b/tests/Levels/data/arithmeticOperators.php @@ -22,25 +22,25 @@ public function doFoo( $intOrLiteralNumericString = '123'; } - $int + $int; - $string + $int; - $literalNumericString + $int; - $intOrString + $int; - $intOrLiteralNumericString + $int; + $r = $int + $int; + $r = $string + $int; + $r = $literalNumericString + $int; + $r = $intOrString + $int; + $r = $intOrLiteralNumericString + $int; $stringOrObject = $string; if (rand(0, 1) === 0) { $stringOrObject = new \stdClass(); } - $stringOrObject + $int; + $r = $stringOrObject + $int; $unionOfLiterals = '123'; if (rand(0, 1) === 0) { $unionOfLiterals = '456'; } - $unionOfLiterals + $int; + $r = $unionOfLiterals + $int; } } From 363f921dd8441777d4fc137deb99beb486c77df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Mirtes?= Date: Sat, 20 Apr 2024 08:37:51 +0200 Subject: [PATCH 22/55] Update lock-closed-issues.yml --- .github/workflows/lock-closed-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml index c2b017b9..fbbe5a5b 100644 --- a/.github/workflows/lock-closed-issues.yml +++ b/.github/workflows/lock-closed-issues.yml @@ -2,7 +2,7 @@ name: 'Lock Issues' on: schedule: - - cron: '0 0 * * *' + - cron: '1 0 * * *' jobs: lock: From 2462e578b2f9b89d0774d284d139d2cd702729bb Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:00:10 +0200 Subject: [PATCH 23/55] Test newer PHP versions --- .github/workflows/build.yml | 6 ++++++ composer.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3204f0b8..5c5bebae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,6 +22,8 @@ jobs: - "8.0" - "8.1" - "8.2" + - "8.3" + - "8.4" steps: - name: "Checkout" @@ -97,6 +99,8 @@ jobs: - "8.0" - "8.1" - "8.2" + - "8.3" + - "8.4" dependencies: - "lowest" - "highest" @@ -140,6 +144,8 @@ jobs: - "8.0" - "8.1" - "8.2" + - "8.3" + - "8.4" dependencies: - "lowest" - "highest" diff --git a/composer.json b/composer.json index 83dbeb9e..816fd9fe 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ ], "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.11" + "phpstan/phpstan": "^1.12" }, "require-dev": { "nikic/php-parser": "^4.13.0", From a567f7b0e5dfe524cc84f177fe5ca2b81f49b92a Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:00:37 +0200 Subject: [PATCH 24/55] Pin build-cs --- .github/workflows/build.yml | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c5bebae..e0a2ef77 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,6 +62,7 @@ jobs: with: repository: "phpstan/build-cs" path: "build-cs" + ref: "1.x" - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/Makefile b/Makefile index a175843c..90e23ba0 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ lint: .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 + git -C build-cs fetch origin && git -C build-cs reset --hard origin/1.x composer install --working-dir build-cs .PHONY: cs From f6fb84ef14e14130659a29a13421b6d59d51b436 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:00:55 +0200 Subject: [PATCH 25/55] Open 2.0.x --- .github/workflows/build.yml | 2 +- composer.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0a2ef77..0dc529dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: pull_request: push: branches: - - "1.6.x" + - "2.0.x" jobs: lint: diff --git a/composer.json b/composer.json index 816fd9fe..daefb4f9 100644 --- a/composer.json +++ b/composer.json @@ -6,15 +6,15 @@ "MIT" ], "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.12" + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0" }, "require-dev": { "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-deprecation-rules": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5" + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" }, "config": { "platform": { From f647999fed4532778509404e31086eae86a6b68e Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:02:00 +0200 Subject: [PATCH 26/55] Stop testing PHP 7.2 and 7.3 --- .github/workflows/build.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0dc529dd..8d659b18 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,8 +16,6 @@ jobs: strategy: matrix: php-version: - - "7.2" - - "7.3" - "7.4" - "8.0" - "8.1" @@ -41,10 +39,6 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" - - name: "Downgrade PHPUnit" - if: matrix.php-version == '7.2' || matrix.php-version == '7.3' - run: "composer require --dev phpunit/phpunit:^7.5.20 --update-with-dependencies" - - name: "Lint" run: "make lint" @@ -94,8 +88,6 @@ jobs: fail-fast: false matrix: php-version: - - "7.2" - - "7.3" - "7.4" - "8.0" - "8.1" @@ -124,10 +116,6 @@ jobs: if: ${{ matrix.dependencies == 'highest' }} run: "composer update --no-interaction --no-progress" - - name: "Downgrade PHPUnit" - if: matrix.php-version == '7.2' || matrix.php-version == '7.3' - run: "composer require --dev phpunit/phpunit:^7.5.20 --update-with-dependencies" - - name: "Tests" run: "make tests" @@ -139,8 +127,6 @@ jobs: fail-fast: false matrix: php-version: - - "7.2" - - "7.3" - "7.4" - "8.0" - "8.1" @@ -171,9 +157,5 @@ jobs: if: ${{ matrix.dependencies == 'highest' }} run: "composer update --no-interaction --no-progress" - - name: "Downgrade PHPUnit" - if: matrix.php-version == '7.2' || matrix.php-version == '7.3' - run: "composer require --dev phpunit/phpunit:^7.5.20 --update-with-dependencies" - - name: "PHPStan" run: "make phpstan" From f8092f978190646c397e5db26a70aae9b3150f98 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:02:23 +0200 Subject: [PATCH 27/55] Update build-cs --- .github/workflows/build.yml | 2 +- Makefile | 2 +- .../BooleanInBooleanAndRule.php | 10 ++++------ .../BooleanInBooleanNotRule.php | 5 ++--- .../BooleansInConditions/BooleanInBooleanOrRule.php | 10 ++++------ .../BooleanInElseIfConditionRule.php | 5 ++--- .../BooleanInIfConditionRule.php | 5 ++--- .../BooleanInTernaryOperatorRule.php | 5 ++--- .../BooleansInConditions/BooleanRuleHelper.php | 7 ++----- src/Rules/Cast/UselessCastRule.php | 5 ++--- .../Classes/RequireParentConstructCallRule.php | 2 +- .../DisallowedLooseComparisonRule.php | 4 ++-- src/Rules/Functions/ArrayFilterStrictRule.php | 13 +++++-------- .../Methods/WrongCaseOfInheritedMethodRule.php | 6 +++--- .../OperandInArithmeticIncrementOrDecrementRule.php | 5 ++--- .../Operators/OperandsInArithmeticAdditionRule.php | 10 ++++------ .../Operators/OperandsInArithmeticDivisionRule.php | 10 ++++------ .../OperandsInArithmeticExponentiationRule.php | 10 ++++------ .../Operators/OperandsInArithmeticModuloRule.php | 10 ++++------ .../OperandsInArithmeticMultiplicationRule.php | 10 ++++------ .../OperandsInArithmeticSubtractionRule.php | 10 ++++------ src/Rules/Operators/OperatorRuleHelper.php | 7 ++----- .../DynamicCallOnStaticMethodsCallableRule.php | 9 +++------ .../StrictCalls/DynamicCallOnStaticMethodsRule.php | 9 +++------ src/Rules/StrictCalls/StrictFunctionCallsRule.php | 9 ++++----- .../MatchingTypeInSwitchCaseConditionRule.php | 5 ++--- .../VariableVariables/VariableMethodCallRule.php | 2 +- .../VariableMethodCallableRule.php | 2 +- .../VariableVariables/VariablePropertyFetchRule.php | 7 +++---- .../VariableStaticMethodCallRule.php | 2 +- .../VariableStaticMethodCallableRule.php | 2 +- .../VariableStaticPropertyFetchRule.php | 2 +- .../BooleanInBooleanAndRuleTest.php | 4 ++-- .../BooleanInBooleanNotRuleTest.php | 4 ++-- .../BooleanInBooleanOrRuleTest.php | 4 ++-- .../BooleanInElseIfConditionRuleTest.php | 4 ++-- .../BooleanInIfConditionRuleTest.php | 4 ++-- .../BooleanInTernaryOperatorRuleTest.php | 4 ++-- tests/Rules/Cast/UselessCastRuleTest.php | 5 ++--- tests/Rules/Functions/ArrayFilterStrictRuleTest.php | 6 ++---- ...InArithmeticIncrementOrDecrementRuleTestCase.php | 4 ++-- .../OperandsInArithmeticAdditionRuleTest.php | 6 +++--- .../OperandsInArithmeticDivisionRuleTest.php | 4 ++-- .../OperandsInArithmeticExponentiationRuleTest.php | 4 ++-- .../OperandsInArithmeticModuloRuleTest.php | 4 ++-- .../OperandsInArithmeticMultiplicationRuleTest.php | 4 ++-- .../OperandsInArithmeticSubtractionRuleTest.php | 4 ++-- 47 files changed, 112 insertions(+), 155 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8d659b18..88543fb5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,7 +56,7 @@ jobs: with: repository: "phpstan/build-cs" path: "build-cs" - ref: "1.x" + ref: "2.x" - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/Makefile b/Makefile index 90e23ba0..b2b6703a 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ lint: .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/1.x + git -C build-cs fetch origin && git -C build-cs reset --hard origin/2.x composer install --working-dir build-cs .PHONY: cs diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php index aebe8add..a3055694 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php @@ -16,11 +16,9 @@ class BooleanInBooleanAndRule implements Rule { - /** @var BooleanRuleHelper */ - private $helper; + private BooleanRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(BooleanRuleHelper $helper, bool $bleedingEdge) { @@ -44,7 +42,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in %s, %s given on the left side.', $nodeText, - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier(sprintf('%s.leftNotBoolean', $identifierType))->build(); } @@ -54,7 +52,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in %s, %s given on the right side.', $nodeText, - $rightType->describe(VerbosityLevel::typeOnly()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier(sprintf('%s.rightNotBoolean', $identifierType))->build(); } diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php index 6fcdd06c..5187cf57 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php @@ -16,8 +16,7 @@ class BooleanInBooleanNotRule implements Rule { - /** @var BooleanRuleHelper */ - private $helper; + private BooleanRuleHelper $helper; public function __construct(BooleanRuleHelper $helper) { @@ -40,7 +39,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in a negated boolean, %s given.', - $expressionType->describe(VerbosityLevel::typeOnly()) + $expressionType->describe(VerbosityLevel::typeOnly()), ))->identifier('booleanNot.exprNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php index e03911cf..d0b91dd1 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php @@ -16,11 +16,9 @@ class BooleanInBooleanOrRule implements Rule { - /** @var BooleanRuleHelper */ - private $helper; + private BooleanRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(BooleanRuleHelper $helper, bool $bleedingEdge) { @@ -44,7 +42,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in %s, %s given on the left side.', $nodeText, - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier(sprintf('%s.leftNotBoolean', $identifierType))->build(); } @@ -54,7 +52,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in %s, %s given on the right side.', $nodeText, - $rightType->describe(VerbosityLevel::typeOnly()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier(sprintf('%s.rightNotBoolean', $identifierType))->build(); } diff --git a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php index 2501b828..550e9857 100644 --- a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php +++ b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php @@ -16,8 +16,7 @@ class BooleanInElseIfConditionRule implements Rule { - /** @var BooleanRuleHelper */ - private $helper; + private BooleanRuleHelper $helper; public function __construct(BooleanRuleHelper $helper) { @@ -40,7 +39,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in an elseif condition, %s given.', - $conditionExpressionType->describe(VerbosityLevel::typeOnly()) + $conditionExpressionType->describe(VerbosityLevel::typeOnly()), ))->identifier('elseif.condNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php index 5adb10ed..5c08894b 100644 --- a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php +++ b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php @@ -16,8 +16,7 @@ class BooleanInIfConditionRule implements Rule { - /** @var BooleanRuleHelper */ - private $helper; + private BooleanRuleHelper $helper; public function __construct(BooleanRuleHelper $helper) { @@ -40,7 +39,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in an if condition, %s given.', - $conditionExpressionType->describe(VerbosityLevel::typeOnly()) + $conditionExpressionType->describe(VerbosityLevel::typeOnly()), ))->identifier('if.condNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php index e1ac9ccb..4fe855a5 100644 --- a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php +++ b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php @@ -16,8 +16,7 @@ class BooleanInTernaryOperatorRule implements Rule { - /** @var BooleanRuleHelper */ - private $helper; + private BooleanRuleHelper $helper; public function __construct(BooleanRuleHelper $helper) { @@ -44,7 +43,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Only booleans are allowed in a ternary operator condition, %s given.', - $conditionExpressionType->describe(VerbosityLevel::typeOnly()) + $conditionExpressionType->describe(VerbosityLevel::typeOnly()), ))->identifier('ternary.condNotBoolean')->build(), ]; } diff --git a/src/Rules/BooleansInConditions/BooleanRuleHelper.php b/src/Rules/BooleansInConditions/BooleanRuleHelper.php index 1e307d63..4ecba329 100644 --- a/src/Rules/BooleansInConditions/BooleanRuleHelper.php +++ b/src/Rules/BooleansInConditions/BooleanRuleHelper.php @@ -12,8 +12,7 @@ class BooleanRuleHelper { - /** @var RuleLevelHelper */ - private $ruleLevelHelper; + private RuleLevelHelper $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { @@ -30,9 +29,7 @@ public function passesAsBoolean(Scope $scope, Expr $expr): bool $scope, $expr, '', - static function (Type $type): bool { - return $type->isBoolean()->yes(); - } + static fn (Type $type): bool => $type->isBoolean()->yes(), ); $foundType = $typeToCheck->getType(); if ($foundType instanceof ErrorType) { diff --git a/src/Rules/Cast/UselessCastRule.php b/src/Rules/Cast/UselessCastRule.php index adc20e14..e2ea72b5 100644 --- a/src/Rules/Cast/UselessCastRule.php +++ b/src/Rules/Cast/UselessCastRule.php @@ -18,8 +18,7 @@ class UselessCastRule implements Rule { - /** @var bool */ - private $treatPhpDocTypesAsCertain; + private bool $treatPhpDocTypesAsCertain; public function __construct(bool $treatPhpDocTypesAsCertain) { @@ -61,7 +60,7 @@ public function processNode(Node $node, Scope $scope): array $addTip(RuleErrorBuilder::message(sprintf( 'Casting to %s something that\'s already %s.', $castType->describe(VerbosityLevel::typeOnly()), - $expressionType->describe(VerbosityLevel::typeOnly()) + $expressionType->describe(VerbosityLevel::typeOnly()), )))->identifier('cast.useless')->build(), ]; } diff --git a/src/Rules/Classes/RequireParentConstructCallRule.php b/src/Rules/Classes/RequireParentConstructCallRule.php index 76d3d16c..31b2faf5 100644 --- a/src/Rules/Classes/RequireParentConstructCallRule.php +++ b/src/Rules/Classes/RequireParentConstructCallRule.php @@ -59,7 +59,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( '%s::__construct() does not call parent constructor from %s.', $classReflection->getName(), - $parentClass->getName() + $parentClass->getName(), ))->identifier('constructor.missingParentCall')->build(), ]; } diff --git a/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php b/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php index 9b709be9..70b8514f 100644 --- a/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedLooseComparisonRule.php @@ -26,7 +26,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof Equal) { return [ RuleErrorBuilder::message( - 'Loose comparison via "==" is not allowed.' + 'Loose comparison via "==" is not allowed.', )->tip('Use strict comparison via "===" instead.') ->identifier('equal.notAllowed') ->build(), @@ -35,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof NotEqual) { return [ RuleErrorBuilder::message( - 'Loose comparison via "!=" is not allowed.' + 'Loose comparison via "!=" is not allowed.', )->tip('Use strict comparison via "!==" instead.') ->identifier('notEqual.notAllowed') ->build(), diff --git a/src/Rules/Functions/ArrayFilterStrictRule.php b/src/Rules/Functions/ArrayFilterStrictRule.php index ff3bf631..65e1fada 100644 --- a/src/Rules/Functions/ArrayFilterStrictRule.php +++ b/src/Rules/Functions/ArrayFilterStrictRule.php @@ -23,14 +23,11 @@ class ArrayFilterStrictRule implements Rule { - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; - /** @var bool */ - private $treatPhpDocTypesAsCertain; + private bool $treatPhpDocTypesAsCertain; - /** @var bool */ - private $checkNullables; + private bool $checkNullables; public function __construct( ReflectionProvider $reflectionProvider, @@ -68,7 +65,7 @@ public function processNode(Node $node, Scope $scope): array $scope, $node->getArgs(), $functionReflection->getVariants(), - $functionReflection->getNamedArgumentsVariants() + $functionReflection->getNamedArgumentsVariants(), ); $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); @@ -132,7 +129,7 @@ public function processNode(Node $node, Scope $scope): array $message = 'Parameter #2 of array_filter() cannot be null to avoid loose comparison semantics (%s given).'; $errorBuilder = RuleErrorBuilder::message(sprintf( $message, - $callbackType->describe(VerbosityLevel::typeOnly()) + $callbackType->describe(VerbosityLevel::typeOnly()), ))->identifier('arrayFilter.strict'); if (!$this->isCallbackTypeNull($nativeCallbackType) && $this->treatPhpDocTypesAsCertain) { diff --git a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php index 1cca26ed..5f800e50 100644 --- a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php +++ b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php @@ -35,7 +35,7 @@ public function processNode( $parentMessage = $this->findMethod( $declaringClass, $declaringClass->getParentClass(), - $methodReflection->getName() + $methodReflection->getName(), ); if ($parentMessage !== null) { $messages[] = $parentMessage; @@ -46,7 +46,7 @@ public function processNode( $interfaceMessage = $this->findMethod( $declaringClass, $interface, - $methodReflection->getName() + $methodReflection->getName(), ); if ($interfaceMessage === null) { continue; @@ -79,7 +79,7 @@ private function findMethod( $methodName, $classReflection->isInterface() ? 'interface' : 'parent', $classReflection->getDisplayName(), - $parentMethod->getName() + $parentMethod->getName(), ))->identifier('method.nameCase')->build(); } diff --git a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php index af82a08c..4e87a885 100644 --- a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php +++ b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php @@ -20,8 +20,7 @@ abstract class OperandInArithmeticIncrementOrDecrementRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; public function __construct(OperatorRuleHelper $helper) { @@ -45,7 +44,7 @@ public function processNode(Node $node, Scope $scope): array $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %s, %s given.', $this->describeOperation(), - $varType->describe(VerbosityLevel::typeOnly()) + $varType->describe(VerbosityLevel::typeOnly()), ))->identifier(sprintf('%s.nonNumeric', $this->getIdentifier()))->build(); } diff --git a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php index 246b609d..fd4b119c 100644 --- a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php @@ -19,11 +19,9 @@ class OperandsInArithmeticAdditionRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { @@ -58,13 +56,13 @@ public function processNode(Node $node, Scope $scope): array if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in +, %s given on the left side.', - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->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()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier('plus.rightNonNumeric')->build(); } diff --git a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php index 8a146ded..642d6e8e 100644 --- a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php @@ -18,11 +18,9 @@ class OperandsInArithmeticDivisionRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { @@ -52,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in /, %s given on the left side.', - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier('div.leftNonNumeric')->build(); } @@ -60,7 +58,7 @@ public function processNode(Node $node, Scope $scope): array 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()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier('div.rightNonNumeric')->build(); } diff --git a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php index fe809ef7..128194ce 100644 --- a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php @@ -18,11 +18,9 @@ class OperandsInArithmeticExponentiationRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { @@ -52,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in **, %s given on the left side.', - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier('pow.leftNonNumeric')->build(); } @@ -60,7 +58,7 @@ public function processNode(Node $node, Scope $scope): array 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()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier('pow.rightNonNumeric')->build(); } diff --git a/src/Rules/Operators/OperandsInArithmeticModuloRule.php b/src/Rules/Operators/OperandsInArithmeticModuloRule.php index 4aad3661..a687c05e 100644 --- a/src/Rules/Operators/OperandsInArithmeticModuloRule.php +++ b/src/Rules/Operators/OperandsInArithmeticModuloRule.php @@ -18,11 +18,9 @@ class OperandsInArithmeticModuloRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { @@ -52,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in %%, %s given on the left side.', - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier('mod.leftNonNumeric')->build(); } @@ -60,7 +58,7 @@ public function processNode(Node $node, Scope $scope): array 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()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier('mod.rightNonNumeric')->build(); } diff --git a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php index f662bdce..e7e055b9 100644 --- a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php @@ -18,11 +18,9 @@ class OperandsInArithmeticMultiplicationRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { @@ -52,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in *, %s given on the left side.', - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier('mul.leftNonNumeric')->build(); } @@ -60,7 +58,7 @@ public function processNode(Node $node, Scope $scope): array 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()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier('mul.rightNonNumeric')->build(); } diff --git a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php index 9bec287d..527f645b 100644 --- a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php @@ -18,11 +18,9 @@ class OperandsInArithmeticSubtractionRule implements Rule { - /** @var OperatorRuleHelper */ - private $helper; + private OperatorRuleHelper $helper; - /** @var bool */ - private $bleedingEdge; + private bool $bleedingEdge; public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { @@ -52,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = RuleErrorBuilder::message(sprintf( 'Only numeric types are allowed in -, %s given on the left side.', - $leftType->describe(VerbosityLevel::typeOnly()) + $leftType->describe(VerbosityLevel::typeOnly()), ))->identifier('minus.leftNonNumeric')->build(); } @@ -60,7 +58,7 @@ public function processNode(Node $node, Scope $scope): array 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()) + $rightType->describe(VerbosityLevel::typeOnly()), ))->identifier('minus.rightNonNumeric')->build(); } diff --git a/src/Rules/Operators/OperatorRuleHelper.php b/src/Rules/Operators/OperatorRuleHelper.php index 28902857..6de54cab 100644 --- a/src/Rules/Operators/OperatorRuleHelper.php +++ b/src/Rules/Operators/OperatorRuleHelper.php @@ -19,8 +19,7 @@ class OperatorRuleHelper { - /** @var RuleLevelHelper */ - private $ruleLevelHelper; + private RuleLevelHelper $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { @@ -75,9 +74,7 @@ private function isSubtypeOfNumber(Scope $scope, Expr $expr): bool $scope, $expr, '', - static function (Type $type) use ($acceptedType): bool { - return $acceptedType->isSuperTypeOf($type)->yes(); - } + static fn (Type $type): bool => $acceptedType->isSuperTypeOf($type)->yes(), )->getType(); if ($type instanceof ErrorType) { diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php index d14b5678..492aa604 100644 --- a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php +++ b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php @@ -18,8 +18,7 @@ class DynamicCallOnStaticMethodsCallableRule implements Rule { - /** @var RuleLevelHelper */ - private $ruleLevelHelper; + private RuleLevelHelper $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { @@ -42,9 +41,7 @@ public function processNode(Node $node, Scope $scope): array $scope, $node->getVar(), '', - static function (Type $type) use ($name): bool { - return $type->canCallMethods()->yes() && $type->hasMethod($name)->yes(); - } + static fn (Type $type): bool => $type->canCallMethods()->yes() && $type->hasMethod($name)->yes(), )->getType(); if ($type instanceof ErrorType || !$type->canCallMethods()->yes() || !$type->hasMethod($name)->yes()) { @@ -57,7 +54,7 @@ static function (Type $type) use ($name): bool { RuleErrorBuilder::message(sprintf( 'Dynamic call to static method %s::%s().', $methodReflection->getDeclaringClass()->getDisplayName(), - $methodReflection->getName() + $methodReflection->getName(), ))->identifier('staticMethod.dynamicCall')->build(), ]; } diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php index 44b180c0..c0ae18b3 100644 --- a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php +++ b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php @@ -21,8 +21,7 @@ class DynamicCallOnStaticMethodsRule implements Rule { - /** @var RuleLevelHelper */ - private $ruleLevelHelper; + private RuleLevelHelper $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { @@ -45,9 +44,7 @@ public function processNode(Node $node, Scope $scope): array $scope, $node->var, '', - static function (Type $type) use ($name): bool { - return $type->canCallMethods()->yes() && $type->hasMethod($name)->yes(); - } + static fn (Type $type): bool => $type->canCallMethods()->yes() && $type->hasMethod($name)->yes(), )->getType(); if ($type instanceof ErrorType || !$type->canCallMethods()->yes() || !$type->hasMethod($name)->yes()) { @@ -68,7 +65,7 @@ static function (Type $type) use ($name): bool { RuleErrorBuilder::message(sprintf( 'Dynamic call to static method %s::%s().', $methodReflection->getDeclaringClass()->getDisplayName(), - $methodReflection->getName() + $methodReflection->getName(), ))->identifier('staticMethod.dynamicCall')->build(), ]; } diff --git a/src/Rules/StrictCalls/StrictFunctionCallsRule.php b/src/Rules/StrictCalls/StrictFunctionCallsRule.php index 2ae134b3..f959fc91 100644 --- a/src/Rules/StrictCalls/StrictFunctionCallsRule.php +++ b/src/Rules/StrictCalls/StrictFunctionCallsRule.php @@ -23,15 +23,14 @@ class StrictFunctionCallsRule implements Rule { /** @var int[] */ - private $functionArguments = [ + private array $functionArguments = [ 'in_array' => 2, 'array_search' => 2, 'base64_decode' => 1, 'array_keys' => 2, ]; - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { @@ -74,7 +73,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Call to function %s() requires parameter #%d to be set.', $functionName, - $argumentPosition + 1 + $argumentPosition + 1, ))->identifier('function.strict')->build(), ]; } @@ -86,7 +85,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Call to function %s() requires parameter #%d to be true.', $functionName, - $argumentPosition + 1 + $argumentPosition + 1, ))->identifier('function.strict')->build(), ]; } diff --git a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php index e52195a1..ded5d345 100644 --- a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php +++ b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php @@ -17,8 +17,7 @@ class MatchingTypeInSwitchCaseConditionRule implements Rule { - /** @var Standard */ - private $printer; + private Standard $printer; public function __construct(Standard $printer) { @@ -48,7 +47,7 @@ public function processNode(Node $node, Scope $scope): array 'Switch condition type (%s) does not match case condition %s (%s).', $conditionType->describe(VerbosityLevel::value()), $this->printer->prettyPrintExpr($case->cond), - $caseType->describe(VerbosityLevel::typeOnly()) + $caseType->describe(VerbosityLevel::typeOnly()), )) ->line($case->getLine()) ->identifier('switch.type') diff --git a/src/Rules/VariableVariables/VariableMethodCallRule.php b/src/Rules/VariableVariables/VariableMethodCallRule.php index f92f84c1..d55fc789 100644 --- a/src/Rules/VariableVariables/VariableMethodCallRule.php +++ b/src/Rules/VariableVariables/VariableMethodCallRule.php @@ -30,7 +30,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Variable method call on %s.', - $scope->getType($node->var)->describe(VerbosityLevel::typeOnly()) + $scope->getType($node->var)->describe(VerbosityLevel::typeOnly()), ))->identifier('method.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableMethodCallableRule.php b/src/Rules/VariableVariables/VariableMethodCallableRule.php index 6a5fd518..dd891a9e 100644 --- a/src/Rules/VariableVariables/VariableMethodCallableRule.php +++ b/src/Rules/VariableVariables/VariableMethodCallableRule.php @@ -30,7 +30,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Variable method call on %s.', - $scope->getType($node->getVar())->describe(VerbosityLevel::typeOnly()) + $scope->getType($node->getVar())->describe(VerbosityLevel::typeOnly()), ))->identifier('method.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariablePropertyFetchRule.php b/src/Rules/VariableVariables/VariablePropertyFetchRule.php index 73ff0888..07c35f26 100644 --- a/src/Rules/VariableVariables/VariablePropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariablePropertyFetchRule.php @@ -18,11 +18,10 @@ class VariablePropertyFetchRule implements Rule { - /** @var ReflectionProvider */ - private $reflectionProvider; + private ReflectionProvider $reflectionProvider; /** @var string[] */ - private $universalObjectCratesClasses; + private array $universalObjectCratesClasses; /** * @param string[] $universalObjectCratesClasses @@ -58,7 +57,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Variable property access on %s.', - $fetchedOnType->describe(VerbosityLevel::typeOnly()) + $fetchedOnType->describe(VerbosityLevel::typeOnly()), ))->identifier('property.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php index eb3a770c..963f01d0 100644 --- a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php +++ b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php @@ -36,7 +36,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Variable static method call on %s.', - $methodCalledOn + $methodCalledOn, ))->identifier('staticMethod.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php index f765da66..2cfebaca 100644 --- a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php +++ b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php @@ -36,7 +36,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Variable static method call on %s.', - $methodCalledOn + $methodCalledOn, ))->identifier('staticMethod.dynamicName')->build(), ]; } diff --git a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php index f27c7792..bc475992 100644 --- a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php @@ -36,7 +36,7 @@ public function processNode(Node $node, Scope $scope): array return [ RuleErrorBuilder::message(sprintf( 'Variable static property access on %s.', - $propertyAccessedOn + $propertyAccessedOn, ))->identifier('staticProperty.dynamicName')->build(), ]; } diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php index c0f448dd..08625e64 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new BooleanInBooleanAndRule( new BooleanRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php index 1d5e017d..ac30c927 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanNotRuleTest.php @@ -16,8 +16,8 @@ protected function getRule(): Rule { return new BooleanInBooleanNotRule( new BooleanRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) - ) + self::getContainer()->getByType(RuleLevelHelper::class), + ), ); } diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php index c9d7ed45..feb8186a 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new BooleanInBooleanOrRule( new BooleanRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } diff --git a/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php index 43cd364b..58875e4d 100644 --- a/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInElseIfConditionRuleTest.php @@ -16,8 +16,8 @@ protected function getRule(): Rule { return new BooleanInElseIfConditionRule( new BooleanRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) - ) + self::getContainer()->getByType(RuleLevelHelper::class), + ), ); } diff --git a/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php index 59324856..d72fb6ff 100644 --- a/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInIfConditionRuleTest.php @@ -16,8 +16,8 @@ protected function getRule(): Rule { return new BooleanInIfConditionRule( new BooleanRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) - ) + self::getContainer()->getByType(RuleLevelHelper::class), + ), ); } diff --git a/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php index a7149e00..033c6346 100644 --- a/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInTernaryOperatorRuleTest.php @@ -16,8 +16,8 @@ protected function getRule(): Rule { return new BooleanInTernaryOperatorRule( new BooleanRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) - ) + self::getContainer()->getByType(RuleLevelHelper::class), + ), ); } diff --git a/tests/Rules/Cast/UselessCastRuleTest.php b/tests/Rules/Cast/UselessCastRuleTest.php index c5a151ea..7ffefe2c 100644 --- a/tests/Rules/Cast/UselessCastRuleTest.php +++ b/tests/Rules/Cast/UselessCastRuleTest.php @@ -11,8 +11,7 @@ class UselessCastRuleTest extends RuleTestCase { - /** @var bool */ - private $treatPhpDocTypesAsCertain; + private bool $treatPhpDocTypesAsCertain; protected function getRule(): Rule { @@ -57,7 +56,7 @@ public function testUselessCast(): void 46, 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', ], - ] + ], ); } diff --git a/tests/Rules/Functions/ArrayFilterStrictRuleTest.php b/tests/Rules/Functions/ArrayFilterStrictRuleTest.php index 45ac87a7..b2412193 100644 --- a/tests/Rules/Functions/ArrayFilterStrictRuleTest.php +++ b/tests/Rules/Functions/ArrayFilterStrictRuleTest.php @@ -11,11 +11,9 @@ class ArrayFilterStrictRuleTest extends RuleTestCase { - /** @var bool */ - private $treatPhpDocTypesAsCertain; + private bool $treatPhpDocTypesAsCertain; - /** @var bool */ - private $checkNullables; + private bool $checkNullables; protected function getRule(): Rule { diff --git a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php index 0efa83a7..a1206dca 100644 --- a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php +++ b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php @@ -17,8 +17,8 @@ protected function getRule(): Rule { return $this->createRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) - ) + self::getContainer()->getByType(RuleLevelHelper::class), + ), ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php index 0d25e12c..6d1383fe 100644 --- a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php @@ -18,9 +18,9 @@ protected function getRule(): Rule { return new OperandsInArithmeticAdditionRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } @@ -55,7 +55,7 @@ public function testRule(): void 'Only numeric types are allowed in +, null given on the right side.', 133, ], - ] + ], ); $this->analyse([__DIR__ . '/data/operators.php'], $messages); diff --git a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php index 74e21357..6f059fcc 100644 --- a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new OperandsInArithmeticDivisionRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php index 2ae96a42..2d7681d0 100644 --- a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new OperandsInArithmeticExponentiationRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php index e58e489e..da766cab 100644 --- a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new OperandsInArithmeticModuloRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php index 51c6a8c3..7a1e62e4 100644 --- a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new OperandsInArithmeticMultiplicationRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php index 3b7cf00f..b6ea825c 100644 --- a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php @@ -16,9 +16,9 @@ protected function getRule(): Rule { return new OperandsInArithmeticSubtractionRule( new OperatorRuleHelper( - self::getContainer()->getByType(RuleLevelHelper::class) + self::getContainer()->getByType(RuleLevelHelper::class), ), - true + true, ); } From 1ccec911e6f4b7825e235d6c0f54a11ce8f187bd Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:06:51 +0200 Subject: [PATCH 28/55] Remove unnecessary dependency on nikic/php-parser --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index daefb4f9..0fc653ce 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,6 @@ "phpstan/phpstan": "^2.0" }, "require-dev": { - "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-phpunit": "^2.0", From 8e2c8b0abb83ec35ba2fca475898880f7e700783 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 4 Sep 2024 23:09:40 +0200 Subject: [PATCH 29/55] Fix deprecations --- src/Rules/Functions/ClosureUsesThisRule.php | 2 +- .../SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rules/Functions/ClosureUsesThisRule.php b/src/Rules/Functions/ClosureUsesThisRule.php index d2cb4a45..4f41d26b 100644 --- a/src/Rules/Functions/ClosureUsesThisRule.php +++ b/src/Rules/Functions/ClosureUsesThisRule.php @@ -42,7 +42,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()) + ->line($closureUse->getStartLine()) ->identifier('closure.useThis') ->build(); } diff --git a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php index ded5d345..3dd0f8b2 100644 --- a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php +++ b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php @@ -49,7 +49,7 @@ public function processNode(Node $node, Scope $scope): array $this->printer->prettyPrintExpr($case->cond), $caseType->describe(VerbosityLevel::typeOnly()), )) - ->line($case->getLine()) + ->line($case->getStartLine()) ->identifier('switch.type') ->build(); } From 5eec39fc6ef36015e6de08949c8e9ae9d64560a3 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 6 Sep 2024 20:44:39 +0200 Subject: [PATCH 30/55] Set `polluteScopeWithBlock` to false --- rules.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/rules.neon b/rules.neon index e5194fdd..3332a306 100644 --- a/rules.neon +++ b/rules.neon @@ -1,6 +1,7 @@ parameters: polluteScopeWithLoopInitialAssignments: false polluteScopeWithAlwaysIterableForeach: false + polluteScopeWithBlock: false checkAlwaysTrueCheckTypeFunctionCall: true checkAlwaysTrueInstanceof: true checkAlwaysTrueStrictComparison: true From 1062d489f1d10e79df42d73fa5352a27741d65f1 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 13 Sep 2024 14:49:46 +0200 Subject: [PATCH 31/55] Fix --- tests/Rules/Cast/UselessCastRuleTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Rules/Cast/UselessCastRuleTest.php b/tests/Rules/Cast/UselessCastRuleTest.php index 7ffefe2c..ec8a02ad 100644 --- a/tests/Rules/Cast/UselessCastRuleTest.php +++ b/tests/Rules/Cast/UselessCastRuleTest.php @@ -49,7 +49,6 @@ public function testUselessCast(): void [ 'Casting to string something that\'s already string.', 39, - 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', ], [ 'Casting to string something that\'s already string.', From 876574c426cfc6531ef26c799d20f0cb97d82f48 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 19 Sep 2024 09:12:27 +0200 Subject: [PATCH 32/55] Fix build --- composer.json | 2 +- tests/Rules/Cast/UselessCastRuleTest.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 816fd9fe..4e8399e1 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ ], "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.12" + "phpstan/phpstan": "^1.12.4" }, "require-dev": { "nikic/php-parser": "^4.13.0", diff --git a/tests/Rules/Cast/UselessCastRuleTest.php b/tests/Rules/Cast/UselessCastRuleTest.php index c5a151ea..21d82ae1 100644 --- a/tests/Rules/Cast/UselessCastRuleTest.php +++ b/tests/Rules/Cast/UselessCastRuleTest.php @@ -50,7 +50,6 @@ public function testUselessCast(): void [ 'Casting to string something that\'s already string.', 39, - 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', ], [ 'Casting to string something that\'s already string.', From daeec748b53de80a97498462513066834ec28f8b Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Thu, 19 Sep 2024 11:03:44 +0200 Subject: [PATCH 33/55] Check if treatPhpDocTypesAsCertain tip is enabled See https://github.com/phpstan/phpstan-src/pull/3452 --- rules.neon | 2 ++ src/Rules/Cast/UselessCastRule.php | 15 +++++++++++++-- src/Rules/Functions/ArrayFilterStrictRule.php | 11 ++++++++--- tests/Rules/Cast/UselessCastRuleTest.php | 5 ++++- .../Rules/Functions/ArrayFilterStrictRuleTest.php | 7 ++++++- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/rules.neon b/rules.neon index e5194fdd..e9be35a2 100644 --- a/rules.neon +++ b/rules.neon @@ -170,6 +170,7 @@ services: class: PHPStan\Rules\Cast\UselessCastRule arguments: treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% + treatPhpDocTypesAsCertainTip: %tips.treatPhpDocTypesAsCertain% - class: PHPStan\Rules\Classes\RequireParentConstructCallRule @@ -197,6 +198,7 @@ services: arguments: treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% checkNullables: %checkNullables% + treatPhpDocTypesAsCertainTip: %tips.treatPhpDocTypesAsCertain% - class: PHPStan\Rules\Functions\ClosureUsesThisRule diff --git a/src/Rules/Cast/UselessCastRule.php b/src/Rules/Cast/UselessCastRule.php index adc20e14..99347cce 100644 --- a/src/Rules/Cast/UselessCastRule.php +++ b/src/Rules/Cast/UselessCastRule.php @@ -21,9 +21,16 @@ class UselessCastRule implements Rule /** @var bool */ private $treatPhpDocTypesAsCertain; - public function __construct(bool $treatPhpDocTypesAsCertain) + /** @var bool */ + private $treatPhpDocTypesAsCertainTip; + + public function __construct( + bool $treatPhpDocTypesAsCertain, + bool $treatPhpDocTypesAsCertainTip + ) { $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; + $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType(): string @@ -55,7 +62,11 @@ public function processNode(Node $node, Scope $scope): array 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%.'); + if (!$this->treatPhpDocTypesAsCertainTip) { + return $ruleErrorBuilder; + } + + return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [ $addTip(RuleErrorBuilder::message(sprintf( diff --git a/src/Rules/Functions/ArrayFilterStrictRule.php b/src/Rules/Functions/ArrayFilterStrictRule.php index ff3bf631..59c05700 100644 --- a/src/Rules/Functions/ArrayFilterStrictRule.php +++ b/src/Rules/Functions/ArrayFilterStrictRule.php @@ -32,15 +32,20 @@ class ArrayFilterStrictRule implements Rule /** @var bool */ private $checkNullables; + /** @var bool */ + private $treatPhpDocTypesAsCertainTip; + public function __construct( ReflectionProvider $reflectionProvider, bool $treatPhpDocTypesAsCertain, - bool $checkNullables + bool $checkNullables, + bool $treatPhpDocTypesAsCertainTip ) { $this->reflectionProvider = $reflectionProvider; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->checkNullables = $checkNullables; + $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType(): string @@ -135,8 +140,8 @@ public function processNode(Node $node, Scope $scope): array $callbackType->describe(VerbosityLevel::typeOnly()) ))->identifier('arrayFilter.strict'); - if (!$this->isCallbackTypeNull($nativeCallbackType) && $this->treatPhpDocTypesAsCertain) { - $errorBuilder->tip('Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.'); + if ($this->treatPhpDocTypesAsCertainTip && !$this->isCallbackTypeNull($nativeCallbackType) && $this->treatPhpDocTypesAsCertain) { + $errorBuilder->treatPhpDocTypesAsCertainTip(); } return [$errorBuilder->build()]; diff --git a/tests/Rules/Cast/UselessCastRuleTest.php b/tests/Rules/Cast/UselessCastRuleTest.php index 21d82ae1..4671a3f6 100644 --- a/tests/Rules/Cast/UselessCastRuleTest.php +++ b/tests/Rules/Cast/UselessCastRuleTest.php @@ -16,7 +16,10 @@ class UselessCastRuleTest extends RuleTestCase protected function getRule(): Rule { - return new UselessCastRule($this->treatPhpDocTypesAsCertain); + return new UselessCastRule( + $this->treatPhpDocTypesAsCertain, + true + ); } protected function shouldTreatPhpDocTypesAsCertain(): bool diff --git a/tests/Rules/Functions/ArrayFilterStrictRuleTest.php b/tests/Rules/Functions/ArrayFilterStrictRuleTest.php index 45ac87a7..4da28d21 100644 --- a/tests/Rules/Functions/ArrayFilterStrictRuleTest.php +++ b/tests/Rules/Functions/ArrayFilterStrictRuleTest.php @@ -19,7 +19,12 @@ class ArrayFilterStrictRuleTest extends RuleTestCase protected function getRule(): Rule { - return new ArrayFilterStrictRule($this->createReflectionProvider(), $this->treatPhpDocTypesAsCertain, $this->checkNullables); + return new ArrayFilterStrictRule( + $this->createReflectionProvider(), + $this->treatPhpDocTypesAsCertain, + $this->checkNullables, + true + ); } protected function shouldTreatPhpDocTypesAsCertain(): bool From 988fab9e77f55c851d478e1dd4880a00428d1a90 Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Tue, 24 Sep 2024 14:01:25 +0200 Subject: [PATCH 34/55] Add more separate rule toggles --- README.md | 8 ++++++-- rules.neon | 30 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 94310115..835ecca7 100644 --- a/README.md +++ b/README.md @@ -66,12 +66,16 @@ parameters: booleansInConditions: false uselessCast: false requireParentConstructorCall: false - disallowedConstructs: false + disallowedBacktick: false + disallowedEmpty: false + disallowedImplicitArrayCreation: false + disallowedShortTernary: false overwriteVariablesWithLoop: false closureUsesThis: false matchingInheritedMethodNames: false numericOperandsInArithmeticOperators: false - strictCalls: false + strictFunctionCalls: false + dynamicCallOnStaticMethod: false switchConditionsMatchingType: false noVariableVariables: false strictArrayFilter: false diff --git a/rules.neon b/rules.neon index 49b1a1f6..c33efe59 100644 --- a/rules.neon +++ b/rules.neon @@ -22,12 +22,16 @@ parameters: booleansInConditions: %strictRules.allRules% uselessCast: %strictRules.allRules% requireParentConstructorCall: %strictRules.allRules% - disallowedConstructs: %strictRules.allRules% + disallowedBacktick: %strictRules.allRules% + disallowedEmpty: %strictRules.allRules% + disallowedImplicitArrayCreation: %strictRules.allRules% + disallowedShortTernary: %strictRules.allRules% overwriteVariablesWithLoop: %strictRules.allRules% closureUsesThis: %strictRules.allRules% matchingInheritedMethodNames: %strictRules.allRules% numericOperandsInArithmeticOperators: %strictRules.allRules% - strictCalls: %strictRules.allRules% + strictFunctionCalls: %strictRules.allRules% + dynamicCallOnStaticMethod: %strictRules.allRules% switchConditionsMatchingType: %strictRules.allRules% noVariableVariables: %strictRules.allRules% strictArrayFilter: [%strictRules.allRules%, %featureToggles.bleedingEdge%] @@ -39,12 +43,16 @@ parametersSchema: booleansInConditions: anyOf(bool(), arrayOf(bool())) uselessCast: anyOf(bool(), arrayOf(bool())) requireParentConstructorCall: anyOf(bool(), arrayOf(bool())) - disallowedConstructs: anyOf(bool(), arrayOf(bool())) + disallowedBacktick: anyOf(bool(), arrayOf(bool())) + disallowedEmpty: anyOf(bool(), arrayOf(bool())) + disallowedImplicitArrayCreation: anyOf(bool(), arrayOf(bool())) + disallowedShortTernary: anyOf(bool(), arrayOf(bool())) overwriteVariablesWithLoop: anyOf(bool(), arrayOf(bool())) closureUsesThis: anyOf(bool(), arrayOf(bool())) matchingInheritedMethodNames: anyOf(bool(), arrayOf(bool())) numericOperandsInArithmeticOperators: anyOf(bool(), arrayOf(bool())) - strictCalls: anyOf(bool(), arrayOf(bool())) + strictFunctionCalls: anyOf(bool(), arrayOf(bool())) + dynamicCallOnStaticMethod: anyOf(bool(), arrayOf(bool())) switchConditionsMatchingType: anyOf(bool(), arrayOf(bool())) noVariableVariables: anyOf(bool(), arrayOf(bool())) strictArrayFilter: anyOf(bool(), arrayOf(bool())) @@ -70,13 +78,13 @@ conditionalTags: PHPStan\Rules\Classes\RequireParentConstructCallRule: phpstan.rules.rule: %strictRules.requireParentConstructorCall% PHPStan\Rules\DisallowedConstructs\DisallowedBacktickRule: - phpstan.rules.rule: %strictRules.disallowedConstructs% + phpstan.rules.rule: %strictRules.disallowedBacktick% PHPStan\Rules\DisallowedConstructs\DisallowedEmptyRule: - phpstan.rules.rule: %strictRules.disallowedConstructs% + phpstan.rules.rule: %strictRules.disallowedEmpty% PHPStan\Rules\DisallowedConstructs\DisallowedImplicitArrayCreationRule: - phpstan.rules.rule: %strictRules.disallowedConstructs% + phpstan.rules.rule: %strictRules.disallowedImplicitArrayCreation% PHPStan\Rules\DisallowedConstructs\DisallowedShortTernaryRule: - phpstan.rules.rule: %strictRules.disallowedConstructs% + phpstan.rules.rule: %strictRules.disallowedShortTernary% PHPStan\Rules\ForeachLoop\OverwriteVariablesWithForeachRule: phpstan.rules.rule: %strictRules.overwriteVariablesWithLoop% PHPStan\Rules\ForLoop\OverwriteVariablesWithForLoopInitRule: @@ -108,11 +116,11 @@ conditionalTags: PHPStan\Rules\Operators\OperandsInArithmeticSubtractionRule: phpstan.rules.rule: %strictRules.numericOperandsInArithmeticOperators% PHPStan\Rules\StrictCalls\DynamicCallOnStaticMethodsRule: - phpstan.rules.rule: %strictRules.strictCalls% + phpstan.rules.rule: %strictRules.dynamicCallOnStaticMethod% PHPStan\Rules\StrictCalls\DynamicCallOnStaticMethodsCallableRule: - phpstan.rules.rule: %strictRules.strictCalls% + phpstan.rules.rule: %strictRules.dynamicCallOnStaticMethod% PHPStan\Rules\StrictCalls\StrictFunctionCallsRule: - phpstan.rules.rule: %strictRules.strictCalls% + phpstan.rules.rule: %strictRules.strictFunctionCalls% PHPStan\Rules\SwitchConditions\MatchingTypeInSwitchCaseConditionRule: phpstan.rules.rule: %strictRules.switchConditionsMatchingType% PHPStan\Rules\VariableVariables\VariableMethodCallRule: From 914b5e3a804d11239b38d5ceb8a90742f94e396f Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 24 Sep 2024 14:21:53 +0200 Subject: [PATCH 35/55] Everything from Bleeding Edge enabled --- rules.neon | 26 ++++--------------- .../BooleanInBooleanAndRule.php | 7 ++--- .../BooleanInBooleanOrRule.php | 7 ++--- .../OperandsInArithmeticAdditionRule.php | 7 ++--- .../OperandsInArithmeticDivisionRule.php | 7 ++--- ...OperandsInArithmeticExponentiationRule.php | 7 ++--- .../OperandsInArithmeticModuloRule.php | 7 ++--- ...OperandsInArithmeticMultiplicationRule.php | 7 ++--- .../OperandsInArithmeticSubtractionRule.php | 7 ++--- .../BooleanInBooleanAndRuleTest.php | 1 - .../BooleanInBooleanOrRuleTest.php | 1 - .../OperandsInArithmeticAdditionRuleTest.php | 1 - .../OperandsInArithmeticDivisionRuleTest.php | 1 - ...andsInArithmeticExponentiationRuleTest.php | 1 - .../OperandsInArithmeticModuloRuleTest.php | 1 - ...andsInArithmeticMultiplicationRuleTest.php | 1 - ...perandsInArithmeticSubtractionRuleTest.php | 1 - 17 files changed, 21 insertions(+), 69 deletions(-) diff --git a/rules.neon b/rules.neon index c33efe59..fad3a2fb 100644 --- a/rules.neon +++ b/rules.neon @@ -6,19 +6,19 @@ parameters: checkAlwaysTrueInstanceof: true checkAlwaysTrueStrictComparison: true checkAlwaysTrueLooseComparison: true - checkDynamicProperties: %featureToggles.bleedingEdge% + checkDynamicProperties: true checkExplicitMixedMissingReturn: true checkFunctionNameCase: true checkInternalClassCaseSensitivity: true reportMaybesInMethodSignatures: true reportStaticMethodSignatures: true reportMaybesInPropertyPhpDocTypes: true - reportWrongPhpDocTypeInVarTag: %featureToggles.bleedingEdge% + reportWrongPhpDocTypeInVarTag: true featureToggles: - illegalConstructorMethodCall: %featureToggles.bleedingEdge% + illegalConstructorMethodCall: true strictRules: allRules: true - disallowedLooseComparison: [%strictRules.allRules%, %featureToggles.bleedingEdge%] + disallowedLooseComparison: %strictRules.allRules% booleansInConditions: %strictRules.allRules% uselessCast: %strictRules.allRules% requireParentConstructorCall: %strictRules.allRules% @@ -34,7 +34,7 @@ parameters: dynamicCallOnStaticMethod: %strictRules.allRules% switchConditionsMatchingType: %strictRules.allRules% noVariableVariables: %strictRules.allRules% - strictArrayFilter: [%strictRules.allRules%, %featureToggles.bleedingEdge%] + strictArrayFilter: %strictRules.allRules% parametersSchema: strictRules: structure([ @@ -155,16 +155,12 @@ 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 @@ -229,33 +225,21 @@ services: - class: PHPStan\Rules\Operators\OperandsInArithmeticAdditionRule - arguments: - bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticDivisionRule - arguments: - bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticExponentiationRule - arguments: - bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticModuloRule - arguments: - bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticMultiplicationRule - arguments: - bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticSubtractionRule - arguments: - bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\StrictCalls\DynamicCallOnStaticMethodsRule diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php index a3055694..eed19aea 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php @@ -18,12 +18,9 @@ class BooleanInBooleanAndRule implements Rule private BooleanRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(BooleanRuleHelper $helper, bool $bleedingEdge) + public function __construct(BooleanRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -35,7 +32,7 @@ public function processNode(Node $node, Scope $scope): array { $originalNode = $node->getOriginalNode(); $messages = []; - $nodeText = $this->bleedingEdge ? $originalNode->getOperatorSigil() : '&&'; + $nodeText = $originalNode->getOperatorSigil(); $identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanAnd ? 'booleanAnd' : 'logicalAnd'; if (!$this->helper->passesAsBoolean($scope, $originalNode->left)) { $leftType = $scope->getType($originalNode->left); diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php index d0b91dd1..cb06a341 100644 --- a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php +++ b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php @@ -18,12 +18,9 @@ class BooleanInBooleanOrRule implements Rule private BooleanRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(BooleanRuleHelper $helper, bool $bleedingEdge) + public function __construct(BooleanRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -35,7 +32,7 @@ public function processNode(Node $node, Scope $scope): array { $originalNode = $node->getOriginalNode(); $messages = []; - $nodeText = $this->bleedingEdge ? $originalNode->getOperatorSigil() : '||'; + $nodeText = $originalNode->getOperatorSigil(); $identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanOr ? 'booleanOr' : 'logicalOr'; if (!$this->helper->passesAsBoolean($scope, $originalNode->left)) { $leftType = $scope->getType($originalNode->left); diff --git a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php index fd4b119c..80de1463 100644 --- a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php @@ -21,12 +21,9 @@ class OperandsInArithmeticAdditionRule implements Rule private OperatorRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) + public function __construct(OperatorRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -39,7 +36,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof BinaryOpPlus) { $left = $node->left; $right = $node->right; - } elseif ($node instanceof AssignOpPlus && $this->bleedingEdge) { + } elseif ($node instanceof AssignOpPlus) { $left = $node->var; $right = $node->expr; } else { diff --git a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php index 642d6e8e..e95b3d62 100644 --- a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php @@ -20,12 +20,9 @@ class OperandsInArithmeticDivisionRule implements Rule private OperatorRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) + public function __construct(OperatorRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -38,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof BinaryOpDiv) { $left = $node->left; $right = $node->right; - } elseif ($node instanceof AssignOpDiv && $this->bleedingEdge) { + } elseif ($node instanceof AssignOpDiv) { $left = $node->var; $right = $node->expr; } else { diff --git a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php index 128194ce..1992b84a 100644 --- a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php @@ -20,12 +20,9 @@ class OperandsInArithmeticExponentiationRule implements Rule private OperatorRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) + public function __construct(OperatorRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -38,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof BinaryOpPow) { $left = $node->left; $right = $node->right; - } elseif ($node instanceof AssignOpPow && $this->bleedingEdge) { + } elseif ($node instanceof AssignOpPow) { $left = $node->var; $right = $node->expr; } else { diff --git a/src/Rules/Operators/OperandsInArithmeticModuloRule.php b/src/Rules/Operators/OperandsInArithmeticModuloRule.php index a687c05e..5b5f3c32 100644 --- a/src/Rules/Operators/OperandsInArithmeticModuloRule.php +++ b/src/Rules/Operators/OperandsInArithmeticModuloRule.php @@ -20,12 +20,9 @@ class OperandsInArithmeticModuloRule implements Rule private OperatorRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) + public function __construct(OperatorRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -38,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof BinaryOpMod) { $left = $node->left; $right = $node->right; - } elseif ($node instanceof AssignOpMod && $this->bleedingEdge) { + } elseif ($node instanceof AssignOpMod) { $left = $node->var; $right = $node->expr; } else { diff --git a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php index e7e055b9..353df4c6 100644 --- a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php @@ -20,12 +20,9 @@ class OperandsInArithmeticMultiplicationRule implements Rule private OperatorRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) + public function __construct(OperatorRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -38,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof BinaryOpMul) { $left = $node->left; $right = $node->right; - } elseif ($node instanceof AssignOpMul && $this->bleedingEdge) { + } elseif ($node instanceof AssignOpMul) { $left = $node->var; $right = $node->expr; } else { diff --git a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php index 527f645b..5559d60f 100644 --- a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php @@ -20,12 +20,9 @@ class OperandsInArithmeticSubtractionRule implements Rule private OperatorRuleHelper $helper; - private bool $bleedingEdge; - - public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) + public function __construct(OperatorRuleHelper $helper) { $this->helper = $helper; - $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string @@ -38,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array if ($node instanceof BinaryOpMinus) { $left = $node->left; $right = $node->right; - } elseif ($node instanceof AssignOpMinus && $this->bleedingEdge) { + } elseif ($node instanceof AssignOpMinus) { $left = $node->var; $right = $node->expr; } else { diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php index 08625e64..ab030c51 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanAndRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new BooleanRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php index feb8186a..5e3e83a2 100644 --- a/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php +++ b/tests/Rules/BooleansInConditions/BooleanInBooleanOrRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new BooleanRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php index 6d1383fe..f1bec0e6 100644 --- a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php @@ -20,7 +20,6 @@ protected function getRule(): Rule new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php index 6f059fcc..57148083 100644 --- a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php index 2d7681d0..539a969c 100644 --- a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php index da766cab..54ccc48a 100644 --- a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php index 7a1e62e4..48641201 100644 --- a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } diff --git a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php index b6ea825c..66dc3b09 100644 --- a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php @@ -18,7 +18,6 @@ protected function getRule(): Rule new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class), ), - true, ); } From ad53bd9f911e7831e8e02cd3e54faf1d44910c33 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 24 Sep 2024 14:25:28 +0200 Subject: [PATCH 36/55] Remove options removed in PHPStan 2.0 --- rules.neon | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rules.neon b/rules.neon index fad3a2fb..ba091691 100644 --- a/rules.neon +++ b/rules.neon @@ -2,10 +2,6 @@ parameters: polluteScopeWithLoopInitialAssignments: false polluteScopeWithAlwaysIterableForeach: false polluteScopeWithBlock: false - checkAlwaysTrueCheckTypeFunctionCall: true - checkAlwaysTrueInstanceof: true - checkAlwaysTrueStrictComparison: true - checkAlwaysTrueLooseComparison: true checkDynamicProperties: true checkExplicitMixedMissingReturn: true checkFunctionNameCase: true From 63956f7896780551ed1ab29e75a6a645d8a0919c Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 24 Sep 2024 17:30:35 +0200 Subject: [PATCH 37/55] Moved illegalConstructorMethodCall rules from phpstan to phpstan-strict-rules --- README.md | 1 + rules.neon | 14 ++- .../IllegalConstructorMethodCallRule.php | 34 ++++++ .../IllegalConstructorStaticCallRule.php | 92 ++++++++++++++++ .../IllegalConstructorMethodCallRuleTest.php | 37 +++++++ .../IllegalConstructorStaticCallRuleTest.php | 59 ++++++++++ tests/Rules/Methods/data/bug-9577.php | 40 +++++++ .../illegal-constructor-call-rule-test.php | 103 ++++++++++++++++++ 8 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 src/Rules/Methods/IllegalConstructorMethodCallRule.php create mode 100644 src/Rules/Methods/IllegalConstructorStaticCallRule.php create mode 100644 tests/Rules/Methods/IllegalConstructorMethodCallRuleTest.php create mode 100644 tests/Rules/Methods/IllegalConstructorStaticCallRuleTest.php create mode 100644 tests/Rules/Methods/data/bug-9577.php create mode 100644 tests/Rules/Methods/data/illegal-constructor-call-rule-test.php diff --git a/README.md b/README.md index 835ecca7..14ade92e 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ parameters: switchConditionsMatchingType: false noVariableVariables: false strictArrayFilter: false + illegalConstructorMethodCall: false ``` Aside from introducing new custom rules, phpstan-strict-rules also [change the default values of some configuration parameters](https://github.com/phpstan/phpstan-strict-rules/blob/1.6.x/rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). diff --git a/rules.neon b/rules.neon index ba091691..f268d243 100644 --- a/rules.neon +++ b/rules.neon @@ -10,8 +10,6 @@ parameters: reportStaticMethodSignatures: true reportMaybesInPropertyPhpDocTypes: true reportWrongPhpDocTypeInVarTag: true - featureToggles: - illegalConstructorMethodCall: true strictRules: allRules: true disallowedLooseComparison: %strictRules.allRules% @@ -31,6 +29,7 @@ parameters: switchConditionsMatchingType: %strictRules.allRules% noVariableVariables: %strictRules.allRules% strictArrayFilter: %strictRules.allRules% + illegalConstructorMethodCall: %strictRules.allRules% parametersSchema: strictRules: structure([ @@ -52,6 +51,7 @@ parametersSchema: switchConditionsMatchingType: anyOf(bool(), arrayOf(bool())) noVariableVariables: anyOf(bool(), arrayOf(bool())) strictArrayFilter: anyOf(bool(), arrayOf(bool())) + illegalConstructorMethodCall: anyOf(bool(), arrayOf(bool())) ]) conditionalTags: @@ -133,6 +133,10 @@ conditionalTags: phpstan.rules.rule: %strictRules.noVariableVariables% PHPStan\Rules\VariableVariables\VariablePropertyFetchRule: phpstan.rules.rule: %strictRules.noVariableVariables% + PHPStan\Rules\Methods\IllegalConstructorMethodCallRule: + phpstan.rules.rule: %strictRules.illegalConstructorMethodCall% + PHPStan\Rules\Methods\IllegalConstructorStaticCallRule: + phpstan.rules.rule: %strictRules.illegalConstructorMethodCall% services: - @@ -207,6 +211,12 @@ services: - class: PHPStan\Rules\Methods\WrongCaseOfInheritedMethodRule + - + class: PHPStan\Rules\Methods\IllegalConstructorMethodCallRule + + - + class: PHPStan\Rules\Methods\IllegalConstructorStaticCallRule + - class: PHPStan\Rules\Operators\OperandInArithmeticPostDecrementRule diff --git a/src/Rules/Methods/IllegalConstructorMethodCallRule.php b/src/Rules/Methods/IllegalConstructorMethodCallRule.php new file mode 100644 index 00000000..1dba6ed6 --- /dev/null +++ b/src/Rules/Methods/IllegalConstructorMethodCallRule.php @@ -0,0 +1,34 @@ + + */ +final class IllegalConstructorMethodCallRule implements Rule +{ + + public function getNodeType(): string + { + return Node\Expr\MethodCall::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== '__construct') { + return []; + } + + return [ + RuleErrorBuilder::message('Call to __construct() on an existing object is not allowed.') + ->identifier('constructor.call') + ->build(), + ]; + } + +} diff --git a/src/Rules/Methods/IllegalConstructorStaticCallRule.php b/src/Rules/Methods/IllegalConstructorStaticCallRule.php new file mode 100644 index 00000000..fa747d6a --- /dev/null +++ b/src/Rules/Methods/IllegalConstructorStaticCallRule.php @@ -0,0 +1,92 @@ + + */ +final class IllegalConstructorStaticCallRule implements Rule +{ + + public function getNodeType(): string + { + return Node\Expr\StaticCall::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== '__construct') { + return []; + } + + if ($this->isCollectCallingConstructor($node, $scope)) { + return []; + } + + return [ + RuleErrorBuilder::message('Static call to __construct() is only allowed on a parent class in the constructor.') + ->identifier('constructor.call') + ->build(), + ]; + } + + private function isCollectCallingConstructor(Node\Expr\StaticCall $node, Scope $scope): bool + { + // __construct should be called from inside constructor + if ($scope->getFunction() === null) { + return false; + } + + if ($scope->getFunction()->getName() !== '__construct') { + if (!$this->isInRenamedTraitConstructor($scope)) { + return false; + } + } + + if (!$scope->isInClass()) { + return false; + } + + if (!$node->class instanceof Node\Name) { + return false; + } + + $parentClasses = array_map(static fn (string $name) => strtolower($name), $scope->getClassReflection()->getParentClassesNames()); + + return in_array(strtolower($scope->resolveName($node->class)), $parentClasses, true); + } + + private function isInRenamedTraitConstructor(Scope $scope): bool + { + if (!$scope->isInClass()) { + return false; + } + + if (!$scope->isInTrait()) { + return false; + } + + if ($scope->getFunction() === null) { + return false; + } + + $traitAliases = $scope->getClassReflection()->getNativeReflection()->getTraitAliases(); + $functionName = $scope->getFunction()->getName(); + if (!array_key_exists($functionName, $traitAliases)) { + return false; + } + + return $traitAliases[$functionName] === sprintf('%s::%s', $scope->getTraitReflection()->getName(), '__construct'); + } + +} diff --git a/tests/Rules/Methods/IllegalConstructorMethodCallRuleTest.php b/tests/Rules/Methods/IllegalConstructorMethodCallRuleTest.php new file mode 100644 index 00000000..8b0f957e --- /dev/null +++ b/tests/Rules/Methods/IllegalConstructorMethodCallRuleTest.php @@ -0,0 +1,37 @@ + + */ +class IllegalConstructorMethodCallRuleTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new IllegalConstructorMethodCallRule(); + } + + public function testMethods(): void + { + $this->analyse([__DIR__ . '/data/illegal-constructor-call-rule-test.php'], [ + [ + 'Call to __construct() on an existing object is not allowed.', + 13, + ], + [ + 'Call to __construct() on an existing object is not allowed.', + 18, + ], + [ + 'Call to __construct() on an existing object is not allowed.', + 60, + ], + ]); + } + +} diff --git a/tests/Rules/Methods/IllegalConstructorStaticCallRuleTest.php b/tests/Rules/Methods/IllegalConstructorStaticCallRuleTest.php new file mode 100644 index 00000000..19904f72 --- /dev/null +++ b/tests/Rules/Methods/IllegalConstructorStaticCallRuleTest.php @@ -0,0 +1,59 @@ + + */ +class IllegalConstructorStaticCallRuleTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new IllegalConstructorStaticCallRule(); + } + + public function testMethods(): void + { + $this->analyse([__DIR__ . '/data/illegal-constructor-call-rule-test.php'], [ + [ + 'Static call to __construct() is only allowed on a parent class in the constructor.', + 31, + ], + [ + 'Static call to __construct() is only allowed on a parent class in the constructor.', + 43, + ], + [ + 'Static call to __construct() is only allowed on a parent class in the constructor.', + 44, + ], + [ + 'Static call to __construct() is only allowed on a parent class in the constructor.', + 49, + ], + [ + 'Static call to __construct() is only allowed on a parent class in the constructor.', + 50, + ], + [ + 'Static call to __construct() is only allowed on a parent class in the constructor.', + 100, + ], + ]); + } + + public function testBug9577(): void + { + if (PHP_VERSION_ID < 80100) { + self::markTestSkipped('Test requires PHP 8.1.'); + } + + $this->analyse([__DIR__ . '/data/bug-9577.php'], []); + } + +} diff --git a/tests/Rules/Methods/data/bug-9577.php b/tests/Rules/Methods/data/bug-9577.php new file mode 100644 index 00000000..2214d45b --- /dev/null +++ b/tests/Rules/Methods/data/bug-9577.php @@ -0,0 +1,40 @@ += 8.1 + +namespace Bug9577IllegalConstructorStaticCall; + +trait StringableMessageTrait +{ + public function __construct( + private readonly \Stringable $StringableMessage, + int $code = 0, + ?\Throwable $previous = null, + ) { + parent::__construct((string) $StringableMessage, $code, $previous); + } + + public function getStringableMessage(): \Stringable + { + return $this->StringableMessage; + } +} + +class SpecializedException extends \RuntimeException +{ + use StringableMessageTrait { + StringableMessageTrait::__construct as __traitConstruct; + } + + public function __construct( + private readonly object $aService, + \Stringable $StringableMessage, + int $code = 0, + ?\Throwable $previous = null, + ) { + $this->__traitConstruct($StringableMessage, $code, $previous); + } + + public function getService(): object + { + return $this->aService; + } +} diff --git a/tests/Rules/Methods/data/illegal-constructor-call-rule-test.php b/tests/Rules/Methods/data/illegal-constructor-call-rule-test.php new file mode 100644 index 00000000..f5198a50 --- /dev/null +++ b/tests/Rules/Methods/data/illegal-constructor-call-rule-test.php @@ -0,0 +1,103 @@ + 1) { + return; + } + $this->__construct($datetime, $timezone); + } + + public function mutate(string $datetime = "now", ?\DateTimeZone $timezone = null): void + { + $this->__construct($datetime, $timezone); + } +} + +class ExtendedDateTimeWithParentCall extends \DateTimeImmutable +{ + public function __construct(string $datetime = "now", ?\DateTimeZone $timezone = null) + { + parent::__construct($datetime, $timezone); + } + + public function mutate(string $datetime = "now", ?\DateTimeZone $timezone = null): void + { + parent::__construct($datetime, $timezone); + } +} + +class ExtendedDateTimeWithSelfCall extends \DateTimeImmutable +{ + public function __construct(string $datetime = "now", ?\DateTimeZone $timezone = null) + { + // Avoid infinite loop + if (count(debug_backtrace()) > 1) { + return; + } + self::__construct($datetime, $timezone); + ExtendedDateTimeWithSelfCall::__construct($datetime, $timezone); + } + + public function mutate(string $datetime = "now", ?\DateTimeZone $timezone = null): void + { + self::__construct($datetime, $timezone); + ExtendedDateTimeWithSelfCall::__construct($datetime, $timezone); + } +} + +class Foo +{ + + public function doFoo() + { + $extendedDateTime = new ExtendedDateTimeWithMethodCall('2022/04/12'); + $extendedDateTime->__construct('2022/04/13'); + } + +} + +abstract class Presenter +{ + + public function __construct() + { + + } + +} + +abstract class BasePresenter extends Presenter +{ + + public function __construct() + { + Presenter::__construct(); + } + +} + +class CatPresenter extends BasePresenter +{ + + public function __construct() + { + Presenter::__construct(); + } + +} + +class DogPresenter extends BasePresenter +{ + + public function __construct() + { + CatPresenter::__construct(); + } + +} From e208c9311872047b903511e2e03cb0df795014b0 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 21:35:25 +0200 Subject: [PATCH 38/55] Fix after PHPStan update --- .../MatchingTypeInSwitchCaseConditionRule.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php index 3dd0f8b2..ba7c92f3 100644 --- a/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php +++ b/src/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRule.php @@ -4,8 +4,8 @@ use PhpParser\Node; use PhpParser\Node\Stmt\Switch_; -use PhpParser\PrettyPrinter\Standard; use PHPStan\Analyser\Scope; +use PHPStan\Node\Printer\Printer; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; @@ -17,9 +17,9 @@ class MatchingTypeInSwitchCaseConditionRule implements Rule { - private Standard $printer; + private Printer $printer; - public function __construct(Standard $printer) + public function __construct(Printer $printer) { $this->printer = $printer; } From 1721dbffc29ce0f689dad7f9666c1e99e47439cd Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 21:38:22 +0200 Subject: [PATCH 39/55] Fix after PHPStan update --- tests/Levels/LevelsIntegrationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Levels/LevelsIntegrationTest.php b/tests/Levels/LevelsIntegrationTest.php index d1e57d7e..38fda091 100644 --- a/tests/Levels/LevelsIntegrationTest.php +++ b/tests/Levels/LevelsIntegrationTest.php @@ -10,7 +10,7 @@ class LevelsIntegrationTest extends LevelsTestCase /** * @return string[][] */ - public function dataTopics(): array + public static function dataTopics(): array { return [ ['arithmeticOperators'], From 03684036b5be8ce41a628e84a11ba71ff1d795c5 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 21:45:01 +0200 Subject: [PATCH 40/55] Fix --- .../MatchingTypeInSwitchCaseConditionRuleTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php b/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php index 553cba5e..ae7cee17 100644 --- a/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php +++ b/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php @@ -2,7 +2,7 @@ namespace PHPStan\Rules\SwitchConditions; -use PhpParser\PrettyPrinter\Standard; +use PHPStan\Node\Printer\Printer; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; @@ -14,7 +14,7 @@ class MatchingTypeInSwitchCaseConditionRuleTest extends RuleTestCase protected function getRule(): Rule { - return new MatchingTypeInSwitchCaseConditionRule(new Standard()); + return new MatchingTypeInSwitchCaseConditionRule(new Printer()); } public function testRule(): void From 5d50bde7ed256a94e50e1466a105f8d53fc5ed3a Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Sep 2024 21:49:16 +0200 Subject: [PATCH 41/55] Fix --- .../MatchingTypeInSwitchCaseConditionRuleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php b/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php index ae7cee17..b8c854d3 100644 --- a/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php +++ b/tests/Rules/SwitchConditions/MatchingTypeInSwitchCaseConditionRuleTest.php @@ -14,7 +14,7 @@ class MatchingTypeInSwitchCaseConditionRuleTest extends RuleTestCase protected function getRule(): Rule { - return new MatchingTypeInSwitchCaseConditionRule(new Printer()); + return new MatchingTypeInSwitchCaseConditionRule(self::getContainer()->getByType(Printer::class)); } public function testRule(): void From b60bffc846824fdeb70d41cfe4de956c8557e2fd Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 7 Oct 2024 09:08:45 +0200 Subject: [PATCH 42/55] Fix --- tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php index f1bec0e6..cc533050 100644 --- a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php @@ -38,7 +38,7 @@ public function testRule(): void if (PHP_VERSION_ID < 80000) { $messages[] = [ - 'Only numeric types are allowed in +, (array|false) given on the left side.', + 'Only numeric types are allowed in +, (list|false) given on the left side.', 110, ]; } From a4a6a08bd4a461e516b9c3b8fdbf0f1883b34158 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 26 Oct 2024 11:44:48 +0200 Subject: [PATCH 43/55] Remove dead test because of raised min-php version --- .../Classes/RequireParentConstructCallRuleTest.php | 9 --------- .../data/call-to-parent-constructor-php-lt-74.php | 11 ----------- 2 files changed, 20 deletions(-) delete mode 100644 tests/Rules/Classes/data/call-to-parent-constructor-php-lt-74.php diff --git a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php index e8d63620..db0c8bae 100644 --- a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php +++ b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php @@ -4,7 +4,6 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; -use const PHP_VERSION_ID; /** * @extends RuleTestCase @@ -44,12 +43,4 @@ public function testCheckInTraits(): void $this->analyse([__DIR__ . '/data/call-to-parent-constructor-in-trait.php'], []); } - 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'], []); - } - } diff --git a/tests/Rules/Classes/data/call-to-parent-constructor-php-lt-74.php b/tests/Rules/Classes/data/call-to-parent-constructor-php-lt-74.php deleted file mode 100644 index 79616947..00000000 --- a/tests/Rules/Classes/data/call-to-parent-constructor-php-lt-74.php +++ /dev/null @@ -1,11 +0,0 @@ - Date: Thu, 12 Dec 2024 21:21:10 +0100 Subject: [PATCH 44/55] Added `strictRulesInstalled` parameter --- composer.json | 2 +- rules.neon | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0fc653ce..2bbc44d6 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ ], "require": { "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.0" + "phpstan/phpstan": "^2.0.4" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", diff --git a/rules.neon b/rules.neon index f268d243..61b49854 100644 --- a/rules.neon +++ b/rules.neon @@ -1,4 +1,5 @@ parameters: + strictRulesInstalled: true polluteScopeWithLoopInitialAssignments: false polluteScopeWithAlwaysIterableForeach: false polluteScopeWithBlock: false From b564ca479e7e735f750aaac4935af965572a7845 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 28 Dec 2024 21:08:16 +0100 Subject: [PATCH 45/55] Handle SimpleXMLElement in VariablePropertyFetchRule --- .../VariablePropertyFetchRule.php | 15 ++++++++++++++- .../VariablePropertyFetchRuleTest.php | 6 +++++- tests/Rules/VariableVariables/data/bug243.php | 7 +++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tests/Rules/VariableVariables/data/bug243.php diff --git a/src/Rules/VariableVariables/VariablePropertyFetchRule.php b/src/Rules/VariableVariables/VariablePropertyFetchRule.php index 73ff0888..61796b0b 100644 --- a/src/Rules/VariableVariables/VariablePropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariablePropertyFetchRule.php @@ -10,6 +10,7 @@ use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; +use SimpleXMLElement; use function sprintf; /** @@ -50,7 +51,11 @@ public function processNode(Node $node, Scope $scope): array continue; } - if ($this->isUniversalObjectCrate($this->reflectionProvider->getClass($referencedClass))) { + $classReflection = $this->reflectionProvider->getClass($referencedClass); + if ( + $this->isUniversalObjectCrate($classReflection) + || $this->isSimpleXMLElement($classReflection) + ) { return []; } } @@ -63,6 +68,14 @@ public function processNode(Node $node, Scope $scope): array ]; } + private function isSimpleXMLElement( + ClassReflection $classReflection + ): bool + { + return $classReflection->getName() === SimpleXMLElement::class + || $classReflection->isSubclassOf(SimpleXMLElement::class); + } + private function isUniversalObjectCrate( ClassReflection $classReflection ): bool diff --git a/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php b/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php index 9126d836..0f79cbfc 100644 --- a/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php +++ b/tests/Rules/VariableVariables/VariablePropertyFetchRuleTest.php @@ -15,7 +15,6 @@ protected function getRule(): Rule { return new VariablePropertyFetchRule($this->createReflectionProvider(), [ 'stdClass', - 'SimpleXMLElement', ]); } @@ -29,4 +28,9 @@ public function testRule(): void ]); } + public function testBug243(): void + { + $this->analyse([__DIR__ . '/data/bug243.php'], []); + } + } diff --git a/tests/Rules/VariableVariables/data/bug243.php b/tests/Rules/VariableVariables/data/bug243.php new file mode 100644 index 00000000..a2db9fba --- /dev/null +++ b/tests/Rules/VariableVariables/data/bug243.php @@ -0,0 +1,7 @@ +{'foo-bar'}; +}; From 8b88b5f818bfa301e0c99154ab622dace071c3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 21 Jan 2025 11:27:41 +0100 Subject: [PATCH 46/55] Deprecated parent constructor must not be called --- .../RequireParentConstructCallRule.php | 1 + .../data/call-to-parent-constructor.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Rules/Classes/RequireParentConstructCallRule.php b/src/Rules/Classes/RequireParentConstructCallRule.php index 31b2faf5..77595810 100644 --- a/src/Rules/Classes/RequireParentConstructCallRule.php +++ b/src/Rules/Classes/RequireParentConstructCallRule.php @@ -113,6 +113,7 @@ private function getParentConstructorClass($classReflection) && $constructor->getDeclaringClass()->getName() === $classReflection->getParentClass()->getName() && !$constructor->isAbstract() && !$constructor->isPrivate() + && !$constructor->isDeprecated() ) || ( $constructorWithClassName !== null && $constructorWithClassName->getDeclaringClass()->getName() === $classReflection->getParentClass()->getName() diff --git a/tests/Rules/Classes/data/call-to-parent-constructor.php b/tests/Rules/Classes/data/call-to-parent-constructor.php index 48975e9d..12ddab7d 100644 --- a/tests/Rules/Classes/data/call-to-parent-constructor.php +++ b/tests/Rules/Classes/data/call-to-parent-constructor.php @@ -181,3 +181,22 @@ public function __construct() } } + +class DeprecatedConstructor +{ + /** @deprecated */ + public function __construct() + { + + } + +} + +class ExtendsDeprecatedConstructor extends DeprecatedConstructor +{ + public function __construct() + { + // should not call deprecated parent + } + +} From a0e19268d2614a0ff089599f43a61cbaecabe05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Mirtes?= Date: Tue, 28 Jan 2025 10:25:26 +0100 Subject: [PATCH 47/55] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index d0053746..142ba011 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016 Ondřej Mirtes +Copyright (c) 2025 PHPStan s.r.o. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 342fa2607b7278a4c9ea72b2dc6562ddca6d52d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Mirtes?= Date: Tue, 28 Jan 2025 10:26:18 +0100 Subject: [PATCH 48/55] Update LICENSE --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index 142ba011..52fba1e2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ MIT License +Copyright (c) 2016 Ondřej Mirtes Copyright (c) 2025 PHPStan s.r.o. Permission is hereby granted, free of charge, to any person obtaining a copy From 51abacdf8bfd4587696132d3ca055362ac242298 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 6 Mar 2025 17:36:31 +0100 Subject: [PATCH 49/55] Fix build --- src/Rules/VariableVariables/VariablePropertyFetchRule.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Rules/VariableVariables/VariablePropertyFetchRule.php b/src/Rules/VariableVariables/VariablePropertyFetchRule.php index 0d077b27..760bff69 100644 --- a/src/Rules/VariableVariables/VariablePropertyFetchRule.php +++ b/src/Rules/VariableVariables/VariablePropertyFetchRule.php @@ -71,8 +71,7 @@ private function isSimpleXMLElement( ClassReflection $classReflection ): bool { - return $classReflection->getName() === SimpleXMLElement::class - || $classReflection->isSubclassOf(SimpleXMLElement::class); + return $classReflection->is(SimpleXMLElement::class); } private function isUniversalObjectCrate( @@ -84,10 +83,7 @@ private function isUniversalObjectCrate( continue; } - if ( - $classReflection->getName() === $className - || $classReflection->isSubclassOf($className) - ) { + if ($classReflection->is($className)) { return true; } } From b20f78c2c7e087630e3ac50e7276b69d3e78abbe Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 12 Mar 2025 16:33:26 +0100 Subject: [PATCH 50/55] Fix build --- .../ForLoop/OverwriteVariablesWithForLoopInitRuleTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Rules/ForLoop/OverwriteVariablesWithForLoopInitRuleTest.php b/tests/Rules/ForLoop/OverwriteVariablesWithForLoopInitRuleTest.php index 7ea45488..c15303e7 100644 --- a/tests/Rules/ForLoop/OverwriteVariablesWithForLoopInitRuleTest.php +++ b/tests/Rules/ForLoop/OverwriteVariablesWithForLoopInitRuleTest.php @@ -62,4 +62,9 @@ public function testRule(): void ]); } + protected function shouldPolluteScopeWithLoopInitialAssignments(): bool + { + return false; + } + } From 3e139cbe67fafa3588e1dbe27ca50f31fdb6236a Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 18 Mar 2025 12:42:40 +0100 Subject: [PATCH 51/55] Check for boolean in while conditions --- README.md | 2 + rules.neon | 12 +++++ .../BooleanInDoWhileConditionRule.php | 46 +++++++++++++++++++ .../BooleanInWhileConditionRule.php | 46 +++++++++++++++++++ .../BooleanInDoWhileConditionRuleTest.php | 34 ++++++++++++++ .../BooleanInWhileConditionRuleTest.php | 34 ++++++++++++++ .../BooleansInConditions/data/conditions.php | 10 ++++ 7 files changed, 184 insertions(+) create mode 100644 src/Rules/BooleansInConditions/BooleanInDoWhileConditionRule.php create mode 100644 src/Rules/BooleansInConditions/BooleanInWhileConditionRule.php create mode 100644 tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php create mode 100644 tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php diff --git a/README.md b/README.md index 14ade92e..88b7e96f 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [PHPStan](https://phpstan.org/) focuses on finding bugs in your code. But in PHP there's a lot of leeway in how stuff can be written. This repository contains additional rules that revolve around strictly and strongly typed code with no loose casting for those who want additional safety in extremely defensive programming: * Require booleans in `if`, `elseif`, ternary operator, after `!`, and on both sides of `&&` and `||`. +* Require booleans in `while` and `do while` loop conditions. * Require numeric operands or arrays in `+` and numeric operands in `-`/`*`/`/`/`**`/`%`. * Require numeric operand in `$var++`, `$var--`, `++$var`and `--$var`. * These functions contain a `$strict` parameter for better type safety, it must be set to `true`: @@ -64,6 +65,7 @@ parameters: strictRules: disallowedLooseComparison: false booleansInConditions: false + booleansInLoopConditions: false uselessCast: false requireParentConstructorCall: false disallowedBacktick: false diff --git a/rules.neon b/rules.neon index 61b49854..dd20b8d1 100644 --- a/rules.neon +++ b/rules.neon @@ -15,6 +15,7 @@ parameters: allRules: true disallowedLooseComparison: %strictRules.allRules% booleansInConditions: %strictRules.allRules% + booleansInLoopConditions: [%strictRules.allRules%, %featureToggles.bleedingEdge%] uselessCast: %strictRules.allRules% requireParentConstructorCall: %strictRules.allRules% disallowedBacktick: %strictRules.allRules% @@ -37,6 +38,7 @@ parametersSchema: allRules: anyOf(bool(), arrayOf(bool())), disallowedLooseComparison: anyOf(bool(), arrayOf(bool())), booleansInConditions: anyOf(bool(), arrayOf(bool())) + booleansInLoopConditions: anyOf(bool(), arrayOf(bool())) uselessCast: anyOf(bool(), arrayOf(bool())) requireParentConstructorCall: anyOf(bool(), arrayOf(bool())) disallowedBacktick: anyOf(bool(), arrayOf(bool())) @@ -64,12 +66,16 @@ conditionalTags: phpstan.rules.rule: %strictRules.booleansInConditions% PHPStan\Rules\BooleansInConditions\BooleanInBooleanOrRule: phpstan.rules.rule: %strictRules.booleansInConditions% + PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule: + phpstan.rules.rule: %strictRules.booleansInLoopConditions% PHPStan\Rules\BooleansInConditions\BooleanInElseIfConditionRule: phpstan.rules.rule: %strictRules.booleansInConditions% PHPStan\Rules\BooleansInConditions\BooleanInIfConditionRule: phpstan.rules.rule: %strictRules.booleansInConditions% PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule: phpstan.rules.rule: %strictRules.booleansInConditions% + PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule: + phpstan.rules.rule: %strictRules.booleansInLoopConditions% PHPStan\Rules\Cast\UselessCastRule: phpstan.rules.rule: %strictRules.uselessCast% PHPStan\Rules\Classes\RequireParentConstructCallRule: @@ -163,6 +169,9 @@ services: - class: PHPStan\Rules\BooleansInConditions\BooleanInBooleanOrRule + - + class: PHPStan\Rules\BooleansInConditions\BooleanInDoWhileConditionRule + - class: PHPStan\Rules\BooleansInConditions\BooleanInElseIfConditionRule @@ -172,6 +181,9 @@ services: - class: PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule + - + class: PHPStan\Rules\BooleansInConditions\BooleanInWhileConditionRule + - class: PHPStan\Rules\Cast\UselessCastRule arguments: diff --git a/src/Rules/BooleansInConditions/BooleanInDoWhileConditionRule.php b/src/Rules/BooleansInConditions/BooleanInDoWhileConditionRule.php new file mode 100644 index 00000000..d0db2962 --- /dev/null +++ b/src/Rules/BooleansInConditions/BooleanInDoWhileConditionRule.php @@ -0,0 +1,46 @@ + + */ +class BooleanInDoWhileConditionRule implements Rule +{ + + private BooleanRuleHelper $helper; + + public function __construct(BooleanRuleHelper $helper) + { + $this->helper = $helper; + } + + public function getNodeType(): string + { + return Node\Stmt\Do_::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if ($this->helper->passesAsBoolean($scope, $node->cond)) { + return []; + } + + $conditionExpressionType = $scope->getType($node->cond); + + return [ + RuleErrorBuilder::message(sprintf( + 'Only booleans are allowed in a do-while condition, %s given.', + $conditionExpressionType->describe(VerbosityLevel::typeOnly()), + ))->identifier('doWhile.condNotBoolean')->build(), + ]; + } + +} diff --git a/src/Rules/BooleansInConditions/BooleanInWhileConditionRule.php b/src/Rules/BooleansInConditions/BooleanInWhileConditionRule.php new file mode 100644 index 00000000..2f1661a6 --- /dev/null +++ b/src/Rules/BooleansInConditions/BooleanInWhileConditionRule.php @@ -0,0 +1,46 @@ + + */ +class BooleanInWhileConditionRule implements Rule +{ + + private BooleanRuleHelper $helper; + + public function __construct(BooleanRuleHelper $helper) + { + $this->helper = $helper; + } + + public function getNodeType(): string + { + return Node\Stmt\While_::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if ($this->helper->passesAsBoolean($scope, $node->cond)) { + return []; + } + + $conditionExpressionType = $scope->getType($node->cond); + + return [ + RuleErrorBuilder::message(sprintf( + 'Only booleans are allowed in a while condition, %s given.', + $conditionExpressionType->describe(VerbosityLevel::typeOnly()), + ))->identifier('while.condNotBoolean')->build(), + ]; + } + +} diff --git a/tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php new file mode 100644 index 00000000..a19b0a31 --- /dev/null +++ b/tests/Rules/BooleansInConditions/BooleanInDoWhileConditionRuleTest.php @@ -0,0 +1,34 @@ + + */ +class BooleanInDoWhileConditionRuleTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new BooleanInDoWhileConditionRule( + new BooleanRuleHelper( + self::getContainer()->getByType(RuleLevelHelper::class), + ), + ); + } + + public function testRule(): void + { + $this->analyse([__DIR__ . '/data/conditions.php'], [ + [ + 'Only booleans are allowed in a do-while condition, string given.', + 60, + ], + ]); + } + +} diff --git a/tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php b/tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php new file mode 100644 index 00000000..82a8a4ed --- /dev/null +++ b/tests/Rules/BooleansInConditions/BooleanInWhileConditionRuleTest.php @@ -0,0 +1,34 @@ + + */ +class BooleanInWhileConditionRuleTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new BooleanInWhileConditionRule( + new BooleanRuleHelper( + self::getContainer()->getByType(RuleLevelHelper::class), + ), + ); + } + + public function testRule(): void + { + $this->analyse([__DIR__ . '/data/conditions.php'], [ + [ + 'Only booleans are allowed in a while condition, string given.', + 55, + ], + ]); + } + +} diff --git a/tests/Rules/BooleansInConditions/data/conditions.php b/tests/Rules/BooleansInConditions/data/conditions.php index 968867ff..f69808ac 100644 --- a/tests/Rules/BooleansInConditions/data/conditions.php +++ b/tests/Rules/BooleansInConditions/data/conditions.php @@ -48,3 +48,13 @@ $explicitMixed and $bool; $bool or $explicitMixed; $explicitMixed or $bool; + +$someBool = true; +$someString = 'string'; +while ($someBool) { $someBool = !$someBool; } +while ($someString) { $someString = ''; } + +$someBool = true; +$someString = 'string'; +do { $someBool = !$someBool; } while ($someBool); +do { $someString = ''; } while ($someString); From 04f299fb0ee7eed4a8e70ab60e6205d9ccd1f3e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 03:31:34 +0000 Subject: [PATCH 52/55] Update metcalfc/changelog-generator action to v4.5.0 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b1a669a9..be6cad08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Generate changelog id: changelog - uses: metcalfc/changelog-generator@v4.3.1 + uses: metcalfc/changelog-generator@v4.5.0 with: myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }} From 3ecc310efdb91a25415b7eca9234b6525cdfcc0c Mon Sep 17 00:00:00 2001 From: simon-tma Date: Mon, 24 Mar 2025 07:12:15 +1100 Subject: [PATCH 53/55] Use relative links for rules.neon The changes to default parameters are different in different branches, so we want to link to the current branch's version of `rules.neon`. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88b7e96f..35e3a070 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ parameters: illegalConstructorMethodCall: false ``` -Aside from introducing new custom rules, phpstan-strict-rules also [change the default values of some configuration parameters](https://github.com/phpstan/phpstan-strict-rules/blob/1.6.x/rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). +Aside from introducing new custom rules, phpstan-strict-rules also [change the default values of some configuration parameters](./rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). ## Enabling rules one-by-one @@ -107,4 +107,4 @@ parameters: booleansInConditions: true ``` -Even with `strictRules.allRules` set to `false`, part of this package is still in effect. That's because phpstan-strict-rules also [change the default values of some configuration parameters](https://github.com/phpstan/phpstan-strict-rules/blob/1.6.x/rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). +Even with `strictRules.allRules` set to `false`, part of this package is still in effect. That's because phpstan-strict-rules also [change the default values of some configuration parameters](./rules.neon#L1) that are present in PHPStan itself. These parameters are [documented on phpstan.org](https://phpstan.org/config-reference#stricter-analysis). From f203fecee620934db200857729453d1180270823 Mon Sep 17 00:00:00 2001 From: Osita Ugwueze <54801980+OsitaDNU@users.noreply.github.com> Date: Sun, 30 Mar 2025 10:12:07 +0100 Subject: [PATCH 54/55] Match Rule Descriptions with Configuration Parameters in README.md --- README.md | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 35e3a070..85b9a5ab 100644 --- a/README.md +++ b/README.md @@ -6,31 +6,29 @@ [PHPStan](https://phpstan.org/) focuses on finding bugs in your code. But in PHP there's a lot of leeway in how stuff can be written. This repository contains additional rules that revolve around strictly and strongly typed code with no loose casting for those who want additional safety in extremely defensive programming: -* Require booleans in `if`, `elseif`, ternary operator, after `!`, and on both sides of `&&` and `||`. -* Require booleans in `while` and `do while` loop conditions. -* Require numeric operands or arrays in `+` and numeric operands in `-`/`*`/`/`/`**`/`%`. -* Require numeric operand in `$var++`, `$var--`, `++$var`and `--$var`. -* These functions contain a `$strict` parameter for better type safety, it must be set to `true`: - * `in_array` (3rd parameter) - * `array_search` (3rd parameter) - * `array_keys` (3rd parameter; only if the 2nd parameter `$search_value` is provided) - * `base64_decode` (2nd parameter) -* Variables assigned in `while` loop condition and `for` loop initial assignment cannot be used after the loop. -* Variables set in foreach that's always looped thanks to non-empty arrays cannot be used after the loop. -* Types in `switch` condition and `case` value must match. PHP compares them loosely by default and that can lead to unexpected results. -* Check that statically declared methods are called statically. -* Disallow `empty()` - it's a very loose comparison (see [manual](https://php.net/empty)), it's recommended to use more strict one. -* Disallow short ternary operator (`?:`) - implies weak comparison, it's recommended to use null coalesce operator (`??`) or ternary operator with strict condition. -* Disallow variable variables (`$$foo`, `$this->$method()` etc.) -* Disallow overwriting variables with foreach key and value variables -* Always true `instanceof`, type-checking `is_*` functions and strict comparisons `===`/`!==`. These checks can be turned off by setting `checkAlwaysTrueInstanceof`/`checkAlwaysTrueCheckTypeFunctionCall`/`checkAlwaysTrueStrictComparison` to false. -* Correct case for referenced and called function names. -* Correct case for inherited and implemented method names. -* Contravariance for parameter types and covariance for return types in inherited methods (also known as Liskov substitution principle - LSP) -* Check LSP even for static methods -* Require calling parent constructor -* Disallow usage of backtick operator (`` $ls = `ls -la` ``) -* Closure should use `$this` directly instead of using `$this` variable indirectly +| Configuration Parameters | Rule Description | +|:---------------------------------------|:--------------------------------------------------------------------------------------------------------| +| `booleansInConditions` | Require booleans in `if`, `elseif`, ternary operator, after `!`, and on both sides of `&&` and `\|\|`. | +| `booleansInLoopConditions` | Require booleans in `while` and `do while` loop conditions. | +| `numericOperandsInArithmeticOperators` | Require numeric operands or arrays in `+` and numeric operands in `-`/`*`/`/`/`**`/`%`. | +| `numericOperandsInArithmeticOperators` | Require numeric operand in `$var++`, `$var--`, `++$var`and `--$var`. | +| `strictFunctionCalls` | These functions contain a `$strict` parameter for better type safety, it must be set to `true`:
* `in_array` (3rd parameter)
* `array_search` (3rd parameter)
* `array_keys` (3rd parameter; only if the 2nd parameter `$search_value` is provided)
* `base64_decode` (2nd parameter). | +| `overwriteVariablesWithLoop` | Variables assigned in `while` loop condition and `for` loop initial assignment cannot be used after the loop. | +| `overwriteVariablesWithLoop` | Variables set in foreach that's always looped thanks to non-empty arrays cannot be used after the loop. | +| `switchConditionsMatchingType` | Types in `switch` condition and `case` value must match. PHP compares them loosely by default and that can lead to unexpected results. | +| `dynamicCallOnStaticMethod` | Check that statically declared methods are called statically. | +| `disallowedEmpty` | Disallow `empty()` - it's a very loose comparison (see [manual](https://php.net/empty)), it's recommended to use more strict one. | +| `disallowedShortTernary` | Disallow short ternary operator (`?:`) - implies weak comparison, it's recommended to use null coalesce operator (`??`) or ternary operator with strict condition. | +| `noVariableVariables` | Disallow variable variables (`$$foo`, `$this->$method()` etc.). | +| `overwriteVariablesWithLoop` | Disallow overwriting variables with foreach key and value variables. | +| `checkAlwaysTrueInstanceof`, `checkAlwaysTrueCheckTypeFunctionCall`, `checkAlwaysTrueStrictComparison` | Always true `instanceof`, type-checking `is_*` functions and strict comparisons `===`/`!==`. These checks can be turned off by setting `checkAlwaysTrueInstanceof`, `checkAlwaysTrueCheckTypeFunctionCall` and `checkAlwaysTrueStrictComparison` to false. | +| | Correct case for referenced and called function names. | +| `matchingInheritedMethodNames` | Correct case for inherited and implemented method names. | +| | Contravariance for parameter types and covariance for return types in inherited methods (also known as Liskov substitution principle - LSP).| +| | Check LSP even for static methods. | +| `requireParentConstructorCall` | Require calling parent constructor. | +| `disallowedBacktick` | Disallow usage of backtick operator (`` $ls = `ls -la` ``). | +| `closureUsesThis` | Closure should use `$this` directly instead of using `$this` variable indirectly. | Additional rules are coming in subsequent releases! From 73c5baac769505ed05fc0e709ad102e6c6698edf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 03:22:50 +0000 Subject: [PATCH 55/55] Update metcalfc/changelog-generator action to v4.6.2 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be6cad08..b8c96d48 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Generate changelog id: changelog - uses: metcalfc/changelog-generator@v4.5.0 + uses: metcalfc/changelog-generator@v4.6.2 with: myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }}