diff --git a/composer.json b/composer.json index aa78d3392..9f9fccd28 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "ocramius/package-versions": "^1.5" }, "require-dev": { - "phpstan/phpstan": "^0.12.19", + "phpstan/phpstan": "^0.12.22", "irstea/phpunit-shim": "^8.5", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2" diff --git a/composer.lock b/composer.lock index 1ace8c842..84327e930 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": "4c258478d7e0be37a3c1267c9382f37f", + "content-hash": "da1e60f0dfc0109a44d3a47b311ae8e5", "packages": [ { "name": "adhocore/json-comment", @@ -581,12 +581,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "6b2234572b5d06a0532e3851e72bdc108e0c4387" + "reference": "8e42604a7a91d52578af0c9a8024635ed5985b97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/6b2234572b5d06a0532e3851e72bdc108e0c4387", - "reference": "6b2234572b5d06a0532e3851e72bdc108e0c4387", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/8e42604a7a91d52578af0c9a8024635ed5985b97", + "reference": "8e42604a7a91d52578af0c9a8024635ed5985b97", "shasum": "" }, "require": { @@ -610,7 +610,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-04-15T11:29:45+00:00" + "time": "2020-04-19T12:18:01+00:00" }, { "name": "pocketmine/raklib", @@ -776,16 +776,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.19", + "version": "0.12.23", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "054f6d76b12ba9a6c13a5a8d5fcdf51219615f4d" + "reference": "71e529efced79e055fa8318b692e7f7d03ea4e75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/054f6d76b12ba9a6c13a5a8d5fcdf51219615f4d", - "reference": "054f6d76b12ba9a6c13a5a8d5fcdf51219615f4d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/71e529efced79e055fa8318b692e7f7d03ea4e75", + "reference": "71e529efced79e055fa8318b692e7f7d03ea4e75", "shasum": "" }, "require": { @@ -828,7 +828,7 @@ "type": "tidelift" } ], - "time": "2020-04-19T20:35:10+00:00" + "time": "2020-05-05T12:55:44+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php b/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php index 906ab3252..717fc598e 100644 --- a/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php +++ b/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php @@ -28,7 +28,6 @@ final class EntityMetadataFlags{ private function __construct(){ //NOOP } - public const ONFIRE = 0; public const SNEAKING = 1; public const RIDING = 2; @@ -101,11 +100,11 @@ final class EntityMetadataFlags{ public const OVER_SCAFFOLDING = 69; public const FALL_THROUGH_SCAFFOLDING = 70; public const BLOCKING = 71; //shield - public const DISABLE_BLOCKING = 72; - //73 is set when a player is attacked while using shield, unclear on purpose - //74 related to shield usage, needs further investigation + public const TRANSITION_BLOCKING = 72; + public const BLOCKED_USING_SHIELD = 73; + public const BLOCKED_USING_DAMAGED_SHIELD = 74; public const SLEEPING = 75; - //76 related to sleeping, unclear usage + public const WANTS_TO_WAKE = 76; public const TRADE_INTEREST = 77; public const DOOR_BREAKER = 78; //... public const BREAKING_OBSTRUCTION = 79; @@ -115,6 +114,10 @@ final class EntityMetadataFlags{ public const ROARING = 83; public const DELAYED_ATTACKING = 84; public const AVOIDING_MOBS = 85; - //86 used by RangedAttackGoal - //87 used by NearestAttackableTargetGoal + public const FACING_TARGET_TO_RANGE_ATTACK = 86; + public const HIDDEN_WHEN_INVISIBLE = 87; //?????????????????? + public const IS_IN_UI = 88; + public const STALKING = 89; + public const EMOTING = 90; + public const CELEBRATING = 91; } diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 1e30358d5..1536baca6 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -468,9 +468,15 @@ class Utils{ * @return string[] an array of tagName => tag value. If the tag has no value, an empty string is used as the value. */ public static function parseDocComment(string $docComment) : array{ - preg_match_all('/(*ANYCRLF)^[\t ]*\* @([a-zA-Z]+)(?:[\t ]+(.+))?[\t ]*$/m', $docComment, $matches); + $rawDocComment = substr($docComment, 3, -2); //remove the opening and closing markers + if($rawDocComment === false){ //usually empty doc comment, but this is safer and statically analysable + return []; + } + preg_match_all('/(*ANYCRLF)^[\t ]*(?:\* )?@([a-zA-Z]+)(?:[\t ]+(.+?))?[\t ]*$/m', $rawDocComment, $matches); - return array_combine($matches[1], $matches[2]); + $result = array_combine($matches[1], $matches[2]); + if($result === false) throw new AssumptionFailedError("array_combine() doesn't return false with two equal-sized arrays"); + return $result; } /** diff --git a/start.sh b/start.sh index ac84f829d..fe4d95a8e 100755 --- a/start.sh +++ b/start.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash DIR="$(cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" cd "$DIR" diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 21bf738f1..0c8e28512 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -26,22 +26,22 @@ parameters: path: ../../../src/command/CommandReader.php - - message: "#^Default value of the parameter \\#4 \\$min \\(\\-30000000\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getRelativeDouble\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#4 \\$min \\(int\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getRelativeDouble\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/command/defaults/VanillaCommand.php - - message: "#^Default value of the parameter \\#5 \\$max \\(30000000\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getRelativeDouble\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#5 \\$max \\(int\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getRelativeDouble\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/command/defaults/VanillaCommand.php - - message: "#^Default value of the parameter \\#3 \\$min \\(\\-30000000\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getDouble\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#3 \\$min \\(int\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getDouble\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/command/defaults/VanillaCommand.php - - message: "#^Default value of the parameter \\#4 \\$max \\(30000000\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getDouble\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#4 \\$max \\(int\\) of method pocketmine\\\\command\\\\defaults\\\\VanillaCommand\\:\\:getDouble\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/command/defaults/VanillaCommand.php @@ -60,11 +60,6 @@ parameters: count: 1 path: ../../../src/item/ItemFactory.php - - - message: "#^Class pocketmine\\\\network\\\\mcpe\\\\StaticPacketCache constructor invoked with 0 parameters, 2 required\\.$#" - count: 1 - path: ../../../src/network/mcpe/StaticPacketCache.php - - message: "#^If condition is always false\\.$#" count: 1 @@ -75,15 +70,20 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php + - + message: "#^Class pocketmine\\\\network\\\\mcpe\\\\StaticPacketCache constructor invoked with 0 parameters, 2 required\\.$#" + count: 1 + path: ../../../src/network/mcpe/StaticPacketCache.php + - message: "#^Class pocketmine\\\\network\\\\mcpe\\\\compression\\\\ZlibCompressor constructor invoked with 0 parameters, 3 required\\.$#" count: 1 path: ../../../src/network/mcpe/compression/ZlibCompressor.php - - message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" + message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" count: 1 - path: ../../../src/utils/Timezone.php + path: ../../../src/utils/Utils.php - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" @@ -91,27 +91,27 @@ parameters: path: ../../../src/world/format/io/region/RegionLoader.php - - message: "#^Default value of the parameter \\#1 \\$pitch \\(0\\) of method pocketmine\\\\world\\\\sound\\\\ClickSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#1 \\$pitch \\(int\\) of method pocketmine\\\\world\\\\sound\\\\ClickSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/world/sound/ClickSound.php - - message: "#^Default value of the parameter \\#1 \\$pitch \\(0\\) of method pocketmine\\\\world\\\\sound\\\\DoorSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#1 \\$pitch \\(int\\) of method pocketmine\\\\world\\\\sound\\\\DoorSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/world/sound/DoorSound.php - - message: "#^Default value of the parameter \\#1 \\$pitch \\(0\\) of method pocketmine\\\\world\\\\sound\\\\FizzSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#1 \\$pitch \\(int\\) of method pocketmine\\\\world\\\\sound\\\\FizzSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/world/sound/FizzSound.php - - message: "#^Default value of the parameter \\#1 \\$pitch \\(0\\) of method pocketmine\\\\world\\\\sound\\\\LaunchSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#1 \\$pitch \\(int\\) of method pocketmine\\\\world\\\\sound\\\\LaunchSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/world/sound/LaunchSound.php - - message: "#^Default value of the parameter \\#1 \\$pitch \\(0\\) of method pocketmine\\\\world\\\\sound\\\\PopSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" + message: "#^Default value of the parameter \\#1 \\$pitch \\(int\\) of method pocketmine\\\\world\\\\sound\\\\PopSound\\:\\:__construct\\(\\) is incompatible with type float\\.$#" count: 1 path: ../../../src/world/sound/PopSound.php diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index 370603bfb..8440b0c91 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -63,6 +63,32 @@ class UtilsTest extends TestCase{ self::assertEquals("HIGHEST", $tags["priority"]); } + /** + * @return string[][] + * @phpstan-return list + */ + public function parseDocCommentOneLineProvider() : array{ + return [ + ["/** @ignoreCancelled true dummy */"], + ["/**@ignoreCancelled true dummy*/"], + ["/** @ignoreCancelled true dummy */"] + ]; + } + + /** + * @dataProvider parseDocCommentOneLineProvider + */ + public function testParseOneLineDocComment(string $comment) : void{ + $tags = Utils::parseDocComment($comment); + self::assertArrayHasKey("ignoreCancelled", $tags); + self::assertEquals("true dummy", $tags["ignoreCancelled"]); + } + + public function testParseEmptyDocComment() : void{ + $tags = Utils::parseDocComment(""); + self::assertCount(0, $tags); + } + public function testNamespacedNiceClosureName() : void{ //be careful with this test. The closure has to be declared on the same line as the assertion. self::assertSame('closure@' . Filesystem::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function() : void{}));