From dbbe1f2d5c04059ee9ddad12a0d33fbaea933683 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 10:41:06 +0000 Subject: [PATCH 01/14] Revert "Entity: remove redundant check from spawnTo()" This reverts commit 3028832cd35c53937bb6502f74d3ad53646b12a7. When I created this commit, I made the flawed assumption that spawnTo() would not be used by plugins. In addition, I was not aware that there are some usages of spawnTo() in the core which do not check for chunk usage, such as in Player->showPlayer(). This caused a collection of problems including memory leaks and crashes due to disconnecting players not removing their references from viewed entities. The reverted commit may be the cause of #3178. --- src/pocketmine/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 3eb596d78..a2b3468e9 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -2048,7 +2048,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param Player $player */ public function spawnTo(Player $player) : void{ - if(!isset($this->hasSpawned[$player->getLoaderId()])){ + if(!isset($this->hasSpawned[$player->getLoaderId()]) and $this->chunk !== null and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])){ $this->hasSpawned[$player->getLoaderId()] = $player; $this->sendSpawnPacket($player); From 00e415fc79fd5d805e31ab4aaeb08d5382248793 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 19:57:19 +0000 Subject: [PATCH 02/14] move phpstan.neon to phpstan.neon.dist to allow phpstan.neon to be locally modified for development --- .gitignore | 1 + phpstan.neon => phpstan.neon.dist | 0 2 files changed, 1 insertion(+) rename phpstan.neon => phpstan.neon.dist (100%) diff --git a/.gitignore b/.gitignore index 7c65b549f..9cca0e13e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ server.properties memory_dumps/* resource_packs/ server.lock +/phpstan.neon # Common IDEs .idea/ diff --git a/phpstan.neon b/phpstan.neon.dist similarity index 100% rename from phpstan.neon rename to phpstan.neon.dist From bc76b1cafe2cced55759dcdc231da192dc891117 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 10:14:15 +0000 Subject: [PATCH 03/14] Server: remove several redundant @var annotations (copy pasta) these are all useless because it is implied by the parameter type anyway. --- src/pocketmine/Server.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 6a1a2c417..be10c0d90 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1798,7 +1798,6 @@ class Server{ return $this->broadcast($message, self::BROADCAST_CHANNEL_USERS); } - /** @var CommandSender[] $recipients */ foreach($recipients as $recipient){ $recipient->sendMessage($message); } @@ -1823,7 +1822,6 @@ class Server{ } } - /** @var Player[] $recipients */ foreach($recipients as $recipient){ $recipient->sendTip($tip); } @@ -1849,7 +1847,6 @@ class Server{ } } - /** @var Player[] $recipients */ foreach($recipients as $recipient){ $recipient->sendPopup($popup); } @@ -1879,7 +1876,6 @@ class Server{ } } - /** @var Player[] $recipients */ foreach($recipients as $recipient){ $recipient->addTitle($title, $subtitle, $fadeIn, $stay, $fadeOut); } From 753a8a693773c248c8409b0264fb88d11b0e6e6c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 10:15:04 +0000 Subject: [PATCH 04/14] Event: remove useless @var $this annotations we are not in a trait here, the scope is always Event. --- src/pocketmine/event/Event.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/event/Event.php b/src/pocketmine/event/Event.php index 015cdaafd..b2c0b9dee 100644 --- a/src/pocketmine/event/Event.php +++ b/src/pocketmine/event/Event.php @@ -56,7 +56,6 @@ abstract class Event{ throw new \BadMethodCallException(get_class($this) . " is not Cancellable"); } - /** @var Event $this */ return $this->isCancelled; } @@ -70,7 +69,6 @@ abstract class Event{ throw new \BadMethodCallException(get_class($this) . " is not Cancellable"); } - /** @var Event $this */ $this->isCancelled = $value; } From 7b75b6928d7d9deb384496e5b2789605770775dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 10:15:50 +0000 Subject: [PATCH 05/14] AvailableCommandsPacket: fixed foreach docs these probably aren't necessary at all to be honest. --- .../network/mcpe/protocol/AvailableCommandsPacket.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 86088c8dc..d938ad485 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -359,12 +359,9 @@ class AvailableCommandsPacket extends DataPacket{ $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index } } - + /** @var CommandParameter[] $overload */ foreach($commandData->overloads as $overload){ - /** - * @var CommandParameter[] $overload - * @var CommandParameter $parameter - */ + /** @var CommandParameter $parameter */ foreach($overload as $parameter){ if($parameter->enum !== null){ if(!isset($enumIndexes[$parameter->enum->enumName])){ From ecb2e6e3af3de6416194214b3a4f8ed7f5e2c889 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 10:17:25 +0000 Subject: [PATCH 06/14] PluginManager: remove useless information from softDepend debug we don't report the parameter type anywhere else, and since PHP doesn't support overloading, we don't need to. This fixes PHPStan 0.12 complaints about ReflectionNamedType. I figured this was the best solution instead of adding an extra few lines of code. --- src/pocketmine/plugin/PluginManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index ee92644b3..0c2abdb27 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -733,7 +733,7 @@ class PluginManager{ $eventClass = $parameters[0]->getClass(); }catch(\ReflectionException $e){ //class doesn't exist if(isset($tags["softDepend"]) && !isset($this->plugins[$tags["softDepend"]])){ - $this->server->getLogger()->debug("Not registering @softDepend listener " . Utils::getNiceClosureName($handlerClosure) . "(" . $parameters[0]->getType()->getName() . ") because plugin \"" . $tags["softDepend"] . "\" not found"); + $this->server->getLogger()->debug("Not registering @softDepend listener " . Utils::getNiceClosureName($handlerClosure) . "() because plugin \"" . $tags["softDepend"] . "\" not found"); continue; } From 73d0f799c21c511778326235d7f290ddf902a226 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 10:29:49 +0000 Subject: [PATCH 07/14] Update to PHPStan 0.12.0 --- phpstan.neon.dist | 34 ++----------------- .../phpstan/configs/optional-com-dotnet.neon | 4 +-- tests/phpstan/configs/optional-leveldb.neon | 14 ++++---- tests/phpstan/configs/phpstan-bugs.neon | 6 ++-- tests/phpstan/configs/pthreads-bugs.neon | 2 +- tests/travis.sh | 2 +- 6 files changed, 17 insertions(+), 45 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e2d3ca6d5..b1fb36c2d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -14,37 +14,9 @@ parameters: reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings ignoreErrors: - - message: "#^pocketmine\\\\Player\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\entity\\\\Human\\.$#" - path: src/pocketmine/Player.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\\.$#" + message: "#^Cannot instantiate interface pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\.$#" count: 1 - path: src/pocketmine/block/Block.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 + path: src/pocketmine/Server.php - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#" @@ -102,4 +74,4 @@ parameters: message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#" count: 1 path: src/pocketmine/command/defaults/TeleportCommand.php - comment: "not actually possible, but high cost to fix warning" +# comment: "not actually possible, but high cost to fix warning" diff --git a/tests/phpstan/configs/optional-com-dotnet.neon b/tests/phpstan/configs/optional-com-dotnet.neon index efa2d82ab..fb725539c 100644 --- a/tests/phpstan/configs/optional-com-dotnet.neon +++ b/tests/phpstan/configs/optional-com-dotnet.neon @@ -3,10 +3,10 @@ parameters: - message: "#^Instantiated class COM not found\\.$#" count: 2 - path: src/pocketmine/network/upnp/UPnP.php + path: ../../../src/pocketmine/network/upnp/UPnP.php - message: "#^Access to property \\$StaticPortMappingCollection on an unknown class COM\\.$#" count: 4 - path: src/pocketmine/network/upnp/UPnP.php + path: ../../../src/pocketmine/network/upnp/UPnP.php diff --git a/tests/phpstan/configs/optional-leveldb.neon b/tests/phpstan/configs/optional-leveldb.neon index 7ad8f1e28..91ff01bb5 100644 --- a/tests/phpstan/configs/optional-leveldb.neon +++ b/tests/phpstan/configs/optional-leveldb.neon @@ -2,29 +2,29 @@ parameters: ignoreErrors: - message: "#^Used constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - message: "#^Constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - message: "#^Instantiated class LevelDB not found\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:createDB\\(\\) has invalid type LevelDB\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:getDatabase\\(\\) has invalid type LevelDB\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - message: "#^Property pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:\\$db has unknown class LevelDB as its type\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - message: "#^Call to method (get|put|delete|close)\\(\\) on an unknown class LevelDB\\.$#" - path: src/pocketmine/level/format/io/leveldb/LevelDB.php + path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 90fef5cea..d6503d71f 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,10 +1,10 @@ parameters: ignoreErrors: - - message: "#^PHPDoc tag @param has invalid value \\(.+\\)\\: Unexpected token \"&\", expected TOKEN_VARIABLE at offset \\d+$#" - path: src/pocketmine + message: "#^PHPDoc tag @param has invalid value \\(.+\\)\\: Unexpected token \"&\", expected variable at offset \\d+$#" + path: ../../../src/pocketmine - message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" - path: src/pocketmine + path: ../../../src/pocketmine diff --git a/tests/phpstan/configs/pthreads-bugs.neon b/tests/phpstan/configs/pthreads-bugs.neon index 65979a989..3b4bcadcb 100644 --- a/tests/phpstan/configs/pthreads-bugs.neon +++ b/tests/phpstan/configs/pthreads-bugs.neon @@ -2,5 +2,5 @@ parameters: ignoreErrors: - message: "#^Variable \\$GLOBALS in isset\\(\\) always exists and is not nullable\\.$#" - path: src/pocketmine/MemoryManager.php + path: ../../../src/pocketmine/MemoryManager.php diff --git a/tests/travis.sh b/tests/travis.sh index a58341493..ba90d4a19 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -21,7 +21,7 @@ if [ $? -ne 0 ]; then exit 1 fi -[ ! -f phpstan.phar ] && echo "Downloading PHPStan..." && curl -sSLO https://github.com/phpstan/phpstan/releases/download/0.11.19/phpstan.phar +[ ! -f phpstan.phar ] && echo "Downloading PHPStan..." && curl -sSLO https://github.com/phpstan/phpstan/releases/download/0.12.0/phpstan.phar "$PHP_BINARY" phpstan.phar analyze --no-progress --memory-limit=2G || exit 1 echo "PHPStan scan succeeded" From 9fc260fb1aaebba500ce771f2472d67d5c248f0d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 19:38:54 +0000 Subject: [PATCH 08/14] keep phpstan.neon.dist ignoreErrors sorted by file --- phpstan.neon.dist | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b1fb36c2d..b918d5fc5 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -18,6 +18,12 @@ parameters: count: 1 path: src/pocketmine/Server.php + - + message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#" + count: 1 + path: src/pocketmine/command/defaults/TeleportCommand.php +# comment: "not actually possible, but high cost to fix warning" + - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#" count: 1 @@ -70,8 +76,3 @@ parameters: message: "#^Constant pocketmine\\\\VERSION not found\\.$#" path: src/pocketmine - - - message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#" - count: 1 - path: src/pocketmine/command/defaults/TeleportCommand.php -# comment: "not actually possible, but high cost to fix warning" From c35d91a104b332d6797233f9ba1d59c0a8b20a32 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 19:42:18 +0000 Subject: [PATCH 09/14] phpstan: allow blanket ignoreErrors in src to reduce merge work for master --- phpstan.neon.dist | 16 ++++++++-------- tests/phpstan/configs/phpstan-bugs.neon | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b918d5fc5..d078a7acf 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -46,33 +46,33 @@ parameters: - message: "#^Constant pocketmine\\\\COMPOSER_AUTOLOADER_PATH not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\DATA not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\GIT_COMMIT not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\PATH not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\PLUGIN_PATH not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\RESOURCE_PATH not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\START_TIME not found\\.$#" - path: src/pocketmine + path: src - message: "#^Constant pocketmine\\\\VERSION not found\\.$#" - path: src/pocketmine + path: src diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index d6503d71f..89defd52a 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -2,9 +2,9 @@ parameters: ignoreErrors: - message: "#^PHPDoc tag @param has invalid value \\(.+\\)\\: Unexpected token \"&\", expected variable at offset \\d+$#" - path: ../../../src/pocketmine + path: ../../../src - message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" - path: ../../../src/pocketmine + path: ../../../src From c57eb26fd5e15b29ef3d0f00b140398ba2557309 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 19:50:15 +0000 Subject: [PATCH 10/14] phpstan-bugs: add some extra patterns for level 3 false positives --- tests/phpstan/configs/phpstan-bugs.neon | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 89defd52a..1f7c01b9c 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -8,3 +8,11 @@ parameters: message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" path: ../../../src + - + message: "#^Cannot access an offset on Threaded\\.$#" + path: ../../../src + + - + message: "#^Cannot assign new offset to Threaded\\.$#" + path: ../../../src + From d867ffc60df0544ca5100bd566ed1db812dd74af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 21:14:09 +0000 Subject: [PATCH 11/14] MetadataStore: fix some doc comments --- src/pocketmine/metadata/MetadataStore.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/metadata/MetadataStore.php b/src/pocketmine/metadata/MetadataStore.php index c6a9736e3..7d2519c8a 100644 --- a/src/pocketmine/metadata/MetadataStore.php +++ b/src/pocketmine/metadata/MetadataStore.php @@ -29,7 +29,7 @@ namespace pocketmine\metadata; use pocketmine\plugin\Plugin; abstract class MetadataStore{ - /** @var \SplObjectStorage[] */ + /** @var \SplObjectStorage[]|MetadataValue[][] */ private $metadataMap; /** @@ -100,7 +100,7 @@ abstract class MetadataStore{ * @param Plugin $owningPlugin */ public function invalidateAll(Plugin $owningPlugin){ - /** @var MetadataValue[] $values */ + /** @var \SplObjectStorage|MetadataValue[] $values */ foreach($this->metadataMap as $values){ if(isset($values[$owningPlugin])){ $values[$owningPlugin]->invalidate(); From 39c607cbd5e134a47fa338628d54eea4e45d6bc3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 21:31:35 +0000 Subject: [PATCH 12/14] Position: mark level field as nullable allowing the level to be null is, to be honest, a big design flaw, but one that can't be fixed without BC breaks. --- src/pocketmine/level/Position.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index 6bcb599bc..608c412c5 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -29,7 +29,7 @@ use function assert; class Position extends Vector3{ - /** @var Level */ + /** @var Level|null */ public $level = null; /** From 8ecf5e02b95c4efc29ccafe455657278c7ea03f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 22:00:19 +0000 Subject: [PATCH 13/14] bad fix for WritableBook phpstan warning master has this shit so much better --- src/pocketmine/item/WritableBook.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index cc73eec18..8b965b787 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -186,16 +186,18 @@ class WritableBook extends Item{ * @return CompoundTag[] */ public function getPages() : array{ - $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); - if($pages === null){ - return []; - } + /** @var CompoundTag[] $pages */ + $pages = $this->getPagesTag()->getValue(); - return $pages->getValue(); + return $pages; } protected function getPagesTag() : ListTag{ - return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag(self::TAG_PAGES, [], NBT::TAG_Compound); + $pagesTag = $this->getNamedTag()->getListTag(self::TAG_PAGES); + if($pagesTag !== null and $pagesTag->getTagType() === NBT::TAG_Compound){ + return $pagesTag; + } + return new ListTag(self::TAG_PAGES, [], NBT::TAG_Compound); } /** From 7b1ae2a82271bd58c0a3834e267bb5bc3bc35292 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 22:12:14 +0000 Subject: [PATCH 14/14] phpstan: green on level 3 --- phpstan.neon.dist | 48 ++++++++++++++- tests/phpstan/configs/gc-hacks.neon | 80 +++++++++++++++++++++++++ tests/phpstan/configs/phpstan-bugs.neon | 15 +++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 tests/phpstan/configs/gc-hacks.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index d078a7acf..170897410 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,11 +1,12 @@ includes: + - tests/phpstan/configs/gc-hacks.neon - tests/phpstan/configs/optional-com-dotnet.neon - tests/phpstan/configs/optional-leveldb.neon - tests/phpstan/configs/phpstan-bugs.neon - tests/phpstan/configs/pthreads-bugs.neon parameters: - level: 2 + level: 3 autoload_files: - tests/phpstan/bootstrap.php - src/pocketmine/PocketMine.php @@ -24,6 +25,51 @@ parameters: path: src/pocketmine/command/defaults/TeleportCommand.php # comment: "not actually possible, but high cost to fix warning" + - + message: "#^Array \\(array\\\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" + count: 2 + path: src/pocketmine/entity/Entity.php + + - + message: "#^Invalid array key type pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/entity/Entity.php + + - + message: "#^Method pocketmine\\\\event\\\\entity\\\\EntityDeathEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\Living but returns pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/EntityDeathEvent.php + + - + message: "#^Method pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\Living but returns pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/EntityShootBowEvent.php + + - + message: "#^Property pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:\\$projectile \\(pocketmine\\\\entity\\\\projectile\\\\Projectile\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/EntityShootBowEvent.php + + - + message: "#^Method pocketmine\\\\event\\\\entity\\\\ItemDespawnEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\object\\\\ItemEntity but returns pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/ItemDespawnEvent.php + + - + message: "#^Method pocketmine\\\\event\\\\entity\\\\ItemSpawnEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\object\\\\ItemEntity but returns pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/ItemSpawnEvent.php + + - + message: "#^Method pocketmine\\\\event\\\\entity\\\\ProjectileHitEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\projectile\\\\Projectile but returns pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/ProjectileHitEvent.php + + - + message: "#^Method pocketmine\\\\event\\\\entity\\\\ProjectileLaunchEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\projectile\\\\Projectile but returns pocketmine\\\\entity\\\\Entity\\.$#" + count: 1 + path: src/pocketmine/event/entity/ProjectileLaunchEvent.php + - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#" count: 1 diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon new file mode 100644 index 000000000..14267631d --- /dev/null +++ b/tests/phpstan/configs/gc-hacks.neon @@ -0,0 +1,80 @@ +#cyclic refs in lots of objects prevent GC, causing increased memory pressure +#the proper fix is to not have cycles, but in the meantime we have these hacks + +parameters: + ignoreErrors: + - + message: "#^Property pocketmine\\\\Player\\:\\:\\$sessionAdapter \\(pocketmine\\\\network\\\\mcpe\\\\PlayerNetworkSessionAdapter\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/Player.php + + - + message: "#^Property pocketmine\\\\Player\\:\\:\\$cursorInventory \\(pocketmine\\\\inventory\\\\PlayerCursorInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/Player.php + + - + message: "#^Property pocketmine\\\\Player\\:\\:\\$craftingGrid \\(pocketmine\\\\inventory\\\\CraftingGrid\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/Player.php + + - + message: "#^Property pocketmine\\\\Player\\:\\:\\$perm \\(pocketmine\\\\permission\\\\PermissibleBase\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/Player.php + + - + message: "#^Property pocketmine\\\\entity\\\\Entity\\:\\:\\$namedtag \\(pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/entity/Entity.php + + - + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\PlayerInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/entity/Human.php + + - + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderChestInventory \\(pocketmine\\\\inventory\\\\EnderChestInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/entity/Human.php + + - + message: "#^Property pocketmine\\\\entity\\\\Living\\:\\:\\$armorInventory \\(pocketmine\\\\inventory\\\\ArmorInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/entity/Living.php + + - + message: "#^Property pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:\\$left \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/inventory/DoubleChestInventory.php + + - + message: "#^Property pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:\\$right \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/inventory/DoubleChestInventory.php + + - + message: "#^Property pocketmine\\\\level\\\\Level\\:\\:\\$provider \\(pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Property pocketmine\\\\level\\\\Level\\:\\:\\$blockMetadata \\(pocketmine\\\\metadata\\\\BlockMetadataStore\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Property pocketmine\\\\level\\\\Level\\:\\:\\$temporalPosition \\(pocketmine\\\\level\\\\Position\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Property pocketmine\\\\tile\\\\Chest\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/tile/Chest.php + + - + message: "#^Property pocketmine\\\\tile\\\\Furnace\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\FurnaceInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/pocketmine/tile/Furnace.php + diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 1f7c01b9c..696fcc8ab 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -16,3 +16,18 @@ parameters: message: "#^Cannot assign new offset to Threaded\\.$#" path: ../../../src + - + message: "#^Offset string does not exist on array\\(\\)\\.$#" + count: 3 + path: ../../../src/pocketmine/MemoryManager.php + + - + message: "#^Offset \\(int\\|string\\) does not exist on array\\(\\)\\.$#" + count: 1 + path: ../../../src/pocketmine/MemoryManager.php + + - + message: "#^Array \\(array\\) does not accept key int\\.$#" + count: 1 + path: ../../../src/pocketmine/plugin/PluginDescription.php +