Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
clxmstaab authored and staabm committed Mar 30, 2022
1 parent e99048b commit 11ac6b3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
38 changes: 38 additions & 0 deletions src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\NeverType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
use function in_array;

class ArrayMergeFunctionDynamicReturnTypeExtension implements DynamicFunctionReturnTypeExtension
{
Expand All @@ -29,6 +32,41 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
}

$allConstant = true;
foreach ($functionCall->getArgs() as $arg) {
$argType = $scope->getType($arg->value);
if ($arg->unpack || !$argType instanceof ConstantArrayType) {
$allConstant = false;
break;
}
}

if ($allConstant) {
$newArrayBuilder = ConstantArrayTypeBuilder::createEmpty();
foreach ($functionCall->getArgs() as $arg) {
$argType = $scope->getType($arg->value);
if (!$argType instanceof ConstantArrayType) {
throw new ShouldNotHappenException();
}

$keyTypes = $argType->getKeyTypes();
$valueTypes = $argType->getValueTypes();
$optionalKeys = $argType->getOptionalKeys();

foreach ($keyTypes as $i => $keyType) {
$isOptional = in_array($i, $optionalKeys, true);

$newArrayBuilder->setOffsetValueType(
$keyType,
$valueTypes[$i],
$isOptional,
);
}
}

return $newArrayBuilder->getArray();
}

$keyTypes = [];
$valueTypes = [];
$nonEmpty = false;
Expand Down
8 changes: 4 additions & 4 deletions tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4707,7 +4707,7 @@ public function dataArrayFunctions(): array
'array_values($generalStringKeys)',
],
[
'non-empty-array<1|\'foo\', stdClass>',
'array{foo: stdClass, 1: stdClass}',
'array_merge($stringOrIntegerKeys)',
],
[
Expand All @@ -4723,15 +4723,15 @@ public function dataArrayFunctions(): array
'array_merge($stringOrIntegerKeys, $generalStringKeys)',
],
[
'non-empty-array<1|\'bar\'|\'foo\', \'foo\'|stdClass>',
'array{foo: stdClass, bar: stdClass, 1: stdClass}',
'array_merge($stringKeys, $stringOrIntegerKeys)',
],
[
'non-empty-array<1|\'bar\'|\'foo\', \'foo\'|stdClass>',
"array{foo: 'foo', 1: stdClass, bar: stdClass}",
'array_merge($stringOrIntegerKeys, $stringKeys)',
],
[
'non-empty-array<0|1|2|\'color\'|\'shape\', 2|4|\'a\'|\'b\'|\'green\'|\'red\'|\'trapezoid\'>',
"array{color: 'green', 0: 'a', 1: 'b', shape: 'trapezoid', 2: 4}",
'array_merge(array("color" => "red", 2, 4), array("a", "b", "color" => "green", "shape" => "trapezoid", 4))',
],
[
Expand Down

0 comments on commit 11ac6b3

Please sign in to comment.