Skip to content

Commit 481e2da

Browse files
committed
NotEqualHandler
1 parent 2bef07e commit 481e2da

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser\Generator\ExprHandler;
4+
5+
use Generator;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\BinaryOp\Equal;
8+
use PhpParser\Node\Expr\BinaryOp\NotEqual;
9+
use PhpParser\Node\Expr\BooleanNot;
10+
use PhpParser\Node\Stmt;
11+
use PHPStan\Analyser\ExpressionContext;
12+
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
13+
use PHPStan\Analyser\Generator\ExprAnalysisResult;
14+
use PHPStan\Analyser\Generator\ExprHandler;
15+
use PHPStan\Analyser\Generator\GeneratorScope;
16+
use PHPStan\Analyser\SpecifiedTypes;
17+
use PHPStan\DependencyInjection\AutowiredService;
18+
19+
/**
20+
* @implements ExprHandler<NotEqual>
21+
*/
22+
#[AutowiredService]
23+
final class NotEqualHandler implements ExprHandler
24+
{
25+
26+
public function supports(Expr $expr): bool
27+
{
28+
return $expr instanceof NotEqual;
29+
}
30+
31+
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
32+
{
33+
$leftResult = yield new ExprAnalysisRequest($stmt, $expr->left, $scope, $context->enterDeep(), $alternativeNodeCallback);
34+
$rightResult = yield new ExprAnalysisRequest($stmt, $expr->right, $leftResult->scope, $context->enterDeep(), $alternativeNodeCallback);
35+
$booleanNotResult = yield ExprAnalysisRequest::createNoopRequest(new BooleanNot(new Equal($expr->left, $expr->right)), $scope);
36+
37+
return new ExprAnalysisResult(
38+
$booleanNotResult->type,
39+
$booleanNotResult->nativeType,
40+
$rightResult->scope,
41+
hasYield: $leftResult->hasYield || $rightResult->hasYield,
42+
isAlwaysTerminating: $leftResult->isAlwaysTerminating || $rightResult->isAlwaysTerminating,
43+
throwPoints: array_merge($leftResult->throwPoints, $rightResult->throwPoints),
44+
impurePoints: array_merge($leftResult->impurePoints, $rightResult->impurePoints),
45+
specifiedTruthyTypes: $booleanNotResult->specifiedTruthyTypes->setRootExpr($expr),
46+
specifiedFalseyTypes: $booleanNotResult->specifiedFalseyTypes->setRootExpr($expr),
47+
specifiedNullTypes: new SpecifiedTypes(),
48+
);
49+
}
50+
51+
}

tests/PHPStan/Analyser/Generator/data/gnsr.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,16 @@ function (mixed $m) {
542542
assertType('mixed', $m);
543543
};
544544

545+
function (mixed $m) {
546+
if ($m != 0) {
547+
assertType("mixed~(0|0.0|'0'|false|null)", $m);
548+
} else {
549+
assertType('0|0.0|string|false|null', $m);
550+
}
551+
552+
assertType('mixed', $m);
553+
};
554+
545555
function (mixed $m) {
546556
if ($m == '') {
547557
assertType("0|0.0|''|false|null", $m);
@@ -572,6 +582,16 @@ function (array $a): void {
572582
assertType("array", $a);
573583
};
574584

585+
function (array $a): void {
586+
if ($a != []) {
587+
assertType("non-empty-array", $a);
588+
} else {
589+
assertType("array{}", $a);
590+
}
591+
592+
assertType("array", $a);
593+
};
594+
575595
function (bool $b): void {
576596
assertType('true', !false);
577597
assertType('false', !true);

0 commit comments

Comments
 (0)