From bfd1b2c63550f91020b07cb08c8cb9bc33b7b2ed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Nov 2022 18:28:07 +0000 Subject: [PATCH 1/2] PHPStan 1.9.1 --- composer.json | 2 +- composer.lock | 14 +++++++------- src/command/defaults/HelpCommand.php | 1 - src/plugin/PluginGraylist.php | 3 +-- src/utils/Utils.php | 2 +- tests/phpstan/configs/phpstan-bugs.neon | 5 +++++ 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 9251a64b6..fbf9f1fd6 100644 --- a/composer.json +++ b/composer.json @@ -53,7 +53,7 @@ "webmozart/path-util": "^2.3" }, "require-dev": { - "phpstan/phpstan": "1.8.11", + "phpstan/phpstan": "1.9.1", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index 4814b9193..b3cd775be 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": "0a402cad3151b4efa4f5da8034293b6d", + "content-hash": "e2b0a5b76ace05c6d6bd760d1f96ebe5", "packages": [ { "name": "adhocore/json-comment", @@ -1510,16 +1510,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.8.11", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "46e223dd68a620da18855c23046ddb00940b4014" + "reference": "a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46e223dd68a620da18855c23046ddb00940b4014", - "reference": "46e223dd68a620da18855c23046ddb00940b4014", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f", + "reference": "a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f", "shasum": "" }, "require": { @@ -1549,7 +1549,7 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.8.11" + "source": "https://github.com/phpstan/phpstan/tree/1.9.1" }, "funding": [ { @@ -1565,7 +1565,7 @@ "type": "tidelift" } ], - "time": "2022-10-24T15:45:13+00:00" + "time": "2022-11-04T13:35:59+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index 3dc581838..3173a1ee2 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -76,7 +76,6 @@ class HelpCommand extends VanillaCommand{ $pageHeight = $sender->getScreenLineHeight(); if($commandName === ""){ - /** @var Command[][] $commands */ $commands = []; foreach($sender->getServer()->getCommandMap()->getCommands() as $command){ if($command->testPermissionSilent($sender)){ diff --git a/src/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php index ef719b72b..84aa3f792 100644 --- a/src/plugin/PluginGraylist.php +++ b/src/plugin/PluginGraylist.php @@ -70,8 +70,7 @@ class PluginGraylist{ } $isWhitelist = match($array["mode"]){ "whitelist" => true, - "blacklist" => false, - default => throw new \InvalidArgumentException("\"mode\" must be either \"whitelist\" or \"blacklist\"") + "blacklist" => false }; $plugins = []; if(isset($array["plugins"])){ diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 35d6595ca..3e8e420b7 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -313,7 +313,7 @@ final class Utils{ } }elseif(($cpuPresent = @file_get_contents("/sys/devices/system/cpu/present")) !== false){ if(preg_match("/^([0-9]+)\\-([0-9]+)$/", trim($cpuPresent), $matches) > 0){ - $processors = (int) ($matches[2] - $matches[1]); + $processors = ((int) $matches[2]) - ((int) $matches[1]); } } break; diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index e50532cfd..c84371b11 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -15,6 +15,11 @@ parameters: count: 1 path: ../../../src/entity/projectile/Projectile.php + - + message: "#^Empty array passed to foreach\\.$#" + count: 1 + path: ../../../src/network/mcpe/cache/ChunkCache.php + - message: "#^Match arm comparison between 4 and 4 is always true\\.$#" count: 1 From 2fdc46c1658ecfe2d7274240ca9cb679563a2263 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Nov 2022 20:23:34 +0000 Subject: [PATCH 2/2] PHPStan 1.9 features --- src/MemoryManager.php | 7 ++++++- src/block/Leaves.php | 1 + src/inventory/transaction/InventoryTransaction.php | 2 ++ src/network/mcpe/convert/ItemTranslator.php | 1 + src/network/upnp/UPnP.php | 1 + src/plugin/PluginManager.php | 3 +++ src/utils/Config.php | 1 + src/utils/Internet.php | 8 ++++++++ src/utils/Process.php | 2 ++ src/world/World.php | 6 ++++++ src/world/format/io/leveldb/LevelDB.php | 5 +++++ src/world/format/io/region/RegionLoader.php | 2 ++ src/world/format/io/region/RegionWorldProvider.php | 2 ++ 13 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 49a728c89..d2dafe706 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -398,7 +398,7 @@ class MemoryManager{ do{ $continue = false; - foreach($objects as $hash => $object){ + foreach(Utils::stringifyKeys($objects) as $hash => $object){ if(!is_object($object)){ continue; } @@ -483,6 +483,11 @@ class MemoryManager{ * @param object[] $objects reference parameter * @param int[] $refCounts reference parameter * + * @phpstan-param array $objects + * @phpstan-param array $refCounts + * @phpstan-param-out array $objects + * @phpstan-param-out array $refCounts + * * @return mixed */ private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 8e7298a0c..4c421b1de 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -84,6 +84,7 @@ class Leaves extends Transparent{ /** * @param true[] $visited reference parameter * @phpstan-param array $visited + * @phpstan-param-out array $visited */ protected function findLog(Vector3 $pos, array &$visited = [], int $distance = 0) : bool{ $index = World::blockHash($pos->x, $pos->y, $pos->z); diff --git a/src/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php index 27bd34e8d..46dacb8ec 100644 --- a/src/inventory/transaction/InventoryTransaction.php +++ b/src/inventory/transaction/InventoryTransaction.php @@ -134,6 +134,8 @@ class InventoryTransaction{ /** * @param Item[] $needItems * @param Item[] $haveItems + * @phpstan-param-out Item[] $needItems + * @phpstan-param-out Item[] $haveItems * * @throws TransactionValidationException */ diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index 4a2036e0b..759eefbca 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -169,6 +169,7 @@ final class ItemTranslator{ } /** + * @phpstan-param-out bool $isComplexMapping * @return int[] * @phpstan-return array{int, int} * @throws TypeConversionException diff --git a/src/network/upnp/UPnP.php b/src/network/upnp/UPnP.php index 0d482ab3d..e1d059339 100644 --- a/src/network/upnp/UPnP.php +++ b/src/network/upnp/UPnP.php @@ -150,6 +150,7 @@ class UPnP{ throw new UPnPException("Failed to recognize the port number from the router's url: {$location}"); } $urlPort = $url['port']; + $err = ""; $response = Internet::getURL($location, 3, [], $err); if($response === null){ throw new UPnPException("Unable to access XML: {$err}"); diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index acffae53e..ea8634bf2 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -316,6 +316,9 @@ class PluginManager{ /** * @param string[][] $dependencyLists * @param Plugin[] $loadedPlugins + * + * @phpstan-param array> $dependencyLists + * @phpstan-param-out array> $dependencyLists */ private function checkDepsForTriage(string $pluginName, string $dependencyType, array &$dependencyLists, array $loadedPlugins, PluginLoadTriage $triage) : void{ if(isset($dependencyLists[$pluginName])){ diff --git a/src/utils/Config.php b/src/utils/Config.php index ffc2db69a..e2bc7733a 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -496,6 +496,7 @@ class Config{ * @param mixed[] $data reference parameter * @phpstan-param array $default * @phpstan-param array $data + * @phpstan-param-out array $data */ private function fillDefaults(array $default, &$data) : int{ $changed = 0; diff --git a/src/utils/Internet.php b/src/utils/Internet.php index a679320bb..7f379d7dc 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -139,10 +139,14 @@ class Internet{ * GETs an URL using cURL * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * + * @phpstan-template TErrorVar of mixed + * * @param int $timeout default 10 * @param string[] $extraHeaders * @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. * @phpstan-param list $extraHeaders + * @phpstan-param TErrorVar $err + * @phpstan-param-out TErrorVar|string $err */ public static function getURL(string $page, int $timeout = 10, array $extraHeaders = [], &$err = null) : ?InternetRequestResult{ try{ @@ -157,11 +161,15 @@ class Internet{ * POSTs data to an URL * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * + * @phpstan-template TErrorVar of mixed + * * @param string[]|string $args * @param string[] $extraHeaders * @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occurred during the operation. * @phpstan-param string|array $args * @phpstan-param list $extraHeaders + * @phpstan-param TErrorVar $err + * @phpstan-param-out TErrorVar|string $err */ public static function postURL(string $page, $args, int $timeout = 10, array $extraHeaders = [], &$err = null) : ?InternetRequestResult{ try{ diff --git a/src/utils/Process.php b/src/utils/Process.php index d66dd80bd..bdc264133 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -152,6 +152,8 @@ final class Process{ * @param string $command Command to execute * @param string|null $stdout Reference parameter to write stdout to * @param string|null $stderr Reference parameter to write stderr to + * @phpstan-param-out string $stdout + * @phpstan-param-out string $stderr * * @return int process exit code */ diff --git a/src/world/World.php b/src/world/World.php index 0071f221f..126a947ee 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -396,6 +396,9 @@ class World implements ChunkManager{ /** * @phpstan-param BlockPosHash $hash + * @phpstan-param-out int $x + * @phpstan-param-out int $y + * @phpstan-param-out int $z */ public static function getBlockXYZ(int $hash, ?int &$x, ?int &$y, ?int &$z) : void{ [$baseX, $baseY, $baseZ] = morton3d_decode($hash); @@ -410,6 +413,8 @@ class World implements ChunkManager{ /** * @phpstan-param ChunkPosHash $hash + * @phpstan-param-out int $x + * @phpstan-param-out int $z */ public static function getXZ(int $hash, ?int &$x, ?int &$z) : void{ [$x, $z] = morton2d_decode($hash); @@ -1764,6 +1769,7 @@ class World implements ChunkManager{ * It'll try to lower the durability if Item is a tool, and set it to Air if broken. * * @param Item $item reference parameter (if null, can break anything) + * @phpstan-param-out Item $item */ public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ $vector = $vector->floor(); diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 5adcd0103..9732a9fbb 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -191,6 +191,11 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } + /** + * @phpstan-param-out int $x + * @phpstan-param-out int $y + * @phpstan-param-out int $z + */ protected static function deserializeExtraDataKey(int $chunkVersion, int $key, ?int &$x, ?int &$y, ?int &$z) : void{ if($chunkVersion >= ChunkVersion::v1_0_0){ $x = ($key >> 12) & 0xf; diff --git a/src/world/format/io/region/RegionLoader.php b/src/world/format/io/region/RegionLoader.php index 92848c6b5..cdba29f68 100644 --- a/src/world/format/io/region/RegionLoader.php +++ b/src/world/format/io/region/RegionLoader.php @@ -276,6 +276,8 @@ class RegionLoader{ /** * @param int $x reference parameter * @param int $z reference parameter + * @phpstan-param-out int $x + * @phpstan-param-out int $z */ protected static function getChunkCoords(int $offset, ?int &$x, ?int &$z) : void{ $x = $offset & 0x1f; diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 91a7937a6..3007b0629 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -92,6 +92,8 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * @param int $regionX reference parameter * @param int $regionZ reference parameter + * @phpstan-param-out int $regionX + * @phpstan-param-out int $regionZ */ public static function getRegionIndex(int $chunkX, int $chunkZ, &$regionX, &$regionZ) : void{ $regionX = $chunkX >> 5;