From 6c7dada2329642baa00606c5122a7dbe740fa3ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 19:44:10 +0000 Subject: [PATCH] finally, integrate phpstan-strict-rules --- composer.json | 3 +- composer.lock | 53 +++++++++++++- phpstan.neon.dist | 70 +++++++++++++++++++ tests/phpstan/configs/phpstan-bugs.neon | 24 +++++++ .../phpstan/configs/runtime-type-checks.neon | 51 ++++++++++++++ 5 files changed, 199 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 3579c4dab..89694fca9 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "require-dev": { "phpstan/phpstan": "^0.12.8", "irstea/phpunit-shim": "^8.5", - "phpstan/phpstan-phpunit": "^0.12.6" + "phpstan/phpstan-phpunit": "^0.12.6", + "phpstan/phpstan-strict-rules": "^0.12.2" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index dd690eca4..6b9ed7cdd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "82c757af39ed282d0d329dcd3053d045", + "content-hash": "3bc1131c6ecd44aef9d1043f49563a6a", "packages": [ { "name": "adhocore/json-comment", @@ -523,6 +523,57 @@ ], "description": "PHPUnit extensions and rules for PHPStan", "time": "2020-01-10T12:07:21+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "0.12.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/a670a59aff7cf96f75d21b974860ada10e25b2ee", + "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee", + "shasum": "" + }, + "require": { + "php": "~7.1", + "phpstan/phpstan": "^0.12.6" + }, + "require-dev": { + "consistence/coding-standard": "^3.0.1", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.5.2" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "0.12-dev" + }, + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "time": "2020-01-20T13:08:52+00:00" } ], "aliases": [], diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ef316e5c4..8bfdcfc29 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -9,6 +9,7 @@ includes: - tests/phpstan/configs/runtime-type-checks.neon - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon + - vendor/phpstan/phpstan-strict-rules/rules.neon parameters: level: 6 @@ -31,11 +32,50 @@ parameters: - tests/phpstan/stubs/chunkutils.stub reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings ignoreErrors: + - + message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/CrashDump.php + + - + message: "#^pocketmine\\\\Player\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\entity\\\\Human\\.$#" + count: 1 + path: src/pocketmine/Player.php + - message: "#^Cannot instantiate interface pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\.$#" count: 1 path: src/pocketmine/Server.php + - + message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^Instanceof between pocketmine\\\\scheduler\\\\AsyncPool and pocketmine\\\\scheduler\\\\AsyncPool will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^Instanceof between pocketmine\\\\command\\\\CommandReader and pocketmine\\\\command\\\\CommandReader will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^Instanceof between pocketmine\\\\network\\\\Network and pocketmine\\\\network\\\\Network will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^pocketmine\\\\block\\\\[A-Za-z\\d]+\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\block\\\\Block\\.$#" + path: src/pocketmine/block + + - + message: "#^pocketmine\\\\block\\\\Block\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\level\\\\Position\\.$#" + count: 1 + path: src/pocketmine/block/Block.php + - message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#" count: 1 @@ -77,6 +117,31 @@ parameters: count: 1 path: src/pocketmine/event/entity/ProjectileLaunchEvent.php + - + message: "#^pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" + count: 1 + path: src/pocketmine/inventory/DoubleChestInventory.php + + - + message: "#^pocketmine\\\\inventory\\\\EnderChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" + count: 1 + path: src/pocketmine/inventory/EnderChestInventory.php + + - + message: "#^pocketmine\\\\item\\\\GoldenAppleEnchanted\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\item\\\\GoldenApple\\.$#" + count: 1 + path: src/pocketmine/item/GoldenAppleEnchanted.php + + - + message: "#^pocketmine\\\\item\\\\WrittenBook\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\item\\\\WritableBook\\.$#" + count: 1 + path: src/pocketmine/item/WrittenBook.php + + - + message: "#^Variable property access on \\$this\\(pocketmine\\\\level\\\\generator\\\\PopulationTask\\)\\.$#" + count: 4 + path: src/pocketmine/level/generator/PopulationTask.php + - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#" count: 1 @@ -87,6 +152,11 @@ parameters: count: 1 path: src/pocketmine/level/generator/normal/Normal.php + - + message: "#^Variable method call on pocketmine\\\\event\\\\Listener\\.$#" + count: 1 + path: src/pocketmine/plugin/MethodEventExecutor.php + - message: "#^Constructor of class pocketmine\\\\scheduler\\\\TaskScheduler has an unused parameter \\$logger\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 66206c073..bdbce964d 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,5 +1,6 @@ parameters: ignoreErrors: + - "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" - message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" path: ../../../src @@ -33,7 +34,30 @@ parameters: count: 1 path: ../../../src/pocketmine/block/Liquid.php + - + #readline() may return false + message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/command/CommandReader.php + + - + #generics corruption, this might show up in other forms too + message: "#^Parameter \\#1 \\$offset \\(int\\) of method pocketmine\\\\entity\\\\AttributeMap\\:\\:offsetGet\\(\\) should be contravariant with parameter \\$offset \\(mixed\\) of method ArrayAccess\\\\:\\:offsetGet\\(\\)$#" + count: 1 + path: ../../../src/pocketmine/entity/AttributeMap.php + - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 path: ../../../src/pocketmine/entity/projectile/Projectile.php + + - + message: "#^Call to function method_exists\\(\\) with pocketmine\\\\network\\\\mcpe\\\\CachedEncapsulatedPacket and '__toString' will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/network/mcpe/protocol/DataPacket.php + + - + #phpstan doesn't understand that SplFixedArray may contain null + message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNotNull\\(\\) with int and string will always evaluate to true\\.$#" + count: 1 + path: ../../../tests/phpunit/block/BlockTest.php diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 7d48cacd9..59776a047 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -1,11 +1,31 @@ parameters: ignoreErrors: + - + message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\level…' will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/Server.php + - #::add() / ::remove() thread parameter message: "#^If condition is always true\\.$#" count: 2 path: ../../../src/pocketmine/ThreadManager.php + - + message: "#^Instanceof between pocketmine\\\\Worker and pocketmine\\\\Worker will always evaluate to true\\.$#" + count: 2 + path: ../../../src/pocketmine/ThreadManager.php + + - + message: "#^Instanceof between pocketmine\\\\plugin\\\\RegisteredListener and pocketmine\\\\plugin\\\\RegisteredListener will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/event/HandlerList.php + + - + #jsonDeserialize(), not currently validated + message: "#^Casting to int something that's already int\\.$#" + count: 3 + path: ../../../src/pocketmine/item/Item.php - #::get() tags parameter message: "#^If condition is always false\\.$#" @@ -24,8 +44,39 @@ parameters: count: 1 path: ../../../src/pocketmine/item/ItemFactory.php + - + message: "#^Call to function is_object\\(\\) with \\*NEVER\\* will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/item/ItemFactory.php + - #->sendBlocks() blocks parameter message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 2 path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Instanceof between pocketmine\\\\math\\\\Vector3 and pocketmine\\\\math\\\\Vector3 will always evaluate to true\\.$#" + count: 2 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Call to function is_object\\(\\) with \\*NEVER\\* will always evaluate to true\\.$#" + count: 2 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\level…' will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/level/generator/GeneratorManager.php + + - + #commands plugin.yml not currently validated, can't be sure + message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/plugin/PluginManager.php