mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix a false flag issue with InvalidConstantAssignmentValue being thrown for constants over a certain length. Usually happens with arrays or lists over 100+ entries in length.
Check if this type was defined via a dockblock or type hint otherwise the inferred type should always match the assigned type, and we don't even need to do additional checks There is an issue with constants over a certain length where additional values are added to fallback_params in the assigned_type but not in const_storage_type which causes a false flag for this error to appear. Usually happens with arrays/lists. Added two separate tests to cover both lists, and arrays to ensure this issue is fixed.
This commit is contained in:
parent
2b642804b7
commit
f553392454
@ -721,19 +721,27 @@ final class ClassConstAnalyzer
|
||||
|
||||
// Check assigned type matches docblock type
|
||||
if ($assigned_type = $statements_analyzer->node_data->getType($const->value)) {
|
||||
if ($const_storage->type !== null
|
||||
$const_storage_type = $const_storage->type;
|
||||
|
||||
if ($const_storage_type !== null
|
||||
&& $const_storage->stmt_location !== null
|
||||
&& $assigned_type !== $const_storage->type
|
||||
&& $assigned_type !== $const_storage_type
|
||||
// Check if this type was defined via a dockblock or type hint otherwise the inferred type
|
||||
// should always match the assigned type and we don't even need to do additional checks
|
||||
// There is an issue with constants over a certain length where additional values
|
||||
// are added to fallback_params in the assigned_type but not in const_storage_type
|
||||
// which causes a false flag for this error to appear. Usually happens with arrays
|
||||
&& ($const_storage_type->from_docblock || $const_storage_type->from_property)
|
||||
&& !UnionTypeComparator::isContainedBy(
|
||||
$statements_analyzer->getCodebase(),
|
||||
$assigned_type,
|
||||
$const_storage->type,
|
||||
$const_storage_type,
|
||||
)
|
||||
) {
|
||||
IssueBuffer::maybeAdd(
|
||||
new InvalidConstantAssignmentValue(
|
||||
"{$class_storage->name}::{$const->name->name} with declared type "
|
||||
. "{$const_storage->type->getId()} cannot be assigned type {$assigned_type->getId()}",
|
||||
. "{$const_storage_type->getId()} cannot be assigned type {$assigned_type->getId()}",
|
||||
$const_storage->stmt_location,
|
||||
"{$class_storage->name}::{$const->name->name}",
|
||||
),
|
||||
|
@ -824,6 +824,242 @@ class ConstantTest extends TestCase
|
||||
A::foo(2);
|
||||
A::foo(3);',
|
||||
],
|
||||
'tooLongArrayInvalidConstantAssignmentValueFalsePositiveWithArray' => [
|
||||
'code' => '<?php
|
||||
class TestInvalidConstantAssignmentValueFalsePositiveWithArray {
|
||||
const LOOKUP = [
|
||||
"00" => null,
|
||||
"01" => null,
|
||||
"02" => null,
|
||||
"03" => null,
|
||||
"04" => null,
|
||||
"05" => null,
|
||||
"06" => null,
|
||||
"07" => null,
|
||||
"08" => null,
|
||||
"09" => null,
|
||||
"10" => null,
|
||||
"11" => null,
|
||||
"12" => null,
|
||||
"13" => null,
|
||||
"14" => null,
|
||||
"15" => null,
|
||||
"16" => null,
|
||||
"17" => null,
|
||||
"18" => null,
|
||||
"19" => null,
|
||||
"20" => null,
|
||||
"21" => null,
|
||||
"22" => null,
|
||||
"23" => null,
|
||||
"24" => null,
|
||||
"25" => null,
|
||||
"26" => null,
|
||||
"27" => null,
|
||||
"28" => null,
|
||||
"29" => null,
|
||||
"30" => null,
|
||||
"31" => null,
|
||||
"32" => null,
|
||||
"33" => null,
|
||||
"34" => null,
|
||||
"35" => null,
|
||||
"36" => null,
|
||||
"37" => null,
|
||||
"38" => null,
|
||||
"39" => null,
|
||||
"40" => null,
|
||||
"41" => null,
|
||||
"42" => null,
|
||||
"43" => null,
|
||||
"44" => null,
|
||||
"45" => null,
|
||||
"46" => null,
|
||||
"47" => null,
|
||||
"48" => null,
|
||||
"49" => null,
|
||||
"50" => null,
|
||||
"51" => null,
|
||||
"52" => null,
|
||||
"53" => null,
|
||||
"54" => null,
|
||||
"55" => null,
|
||||
"56" => null,
|
||||
"57" => null,
|
||||
"58" => null,
|
||||
"59" => null,
|
||||
"60" => null,
|
||||
"61" => null,
|
||||
"62" => null,
|
||||
"63" => null,
|
||||
"64" => null,
|
||||
"65" => null,
|
||||
"66" => null,
|
||||
"67" => null,
|
||||
"68" => null,
|
||||
"69" => null,
|
||||
"70" => self::SUCCEED,
|
||||
"71" => self::FAIL,
|
||||
"72" => null,
|
||||
"73" => null,
|
||||
"74" => null,
|
||||
"75" => null,
|
||||
"76" => null,
|
||||
"77" => null,
|
||||
"78" => null,
|
||||
"79" => null,
|
||||
"80" => null,
|
||||
"81" => null,
|
||||
"82" => null,
|
||||
"83" => null,
|
||||
"84" => null,
|
||||
"85" => null,
|
||||
"86" => null,
|
||||
"87" => null,
|
||||
"88" => null,
|
||||
"89" => null,
|
||||
"90" => null,
|
||||
"91" => null,
|
||||
"92" => null,
|
||||
"93" => null,
|
||||
"94" => null,
|
||||
"95" => null,
|
||||
"96" => null,
|
||||
"97" => null,
|
||||
"98" => null,
|
||||
"99" => null,
|
||||
"100" => null,
|
||||
"101" => null,
|
||||
];
|
||||
|
||||
const SUCCEED = "SUCCEED";
|
||||
const FAIL = "FAIL";
|
||||
|
||||
public static function will_succeed(string $code) : bool {
|
||||
// Seems to fail when the array has over 100+ entries, and at least one value references
|
||||
// another constant from the same class (even nested)
|
||||
return (self::LOOKUP[$code] ?? null) === self::SUCCEED;
|
||||
}
|
||||
}',
|
||||
],
|
||||
'tooLongArrayInvalidConstantAssignmentValueFalsePositiveWithList' => [
|
||||
'code' => '<?php
|
||||
class TestInvalidConstantAssignmentValueFalsePositiveWithList {
|
||||
const LOOKUP = [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
self::SUCCEED,
|
||||
self::FAIL,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
];
|
||||
|
||||
const SUCCEED = "SUCCEED";
|
||||
const FAIL = "FAIL";
|
||||
|
||||
public static function will_succeed(int $code) : bool {
|
||||
// Seems to fail when the array has over 100+ entries, and at least one value references
|
||||
// another constant from the same class (even nested)
|
||||
return (self::LOOKUP[$code] ?? null) === self::SUCCEED;
|
||||
}
|
||||
}',
|
||||
],
|
||||
'valueOf' => [
|
||||
'code' => '<?php
|
||||
class A {
|
||||
|
Loading…
Reference in New Issue
Block a user