mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-18 15:05:56 +00:00
Update to PHPStan 2.x
This commit is contained in:
parent
d25ec58a6f
commit
9633b7d8a7
@ -52,9 +52,9 @@
|
||||
"symfony/filesystem": "~6.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.11.11",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpstan/phpstan": "2.1.1",
|
||||
"phpstan/phpstan-phpunit": "^2.0.0",
|
||||
"phpstan/phpstan-strict-rules": "^2.0.0",
|
||||
"phpunit/phpunit": "^10.5.24"
|
||||
},
|
||||
"autoload": {
|
||||
|
58
composer.lock
generated
58
composer.lock
generated
@ -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": "732102eca72dc1d29e7b67dfbce07653",
|
||||
"content-hash": "994ccffe45f066768542019f6f9d237b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -1386,20 +1386,20 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.11.11",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3"
|
||||
"reference": "cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3",
|
||||
"reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7",
|
||||
"reference": "cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2|^8.0"
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan-shim": "*"
|
||||
@ -1440,34 +1440,33 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-08-19T14:37:29+00:00"
|
||||
"time": "2025-01-05T16:43:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
"version": "1.4.0",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
||||
"reference": "f3ea021866f4263f07ca3636bf22c64be9610c11"
|
||||
"reference": "e32ac656788a5bf3dedda89e6a2cad5643bf1a18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/f3ea021866f4263f07ca3636bf22c64be9610c11",
|
||||
"reference": "f3ea021866f4263f07ca3636bf22c64be9610c11",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/e32ac656788a5bf3dedda89e6a2cad5643bf1a18",
|
||||
"reference": "e32ac656788a5bf3dedda89e6a2cad5643bf1a18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpstan": "^1.11"
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpstan/phpstan": "^2.0.4"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic/php-parser": "^4.13.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/phpstan-strict-rules": "^1.5.1",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
"phpstan/phpstan-strict-rules": "^2.0",
|
||||
"phpunit/phpunit": "^9.6"
|
||||
},
|
||||
"type": "phpstan-extension",
|
||||
"extra": {
|
||||
@ -1490,34 +1489,33 @@
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.4.0"
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.3"
|
||||
},
|
||||
"time": "2024-04-20T06:39:00+00:00"
|
||||
"time": "2024-12-19T09:14:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-strict-rules",
|
||||
"version": "1.6.0",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
|
||||
"reference": "363f921dd8441777d4fc137deb99beb486c77df1"
|
||||
"reference": "ed6fea0ad4ad9c7e25f3ad2e7c4d420cf1e67fe3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/363f921dd8441777d4fc137deb99beb486c77df1",
|
||||
"reference": "363f921dd8441777d4fc137deb99beb486c77df1",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/ed6fea0ad4ad9c7e25f3ad2e7c4d420cf1e67fe3",
|
||||
"reference": "ed6fea0ad4ad9c7e25f3ad2e7c4d420cf1e67fe3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpstan": "^1.11"
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpstan/phpstan": "^2.0.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic/php-parser": "^4.13.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.6"
|
||||
},
|
||||
"type": "phpstan-extension",
|
||||
"extra": {
|
||||
@ -1539,9 +1537,9 @@
|
||||
"description": "Extra strict and opinionated rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.0"
|
||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.1"
|
||||
},
|
||||
"time": "2024-04-20T06:37:51+00:00"
|
||||
"time": "2024-12-12T20:21:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
@ -1,6 +1,7 @@
|
||||
includes:
|
||||
- tests/phpstan/analyse-for-current-php-version.neon.php
|
||||
- tests/phpstan/configs/actual-problems.neon
|
||||
- tests/phpstan/configs/dependency-problems.neon
|
||||
- tests/phpstan/configs/impossible-generics.neon
|
||||
- tests/phpstan/configs/php-bugs.neon
|
||||
- tests/phpstan/configs/phpstan-bugs.neon
|
||||
@ -31,6 +32,7 @@ parameters:
|
||||
paths:
|
||||
- build
|
||||
- src
|
||||
- tests/phpstan/DummyPluginOwned.php
|
||||
- tests/phpstan/rules
|
||||
- tests/phpunit
|
||||
- tests/plugins/TesterPlugin
|
||||
|
@ -51,9 +51,8 @@ final class CommandStringHelper{
|
||||
foreach($matches[0] as $k => $_){
|
||||
for($i = 1; $i <= 2; ++$i){
|
||||
if($matches[$i][$k] !== ""){
|
||||
/** @var string $match */ //phpstan can't understand preg_match and friends by itself :(
|
||||
$match = $matches[$i][$k];
|
||||
$args[(int) $k] = preg_replace('/\\\\([\\\\"])/u', '$1', $match) ?? throw new AssumptionFailedError(preg_last_error_msg());
|
||||
$args[] = preg_replace('/\\\\([\\\\"])/u', '$1', $match) ?? throw new AssumptionFailedError(preg_last_error_msg());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ final class Utils{
|
||||
|
||||
/**
|
||||
* @phpstan-return \Closure(object) : object
|
||||
* @deprecated
|
||||
*/
|
||||
public static function cloneCallback() : \Closure{
|
||||
return static function(object $o){
|
||||
@ -179,15 +180,13 @@ final class Utils{
|
||||
* @phpstan-template TValue of object
|
||||
*
|
||||
* @param object[] $array
|
||||
* @phpstan-param array<TKey, TValue> $array
|
||||
* @phpstan-param array<TKey, TValue>|list<TValue> $array
|
||||
*
|
||||
* @return object[]
|
||||
* @phpstan-return array<TKey, TValue>
|
||||
* @phpstan-return ($array is list<TValue> ? list<TValue> : array<TKey, TValue>)
|
||||
*/
|
||||
public static function cloneObjectArray(array $array) : array{
|
||||
/** @phpstan-var \Closure(TValue) : TValue $callback */
|
||||
$callback = self::cloneCallback();
|
||||
return array_map($callback, $array);
|
||||
return array_map(fn(object $o) => clone $o, $array);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,6 +215,9 @@ abstract class RegionWorldProvider extends BaseWorldProvider{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return \RegexIterator<mixed, string, \FilesystemIterator>
|
||||
*/
|
||||
private function createRegionIterator() : \RegexIterator{
|
||||
return new \RegexIterator(
|
||||
new \FilesystemIterator(
|
||||
|
@ -117,7 +117,7 @@ final class FlatGeneratorOptions{
|
||||
}
|
||||
}
|
||||
}
|
||||
$options[(string) $option] = $params;
|
||||
$options[$option] = $params;
|
||||
}
|
||||
return new self($structure, $biomeId, $options);
|
||||
}
|
||||
|
28
tests/phpstan/DummyPluginOwned.php
Normal file
28
tests/phpstan/DummyPluginOwned.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\plugin;
|
||||
|
||||
class DummyPluginOwned{
|
||||
use PluginOwnedTrait;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
73
tests/phpstan/configs/dependency-problems.neon
Normal file
73
tests/phpstan/configs/dependency-problems.neon
Normal file
@ -0,0 +1,73 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: '#^Method pocketmine\\network\\mcpe\\convert\\BlockStateDictionary\:\:loadPaletteFromString\(\) should return list\<pocketmine\\data\\bedrock\\block\\BlockStateData\> but returns array\<pocketmine\\data\\bedrock\\block\\BlockStateData\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/convert/BlockStateDictionary.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#3 \$entityNBT of class pocketmine\\world\\format\\io\\ChunkData constructor expects list\<pocketmine\\nbt\\tag\\CompoundTag\>, array\<pocketmine\\nbt\\tag\\CompoundTag\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/io/leveldb/LevelDB.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#4 \$tileNBT of class pocketmine\\world\\format\\io\\ChunkData constructor expects list\<pocketmine\\nbt\\tag\\CompoundTag\>, array\<pocketmine\\nbt\\tag\\CompoundTag\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/io/leveldb/LevelDB.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of static method pocketmine\\world\\format\\io\\ChunkUtils\:\:convertBiomeColors\(\) expects list\<int\>, array\<int\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/io/region/Anvil.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of static method pocketmine\\world\\format\\io\\ChunkUtils\:\:convertBiomeColors\(\) expects list\<int\>, array\<int\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/io/region/McRegion.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of static method pocketmine\\world\\format\\io\\ChunkUtils\:\:convertBiomeColors\(\) expects list\<int\>, array\<int\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/io/region/PMAnvil.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$oldNewStateList of function pocketmine\\tools\\blockstate_upgrade_schema_utils\\buildUpgradeTableFromData expects list\<pocketmine\\nbt\\TreeRoot\>, array\<pocketmine\\nbt\\TreeRoot\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../tools/blockstate-upgrade-schema-utils.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$input of class pocketmine\\crafting\\json\\ShapelessRecipeData constructor expects list\<pocketmine\\crafting\\json\\RecipeIngredientData\>, array\<pocketmine\\crafting\\json\\RecipeIngredientData\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../tools/generate-bedrock-data-from-packets.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#2 \$output of class pocketmine\\crafting\\json\\ShapelessRecipeData constructor expects list\<pocketmine\\crafting\\json\\ItemStackData\>, array\<pocketmine\\crafting\\json\\ItemStackData\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../tools/generate-bedrock-data-from-packets.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#3 \$output of class pocketmine\\crafting\\json\\ShapedRecipeData constructor expects list\<pocketmine\\crafting\\json\\ItemStackData\>, array\<pocketmine\\crafting\\json\\ItemStackData\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../tools/generate-bedrock-data-from-packets.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#5 \$unlockingIngredients of class pocketmine\\crafting\\json\\ShapelessRecipeData constructor expects list\<pocketmine\\crafting\\json\\RecipeIngredientData\>, array\<pocketmine\\crafting\\json\\RecipeIngredientData\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../tools/generate-bedrock-data-from-packets.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#6 \$unlockingIngredients of class pocketmine\\crafting\\json\\ShapedRecipeData constructor expects list\<pocketmine\\crafting\\json\\RecipeIngredientData\>, array\<pocketmine\\crafting\\json\\RecipeIngredientData\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../tools/generate-bedrock-data-from-packets.php
|
@ -1,12 +1,14 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Method pocketmine\\\\event\\\\RegisteredListener\\:\\:__construct\\(\\) has parameter \\$handler with no signature specified for Closure\\.$#"
|
||||
message: '#^Method pocketmine\\event\\RegisteredListener\:\:__construct\(\) has parameter \$handler with no signature specified for Closure\.$#'
|
||||
identifier: missingType.callable
|
||||
count: 1
|
||||
path: ../../../src/event/RegisteredListener.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\event\\\\RegisteredListener\\:\\:getHandler\\(\\) return type has no signature specified for Closure\\.$#"
|
||||
message: '#^Method pocketmine\\event\\RegisteredListener\:\:getHandler\(\) return type has no signature specified for Closure\.$#'
|
||||
identifier: missingType.callable
|
||||
count: 1
|
||||
path: ../../../src/event/RegisteredListener.php
|
||||
|
||||
|
@ -1,112 +1,260 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Method pocketmine\\\\block\\\\DoubleTallGrass\\:\\:traitGetDropsForIncompatibleTool\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||
message: '#^Access to an undefined property object\:\:\$crashId\.$#'
|
||||
identifier: property.notFound
|
||||
count: 1
|
||||
path: ../../../src/Server.php
|
||||
|
||||
-
|
||||
message: '#^Access to an undefined property object\:\:\$crashUrl\.$#'
|
||||
identifier: property.notFound
|
||||
count: 1
|
||||
path: ../../../src/Server.php
|
||||
|
||||
-
|
||||
message: '#^Access to an undefined property object\:\:\$error\.$#'
|
||||
identifier: property.notFound
|
||||
count: 1
|
||||
path: ../../../src/Server.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\block\\Block\:\:readStateFromWorld\(\) is marked as impure but does not have any side effects\.$#'
|
||||
identifier: impureMethod.pure
|
||||
count: 1
|
||||
path: ../../../src/block/Block.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\block\\DoubleTallGrass\:\:traitGetDropsForIncompatibleTool\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: ../../../src/block/DoubleTallGrass.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:ACACIA_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:ACACIA_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:BIRCH_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:BIRCH_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:CHERRY_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:CHERRY_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:CRIMSON_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:CRIMSON_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:DARK_OAK_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:DARK_OAK_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:JUNGLE_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:JUNGLE_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:MANGROVE_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:MANGROVE_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:OAK_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:OAK_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:PALE_OAK_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:PALE_OAK_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:SPRUCE_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:SPRUCE_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Creating callable from a non\\-native static method pocketmine\\\\item\\\\VanillaItems\\:\\:WARPED_SIGN\\(\\)\\.$#"
|
||||
message: '#^Creating callable from a non\-native static method pocketmine\\item\\VanillaItems\:\:WARPED_SIGN\(\)\.$#'
|
||||
identifier: callable.nonNativeMethod
|
||||
count: 1
|
||||
path: ../../../src/block/VanillaBlocks.php
|
||||
|
||||
-
|
||||
message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#"
|
||||
message: '#^Strict comparison using \=\=\= between \*NEVER\* and 5 will always evaluate to false\.$#'
|
||||
identifier: identical.alwaysFalse
|
||||
count: 1
|
||||
path: ../../../src/command/defaults/TeleportCommand.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\crafting\\ShapedRecipe\:\:getIngredientMap\(\) should return list\<list\<pocketmine\\crafting\\RecipeIngredient\|null\>\> but returns array\<int\<0, max\>, non\-empty\-array\<int\<0, max\>, pocketmine\\crafting\\RecipeIngredient\|null\>\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../src/crafting/ShapedRecipe.php
|
||||
|
||||
-
|
||||
message: '#^Property pocketmine\\crash\\CrashDumpData\:\:\$parameters \(list\<string\>\) does not accept array\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 1
|
||||
path: ../../../src/crash/CrashDump.php
|
||||
|
||||
-
|
||||
message: '#^Call to function assert\(\) with false and ''unknown hit type'' will always evaluate to false\.$#'
|
||||
identifier: function.impossibleType
|
||||
count: 1
|
||||
path: ../../../src/entity/projectile/Projectile.php
|
||||
|
||||
-
|
||||
message: "#^Property pocketmine\\\\network\\\\mcpe\\\\raklib\\\\PthreadsChannelWriter\\:\\:\\$buffer is never read, only written\\.$#"
|
||||
message: '#^Property pocketmine\\item\\WritableBookBase\:\:\$pages \(list\<pocketmine\\item\\WritableBookPage\>\) does not accept non\-empty\-array\<int, pocketmine\\item\\WritableBookPage\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 1
|
||||
path: ../../../src/item/WritableBookBase.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\network\\mcpe\\compression\\ZlibCompressor\:\:getNetworkId\(\) never returns 1 so it can be removed from the return type\.$#'
|
||||
identifier: return.unusedType
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/compression/ZlibCompressor.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\network\\mcpe\\compression\\ZlibCompressor\:\:getNetworkId\(\) never returns 255 so it can be removed from the return type\.$#'
|
||||
identifier: return.unusedType
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/compression/ZlibCompressor.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$states of class pocketmine\\network\\mcpe\\convert\\BlockStateDictionary constructor expects list\<pocketmine\\network\\mcpe\\convert\\BlockStateDictionaryEntry\>, array\<int\<0, max\>, pocketmine\\network\\mcpe\\convert\\BlockStateDictionaryEntry\> given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/convert/BlockStateDictionary.php
|
||||
|
||||
-
|
||||
message: '#^Cannot access offset ''default'' on mixed\.$#'
|
||||
identifier: offsetAccess.nonOffsetAccessible
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/convert/LegacySkinAdapter.php
|
||||
|
||||
-
|
||||
message: '#^Property pocketmine\\network\\mcpe\\raklib\\PthreadsChannelWriter\:\:\$buffer is never read, only written\.$#'
|
||||
identifier: property.onlyWritten
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/raklib/PthreadsChannelWriter.php
|
||||
|
||||
-
|
||||
message: "#^Property pocketmine\\\\network\\\\mcpe\\\\raklib\\\\SnoozeAwarePthreadsChannelWriter\\:\\:\\$buffer is never read, only written\\.$#"
|
||||
message: '#^Property pocketmine\\network\\mcpe\\raklib\\SnoozeAwarePthreadsChannelWriter\:\:\$buffer is never read, only written\.$#'
|
||||
identifier: property.onlyWritten
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/raklib/SnoozeAwarePthreadsChannelWriter.php
|
||||
|
||||
-
|
||||
message: "#^Dead catch \\- RuntimeException is never thrown in the try block\\.$#"
|
||||
message: '#^Dead catch \- RuntimeException is never thrown in the try block\.$#'
|
||||
identifier: catch.neverThrown
|
||||
count: 1
|
||||
path: ../../../src/plugin/PluginManager.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\timings\\\\TimingsHandler\\:\\:lazyGetSet\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\<T of object\\> but returns pocketmine\\\\utils\\\\ObjectSet\\<object\\>\\.$#"
|
||||
message: '#^Binary operation "\." between mixed and ''/''\|''\\\\'' results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 1
|
||||
path: ../../../src/thread/ThreadSafeClassLoader.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "\." between mixed and non\-falsy\-string results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 1
|
||||
path: ../../../src/thread/ThreadSafeClassLoader.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\timings\\TimingsHandler\:\:lazyGetSet\(\) should return pocketmine\\utils\\ObjectSet\<T of object\> but returns pocketmine\\utils\\ObjectSet\<object\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../src/timings/TimingsHandler.php
|
||||
|
||||
-
|
||||
message: "#^Casting to int something that's already int\\.$#"
|
||||
message: '#^Parameter &\$where @param\-out type of method pocketmine\\timings\\TimingsHandler\:\:lazyGetSet\(\) expects pocketmine\\utils\\ObjectSet\<T of object\>, pocketmine\\utils\\ObjectSet\<object\> given\.$#'
|
||||
identifier: paramOut.type
|
||||
count: 1
|
||||
path: ../../../src/timings/TimingsHandler.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "\*" between mixed and 3600 results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 1
|
||||
path: ../../../src/utils/Timezone.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "\*" between mixed and 60 results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 1
|
||||
path: ../../../src/utils/Timezone.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "\+" between \(float\|int\) and mixed results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 1
|
||||
path: ../../../src/utils/Timezone.php
|
||||
|
||||
-
|
||||
message: '#^Property pocketmine\\world\\format\\io\\region\\RegionLoader\:\:\$locationTable \(list\<pocketmine\\world\\format\\io\\region\\RegionLocationTableEntry\|null\>\) does not accept non\-empty\-array\<int, pocketmine\\world\\format\\io\\region\\RegionLocationTableEntry\|null\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 2
|
||||
path: ../../../src/world/format/io/region/RegionLoader.php
|
||||
|
||||
-
|
||||
message: '#^Property pocketmine\\world\\format\\io\\region\\RegionLoader\:\:\$locationTable \(list\<pocketmine\\world\\format\\io\\region\\RegionLocationTableEntry\|null\>\) does not accept non\-empty\-array\<int\<0, max\>, pocketmine\\world\\format\\io\\region\\RegionLocationTableEntry\|null\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 3
|
||||
path: ../../../src/world/format/io/region/RegionLoader.php
|
||||
|
||||
-
|
||||
message: '#^Method pocketmine\\world\\format\\io\\region\\RegionWorldProvider\:\:createRegionIterator\(\) should return RegexIterator\<mixed, string, FilesystemIterator\> but returns RegexIterator\<mixed, mixed, Traversable\<TKey, TValue\>\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/io/region/RegionWorldProvider.php
|
||||
|
||||
-
|
||||
message: '#^Casting to int something that''s already int\.$#'
|
||||
identifier: cast.useless
|
||||
count: 1
|
||||
path: ../../../src/world/generator/normal/Normal.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertFalse\\(\\) with false will always evaluate to true\\.$#"
|
||||
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertFalse\(\) with false will always evaluate to true\.$#'
|
||||
identifier: staticMethod.alreadyNarrowedType
|
||||
count: 1
|
||||
path: ../../phpunit/promise/PromiseTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertTrue\\(\\) with false and 'All promise should…' will always evaluate to false\\.$#"
|
||||
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertTrue\(\) with false and ''All promise should…'' will always evaluate to false\.$#'
|
||||
identifier: staticMethod.impossibleType
|
||||
count: 1
|
||||
path: ../../phpunit/promise/PromiseTest.php
|
||||
|
||||
-
|
||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertTrue\\(\\) with false will always evaluate to false\\.$#"
|
||||
message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertTrue\(\) with false will always evaluate to false\.$#'
|
||||
identifier: staticMethod.impossibleType
|
||||
count: 2
|
||||
path: ../../phpunit/promise/PromiseTest.php
|
||||
|
||||
-
|
||||
message: "#^Strict comparison using \\=\\=\\= between 0 and 0 will always evaluate to true\\.$#"
|
||||
message: '#^Strict comparison using \=\=\= between 0 and 0 will always evaluate to true\.$#'
|
||||
identifier: identical.alwaysTrue
|
||||
count: 1
|
||||
path: ../rules/UnsafeForeachArrayOfStringRule.php
|
||||
|
||||
|
@ -1,22 +1,32 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Cannot call method collectGarbage\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#"
|
||||
message: '#^Cannot call method collectGarbage\(\) on pocketmine\\world\\format\\SubChunk\|null\.$#'
|
||||
identifier: method.nonObject
|
||||
count: 1
|
||||
path: ../../../src/world/format/Chunk.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunks\\(\\) should return array\\<int, pocketmine\\\\world\\\\format\\\\SubChunk\\> but returns array\\<int, pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\>\\.$#"
|
||||
message: '#^Method pocketmine\\world\\format\\Chunk\:\:getSubChunks\(\) should return array\<int, pocketmine\\world\\format\\SubChunk\> but returns array\<int, pocketmine\\world\\format\\SubChunk\|null\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/Chunk.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\)\\: mixed\\)\\|null, Closure\\(pocketmine\\\\world\\\\format\\\\SubChunk\\)\\: pocketmine\\\\world\\\\format\\\\SubChunk given\\.$#"
|
||||
message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(pocketmine\\world\\format\\SubChunk\|null\)\: mixed\)\|null, Closure\(pocketmine\\world\\format\\SubChunk\)\: pocketmine\\world\\format\\SubChunk given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/Chunk.php
|
||||
|
||||
-
|
||||
message: "#^Method pocketmine\\\\world\\\\format\\\\HeightArray\\:\\:getValues\\(\\) should return non\\-empty\\-array\\<int, int\\> but returns array\\<int, int\\|null\\>\\.$#"
|
||||
message: '#^Method pocketmine\\world\\format\\HeightArray\:\:getValues\(\) should return non\-empty\-list\<int\> but returns array\<int, int\|null\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../../../src/world/format/HeightArray.php
|
||||
|
||||
-
|
||||
message: '#^Offset int might not exist on SplFixedArray\<float\>\|null\.$#'
|
||||
identifier: offsetAccess.notFound
|
||||
count: 4
|
||||
path: ../../../src/world/generator/noise/Noise.php
|
||||
|
||||
|
@ -28,7 +28,6 @@ use PhpParser\Node\Expr\StaticCall;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use pocketmine\utils\LegacyEnumShimTrait;
|
||||
use function sprintf;
|
||||
|
||||
@ -51,18 +50,15 @@ final class DeprecatedLegacyEnumAccessRule implements Rule{
|
||||
$scope->resolveTypeByName($node->class) :
|
||||
$scope->getType($node->class);
|
||||
|
||||
if(!$classType instanceof TypeWithClassName){
|
||||
return [];
|
||||
}
|
||||
$errors = [];
|
||||
$reflections = $classType->getObjectClassReflections();
|
||||
foreach($reflections as $reflection){
|
||||
if(!$reflection->hasTraitUse(LegacyEnumShimTrait::class) || !$reflection->implementsInterface(\UnitEnum::class)){
|
||||
continue;
|
||||
}
|
||||
|
||||
$reflection = $classType->getClassReflection();
|
||||
if($reflection === null || !$reflection->hasTraitUse(LegacyEnumShimTrait::class) || !$reflection->implementsInterface(\UnitEnum::class)){
|
||||
return [];
|
||||
}
|
||||
|
||||
if(!$reflection->hasNativeMethod($caseName)){
|
||||
return [
|
||||
RuleErrorBuilder::message(sprintf(
|
||||
if(!$reflection->hasNativeMethod($caseName)){
|
||||
$errors[] = RuleErrorBuilder::message(sprintf(
|
||||
'Use of legacy enum case accessor %s::%s().',
|
||||
$reflection->getName(),
|
||||
$caseName
|
||||
@ -70,10 +66,11 @@ final class DeprecatedLegacyEnumAccessRule implements Rule{
|
||||
'Access the enum constant directly instead (remove the brackets), e.g. %s::%s',
|
||||
$reflection->getName(),
|
||||
$caseName
|
||||
))->build()
|
||||
];
|
||||
))->identifier('pocketmine.enum.deprecatedAccessor')
|
||||
->build();
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use PHPStan\Type\VerbosityLevel;
|
||||
@ -61,7 +60,7 @@ class DisallowEnumComparisonRule implements Rule{
|
||||
$node instanceof Identical ? '===' : '!==',
|
||||
$leftType->describe(VerbosityLevel::value()),
|
||||
$rightType->describe(VerbosityLevel::value())
|
||||
))->build()];
|
||||
))->identifier('pocketmine.enum.badComparison')->build()];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@ -69,7 +68,7 @@ class DisallowEnumComparisonRule implements Rule{
|
||||
private function checkForEnumTypes(Type $comparedType) : bool{
|
||||
//TODO: what we really want to do here is iterate over the contained types, but there's no universal way to
|
||||
//do that. This might break with other circumstances.
|
||||
if($comparedType instanceof ObjectType){
|
||||
if($comparedType->isObject()->yes()){
|
||||
$types = [$comparedType];
|
||||
}elseif($comparedType instanceof UnionType){
|
||||
$types = $comparedType->getTypes();
|
||||
@ -77,12 +76,14 @@ class DisallowEnumComparisonRule implements Rule{
|
||||
return false;
|
||||
}
|
||||
foreach($types as $containedType){
|
||||
if(!($containedType instanceof ObjectType)){
|
||||
if(!($containedType->isObject()->yes())){
|
||||
continue;
|
||||
}
|
||||
$class = $containedType->getClassReflection();
|
||||
if($class !== null && $class->hasTraitUse(EnumTrait::class)){
|
||||
return true;
|
||||
$classes = $containedType->getObjectClassReflections();
|
||||
foreach($classes as $class){
|
||||
if($class->hasTraitUse(EnumTrait::class)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -44,6 +44,7 @@ final class DisallowForeachByReferenceRule implements Rule{
|
||||
return [
|
||||
RuleErrorBuilder::message("Foreach by-reference is not allowed, because it has surprising behaviour.")
|
||||
->tip("If the value variable is used outside of the foreach construct (e.g. in a second foreach), the iterable's contents will be unexpectedly altered.")
|
||||
->identifier('pocketmine.foreach.byRef')
|
||||
->build()
|
||||
];
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ final class UnsafeForeachArrayOfStringRule implements Rule{
|
||||
RuleErrorBuilder::message(sprintf(
|
||||
"Unsafe foreach on array with key type %s (they might be casted to int).",
|
||||
$iterableType->getIterableKeyType()->describe(VerbosityLevel::value())
|
||||
))->tip($tip)->build()
|
||||
))->tip($tip)->identifier('pocketmine.foreach.stringKeys')->build()
|
||||
];
|
||||
}
|
||||
return [];
|
||||
|
@ -23,6 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils\fixtures;
|
||||
|
||||
trait TestTrait{
|
||||
trait TestTrait{ // @phpstan-ignore trait.unused
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user