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:
commit
b46fb1460d
@ -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,
|
||||
|
@ -712,7 +712,6 @@ class ClassConstAnalyzer
|
||||
"{$class_storage->name}::{$const->name->name}"
|
||||
),
|
||||
$const_storage->suppressed_issues,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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)'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user