|
5 | 5 | use PhpParser\Node\Expr\FuncCall; |
6 | 6 | use PHPStan\Analyser\Scope; |
7 | 7 | use PHPStan\Reflection\FunctionReflection; |
8 | | -use PHPStan\ShouldNotHappenException; |
9 | 8 | use PHPStan\TrinaryLogic; |
10 | 9 | use PHPStan\Type\Accessory\AccessoryArrayListType; |
11 | 10 | use PHPStan\Type\Accessory\NonEmptyArrayType; |
12 | 11 | use PHPStan\Type\ArrayType; |
13 | 12 | use PHPStan\Type\Constant\ConstantArrayType; |
14 | 13 | use PHPStan\Type\Constant\ConstantArrayTypeBuilder; |
15 | 14 | use PHPStan\Type\Constant\ConstantIntegerType; |
| 15 | +use PHPStan\Type\Constant\ConstantStringType; |
16 | 16 | use PHPStan\Type\DynamicFunctionReturnTypeExtension; |
17 | 17 | use PHPStan\Type\IntegerType; |
18 | 18 | use PHPStan\Type\NeverType; |
@@ -72,22 +72,19 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, |
72 | 72 | if ($allConstant->yes()) { |
73 | 73 | $newArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); |
74 | 74 | 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 | + } |
78 | 81 | } |
79 | 82 |
|
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) { |
87 | 84 | $newArrayBuilder->setOffsetValueType( |
88 | 85 | $keyType instanceof ConstantIntegerType ? null : $keyType, |
89 | | - $valueTypes[$k], |
90 | | - $isOptional, |
| 86 | + $argType->getOffsetValueType($keyType), |
| 87 | + !$argType->hasOffsetValueType($keyType)->yes(), |
91 | 88 | ); |
92 | 89 | } |
93 | 90 | } |
@@ -135,29 +132,4 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, |
135 | 132 | return $arrayType; |
136 | 133 | } |
137 | 134 |
|
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 | | - |
163 | 135 | } |
0 commit comments