|
7 | 7 | use InvalidArgumentException;
|
8 | 8 | use Psalm\CodeLocation;
|
9 | 9 | use Psalm\Codebase;
|
| 10 | +use Psalm\Internal\Type\TypeCombiner; |
10 | 11 | use Psalm\Internal\TypeVisitor\CanContainObjectTypeVisitor;
|
11 | 12 | use Psalm\Internal\TypeVisitor\ClasslikeReplacer;
|
12 | 13 | use Psalm\Internal\TypeVisitor\ContainsClassLikeVisitor;
|
|
16 | 17 | use Psalm\Internal\TypeVisitor\TypeScanner;
|
17 | 18 | use Psalm\StatementsSource;
|
18 | 19 | use Psalm\Storage\FileStorage;
|
| 20 | +use Psalm\Type; |
19 | 21 | use Psalm\Type\Atomic\TArray;
|
20 | 22 | use Psalm\Type\Atomic\TCallable;
|
21 | 23 | use Psalm\Type\Atomic\TClassString;
|
@@ -411,19 +413,59 @@ public function hasArray(): bool
|
411 | 413 | }
|
412 | 414 |
|
413 | 415 | /**
|
414 |
| - * @return list<(TArray|TKeyedArray)> |
| 416 | + * @return list<(TArray|TKeyedArray|TClassStringMap)> |
415 | 417 | */
|
416 | 418 | public function getArrays(): array
|
417 | 419 | {
|
418 | 420 | $result = [];
|
419 | 421 | foreach ($this->types as $t) {
|
420 |
| - if ($t instanceof TKeyedArray || $t instanceof TArray) { |
| 422 | + if ($t instanceof TKeyedArray || $t instanceof TArray || $t instanceof TClassStringMap) { |
421 | 423 | $result []= $t;
|
422 | 424 | }
|
423 | 425 | }
|
424 | 426 | return $result;
|
425 | 427 | }
|
426 | 428 |
|
| 429 | + |
| 430 | + /** |
| 431 | + * @return list<Union> |
| 432 | + */ |
| 433 | + public function getArrayKeyTypes(): array |
| 434 | + { |
| 435 | + $result = []; |
| 436 | + foreach ($this->types as $t) { |
| 437 | + if ($t instanceof TKeyedArray) { |
| 438 | + $result []= $t->getGenericKeyType(); |
| 439 | + } elseif ($t instanceof TArray) { |
| 440 | + $result []= $t->type_params[0]; |
| 441 | + } elseif ($t instanceof TClassStringMap) { |
| 442 | + $result []= Type::getClassString($t->as_type?->value ?? 'object'); |
| 443 | + } |
| 444 | + } |
| 445 | + return $result; |
| 446 | + } |
| 447 | + |
| 448 | + /** |
| 449 | + * @return list<Union> |
| 450 | + */ |
| 451 | + public function getArrayValueTypes(): array |
| 452 | + { |
| 453 | + $result = []; |
| 454 | + foreach ($this->types as $t) { |
| 455 | + if ($t instanceof TKeyedArray) { |
| 456 | + $result []= $t->getGenericValueType(); |
| 457 | + } elseif ($t instanceof TArray) { |
| 458 | + $result []= $t->type_params[1]; |
| 459 | + } elseif ($t instanceof TClassStringMap) { |
| 460 | + if ($t->as_type) { |
| 461 | + $result []= new Union([$t->as_type]); |
| 462 | + } else { |
| 463 | + $result []= Type::getObject(); |
| 464 | + } |
| 465 | + } |
| 466 | + } |
| 467 | + return $result; |
| 468 | + } |
427 | 469 | /**
|
428 | 470 | * @psalm-mutation-free
|
429 | 471 | */
|
@@ -1090,6 +1132,7 @@ public function isArray(): bool
|
1090 | 1132 | foreach ($this->types as $t) {
|
1091 | 1133 | if (!$t instanceof TKeyedArray
|
1092 | 1134 | && !$t instanceof TArray
|
| 1135 | + && !$t instanceof TClassStringMap |
1093 | 1136 | ) {
|
1094 | 1137 | return false;
|
1095 | 1138 | }
|
|
0 commit comments