From a733f094ac6994cafed3e0577bac103ee7c87926 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jan 2020 19:45:05 +0000 Subject: [PATCH] phpstan: added a custom rule to disallow strict equality operators on enum members comparing enums with equality operators is unreliable because there is no guarantee that the enum objects won't be somehow duplicated, through serialization, cloning or ext-parallel dumb object copying. This means that two equal enum objects may not be thw same object. --- composer.json | 3 +- phpstan.neon.dist | 1 + .../rules/DisallowEnumComparisonRule.php | 67 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 tests/phpstan/rules/DisallowEnumComparisonRule.php diff --git a/composer.json b/composer.json index 174f5cf52..fd32dd01a 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,8 @@ }, "autoload-dev": { "psr-4": { - "pocketmine\\": "tests/phpunit/" + "pocketmine\\": "tests/phpunit/", + "pocketmine\\phpstan\\rules\\": "tests/phpstan/rules" } }, "repositories": [ diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 76ae2d5b0..a5e8645a5 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,6 +13,7 @@ parameters: - build/server-phar.php paths: - src + - tests/phpstan/rules - build/server-phar.php dynamicConstantNames: - pocketmine\IS_DEVELOPMENT_BUILD diff --git a/tests/phpstan/rules/DisallowEnumComparisonRule.php b/tests/phpstan/rules/DisallowEnumComparisonRule.php new file mode 100644 index 000000000..0e62fc96b --- /dev/null +++ b/tests/phpstan/rules/DisallowEnumComparisonRule.php @@ -0,0 +1,67 @@ +left, $node->right] as $n){ + $type = $scope->getType($n); + if(!($type instanceof ObjectType)){ + continue; + } + $class = $type->getClassReflection(); + if($class === null or !$class->hasTraitUse(EnumTrait::class)){ + continue; + } + $result[] = RuleErrorBuilder::message(sprintf( + 'Strict comparison using %s involving enum %s is not reliable.', + $node instanceof Identical ? '===' : '!==', + $type->describe(VerbosityLevel::value()) + ))->build(); + } + return $result; + } +} \ No newline at end of file