diff --git a/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php b/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php index fac42790..6644b3f9 100644 --- a/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php +++ b/src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php @@ -7,6 +7,10 @@ use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; +use PHPStan\Type\Constant\ConstantBooleanType; +use PHPStan\Type\StaticTypeFactory; +use PHPStan\Type\Type; +use PHPStan\Type\TypeCombinator; /** * @implements Rule @@ -25,6 +29,10 @@ public function processNode(Node $node, Scope $scope): array return []; } + if ($scope->getType($node->cond)->isSuperTypeOf($this->getNonBooleanFalseyType())->no()) { + return []; + } + return [ RuleErrorBuilder::message('Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.') ->identifier('ternary.shortNotAllowed') @@ -32,4 +40,18 @@ public function processNode(Node $node, Scope $scope): array ]; } + private function getNonBooleanFalseyType(): Type + { + static $falseyWithoutFalse; + + if ($falseyWithoutFalse === null) { + $falseyWithoutFalse = TypeCombinator::remove( + StaticTypeFactory::falsey(), + new ConstantBooleanType(false), + ); + } + + return $falseyWithoutFalse; + } + } diff --git a/tests/Rules/DisallowedConstructs/DisallowedShortTernaryRuleTest.php b/tests/Rules/DisallowedConstructs/DisallowedShortTernaryRuleTest.php index 3f3b944a..4c0f58a7 100644 --- a/tests/Rules/DisallowedConstructs/DisallowedShortTernaryRuleTest.php +++ b/tests/Rules/DisallowedConstructs/DisallowedShortTernaryRuleTest.php @@ -21,11 +21,43 @@ public function testRule(): void $this->analyse([__DIR__ . '/data/short-ternary.php'], [ [ 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', - 3, + 6, ], [ 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', - 4, + 7, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 13, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 14, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 31, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 32, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 37, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 38, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 49, + ], + [ + 'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.', + 50, ], ]); } diff --git a/tests/Rules/DisallowedConstructs/data/short-ternary.php b/tests/Rules/DisallowedConstructs/data/short-ternary.php index 1d5e9e1a..063e430a 100644 --- a/tests/Rules/DisallowedConstructs/data/short-ternary.php +++ b/tests/Rules/DisallowedConstructs/data/short-ternary.php @@ -1,5 +1,56 @@