Skip to content

Commit

Permalink
Find unnecessary ternary operators
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitriy Dymarchuk authored Sep 30, 2020
1 parent 334898a commit c5fa47c
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
7 changes: 7 additions & 0 deletions rules.neon
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ rules:
- PHPStan\Rules\VariableVariables\VariableStaticPropertyFetchRule
- PHPStan\Rules\VariableVariables\VariableVariablesRule

conditionalTags:
PHPStan\Rules\Operators\OperandsInTernaryOperatorRule:
phpstan.rules.rule: %featureToggles.bleedingEdge%

services:
-
class: PHPStan\Rules\Operators\OperandsInTernaryOperatorRule

-
class: PHPStan\Rules\BooleansInConditions\BooleanRuleHelper

Expand Down
39 changes: 39 additions & 0 deletions src/Rules/Operators/OperandsInTernaryOperatorRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Operators;

use PhpParser\Node;
use PhpParser\Node\Expr\Ternary;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Type\ConstantType;
use PHPStan\Type\VerbosityLevel;

/**
* @implements \PHPStan\Rules\Rule<\PhpParser\Node\Expr\Ternary>
*/
class OperandsInTernaryOperatorRule implements Rule
{

public function getNodeType(): string
{
return Ternary::class;
}

public function processNode(Node $node, Scope $scope): array
{
$ifType = $node->if === null ? $scope->getType($node->cond) : $scope->getType($node->if);
$elseType = $scope->getType($node->else);
if ($ifType instanceof ConstantType && $elseType instanceof ConstantType) {
if ($ifType->equals($elseType)) {
return [sprintf(
'If and else parts of ternary operator are equal (%s).',
$ifType->describe(VerbosityLevel::value())
)];
}
}

return [];
}

}
44 changes: 44 additions & 0 deletions tests/Rules/Operators/OperandsInTernaryOperatorRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Operators;

use PHPStan\Rules\Rule;

/**
* @extends \PHPStan\Testing\RuleTestCase<OperandsInTernaryOperatorRule>
*/
class OperandsInTernaryOperatorRuleTest extends \PHPStan\Testing\RuleTestCase
{

protected function getRule(): Rule
{
return new OperandsInTernaryOperatorRule();
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/operators.php'], [
[
'If and else parts of ternary operator are equal (true).',
113,
],
[
'If and else parts of ternary operator are equal (array()).',
118,
],
[
'If and else parts of ternary operator are equal (\'string_val\').',
119,
],
[
'If and else parts of ternary operator are equal (array(23, 24)).',
121,
],
[
'If and else parts of ternary operator are equal (array(1 => 1)).',
122,
],
]);
}

}
15 changes: 15 additions & 0 deletions tests/Rules/Operators/data/operators.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,18 @@ function (array $array, int $int, $mixed) {

explode($mixed, $mixed) + $int;
};

foo() ? true : true;
foo() ? true : null;
foo() ? $object : true;
foo() ? $object : false;
foo() ? $object : null;
foo() ? [] : [];
foo() ? 'string_val' : 'string_val';
foo() ? [23, 24] : [23, 25];
foo() ? [23, 24] : [23, 24];
foo() ? [1 => 1] : ['1' => 1];
foo() ? [1 => 1] : ['asd' => 1];
$object ?: $object;
foo() ? false : true;
foo() ? true : false;

0 comments on commit c5fa47c

Please sign in to comment.