Skip to content

Commit 4556931

Browse files
committed
Simplify and improve solution
1 parent 8952033 commit 4556931

File tree

3 files changed

+12
-40
lines changed

3 files changed

+12
-40
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1470,7 +1470,7 @@ parameters:
14701470
-
14711471
message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantArrayType is error\-prone and deprecated\. Use Type\:\:getConstantArrays\(\) instead\.$#'
14721472
identifier: phpstanApi.instanceofType
1473-
count: 2
1473+
count: 1
14741474
path: src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php
14751475

14761476
-

src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
use PhpParser\Node\Expr\FuncCall;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\FunctionReflection;
8-
use PHPStan\ShouldNotHappenException;
98
use PHPStan\TrinaryLogic;
109
use PHPStan\Type\Accessory\AccessoryArrayListType;
1110
use PHPStan\Type\Accessory\NonEmptyArrayType;
1211
use PHPStan\Type\ArrayType;
1312
use PHPStan\Type\Constant\ConstantArrayType;
1413
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
1514
use PHPStan\Type\Constant\ConstantIntegerType;
15+
use PHPStan\Type\Constant\ConstantStringType;
1616
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
1717
use PHPStan\Type\IntegerType;
1818
use PHPStan\Type\NeverType;
@@ -72,22 +72,19 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
7272
if ($allConstant->yes()) {
7373
$newArrayBuilder = ConstantArrayTypeBuilder::createEmpty();
7474
foreach ($argTypes as $argType) {
75-
$constantArrayType = $this->untagConstantArrayUnion($argType);
76-
if (!$constantArrayType instanceof ConstantArrayType) {
77-
throw new ShouldNotHappenException();
75+
/** @var array<int|string, ConstantIntegerType|ConstantStringType> $keyTypes */
76+
$keyTypes = [];
77+
foreach ($argType->getConstantArrays() as $constantArray) {
78+
foreach ($constantArray->getKeyTypes() as $keyType) {
79+
$keyTypes[$keyType->getValue()] = $keyType;
80+
}
7881
}
7982

80-
$keyTypes = $constantArrayType->getKeyTypes();
81-
$valueTypes = $constantArrayType->getValueTypes();
82-
$optionalKeys = $constantArrayType->getOptionalKeys();
83-
84-
foreach ($keyTypes as $k => $keyType) {
85-
$isOptional = in_array($k, $optionalKeys, true);
86-
83+
foreach ($keyTypes as $keyType) {
8784
$newArrayBuilder->setOffsetValueType(
8885
$keyType instanceof ConstantIntegerType ? null : $keyType,
89-
$valueTypes[$k],
90-
$isOptional,
86+
$argType->getOffsetValueType($keyType),
87+
!$argType->hasOffsetValueType($keyType)->yes(),
9188
);
9289
}
9390
}
@@ -135,29 +132,4 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
135132
return $arrayType;
136133
}
137134

138-
/**
139-
* array{0: 17, foo: 'bar'}|array{0: 19, foo: 'bar', fofoo: 'barbar'}
140-
* ->
141-
* array{0: 17|19, foo: 'bar', foofo?: 'barbar'}
142-
*/
143-
private function untagConstantArrayUnion(Type $constantArrayType): Type
144-
{
145-
$constantArrayTypes = $constantArrayType->getConstantArrays();
146-
if (count($constantArrayTypes) === 1) {
147-
return $constantArrayTypes[0];
148-
}
149-
150-
$builder = ConstantArrayTypeBuilder::createEmpty();
151-
$keyTypes = $constantArrayType->getKeysArray()->getIterableValueType()->getFiniteTypes();
152-
foreach ($keyTypes as $keyType) {
153-
$builder->setOffsetValueType(
154-
$keyType,
155-
$constantArrayType->getOffsetValueType($keyType),
156-
!$constantArrayType->hasOffsetValueType($keyType)->yes(),
157-
);
158-
}
159-
160-
return $builder->getArray();
161-
}
162-
163135
}

tests/PHPStan/Analyser/nsrt/array-merge2.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function arrayMergeArrayShapes($array1, $array2): void
2121
assertType("array{foo: '1', bar: '2', lall2: '3', 0: '4', 1: '6', lall: '3', 2: '2', 3: '3'}", array_merge($array2, $array1));
2222
assertType("array{foo: 3, bar: '2', lall2: '3', 0: '4', 1: '6', lall: '3', 2: '2', 3: '3'}", array_merge($array2, $array1, ['foo' => 3]));
2323
assertType("array{foo: 3, bar: '2', lall2: '3', 0: '4', 1: '6', lall: '3', 2: '2', 3: '3'}", array_merge($array2, $array1, ...[['foo' => 3]]));
24-
assertType("array{foo: '1', bar: '2'|'4', lall2?: '3', lall?: '3', 0: '2'|'4', 1: '3'|'6'}", array_merge(rand(0, 1) ? $array1 : $array2, []));
24+
assertType("array{foo: '1', bar: '2'|'4', lall?: '3', 0: '2'|'4', 1: '3'|'6', lall2?: '3'}", array_merge(rand(0, 1) ? $array1 : $array2, []));
2525
assertType("array{foo?: 3, bar?: 3}", array_merge([], ...[rand(0, 1) ? ['foo' => 3] : ['bar' => 3]]));
2626
}
2727

0 commit comments

Comments
 (0)