From 500ae8a0070a827b8042e79fa5f8066eba980d97 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 16 Dec 2022 15:21:28 +0100 Subject: [PATCH] more accessories --- src/Parser/OversizedConstantArrayVisitor.php | 19 +++++++++++-------- .../InitializerExprTypeResolver.php | 13 ++++++++----- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/Parser/OversizedConstantArrayVisitor.php b/src/Parser/OversizedConstantArrayVisitor.php index 890d4471a2a..c701bb5d1b2 100644 --- a/src/Parser/OversizedConstantArrayVisitor.php +++ b/src/Parser/OversizedConstantArrayVisitor.php @@ -12,6 +12,7 @@ use PhpParser\NodeVisitorAbstract; use PHPStan\Analyser\GetTypeHelper; use PHPStan\ShouldNotHappenException; +use PHPStan\Type\Accessory\AccessoryArrayListType; use PHPStan\Type\Accessory\NonEmptyArrayType; use PHPStan\Type\ArrayType; use PHPStan\Type\BenevolentUnionType; @@ -83,6 +84,7 @@ public function leaveNode(Node $node): ?Node */ private function inspectArrayItems(Array_ $node): void { + $isList = true; $valueType = []; $itemKeyTypes = []; @@ -96,6 +98,7 @@ private function inspectArrayItems(Array_ $node): void if ($key !== null) { $keyValue = $this->getValueFromExpr($key); $itemKeyTypes[gettype($keyValue)] = true; // de-duplicate values + $isList = false; } $value = $item->value; @@ -106,16 +109,16 @@ private function inspectArrayItems(Array_ $node): void throw new ShouldNotHappenException(); } + $types = []; + $types[] = new ArrayType($arrayTypes[0], $arrayTypes[1]); if (count($value->items) > 0) { - $valueType[] = TypeCombinator::intersect( - new ArrayType($arrayTypes[0], $arrayTypes[1]), - new NonEmptyArrayType(), - ); - - continue; + $types[] = new NonEmptyArrayType(); + } + if ($arrayTypes[2] === true) { + $types[] = new AccessoryArrayListType(); } - $valueType[] = new ArrayType($arrayTypes[0], $arrayTypes[1]); + $valueType[] = TypeCombinator::intersect(...$types); continue; } @@ -141,7 +144,7 @@ private function inspectArrayItems(Array_ $node): void $valueType[] = $type; } - $node->setAttribute(self::ARRAY_TYPES, [$keyType, TypeCombinator::union(...$valueType)]); + $node->setAttribute(self::ARRAY_TYPES, [$keyType, TypeCombinator::union(...$valueType), $isList]); } /** diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index 10eab4ac517..60469f787f1 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -446,11 +446,14 @@ public function getArrayType(Expr\Array_ $expr, callable $getTypeCallback): Type // degrade oversized constant arrays $oversizedArrayTypes = $expr->getAttribute(OversizedConstantArrayVisitor::ARRAY_TYPES); if (is_array($oversizedArrayTypes)) { - return TypeCombinator::intersect( - new ArrayType($oversizedArrayTypes[0], $oversizedArrayTypes[1]), - new NonEmptyArrayType(), - new OversizedArrayType() - ); + $types = []; + $types[] = new ArrayType($oversizedArrayTypes[0], $oversizedArrayTypes[1]); + $types[] = new NonEmptyArrayType(); + $types[] = new OversizedArrayType(); + if ($oversizedArrayTypes[2] === true) { + $types[] = new AccessoryArrayListType(); + } + return TypeCombinator::intersect(...$types); } $arrayBuilder = ConstantArrayTypeBuilder::createEmpty();