Skip to content

Commit 7a1ece1

Browse files
staabmondrejmirtes
authored andcommitted
Use Type->setExistingOffsetValueType() more
1 parent 4ce1052 commit 7a1ece1

File tree

6 files changed

+48
-14
lines changed

6 files changed

+48
-14
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5936,9 +5936,18 @@ private function produceArrayDimFetchAssignValueToWrite(array $dimFetchStack, ar
59365936
}
59375937
$offsetValueType = TypeCombinator::intersect($offsetValueType, TypeCombinator::union(...$types));
59385938
}
5939-
$valueToWrite = $offsetValueType->setOffsetValueType($offsetType, $valueToWrite, $i === 0);
59405939

59415940
$arrayDimFetch = $dimFetchStack[$i] ?? null;
5941+
if (
5942+
$offsetType !== null
5943+
&& $arrayDimFetch !== null
5944+
&& $scope->hasExpressionType($arrayDimFetch)->yes()
5945+
) {
5946+
$valueToWrite = $offsetValueType->setExistingOffsetValueType($offsetType, $valueToWrite);
5947+
} else {
5948+
$valueToWrite = $offsetValueType->setOffsetValueType($offsetType, $valueToWrite, $i === 0);
5949+
}
5950+
59425951
if ($arrayDimFetch === null || !$offsetValueType->isList()->yes()) {
59435952
continue;
59445953
}

src/Type/Accessory/AccessoryArrayListType.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
151151
return $this;
152152
}
153153

154-
if (
155-
$valueType->isArray()->yes()
156-
&& IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($offsetType)->yes()
157-
) {
158-
return $this;
159-
}
160-
161154
return new ErrorType();
162155
}
163156

src/Type/Accessory/HasOffsetValueType.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
184184

185185
public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type
186186
{
187+
if (!$offsetType->equals($this->offsetType)) {
188+
return $this;
189+
}
190+
187191
return new self($this->offsetType, $valueType);
188192
}
189193

src/Type/ArrayType.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,30 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
356356

357357
public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type
358358
{
359-
return new self(
360-
$this->keyType,
361-
TypeCombinator::union($this->itemType, $valueType),
359+
if ($offsetType instanceof ConstantStringType || $offsetType instanceof ConstantIntegerType) {
360+
if ($offsetType->isSuperTypeOf($this->keyType)->yes()) {
361+
$builder = ConstantArrayTypeBuilder::createEmpty();
362+
$builder->setOffsetValueType($offsetType, $valueType);
363+
return $builder->getArray();
364+
}
365+
366+
return TypeCombinator::intersect(
367+
new self(
368+
TypeCombinator::union($this->keyType, $offsetType),
369+
TypeCombinator::union($this->itemType, $valueType),
370+
),
371+
new HasOffsetValueType($offsetType, $valueType),
372+
new NonEmptyArrayType(),
373+
);
374+
}
375+
376+
377+
return TypeCombinator::intersect(
378+
new self(
379+
$this->keyType,
380+
TypeCombinator::union($this->itemType, $valueType)
381+
),
382+
new NonEmptyArrayType(),
362383
);
363384
}
364385

src/Type/Constant/ConstantArrayType.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,11 +694,17 @@ public function setExistingOffsetValueType(Type $offsetType, Type $valueType): T
694694
{
695695
$offsetType = $offsetType->toArrayKey();
696696
$builder = ConstantArrayTypeBuilder::createFromConstantArray($this);
697+
$unionValues = $offsetType instanceof UnionType && count($offsetType->getTypes()) > 1;
697698
foreach ($this->keyTypes as $keyType) {
698699
if ($offsetType->isSuperTypeOf($keyType)->no()) {
699700
continue;
700701
}
701702

703+
if ($unionValues) {
704+
$builder->setOffsetValueType($keyType, TypeCombinator::union($this->getOffsetValueType($keyType), $valueType));
705+
continue;
706+
}
707+
702708
$builder->setOffsetValueType($keyType, $valueType);
703709
}
704710

src/Type/IntersectionType.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -802,9 +802,6 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
802802
}
803803

804804
$result = $this->intersectTypes(static fn (Type $type): Type => $type->setOffsetValueType($offsetType, $valueType, $unionValues));
805-
if ($this->isList()->yes() && $valueType->isArray()->yes()) {
806-
$result = TypeCombinator::intersect($result, new AccessoryArrayListType());
807-
}
808805

809806
if (
810807
$offsetType !== null
@@ -832,6 +829,10 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
832829
}
833830
}
834831

832+
if ($this->isList()->yes() && $this->getIterableValueType()->isArray()->yes()) {
833+
$result = TypeCombinator::intersect($result, new AccessoryArrayListType());
834+
}
835+
835836
return $result;
836837
}
837838

0 commit comments

Comments
 (0)