1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

array unpacking with strings

This commit is contained in:
orklah 2021-10-08 17:13:29 +02:00
parent d54032078d
commit 690c24f824
3 changed files with 21 additions and 33 deletions

View File

@ -488,29 +488,20 @@ class ArrayAnalyzer
if ($unpacked_atomic_type instanceof Type\Atomic\TKeyedArray) {
foreach ($unpacked_atomic_type->properties as $key => $property_value) {
if (\is_string($key)) {
if (IssueBuffer::accepts(
new DuplicateArrayKey(
'String keys are not supported in unpacked arrays',
new CodeLocation($statements_analyzer->getSource(), $item->value)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
return;
$new_offset = $key;
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TLiteralString($new_offset);
} else {
$new_offset = $array_creation_info->int_offset++;
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TLiteralInt($new_offset);
}
$new_int_offset = $array_creation_info->int_offset++;
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TLiteralInt($new_int_offset);
$array_creation_info->item_value_atomic_types = array_merge(
$array_creation_info->item_value_atomic_types,
array_values($property_value->getAtomicTypes())
);
$array_creation_info->array_keys[$new_int_offset] = true;
$array_creation_info->property_types[$new_int_offset] = $property_value;
$array_creation_info->array_keys[$new_offset] = true;
$array_creation_info->property_types[$new_offset] = $property_value;
}
} else {
$codebase = $statements_analyzer->getCodebase();
@ -529,15 +520,7 @@ class ArrayAnalyzer
$array_creation_info->can_create_objectlike = false;
if ($unpacked_atomic_type->type_params[0]->hasString()) {
if (IssueBuffer::accepts(
new DuplicateArrayKey(
'String keys are not supported in unpacked arrays',
new CodeLocation($statements_analyzer->getSource(), $item->value)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TString();
} elseif ($unpacked_atomic_type->type_params[0]->hasInt()) {
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TInt();
}

View File

@ -669,12 +669,7 @@ class SimpleTypeInferer
): bool {
foreach ($unpacked_array_type->getAtomicTypes() as $unpacked_atomic_type) {
if ($unpacked_atomic_type instanceof Type\Atomic\TKeyedArray) {
foreach ($unpacked_atomic_type->properties as $key => $property_value) {
if (\is_string($key)) {
// string keys are not supported in unpacked arrays
return false;
}
foreach ($unpacked_atomic_type->properties as $property_value) {
$new_int_offset = $array_creation_info->int_offset++;
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TLiteralInt($new_int_offset);
@ -694,8 +689,7 @@ class SimpleTypeInferer
$array_creation_info->can_create_objectlike = false;
if ($unpacked_atomic_type->type_params[0]->hasString()) {
// string keys are not supported in unpacked arrays
return false;
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TString();
}
if ($unpacked_atomic_type->type_params[0]->hasInt()) {

View File

@ -1234,6 +1234,17 @@ class ArrayAssignmentTest extends TestCase
'$arr3' => 'array{1: int, 2: int, 3: int, 4: int}',
]
],
'arraySpreadWithString' => [
'<?php
$x = [
"a" => 0,
...["a" => 1],
...["b" => 2]
];',
[
'$x' => 'array{a: 1, b: 2}',
]
],
'listPropertyAssignmentAfterIsset' => [
'<?php
class Collection {