Skip to content

Commit 1cdd9ba

Browse files
herndlmondrejmirtes
authored andcommitted
Improve ConstantArrayType union performance
1 parent a29dc57 commit 1cdd9ba

File tree

3 files changed

+8
-54
lines changed

3 files changed

+8
-54
lines changed

src/Type/TypeCombinator.php

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use PHPStan\Type\Accessory\HasOffsetType;
77
use PHPStan\Type\Accessory\NonEmptyArrayType;
88
use PHPStan\Type\Constant\ConstantArrayType;
9-
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
109
use PHPStan\Type\Constant\ConstantBooleanType;
1110
use PHPStan\Type\Constant\ConstantFloatType;
1211
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -18,6 +17,7 @@
1817
use PHPStan\Type\Generic\TemplateUnionType;
1918
use function array_intersect_key;
2019
use function array_key_exists;
20+
use function array_map;
2121
use function array_merge;
2222
use function array_slice;
2323
use function array_splice;
@@ -556,56 +556,10 @@ private static function processArrayTypes(array $arrayTypes, array $accessoryTyp
556556
];
557557
}
558558

559-
/** @var ConstantArrayType[] $arrayTypes */
560-
$arrayTypes = $arrayTypes;
561-
562-
/** @var int[] $constantKeyTypesNumbered */
563-
$constantKeyTypesNumbered = $constantKeyTypesNumbered;
564-
565-
$constantArraysBuckets = [];
566-
foreach ($arrayTypes as $arrayTypeAgain) {
567-
$arrayIndex = 0;
568-
foreach ($arrayTypeAgain->getKeyTypes() as $keyType) {
569-
$arrayIndex += $constantKeyTypesNumbered[$keyType->getValue()];
570-
}
571-
572-
if (!array_key_exists($arrayIndex, $constantArraysBuckets)) {
573-
$bucket = [];
574-
foreach ($arrayTypeAgain->getKeyTypes() as $i => $keyType) {
575-
$bucket[$keyType->getValue()] = [
576-
'keyType' => $keyType,
577-
'valueType' => $arrayTypeAgain->getValueTypes()[$i],
578-
'optional' => $arrayTypeAgain->isOptionalKey($i),
579-
];
580-
}
581-
$constantArraysBuckets[$arrayIndex] = $bucket;
582-
continue;
583-
}
584-
585-
$bucket = $constantArraysBuckets[$arrayIndex];
586-
foreach ($arrayTypeAgain->getKeyTypes() as $i => $keyType) {
587-
$bucket[$keyType->getValue()]['valueType'] = self::union(
588-
$bucket[$keyType->getValue()]['valueType'],
589-
$arrayTypeAgain->getValueTypes()[$i],
590-
);
591-
$bucket[$keyType->getValue()]['optional'] = $bucket[$keyType->getValue()]['optional'] || $arrayTypeAgain->isOptionalKey($i);
592-
}
593-
594-
$constantArraysBuckets[$arrayIndex] = $bucket;
595-
}
596-
597-
$resultArrays = [];
598-
foreach ($constantArraysBuckets as $bucket) {
599-
$builder = ConstantArrayTypeBuilder::createEmpty();
600-
foreach ($bucket as $data) {
601-
$builder->setOffsetValueType($data['keyType'], $data['valueType'], $data['optional']);
602-
}
603-
604-
$arr = self::intersect($builder->getArray(), ...$accessoryTypes);
605-
$resultArrays[] = $arr;
606-
}
607-
608-
return self::reduceArrays($resultArrays);
559+
return array_map(
560+
static fn (Type $arrayType) => self::intersect($arrayType, ...$accessoryTypes),
561+
self::reduceArrays($arrayTypes),
562+
);
609563
}
610564

611565
/**

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8035,7 +8035,7 @@ public function dataArrayKeysInBranches(): array
80358035
{
80368036
return [
80378037
[
8038-
'array{i: int<1, max>, j: int, k: int<1, max>, key: DateTimeImmutable, l: 1, m: 5, n?: \'str\'}',
8038+
'array{i: int<1, max>, j: int, k: int<1, max>, l: 1, m: 5, key: DateTimeImmutable, n?: \'str\'}',
80398039
'$array',
80408040
],
80418041
[
@@ -9038,7 +9038,7 @@ public function dataGeneralizeScope(): array
90389038
{
90399039
return [
90409040
[
9041-
'array<non-empty-array<int|string, array{hitCount: int<0, max>, loadCount: int<0, max>, removeCount: int<0, max>, saveCount: int<0, max>}>>',
9041+
'array<non-empty-array<int|string, array{saveCount: int<0, max>, removeCount: int<0, max>, loadCount: int<0, max>, hitCount: int<0, max>}>>',
90429042
'$statistics',
90439043
],
90449044
];

tests/PHPStan/Type/TypeCombinatorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3967,7 +3967,7 @@ public function testSpecificUnionConstantArray(): void
39673967
}
39683968
$resultType = TypeCombinator::union(...$arrays);
39693969
$this->assertInstanceOf(ConstantArrayType::class, $resultType);
3970-
$this->assertSame('array{0: string, test?: string, 1?: string, 2?: string, 3?: string, 4?: string}', $resultType->describe(VerbosityLevel::precise()));
3970+
$this->assertSame('array{0: string, 1?: string, 2?: string, 3?: string, 4?: string, test?: string}', $resultType->describe(VerbosityLevel::precise()));
39713971
}
39723972

39733973
}

0 commit comments

Comments
 (0)