Skip to content

Commit 944b629

Browse files
herndlmondrejmirtes
authored andcommitted
Improve all* handling
1 parent fe8354a commit 944b629

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php

+21-9
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ private function handleAllNot(
786786
): SpecifiedTypes
787787
{
788788
if ($methodName === 'allNotNull') {
789-
return $this->arrayOrIterable(
789+
return $this->allArrayOrIterable(
790790
$scope,
791791
$node->getArgs()[0]->value,
792792
static function (Type $type): Type {
@@ -806,7 +806,7 @@ static function (Type $type): Type {
806806
return new SpecifiedTypes([], []);
807807
}
808808

809-
return $this->arrayOrIterable(
809+
return $this->allArrayOrIterable(
810810
$scope,
811811
$node->getArgs()[0]->value,
812812
static function (Type $type) use ($objectType): Type {
@@ -817,7 +817,7 @@ static function (Type $type) use ($objectType): Type {
817817

818818
if ($methodName === 'allNotSame') {
819819
$valueType = $scope->getType($node->getArgs()[1]->value);
820-
return $this->arrayOrIterable(
820+
return $this->allArrayOrIterable(
821821
$scope,
822822
$node->getArgs()[0]->value,
823823
static function (Type $type) use ($valueType): Type {
@@ -864,7 +864,7 @@ private function handleAll(
864864
$type = $typeModifier($type);
865865
}
866866

867-
return $this->arrayOrIterable(
867+
return $this->allArrayOrIterable(
868868
$scope,
869869
$node->getArgs()[0]->value,
870870
static function () use ($type): Type {
@@ -877,7 +877,7 @@ static function () use ($type): Type {
877877
return $specifiedTypes;
878878
}
879879

880-
private function arrayOrIterable(
880+
private function allArrayOrIterable(
881881
Scope $scope,
882882
Expr $expr,
883883
Closure $typeCallback,
@@ -892,18 +892,30 @@ private function arrayOrIterable(
892892
if ($arrayType instanceof ConstantArrayType) {
893893
$builder = ConstantArrayTypeBuilder::createEmpty();
894894
foreach ($arrayType->getKeyTypes() as $i => $keyType) {
895-
$valueType = $arrayType->getValueTypes()[$i];
896-
$builder->setOffsetValueType($keyType, $typeCallback($valueType), $arrayType->isOptionalKey($i));
895+
$valueType = $typeCallback($arrayType->getValueTypes()[$i]);
896+
if ($valueType instanceof NeverType) {
897+
continue 2;
898+
}
899+
$builder->setOffsetValueType($keyType, $valueType, $arrayType->isOptionalKey($i));
897900
}
898901
$newArrayTypes[] = $builder->getArray();
899902
} else {
900-
$newArrayTypes[] = new ArrayType($arrayType->getKeyType(), $typeCallback($arrayType->getItemType()));
903+
$itemType = $typeCallback($arrayType->getItemType());
904+
if ($itemType instanceof NeverType) {
905+
continue;
906+
}
907+
$newArrayTypes[] = new ArrayType($arrayType->getKeyType(), $itemType);
901908
}
902909
}
903910

904911
$specifiedType = TypeCombinator::union(...$newArrayTypes);
905912
} elseif ((new IterableType(new MixedType(), new MixedType()))->isSuperTypeOf($currentType)->yes()) {
906-
$specifiedType = new IterableType($currentType->getIterableKeyType(), $typeCallback($currentType->getIterableValueType()));
913+
$itemType = $typeCallback($currentType->getIterableValueType());
914+
if ($itemType instanceof NeverType) {
915+
$specifiedType = $itemType;
916+
} else {
917+
$specifiedType = new IterableType($currentType->getIterableKeyType(), $itemType);
918+
}
907919
} else {
908920
return new SpecifiedTypes([], []);
909921
}

tests/Type/WebMozartAssert/data/collection.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,20 @@ public function allNotInstanceOf(array $a, array $b, array $c): void
9898
assertType('array<PHPStan\Type\WebMozartAssert\CollectionFoo>', $c);
9999
}
100100

101-
public function allNotNull(array $arr): void
101+
public function allNotNull(array $arr, iterable $iter): void
102102
{
103103
/** @var (int|null)[] $arr */
104104
Assert::allNotNull($arr);
105105
assertType('array<int>', $arr);
106106

107+
/** @var null[] $arr */
108+
Assert::allNotNull($arr);
109+
assertType('*NEVER*', $arr);
110+
111+
/** @var iterable<null> $iter */
112+
Assert::allNotNull($iter);
113+
assertType('*NEVER*', $iter);
114+
107115
/** @var array{baz: float|null}|array{foo?: string|null, bar: int|null} $arr */
108116
Assert::allNotNull($arr);
109117
assertType('array{baz: float}|array{foo?: string, bar: int}', $arr);
@@ -117,7 +125,11 @@ public function allNotSame(array $arr): void
117125

118126
/** @var array{-1, -2, -3}|array{1, 2, 3} $arr */
119127
Assert::allNotSame($arr, -1);
120-
assertType('array{*NEVER*, -2, -3}|array{1, 2, 3}', $arr);
128+
assertType('array{1, 2, 3}', $arr);
129+
130+
/** @var array{-1, -2, -3} $arr */
131+
Assert::allNotSame($arr, -1);
132+
assertType('*NEVER*', $arr);
121133
}
122134

123135
public function allSubclassOf(array $a, iterable $b, $c): void

0 commit comments

Comments
 (0)