Skip to content

Commit

Permalink
Revert support array-shapes in array_merge
Browse files Browse the repository at this point in the history
This reverts commit f21b218.
  • Loading branch information
ondrejmirtes committed Aug 30, 2021
1 parent d28f785 commit 53817aa
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 138 deletions.
53 changes: 11 additions & 42 deletions src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeUtils;
use PHPStan\Type\UnionType;

class ArrayMergeFunctionDynamicReturnTypeExtension implements \PHPStan\Type\DynamicFunctionReturnTypeExtension
{
Expand All @@ -30,63 +30,32 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,

$keyTypes = [];
$valueTypes = [];
$returnedArrayBuilder = ConstantArrayTypeBuilder::createEmpty();
$returnedArrayBuilderFilled = false;
$nonEmpty = false;
$offsetCount = 0;
foreach ($functionCall->args as $arg) {
$argType = $scope->getType($arg->value);

if ($arg->unpack) {
$argType = $argType->getIterableValueType();
}

$arrays = TypeUtils::getConstantArrays($argType);
if (count($arrays) > 0) {
foreach ($arrays as $constantArray) {
foreach ($constantArray->getKeyTypes() as $i => $keyType) {
$returnedArrayBuilderFilled = true;
$offsetCount++;
if ($offsetCount > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) {
$returnedArrayBuilder->degradeToGeneralArray();
}

$returnedArrayBuilder->setOffsetValueType(
is_numeric($keyType->getValue()) ? null : $keyType,
$constantArray->getValueTypes()[$i]
);
if ($argType instanceof UnionType) {
foreach ($argType->getTypes() as $innerType) {
$argType = $innerType;
}
}

} else {
$keyTypes[] = TypeUtils::generalizeType($argType->getIterableKeyType(), GeneralizePrecision::moreSpecific());
$valueTypes[] = $argType->getIterableValueType();
}

$keyTypes[] = TypeUtils::generalizeType($argType->getIterableKeyType(), GeneralizePrecision::moreSpecific());
$valueTypes[] = $argType->getIterableValueType();

if (!$argType->isIterableAtLeastOnce()->yes()) {
continue;
}

$nonEmpty = true;
}

if (count($keyTypes) > 0) {
$arrayType = new ArrayType(
TypeCombinator::union(...$keyTypes),
TypeCombinator::union(...$valueTypes)
);

if ($returnedArrayBuilderFilled) {
$arrayType = TypeCombinator::union($returnedArrayBuilder->getArray(), $arrayType);
}
} elseif ($returnedArrayBuilderFilled) {
$arrayType = $returnedArrayBuilder->getArray();
} else {
$arrayType = new ArrayType(
TypeCombinator::union(...$keyTypes),
TypeCombinator::union(...$valueTypes)
);
}
$arrayType = new ArrayType(
TypeCombinator::union(...$keyTypes),
TypeCombinator::union(...$valueTypes)
);

if ($nonEmpty) {
$arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType());
Expand Down
25 changes: 6 additions & 19 deletions tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5153,44 +5153,31 @@ public function dataArrayFunctions(): array
'array_values($generalStringKeys)',
],
[
"array('foo' => stdClass, 0 => stdClass)",
'array<int|non-empty-string, stdClass>&nonEmpty',
'array_merge($stringOrIntegerKeys)',
],
[
'array<int|string, DateTimeImmutable|int>',
'array_merge($generalStringKeys, $generalDateTimeValues)',
],
[
'array<0|string, int|stdClass>&nonEmpty',
'array<int|string, int|stdClass>&nonEmpty',
'array_merge($generalStringKeys, $stringOrIntegerKeys)',
],
[
'array<0|string, int|stdClass>&nonEmpty',
'array<int|string, int|stdClass>&nonEmpty',
'array_merge($stringOrIntegerKeys, $generalStringKeys)',
],
[
"array('foo' => stdClass, 'bar' => stdClass, 0 => stdClass)",
'array<int|non-empty-string, \'foo\'|stdClass>&nonEmpty',
'array_merge($stringKeys, $stringOrIntegerKeys)',
],
[
"array('foo' => 1, 'bar' => 2, 0 => 2, 1 => 3)",
"array_merge(['foo' => 4, 'bar' => 5], ...[['foo' => 1, 'bar' => 2], [2, 3]])",
],
[
"array('foo' => 1, 'foo2' => stdClass)",
'array_merge([\'foo\' => new stdClass()], ...[[\'foo2\' => new stdClass()], [\'foo\' => 1]])',
],

[
"array('foo' => 1, 'foo2' => stdClass)",
'array_merge([\'foo\' => new stdClass()], ...[[\'foo2\' => new stdClass()], [\'foo\' => 1]])',
],
[
"array('foo' => 'foo', 0 => stdClass, 'bar' => stdClass)",
'array<int|non-empty-string, \'foo\'|stdClass>&nonEmpty',
'array_merge($stringOrIntegerKeys, $stringKeys)',
],
[
"array('color' => 'green', 0 => 2, 1 => 4, 2 => 'a', 3 => 'b', 'shape' => 'trapezoid', 4 => 4)",
'array<int|non-empty-string, 2|4|\'a\'|\'b\'|\'green\'|\'red\'|\'trapezoid\'>&nonEmpty',
'array_merge(array("color" => "red", 2, 4), array("a", "b", "color" => "green", "shape" => "trapezoid", 4))',
],
[
Expand Down
2 changes: 0 additions & 2 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/throw-expr.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/array-merge.php');

yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-array.php');

if (PHP_VERSION_ID >= 80000 || self::$useStaticReflectionProvider) {
Expand Down
75 changes: 0 additions & 75 deletions tests/PHPStan/Analyser/data/array-merge.php

This file was deleted.

0 comments on commit 53817aa

Please sign in to comment.