1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Merge pull request #7992 from AndrolGenhald/bugfix/7973

Fix class const issue when using floats declared in future consts (fixes #7973).
This commit is contained in:
orklah 2022-05-21 14:02:05 +02:00 committed by GitHub
commit b46fb1460d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 4 deletions

View File

@ -47,6 +47,7 @@ use Psalm\Type\Union;
use function array_diff_key;
use function array_values;
use function count;
use function get_class;
use function is_int;
use function is_numeric;
use function max;
@ -309,8 +310,8 @@ class ArithmeticOpAnalyzer
bool &$has_string_increment,
Union &$result_type = null
): ?Union {
if ($left_type_part instanceof TLiteralInt
&& $right_type_part instanceof TLiteralInt
if (($left_type_part instanceof TLiteralInt || $left_type_part instanceof TLiteralFloat)
&& ($right_type_part instanceof TLiteralInt || $right_type_part instanceof TLiteralFloat)
&& (
//we don't try to do arithmetics on variables in loops
$context === null
@ -318,6 +319,21 @@ class ArithmeticOpAnalyzer
|| (!$left instanceof PhpParser\Node\Expr\Variable && !$right instanceof PhpParser\Node\Expr\Variable)
)
) {
// get_class is fine here because both classes are final.
if ($statements_source !== null
&& $config->strict_binary_operands
&& get_class($left_type_part) !== get_class($right_type_part)
) {
IssueBuffer::maybeAdd(
new InvalidOperand(
'Cannot process numeric types together in strict operands mode, '.
'please cast explicitly',
new CodeLocation($statements_source, $parent)
),
$statements_source->getSuppressedIssues()
);
}
// time for some arithmetic!
$calculated_type = self::arithmeticOperation(
$parent,

View File

@ -712,7 +712,6 @@ class ClassConstAnalyzer
"{$class_storage->name}::{$const->name->name}"
),
$const_storage->suppressed_issues,
true
);
}
}

View File

@ -191,7 +191,7 @@ class BinaryOperationTest extends TestCase
$this->analyzeFile('somefile.php', new Context());
}
public function testDifferingNumericTypesAdditionInStrictMode(): void
public function testDifferingNumericLiteralTypesAdditionInStrictMode(): void
{
$config = Config::getInstance();
$config->strict_binary_operands = true;
@ -208,6 +208,25 @@ class BinaryOperationTest extends TestCase
$this->analyzeFile('somefile.php', new Context());
}
public function testDifferingNumericTypesAdditionInStrictMode(): void
{
$config = Config::getInstance();
$config->strict_binary_operands = true;
$this->addFile(
'somefile.php',
'<?php
/** @var float */
$b = 4.1;
$a = 5 + $b;'
);
$this->expectException(CodeException::class);
$this->expectExceptionMessage('InvalidOperand');
$this->analyzeFile('somefile.php', new Context());
}
public function testConcatenationWithNumberInStrictMode(): void
{
$config = Config::getInstance();
@ -852,6 +871,12 @@ class BinaryOperationTest extends TestCase
return 1;
}',
],
'calculateLiteralResultForFloats' => [
'code' => '<?php
$foo = 1.0 + 2.0;
',
'assertions' => ['$foo===' => 'float(3)'],
],
];
}

View File

@ -1419,6 +1419,15 @@ class ConstantTest extends TestCase
interface Bar extends Foo {}
',
],
'classConstsUsingFutureFloatDeclarationWithMultipleLevels' => [
'code' => '<?php
class Foo {
public const BAZ = self::BAR + 1.0;
public const BAR = self::FOO + 1.0;
public const FOO = 1.0;
}
',
],
];
}