Skip to content

Commit

Permalink
Fix Psalm self-issues
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Jan 18, 2022
1 parent 5c70cae commit 284c23a
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
Expand Up @@ -779,8 +779,10 @@ public static function processFunctionCall(
$class_string_type = new TClassString();
if ($class_exists_check_type === 1) {
$class_string_type->is_loaded = true;
$if_types[$first_var_name] = [[new IsIdentical($class_string_type)]];
} else {
$if_types[$first_var_name] = [[new IsType($class_string_type)]];
}
$if_types[$first_var_name] = [[new IsType($class_string_type)]];
}
} elseif ($class_exists_check_type = self::hasTraitExistsCheck($expr)) {
if ($first_var_name) {
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Type/NegatedAssertionReconciler.php
Expand Up @@ -182,7 +182,7 @@ public static function reconcile(
$existing_var_type->removeType('array-key');
$existing_var_type->addType(new TString);
} elseif ($assertion instanceof IsClassNotEqual) {
$assertion_type = Atomic::create($assertion->type);
// do nothing
} elseif ($existing_var_type->isSingle()
&& $existing_var_type->hasNamedObjectType()
&& $assertion_type instanceof TNamedObject
Expand Down
3 changes: 3 additions & 0 deletions src/Psalm/Internal/Type/TypeCombination.php
Expand Up @@ -38,6 +38,9 @@ class TypeCombination
/** @var array<int, bool>|null */
public $array_counts = [];

/** @var array<int, bool>|null */
public $array_min_counts = [];

/** @var bool */
public $array_sometimes_filled = false;

Expand Down
36 changes: 36 additions & 0 deletions src/Psalm/Internal/Type/TypeCombiner.php
Expand Up @@ -545,6 +545,14 @@ private static function scrapeTypeProperties(
}
}

if ($combination->array_min_counts !== null) {
if ($type->min_count === null) {
$combination->array_min_counts = null;
} else {
$combination->array_min_counts[$type->min_count] = true;
}
}

$combination->array_sometimes_filled = true;
} else {
$combination->array_always_filled = false;
Expand Down Expand Up @@ -586,6 +594,14 @@ private static function scrapeTypeProperties(
}
}

if ($combination->array_min_counts !== null) {
if ($type->min_count === null) {
$combination->array_min_counts = null;
} else {
$combination->array_min_counts[$type->min_count] = true;
}
}

$combination->array_sometimes_filled = true;
} else {
$combination->array_always_filled = false;
Expand Down Expand Up @@ -717,6 +733,16 @@ private static function scrapeTypeProperties(
$combination->array_counts[count($type->properties)] = true;
}

if ($combination->array_min_counts !== null) {
$min_prop_count = count(
array_filter(
$type->properties,
fn($p) => $p->possibly_undefined
)
);
$combination->array_min_counts[$min_prop_count] = true;
}

foreach ($possibly_undefined_entries as $possibly_undefined_type) {
$possibly_undefined_type->possibly_undefined = true;
}
Expand Down Expand Up @@ -1483,6 +1509,11 @@ private static function getArrayTypeFromGenericParams(
/** @psalm-suppress PropertyTypeCoercion */
$array_type->count = array_keys($combination->array_counts)[0];
}

if ($combination->array_min_counts) {
/** @psalm-suppress PropertyTypeCoercion */
$array_type->min_count = min(array_keys($combination->array_min_counts));
}
}
} else {
$array_type = new TNonEmptyArray($generic_type_params);
Expand All @@ -1491,6 +1522,11 @@ private static function getArrayTypeFromGenericParams(
/** @psalm-suppress PropertyTypeCoercion */
$array_type->count = array_keys($combination->array_counts)[0];
}

if ($combination->array_min_counts) {
/** @psalm-suppress PropertyTypeCoercion */
$array_type->min_count = min(array_keys($combination->array_min_counts));
}
}
} else {
if ($combination->all_arrays_class_string_maps
Expand Down
24 changes: 24 additions & 0 deletions tests/ArrayAccessTest.php
Expand Up @@ -317,6 +317,30 @@ function bar(array $list) : void {
$this->analyzeFile('somefile.php', new Context());
}

public function testCountOnKeyedArrayInRangeWithUpdate(): void
{
Config::getInstance()->ensure_array_int_offsets_exist = true;

$this->addFile(
'somefile.php',
'<?php
/** @param non-empty-list<string> $list */
function bar(array $list) : void {
if (rand(0, 1)) {
$list = ["a"];
}
if (count($list) > 1) {
if ($list[1][0] === "a") {
$list[1] = "foo";
}
echo $list[1];
}
}'
);

$this->analyzeFile('somefile.php', new Context());
}

public function testCountOnKeyedArrayOutOfRange(): void
{
Config::getInstance()->ensure_array_int_offsets_exist = true;
Expand Down

0 comments on commit 284c23a

Please sign in to comment.