Skip to content

Commit edfabec

Browse files
committed
Added specifying types to cast handlers
1 parent 481e2da commit edfabec

File tree

5 files changed

+66
-8
lines changed

5 files changed

+66
-8
lines changed

src/Analyser/Generator/ExprHandler/CastBoolHandler.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
use Generator;
66
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\BinaryOp\Equal;
8+
use PhpParser\Node\Expr\ConstFetch;
9+
use PhpParser\Node\Name\FullyQualified;
710
use PhpParser\Node\Stmt;
811
use PHPStan\Analyser\ExpressionContext;
912
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
@@ -35,6 +38,8 @@ public function analyseExpr(
3538
{
3639
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
3740

41+
$equalExprResult = yield ExprAnalysisRequest::createNoopRequest(new Equal($expr->expr, new ConstFetch(new FullyQualified('true'))), $scope);
42+
3843
return new ExprAnalysisResult(
3944
$exprResult->type->toBoolean(),
4045
$exprResult->nativeType->toBoolean(),
@@ -43,8 +48,8 @@ public function analyseExpr(
4348
isAlwaysTerminating: false,
4449
throwPoints: [],
4550
impurePoints: [],
46-
specifiedTruthyTypes: new SpecifiedTypes(),
47-
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedTruthyTypes: $equalExprResult->specifiedTruthyTypes->setRootExpr($expr),
52+
specifiedFalseyTypes: $equalExprResult->specifiedFalseyTypes->setRootExpr($expr),
4853
specifiedNullTypes: new SpecifiedTypes(),
4954
);
5055
}

src/Analyser/Generator/ExprHandler/CastDoubleHandler.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
use Generator;
66
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\BinaryOp\NotEqual;
8+
use PhpParser\Node\Scalar\Float_;
9+
use PhpParser\Node\Scalar\Int_ as ScalarInt;
710
use PhpParser\Node\Stmt;
811
use PHPStan\Analyser\ExpressionContext;
912
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
@@ -35,6 +38,8 @@ public function analyseExpr(
3538
{
3639
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
3740

41+
$notEqualExprResult = yield ExprAnalysisRequest::createNoopRequest(new NotEqual($expr->expr, new Float_(0)), $scope);
42+
3843
return new ExprAnalysisResult(
3944
$exprResult->type->toFloat(),
4045
$exprResult->nativeType->toFloat(),
@@ -43,8 +48,8 @@ public function analyseExpr(
4348
isAlwaysTerminating: false,
4449
throwPoints: [],
4550
impurePoints: [],
46-
specifiedTruthyTypes: new SpecifiedTypes(),
47-
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedTruthyTypes: $notEqualExprResult->specifiedTruthyTypes->setRootExpr($expr),
52+
specifiedFalseyTypes: $notEqualExprResult->specifiedFalseyTypes->setRootExpr($expr),
4853
specifiedNullTypes: new SpecifiedTypes(),
4954
);
5055
}

src/Analyser/Generator/ExprHandler/CastIntHandler.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use Generator;
66
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\BinaryOp\NotEqual;
78
use PhpParser\Node\Expr\Cast\Int_;
9+
use PhpParser\Node\Scalar\Int_ as ScalarInt;
810
use PhpParser\Node\Stmt;
911
use PHPStan\Analyser\ExpressionContext;
1012
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
@@ -36,6 +38,8 @@ public function analyseExpr(
3638
{
3739
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
3840

41+
$notEqualExprResult = yield ExprAnalysisRequest::createNoopRequest(new NotEqual($expr->expr, new ScalarInt(0)), $scope);
42+
3943
return new ExprAnalysisResult(
4044
$exprResult->type->toInteger(),
4145
$exprResult->nativeType->toInteger(),
@@ -44,8 +48,8 @@ public function analyseExpr(
4448
isAlwaysTerminating: false,
4549
throwPoints: [],
4650
impurePoints: [],
47-
specifiedTruthyTypes: new SpecifiedTypes(),
48-
specifiedFalseyTypes: new SpecifiedTypes(),
51+
specifiedTruthyTypes: $notEqualExprResult->specifiedTruthyTypes->setRootExpr($expr),
52+
specifiedFalseyTypes: $notEqualExprResult->specifiedFalseyTypes->setRootExpr($expr),
4953
specifiedNullTypes: new SpecifiedTypes(),
5054
);
5155
}

src/Analyser/Generator/ExprHandler/CastStringHandler.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Generator;
66
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\BinaryOp\NotEqual;
8+
use PhpParser\Node\Scalar\String_;
79
use PhpParser\Node\Stmt;
810
use PHPStan\Analyser\ExpressionContext;
911
use PHPStan\Analyser\Generator\ExprAnalysisRequest;
@@ -35,6 +37,8 @@ public function analyseExpr(
3537
{
3638
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
3739

40+
$notEqualExprResult = yield ExprAnalysisRequest::createNoopRequest(new NotEqual($expr->expr, new String_('')), $scope);
41+
3842
return new ExprAnalysisResult(
3943
$exprResult->type->toString(),
4044
$exprResult->nativeType->toString(),
@@ -43,8 +47,8 @@ public function analyseExpr(
4347
isAlwaysTerminating: false,
4448
throwPoints: [],
4549
impurePoints: [],
46-
specifiedTruthyTypes: new SpecifiedTypes(),
47-
specifiedFalseyTypes: new SpecifiedTypes(),
50+
specifiedTruthyTypes: $notEqualExprResult->specifiedTruthyTypes->setRootExpr($expr),
51+
specifiedFalseyTypes: $notEqualExprResult->specifiedFalseyTypes->setRootExpr($expr),
4852
specifiedNullTypes: new SpecifiedTypes(),
4953
);
5054
}

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,3 +597,43 @@ function (bool $b): void {
597597
assertType('false', !true);
598598
assertType('bool', !$b);
599599
};
600+
601+
function (mixed $m): void {
602+
if ((bool) $m) {
603+
assertType("mixed~(0|0.0|''|'0'|array{}|false|null)", $m);
604+
} else {
605+
assertType("0|0.0|''|'0'|array{}|false|null", $m);
606+
}
607+
608+
assertType("mixed", $m);
609+
};
610+
611+
function (mixed $m): void {
612+
if ((string) $m) {
613+
assertType("non-empty-array", $m);
614+
} else {
615+
assertType("non-empty-array", $m);
616+
}
617+
618+
assertType("mixed", $m);
619+
};
620+
621+
function (mixed $m): void {
622+
if ((int) $m) {
623+
assertType("non-empty-array", $m);
624+
} else {
625+
assertType("non-empty-array", $m);
626+
}
627+
628+
assertType("mixed", $m);
629+
};
630+
631+
function (mixed $m): void {
632+
if ((float) $m) {
633+
assertType("non-empty-array", $m);
634+
} else {
635+
assertType("non-empty-array", $m);
636+
}
637+
638+
assertType("mixed", $m);
639+
};

0 commit comments

Comments
 (0)