1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 13:51:54 +01:00

Merge pull request #7696 from AndrolGenhald/improve-bool-to-int-cast

This commit is contained in:
Bruce Weirdan 2022-02-18 22:17:29 +02:00 committed by GitHub
commit 6a68287700
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 7 deletions

View File

@ -45,7 +45,6 @@ use Psalm\Type\Union;
use function array_merge;
use function array_pop;
use function array_values;
use function count;
use function get_class;
/**
@ -77,12 +76,26 @@ class CastAnalyzer
$valid_int_type = Type::getInt(false, (int)$maybe_type->getSingleStringLiteral()->value);
}
if (count($maybe_type->getAtomicTypes()) === 1
&& $maybe_type->getSingleAtomic() instanceof Type\Atomic\TBool) {
$valid_int_type = new Union([
new TLiteralInt(0),
new TLiteralInt(1),
]);
if ($maybe_type->hasBool()) {
$casted_type = clone $maybe_type;
if (isset($casted_type->getAtomicTypes()['bool'])) {
$casted_type->addType(new TLiteralInt(0));
$casted_type->addType(new TLiteralInt(1));
} else {
if (isset($casted_type->getAtomicTypes()['true'])) {
$casted_type->addType(new TLiteralInt(1));
}
if (isset($casted_type->getAtomicTypes()['false'])) {
$casted_type->addType(new TLiteralInt(0));
}
}
$casted_type->removeType('bool');
$casted_type->removeType('true');
$casted_type->removeType('false');
if ($casted_type->isInt()) {
$valid_int_type = $casted_type;
}
}
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {

47
tests/CastTest.php Normal file
View File

@ -0,0 +1,47 @@
<?php
namespace Psalm\Tests;
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;
class CastTest extends TestCase
{
use ValidCodeAnalysisTestTrait;
/**
* @return iterable<string,array{code:string,assertions?:array<string,string>,ignored_issues?:list<string>,php_version?:string}>
*/
public function providerValidCodeParse(): iterable
{
yield 'castFalseOrIntToInt' => [
'code' => '<?php
/** @var false|int<10, 20> */
$intOrFalse = 10;
$int = (int) $intOrFalse;
',
'assertions' => [
'$int===' => '0|int<10, 20>',
],
];
yield 'castTrueOrIntToInt' => [
'code' => '<?php
/** @var true|int<10, 20> */
$intOrTrue = 10;
$int = (int) $intOrTrue;
',
'assertions' => [
'$int===' => '1|int<10, 20>',
],
];
yield 'castBoolOrIntToInt' => [
'code' => '<?php
/** @var bool|int<10, 20> */
$intOrBool = 10;
$int = (int) $intOrBool;
',
'assertions' => [
'$int===' => '0|1|int<10, 20>',
],
];
}
}