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/README.md b/README.md
index 246c0c84..9dee7781 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,8 @@
* Require calling parent constructor
* Disallow usage of backtick operator (`` $ls = `ls -la` ``)
* Closure should use `$this` directly instead of using `$this` variable indirectly
+* Report useless casts
+* Disallow explicit casting of potential `null` values (with [https://phpstan.org/blog/what-is-bleeding-edge](bleeding edge) enabled)
Additional rules are coming in subsequent releases!
@@ -65,6 +67,7 @@ parameters:
disallowedLooseComparison: false
booleansInConditions: false
uselessCast: false
+ nullCast: false
requireParentConstructorCall: false
disallowedConstructs: false
overwriteVariablesWithLoop: false
diff --git a/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 b52da6f8..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.2",
- "source": {
- "type": "git",
- "url": "https://github.com/consistence-community/coding-standard.git",
- "reference": "adb4be482e76990552bf624309d2acc8754ba1bd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/consistence-community/coding-standard/zipball/adb4be482e76990552bf624309d2acc8754ba1bd",
- "reference": "adb4be482e76990552bf624309d2acc8754ba1bd",
- "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.2"
- },
- "time": "2022-06-21T08:36:36+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.16.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e27e92d939e2e3636f0a1f0afaba59692c0bf571",
- "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571",
- "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.16.1"
- },
- "time": "2023-02-07T18:11:17+00:00"
- },
- {
- "name": "slevomat/coding-standard",
- "version": "8.9.0",
- "source": {
- "type": "git",
- "url": "https://github.com/slevomat/coding-standard.git",
- "reference": "8f11e0f5ff984d6862bb9d83aa513dc05a1773ef"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/8f11e0f5ff984d6862bb9d83aa513dc05a1773ef",
- "reference": "8f11e0f5ff984d6862bb9d83aa513dc05a1773ef",
- "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",
- "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-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"
- },
- "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.9.0"
- },
- "funding": [
- {
- "url": "https://github.com/kukulich",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard",
- "type": "tidelift"
- }
- ],
- "time": "2023-03-25T15:52:37+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/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",
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
-
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/rules.neon b/rules.neon
index 46632c0c..ba0c7d07 100644
--- a/rules.neon
+++ b/rules.neon
@@ -20,6 +20,7 @@ parameters:
disallowedLooseComparison: [%strictRules.allRules%, %featureToggles.bleedingEdge%]
booleansInConditions: %strictRules.allRules%
uselessCast: %strictRules.allRules%
+ nullCast: [%strictRules.allRules%, %featureToggles.bleedingEdge%]
requireParentConstructorCall: %strictRules.allRules%
disallowedConstructs: %strictRules.allRules%
overwriteVariablesWithLoop: %strictRules.allRules%
@@ -36,6 +37,7 @@ parametersSchema:
disallowedLooseComparison: anyOf(bool(), arrayOf(bool())),
booleansInConditions: anyOf(bool(), arrayOf(bool()))
uselessCast: anyOf(bool(), arrayOf(bool()))
+ nullCast: anyOf(bool(), arrayOf(bool()))
requireParentConstructorCall: anyOf(bool(), arrayOf(bool()))
disallowedConstructs: anyOf(bool(), arrayOf(bool()))
overwriteVariablesWithLoop: anyOf(bool(), arrayOf(bool()))
@@ -64,6 +66,8 @@ conditionalTags:
phpstan.rules.rule: %strictRules.booleansInConditions%
PHPStan\Rules\Cast\UselessCastRule:
phpstan.rules.rule: %strictRules.uselessCast%
+ PHPStan\Rules\Cast\NullCastRule:
+ phpstan.rules.rule: %strictRules.nullCast%
PHPStan\Rules\Classes\RequireParentConstructCallRule:
phpstan.rules.rule: %strictRules.requireParentConstructorCall%
PHPStan\Rules\DisallowedConstructs\DisallowedBacktickRule:
@@ -142,12 +146,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
@@ -163,6 +171,11 @@ services:
arguments:
treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain%
+ -
+ class: PHPStan\Rules\Cast\NullCastRule
+ arguments:
+ treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain%
+
-
class: PHPStan\Rules\Classes\RequireParentConstructCallRule
diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanAndRule.php
index 53140ccf..aebe8add 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;
@@ -18,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
@@ -32,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[] = sprintf(
- 'Only booleans are allowed in &&, %s given on the left side.',
+ $messages[] = RuleErrorBuilder::message(sprintf(
+ 'Only booleans are allowed in %s, %s given on the left side.',
+ $nodeText,
$leftType->describe(VerbosityLevel::typeOnly())
- );
+ ))->identifier(sprintf('%s.leftNotBoolean', $identifierType))->build();
}
$rightScope = $node->getRightScope();
if (!$this->helper->passesAsBoolean($rightScope, $originalNode->right)) {
$rightType = $rightScope->getType($originalNode->right);
- $messages[] = sprintf(
- 'Only booleans are allowed in &&, %s given on the right side.',
+ $messages[] = RuleErrorBuilder::message(sprintf(
+ 'Only booleans are allowed in %s, %s given on the right side.',
+ $nodeText,
$rightType->describe(VerbosityLevel::typeOnly())
- );
+ ))->identifier(sprintf('%s.rightNotBoolean', $identifierType))->build();
}
return $messages;
diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanNotRule.php
index 0e53c873..6fcdd06c 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())
- ),
+ ))->identifier('booleanNot.exprNotBoolean')->build(),
];
}
diff --git a/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php b/src/Rules/BooleansInConditions/BooleanInBooleanOrRule.php
index bf98c5cd..e03911cf 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;
@@ -18,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
@@ -32,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[] = sprintf(
- 'Only booleans are allowed in ||, %s given on the left side.',
+ $messages[] = RuleErrorBuilder::message(sprintf(
+ 'Only booleans are allowed in %s, %s given on the left side.',
+ $nodeText,
$leftType->describe(VerbosityLevel::typeOnly())
- );
+ ))->identifier(sprintf('%s.leftNotBoolean', $identifierType))->build();
}
$rightScope = $node->getRightScope();
if (!$this->helper->passesAsBoolean($rightScope, $originalNode->right)) {
$rightType = $rightScope->getType($originalNode->right);
- $messages[] = sprintf(
- 'Only booleans are allowed in ||, %s given on the right side.',
+ $messages[] = RuleErrorBuilder::message(sprintf(
+ 'Only booleans are allowed in %s, %s given on the right side.',
+ $nodeText,
$rightType->describe(VerbosityLevel::typeOnly())
- );
+ ))->identifier(sprintf('%s.rightNotBoolean', $identifierType))->build();
}
return $messages;
diff --git a/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInElseIfConditionRule.php
index 8dfe3dac..2501b828 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())
- ),
+ ))->identifier('elseif.condNotBoolean')->build(),
];
}
diff --git a/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php b/src/Rules/BooleansInConditions/BooleanInIfConditionRule.php
index 7b1cbfb8..5adb10ed 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())
- ),
+ ))->identifier('if.condNotBoolean')->build(),
];
}
diff --git a/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php b/src/Rules/BooleansInConditions/BooleanInTernaryOperatorRule.php
index 5d389b7a..e1ac9ccb 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())
- ),
+ ))->identifier('ternary.condNotBoolean')->build(),
];
}
diff --git a/src/Rules/Cast/NullCastRule.php b/src/Rules/Cast/NullCastRule.php
new file mode 100644
index 00000000..17b5859e
--- /dev/null
+++ b/src/Rules/Cast/NullCastRule.php
@@ -0,0 +1,80 @@
+
+ */
+class NullCastRule implements Rule
+{
+
+ /** @var bool */
+ private $treatPhpDocTypesAsCertain;
+
+ public function __construct(bool $treatPhpDocTypesAsCertain)
+ {
+ $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain;
+ }
+
+ public function getNodeType(): string
+ {
+ return Cast::class;
+ }
+
+ public function processNode(Node $node, Scope $scope): array
+ {
+ $castType = $scope->getType($node);
+ if ($castType instanceof ErrorType) {
+ return [];
+ }
+ $castType = $castType->generalize(GeneralizePrecision::lessSpecific());
+
+ if ($this->treatPhpDocTypesAsCertain) {
+ $expressionType = $scope->getType($node->expr);
+ } else {
+ $expressionType = $scope->getNativeType($node->expr);
+ }
+
+ // This is handled by PhpStan at level 9
+ if ($expressionType->isSuperTypeOf(new MixedType())->yes()) {
+ return [];
+ }
+
+ if (!$expressionType->isNull()->no()) {
+ $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $node): RuleErrorBuilder {
+ if (!$this->treatPhpDocTypesAsCertain) {
+ return $ruleErrorBuilder;
+ }
+
+ $expressionTypeWithoutPhpDoc = $scope->getNativeType($node->expr);
+ if (!(new NullType())->isSuperTypeOf($expressionTypeWithoutPhpDoc)->no()) {
+ return $ruleErrorBuilder;
+ }
+
+ return $ruleErrorBuilder->tip('Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false> in your %configurationFile%>.');
+ };
+ return [
+ $addTip(RuleErrorBuilder::message(sprintf(
+ 'Only non-null values should be cast to %s, %s given.',
+ $castType->describe(VerbosityLevel::typeOnly()),
+ $expressionType->describe(VerbosityLevel::typeOnly())
+ )))->identifier('cast.null')->build(),
+ ];
+ }
+
+ return [];
+ }
+
+}
diff --git a/src/Rules/Cast/UselessCastRule.php b/src/Rules/Cast/UselessCastRule.php
index c156a09a..adc20e14 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);
@@ -64,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 c07e04e4..76d3d16c 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()) {
@@ -50,34 +50,18 @@ public function processNode(Node $node, Scope $scope): array
}
if ($this->callsParentConstruct($node)) {
- if ($classReflection->getParentClass() === false) {
- return [
- sprintf(
- '%s::__construct() calls parent constructor but does not extend any class.',
- $classReflection->getName()
- ),
- ];
- }
+ return [];
+ }
- if ($this->getParentConstructorClass($classReflection) === false) {
- return [
- sprintf(
- '%s::__construct() calls parent constructor but parent does not have one.',
- $classReflection->getName()
- ),
- ];
- }
- } else {
- $parentClass = $this->getParentConstructorClass($classReflection);
- if ($parentClass !== false) {
- return [
- sprintf(
- '%s::__construct() does not call parent constructor from %s.',
- $classReflection->getName(),
- $parentClass->getName()
- ),
- ];
- }
+ $parentClass = $this->getParentConstructorClass($classReflection);
+ if ($parentClass !== false) {
+ return [
+ RuleErrorBuilder::message(sprintf(
+ '%s::__construct() does not call parent constructor from %s.',
+ $classReflection->getName(),
+ $parentClass->getName()
+ ))->identifier('constructor.missingParentCall')->build(),
+ ];
}
return [];
diff --git a/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php b/src/Rules/DisallowedConstructs/DisallowedBacktickRule.php
index aab3824d..76e401ce 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,12 @@ 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.')
+ ->identifier('backtick.notAllowed')
+ ->build(),
];
}
diff --git a/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php b/src/Rules/DisallowedConstructs/DisallowedEmptyRule.php
index 9a867cd5..d19f5ea2 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,12 @@ 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.')
+ ->identifier('empty.notAllowed')
+ ->build(),
];
}
diff --git a/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php b/src/Rules/DisallowedConstructs/DisallowedImplicitArrayCreationRule.php
index 322d0dac..cee777ce 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,17 @@ 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))
+ ->identifier('variable.implicitArray')
+ ->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))
+ ->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 59db24ac..fac42790 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,9 @@ 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.')
+ ->identifier('ternary.shortNotAllowed')
+ ->build(),
];
}
diff --git a/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php b/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php
index ca8f631c..f710474e 100644
--- a/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php
+++ b/src/Rules/ForLoop/OverwriteVariablesWithForLoopInitRule.php
@@ -7,7 +7,9 @@
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\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,9 @@ 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))
+ ->identifier('for.variableOverwrite')
+ ->build();
}
if (
diff --git a/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php b/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php
index dbf16d25..0cf620c3 100644
--- a/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php
+++ b/src/Rules/ForeachLoop/OverwriteVariablesWithForeachRule.php
@@ -6,22 +6,23 @@
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;
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 +31,9 @@ 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))
+ ->identifier('foreach.keyOverwrite')
+ ->build();
}
foreach ($this->checkValueVar($scope, $node->valueVar) as $error) {
@@ -41,7 +44,7 @@ public function processNode(Node $node, Scope $scope): array
}
/**
- * @return string[]
+ * @return list
*/
private function checkValueVar(Scope $scope, Expr $expr): array
{
@@ -51,7 +54,9 @@ 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))
+ ->identifier('foreach.valueOverwrite')
+ ->build();
}
if (
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 be62e245..1cca26ed 100644
--- a/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php
+++ b/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php
@@ -6,7 +6,9 @@
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassMethodNode;
use PHPStan\Reflection\ClassReflection;
+use PHPStan\Rules\IdentifierRuleError;
use PHPStan\Rules\Rule;
+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
+ ): ?IdentifierRuleError
{
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()
- );
+ ))->identifier('method.nameCase')->build();
}
}
diff --git a/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php b/src/Rules/Operators/OperandInArithmeticIncrementOrDecrementRule.php
index 13364758..af82a08c 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())
- );
+ ))->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 ba29b5a7..246b609d 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())
- );
+ ))->identifier('plus.leftNonNumeric')->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())
- );
+ ))->identifier('plus.rightNonNumeric')->build();
}
return $messages;
diff --git a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php
index 663ff36e..8a146ded 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())
- );
+ ))->identifier('div.leftNonNumeric')->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())
- );
+ ))->identifier('div.rightNonNumeric')->build();
}
return $messages;
diff --git a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php
index 40f7ae7e..fe809ef7 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())
- );
+ ))->identifier('pow.leftNonNumeric')->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())
- );
+ ))->identifier('pow.rightNonNumeric')->build();
}
return $messages;
diff --git a/src/Rules/Operators/OperandsInArithmeticModuloRule.php b/src/Rules/Operators/OperandsInArithmeticModuloRule.php
index 38e0d38d..4aad3661 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())
- );
+ ))->identifier('mod.leftNonNumeric')->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())
- );
+ ))->identifier('mod.rightNonNumeric')->build();
}
return $messages;
diff --git a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php
index f1e4c064..f662bdce 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())
- );
+ ))->identifier('mul.leftNonNumeric')->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())
- );
+ ))->identifier('mul.rightNonNumeric')->build();
}
return $messages;
diff --git a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php
index 5333c2a1..9bec287d 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())
- );
+ ))->identifier('minus.leftNonNumeric')->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())
- );
+ ))->identifier('minus.rightNonNumeric')->build();
}
return $messages;
diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsCallableRule.php
index 95e27fec..d14b5678 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()
+ ))->identifier('staticMethod.dynamicCall')->build(),
+ ];
}
return [];
diff --git a/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php b/src/Rules/StrictCalls/DynamicCallOnStaticMethodsRule.php
index 5319c3a8..44b180c0 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()
+ ))->identifier('staticMethod.dynamicCall')->build(),
+ ];
}
return [];
diff --git a/src/Rules/StrictCalls/StrictFunctionCallsRule.php b/src/Rules/StrictCalls/StrictFunctionCallsRule.php
index b27c25fe..2b6cd899 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
+ ))->identifier('function.strict')->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
+ ))->identifier('function.strict')->build(),
+ ];
}
return [];
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 4221cfa8..f92f84c1 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())
- ),
+ ))->identifier('method.dynamicName')->build(),
];
}
diff --git a/src/Rules/VariableVariables/VariableMethodCallableRule.php b/src/Rules/VariableVariables/VariableMethodCallableRule.php
index f293b562..6a5fd518 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())
- ),
+ ))->identifier('method.dynamicName')->build(),
];
}
diff --git a/src/Rules/VariableVariables/VariablePropertyFetchRule.php b/src/Rules/VariableVariables/VariablePropertyFetchRule.php
index 1b7fe52d..73ff0888 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())
- ),
+ ))->identifier('property.dynamicName')->build(),
];
}
diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallRule.php
index 0d6b8202..eb3a770c 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
- ),
+ ))->identifier('staticMethod.dynamicName')->build(),
];
}
diff --git a/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php b/src/Rules/VariableVariables/VariableStaticMethodCallableRule.php
index 8ede1f00..f765da66 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
- ),
+ ))->identifier('staticMethod.dynamicName')->build(),
];
}
diff --git a/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php b/src/Rules/VariableVariables/VariableStaticPropertyFetchRule.php
index 4b410a7f..f27c7792 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
- ),
+ ))->identifier('staticProperty.dynamicName')->build(),
];
}
diff --git a/src/Rules/VariableVariables/VariableVariablesRule.php b/src/Rules/VariableVariables/VariableVariablesRule.php
index 9768f21b..f78e4ef4 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,9 @@ public function processNode(Node $node, Scope $scope): array
}
return [
- 'Variable variables are not allowed.',
+ RuleErrorBuilder::message('Variable variables are not allowed.')
+ ->identifier('variable.dynamicName')
+ ->build(),
];
}
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/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/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/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/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;
diff --git a/tests/Rules/Cast/NullCastRuleTest.php b/tests/Rules/Cast/NullCastRuleTest.php
new file mode 100644
index 00000000..a8d1caf9
--- /dev/null
+++ b/tests/Rules/Cast/NullCastRuleTest.php
@@ -0,0 +1,87 @@
+
+ */
+class NullCastRuleTest extends RuleTestCase
+{
+
+ /** @var bool */
+ private $treatPhpDocTypesAsCertain;
+
+ protected function getRule(): Rule
+ {
+ return new NullCastRule($this->treatPhpDocTypesAsCertain);
+ }
+
+ protected function shouldTreatPhpDocTypesAsCertain(): bool
+ {
+ return $this->treatPhpDocTypesAsCertain;
+ }
+
+ public function testNullCast(): void
+ {
+ require_once __DIR__ . '/data/null-cast.php';
+ $this->treatPhpDocTypesAsCertain = true;
+ $this->analyse(
+ [__DIR__ . '/data/null-cast.php'],
+ [
+ [
+ 'Only non-null values should be cast to int, int|null given.',
+ 6,
+ ],
+ [
+ 'Only non-null values should be cast to int, string|null given.',
+ 8,
+ ],
+ [
+ 'Only non-null values should be cast to float, int|null given.',
+ 9,
+ ],
+ [
+ 'Only non-null values should be cast to float, string|null given.',
+ 11,
+ ],
+ [
+ 'Only non-null values should be cast to string, string|null given.',
+ 12,
+ ],
+ [
+ 'Only non-null values should be cast to stdClass, string|null given.',
+ 13,
+ ],
+ [
+ 'Only non-null values should be cast to stdClass, null given.',
+ 15,
+ ],
+ [
+ 'Only non-null values should be cast to array, null given.',
+ 17,
+ ],
+ ]
+ );
+ }
+
+ public function testDoNotReportPhpDoc(): void
+ {
+ $this->treatPhpDocTypesAsCertain = false;
+ $this->analyse([__DIR__ . '/data/null-cast-not-phpdoc.php'], []);
+ }
+
+ public function testReportPhpDoc(): void
+ {
+ $this->treatPhpDocTypesAsCertain = true;
+ $this->analyse([__DIR__ . '/data/null-cast-not-phpdoc.php'], [
+ [
+ 'Only non-null values should be cast to int, int|null given.',
+ 17,
+ ],
+ ]);
+ }
+
+}
diff --git a/tests/Rules/Cast/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/Cast/data/null-cast-not-phpdoc.php b/tests/Rules/Cast/data/null-cast-not-phpdoc.php
new file mode 100644
index 00000000..42f2bf22
--- /dev/null
+++ b/tests/Rules/Cast/data/null-cast-not-phpdoc.php
@@ -0,0 +1,20 @@
+= 8.0
+
+namespace NullCast;
+
+function foo(?int $a, string $b, ?string $c, mixed $d) {
+ (int)$a;
+ (int)$b;
+ (int)$c;
+ (float)$a;
+ (float)$b;
+ (float)$c;
+ (string)$c;
+ (object)$c;
+ (object)'null';
+ (object)null;
+ (array)'null';
+ (array)null;
+ (int)$d;
+}
diff --git a/tests/Rules/Classes/RequireParentConstructCallRuleTest.php b/tests/Rules/Classes/RequireParentConstructCallRuleTest.php
index caeee5c8..e8d63620 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
{
@@ -17,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,
@@ -50,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'], []);
}
}
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/OperandInArithmeticIncrementOrDecrementRuleTestCase.php
similarity index 79%
rename from tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php
rename to tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php
index 02e38f43..0efa83a7 100644
--- a/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTest.php
+++ b/tests/Rules/Operators/OperandInArithmeticIncrementOrDecrementRuleTestCase.php
@@ -6,7 +6,11 @@
use PHPStan\Rules\RuleLevelHelper;
use PHPStan\Testing\RuleTestCase;
-abstract class OperandInArithmeticIncrementOrDecrementRuleTest extends RuleTestCase
+/**
+ * @template T of Rule
+ * @extends RuleTestCase
+ */
+abstract class OperandInArithmeticIncrementOrDecrementRuleTestCase extends RuleTestCase
{
protected function getRule(): Rule
@@ -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..c4ea1569 100644
--- a/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php
+++ b/tests/Rules/Operators/OperandInArithmeticPostDecrementRuleTest.php
@@ -4,7 +4,10 @@
use PHPStan\Rules\Rule;
-class OperandInArithmeticPostDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest
+/**
+ * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase
+ */
+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 0b18f3a9..94357e60 100644
--- a/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php
+++ b/tests/Rules/Operators/OperandInArithmeticPostIncrementRuleTest.php
@@ -4,7 +4,10 @@
use PHPStan\Rules\Rule;
-class OperandInArithmeticPostIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest
+/**
+ * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase
+ */
+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 2e695f89..2bb021a9 100644
--- a/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php
+++ b/tests/Rules/Operators/OperandInArithmeticPreDecrementRuleTest.php
@@ -4,7 +4,10 @@
use PHPStan\Rules\Rule;
-class OperandInArithmeticPreDecrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest
+/**
+ * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase
+ */
+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 47449369..2ffe1bb6 100644
--- a/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php
+++ b/tests/Rules/Operators/OperandInArithmeticPreIncrementRuleTest.php
@@ -4,7 +4,10 @@
use PHPStan\Rules\Rule;
-class OperandInArithmeticPreIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTest
+/**
+ * @extends OperandInArithmeticIncrementOrDecrementRuleTestCase
+ */
+class OperandInArithmeticPreIncrementRuleTest extends OperandInArithmeticIncrementOrDecrementRuleTestCase
{
protected function createRule(OperatorRuleHelper $helper): Rule
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
{