Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect always truthy/falsey conditions
- Loading branch information
1 parent
254a454
commit 689e956
Showing
54 changed files
with
1,050 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Comparison; | ||
|
||
use PHPStan\Type\Constant\ConstantBooleanType; | ||
|
||
class BooleanAndConstantConditionRule implements \PHPStan\Rules\Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return \PhpParser\Node\Expr\BinaryOp\BooleanAnd::class; | ||
} | ||
|
||
/** | ||
* @param \PhpParser\Node\Expr\BinaryOp\BooleanAnd $node | ||
* @param \PHPStan\Analyser\Scope $scope | ||
* @return string[] | ||
*/ | ||
public function processNode( | ||
\PhpParser\Node $node, | ||
\PHPStan\Analyser\Scope $scope | ||
): array | ||
{ | ||
$messages = []; | ||
$leftType = ConstantConditionRuleHelper::getBooleanType($scope, $node->left); | ||
if ($leftType instanceof ConstantBooleanType) { | ||
$messages[] = sprintf( | ||
'Left side of && is always %s.', | ||
$leftType->getValue() ? 'true' : 'false' | ||
); | ||
} | ||
|
||
$rightType = ConstantConditionRuleHelper::getBooleanType( | ||
$scope->filterByTruthyValue($node->left), | ||
$node->right | ||
); | ||
if ($rightType instanceof ConstantBooleanType) { | ||
$messages[] = sprintf( | ||
'Right side of && is always %s.', | ||
$rightType->getValue() ? 'true' : 'false' | ||
); | ||
} | ||
|
||
return $messages; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Comparison; | ||
|
||
use PHPStan\Type\Constant\ConstantBooleanType; | ||
|
||
class BooleanNotConstantConditionRule implements \PHPStan\Rules\Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return \PhpParser\Node\Expr\BooleanNot::class; | ||
} | ||
|
||
/** | ||
* @param \PhpParser\Node\Expr\BooleanNot $node | ||
* @param \PHPStan\Analyser\Scope $scope | ||
* @return string[] | ||
*/ | ||
public function processNode( | ||
\PhpParser\Node $node, | ||
\PHPStan\Analyser\Scope $scope | ||
): array | ||
{ | ||
$exprType = ConstantConditionRuleHelper::getBooleanType($scope, $node->expr); | ||
if ($exprType instanceof ConstantBooleanType) { | ||
return [ | ||
sprintf( | ||
'Negated boolean is always %s.', | ||
$exprType->getValue() ? 'false' : 'true' | ||
), | ||
]; | ||
} | ||
|
||
return []; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Comparison; | ||
|
||
use PHPStan\Type\Constant\ConstantBooleanType; | ||
|
||
class BooleanOrConstantConditionRule implements \PHPStan\Rules\Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return \PhpParser\Node\Expr\BinaryOp\BooleanOr::class; | ||
} | ||
|
||
/** | ||
* @param \PhpParser\Node\Expr\BinaryOp\BooleanOr $node | ||
* @param \PHPStan\Analyser\Scope $scope | ||
* @return string[] | ||
*/ | ||
public function processNode( | ||
\PhpParser\Node $node, | ||
\PHPStan\Analyser\Scope $scope | ||
): array | ||
{ | ||
$messages = []; | ||
$leftType = ConstantConditionRuleHelper::getBooleanType($scope, $node->left); | ||
if ($leftType instanceof ConstantBooleanType) { | ||
$messages[] = sprintf( | ||
'Left side of || is always %s.', | ||
$leftType->getValue() ? 'true' : 'false' | ||
); | ||
} | ||
|
||
$rightType = ConstantConditionRuleHelper::getBooleanType( | ||
$scope->filterByFalseyValue($node->left), | ||
$node->right | ||
); | ||
if ($rightType instanceof ConstantBooleanType) { | ||
$messages[] = sprintf( | ||
'Right side of || is always %s.', | ||
$rightType->getValue() ? 'true' : 'false' | ||
); | ||
} | ||
|
||
return $messages; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Comparison; | ||
|
||
use PhpParser\Node\Expr; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Type\BooleanType; | ||
|
||
class ConstantConditionRuleHelper | ||
{ | ||
|
||
public static function getBooleanType( | ||
Scope $scope, | ||
Expr $expr | ||
): BooleanType | ||
{ | ||
if ( | ||
$expr instanceof Expr\Instanceof_ | ||
|| $expr instanceof Expr\FuncCall | ||
|| $expr instanceof Expr\BinaryOp\Identical | ||
|| $expr instanceof Expr\BinaryOp\NotIdentical | ||
) { | ||
// already checked by different rules | ||
return new BooleanType(); | ||
} | ||
|
||
return $scope->getType($expr)->toBoolean(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Comparison; | ||
|
||
use PHPStan\Type\Constant\ConstantBooleanType; | ||
|
||
class ElseIfConstantConditionRule implements \PHPStan\Rules\Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return \PhpParser\Node\Stmt\ElseIf_::class; | ||
} | ||
|
||
/** | ||
* @param \PhpParser\Node\Stmt\ElseIf_ $node | ||
* @param \PHPStan\Analyser\Scope $scope | ||
* @return string[] | ||
*/ | ||
public function processNode( | ||
\PhpParser\Node $node, | ||
\PHPStan\Analyser\Scope $scope | ||
): array | ||
{ | ||
$exprType = ConstantConditionRuleHelper::getBooleanType($scope, $node->cond); | ||
if ($exprType instanceof ConstantBooleanType) { | ||
return [ | ||
sprintf( | ||
'Elseif condition is always %s.', | ||
$exprType->getValue() ? 'true' : 'false' | ||
), | ||
]; | ||
} | ||
|
||
return []; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Comparison; | ||
|
||
use PHPStan\Type\Constant\ConstantBooleanType; | ||
|
||
class IfConstantConditionRule implements \PHPStan\Rules\Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return \PhpParser\Node\Stmt\If_::class; | ||
} | ||
|
||
/** | ||
* @param \PhpParser\Node\Stmt\If_ $node | ||
* @param \PHPStan\Analyser\Scope $scope | ||
* @return string[] | ||
*/ | ||
public function processNode( | ||
\PhpParser\Node $node, | ||
\PHPStan\Analyser\Scope $scope | ||
): array | ||
{ | ||
$exprType = ConstantConditionRuleHelper::getBooleanType($scope, $node->cond); | ||
if ($exprType instanceof ConstantBooleanType) { | ||
return [ | ||
sprintf( | ||
'If condition is always %s.', | ||
$exprType->getValue() ? 'true' : 'false' | ||
), | ||
]; | ||
} | ||
|
||
return []; | ||
} | ||
|
||
} |
Oops, something went wrong.