From b1fd8cf16871ec348d816a59c3f00bfcb29b7fa7 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 26 Oct 2025 10:21:46 +0100 Subject: [PATCH] Don't double negate --- src/Infection/TrinaryLogicMutator.php | 34 ++++++++++++++++++++- tests/Infection/TrinaryLogicMutatorTest.php | 16 ++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/Infection/TrinaryLogicMutator.php b/src/Infection/TrinaryLogicMutator.php index eb527a2..58e3ec9 100644 --- a/src/Infection/TrinaryLogicMutator.php +++ b/src/Infection/TrinaryLogicMutator.php @@ -5,12 +5,13 @@ use Infection\Mutator\Definition; use Infection\Mutator\Mutator; use Infection\Mutator\MutatorCategory; +use Infection\PhpParser\Visitor\ParentConnector; use LogicException; use PhpParser\Node; use function in_array; /** - * @implements Mutator + * @implements Mutator */ final class TrinaryLogicMutator implements Mutator { @@ -38,6 +39,18 @@ public function getName(): string public function canMutate(Node $node): bool { + if ($node instanceof Node\Expr\MethodCall) { + $parentNode = ParentConnector::getParent($node); + + if ($parentNode instanceof Node\Expr\BooleanNot) { + return false; + } + } + + if ($node instanceof Node\Expr\BooleanNot) { + $node = $node->expr; + } + if (!$node instanceof Node\Expr\MethodCall) { return false; } @@ -55,6 +68,25 @@ public function canMutate(Node $node): bool public function mutate(Node $node): iterable { + if ($node instanceof Node\Expr\BooleanNot) { + $node = $node->expr; + if (!$node instanceof Node\Expr\MethodCall) { + throw new LogicException(); + } + + if (!$node->name instanceof Node\Identifier) { + throw new LogicException(); + } + + if ($node->name->name === 'yes') { + yield new Node\Expr\MethodCall($node->var, 'no'); + } else { + yield new Node\Expr\MethodCall($node->var, 'yes'); + } + + return; + } + if (!$node->name instanceof Node\Identifier) { throw new LogicException(); } diff --git a/tests/Infection/TrinaryLogicMutatorTest.php b/tests/Infection/TrinaryLogicMutatorTest.php index 82414b6..c204545 100644 --- a/tests/Infection/TrinaryLogicMutatorTest.php +++ b/tests/Infection/TrinaryLogicMutatorTest.php @@ -78,6 +78,22 @@ public static function mutationsProvider(): iterable $trinary = \PHPStan\Type\IsSuperTypeOfResult::createYes(); !$trinary->no(); PHP +, + ]; + + yield 'It does not double negate' => [ + <<<'PHP' + yes(); + PHP +, + <<<'PHP' + no(); + PHP , ]; }