Skip to content

Commit 5954bb8

Browse files
committed
Fixed failing tests
1 parent c501918 commit 5954bb8

File tree

3 files changed

+46
-26
lines changed

3 files changed

+46
-26
lines changed

src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@
1111
use PHPStan\Analyser\TypeSpecifierContext;
1212
use PHPStan\Reflection\MethodReflection;
1313
use PHPStan\Type\ArrayType;
14+
use PHPStan\Type\Constant\ConstantArrayType;
15+
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
1416
use PHPStan\Type\Constant\ConstantStringType;
1517
use PHPStan\Type\IterableType;
1618
use PHPStan\Type\MixedType;
1719
use PHPStan\Type\ObjectType;
1820
use PHPStan\Type\StaticMethodTypeSpecifyingExtension;
1921
use PHPStan\Type\Type;
2022
use PHPStan\Type\TypeCombinator;
23+
use PHPStan\Type\TypeUtils;
2124

2225
class AssertTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
2326
{
@@ -109,7 +112,13 @@ public function specifyTypes(
109112
reset($sureTypes);
110113
$exprString = key($sureTypes);
111114
$sureType = $sureTypes[$exprString];
112-
return $this->arrayOrIterable($scope, $sureType[0], $sureType[1]);
115+
return $this->arrayOrIterable(
116+
$scope,
117+
$sureType[0],
118+
function () use ($sureType): Type {
119+
return $sureType[1];
120+
}
121+
);
113122
}
114123
if (count($specifiedTypes->getSureNotTypes()) > 0) {
115124
throw new \PHPStan\ShouldNotHappenException();
@@ -325,39 +334,35 @@ private function handleAllNot(
325334
): SpecifiedTypes
326335
{
327336
if ($methodName === 'allNotNull') {
328-
$expr = $node->args[0]->value;
329-
$currentType = $scope->getType($expr);
330337
return $this->arrayOrIterable(
331338
$scope,
332-
$expr,
333-
TypeCombinator::removeNull($currentType->getIterableValueType())
339+
$node->args[0]->value,
340+
function (Type $type): Type {
341+
return TypeCombinator::removeNull($type);
342+
}
334343
);
335344
} elseif ($methodName === 'allNotInstanceOf') {
336345
$classType = $scope->getType($node->args[1]->value);
337346
if (!$classType instanceof ConstantStringType) {
338347
return new SpecifiedTypes([], []);
339348
}
340349

341-
$expr = $node->args[0]->value;
342-
$currentType = $scope->getType($expr);
350+
$objectType = new ObjectType($classType->getValue());
343351
return $this->arrayOrIterable(
344352
$scope,
345-
$expr,
346-
TypeCombinator::remove(
347-
$currentType->getIterableValueType(),
348-
new ObjectType($classType->getValue())
349-
)
353+
$node->args[0]->value,
354+
function (Type $type) use ($objectType): Type {
355+
return TypeCombinator::remove($type, $objectType);
356+
}
350357
);
351358
} elseif ($methodName === 'allNotSame') {
352-
$expr = $node->args[0]->value;
353-
$currentType = $scope->getType($expr);
359+
$valueType = $scope->getType($node->args[1]->value);
354360
return $this->arrayOrIterable(
355361
$scope,
356-
$expr,
357-
TypeCombinator::remove(
358-
$currentType->getIterableValueType(),
359-
$scope->getType($node->args[1]->value)
360-
)
362+
$node->args[0]->value,
363+
function (Type $type) use ($valueType): Type {
364+
return TypeCombinator::remove($type, $valueType);
365+
}
361366
);
362367
}
363368

@@ -367,14 +372,29 @@ private function handleAllNot(
367372
private function arrayOrIterable(
368373
Scope $scope,
369374
\PhpParser\Node\Expr $expr,
370-
Type $type
375+
\Closure $typeCallback
371376
): SpecifiedTypes
372377
{
373378
$currentType = $scope->getType($expr);
374-
if ((new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($currentType)->yes()) {
375-
$specifiedType = new ArrayType($currentType->getIterableKeyType(), $type);
379+
$arrayTypes = TypeUtils::getArrays($currentType);
380+
if (count($arrayTypes) > 0) {
381+
$newArrayTypes = [];
382+
foreach ($arrayTypes as $arrayType) {
383+
if ($arrayType instanceof ConstantArrayType) {
384+
$builder = ConstantArrayTypeBuilder::createEmpty();
385+
foreach ($arrayType->getKeyTypes() as $i => $keyType) {
386+
$valueType = $arrayType->getValueTypes()[$i];
387+
$builder->setOffsetValueType($keyType, $typeCallback($valueType));
388+
}
389+
$newArrayTypes[] = $builder->getArray();
390+
} else {
391+
$newArrayTypes[] = new ArrayType($arrayType->getKeyType(), $typeCallback($arrayType->getItemType()));
392+
}
393+
}
394+
395+
$specifiedType = TypeCombinator::union(...$newArrayTypes);
376396
} elseif ((new IterableType(new MixedType(), new MixedType()))->isSuperTypeOf($currentType)->yes()) {
377-
$specifiedType = new IterableType($currentType->getIterableKeyType(), $type);
397+
$specifiedType = new IterableType($currentType->getIterableKeyType(), $typeCallback($currentType->getIterableValueType()));
378398
} else {
379399
return new SpecifiedTypes([], []);
380400
}

tests/Type/WebMozartAssert/AssertTypeSpecifyingExtensionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public function testExtension(): void
134134
100,
135135
],
136136
[
137-
'Variable $z is: array<0|1|2, 1>',
137+
'Variable $z is: array(1, -2|2, -3|3)',
138138
107,
139139
],
140140
[

tests/Type/WebMozartAssert/data/data.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ public function doFoo($a, $b, array $c, iterable $d, $e, $f, $g, $h, $i, $j, $k,
9999
Assert::notSame($y, 1);
100100
$y;
101101

102-
$z = [1, 1, 1];
102+
$z = [1, 2, 3];
103103
if (doFoo()) {
104-
$z = [-1, -1, -1];
104+
$z = [-1, -2, -3];
105105
}
106106
Assert::allNotSame($z, -1);
107107
$z;

0 commit comments

Comments
 (0)