Skip to content

Commit

Permalink
Fixed failing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 23, 2018
1 parent c501918 commit 5954bb8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 26 deletions.
66 changes: 43 additions & 23 deletions src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
use PHPStan\Analyser\TypeSpecifierContext;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\IterableType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StaticMethodTypeSpecifyingExtension;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeUtils;

class AssertTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
{
Expand Down Expand Up @@ -109,7 +112,13 @@ public function specifyTypes(
reset($sureTypes);
$exprString = key($sureTypes);
$sureType = $sureTypes[$exprString];
return $this->arrayOrIterable($scope, $sureType[0], $sureType[1]);
return $this->arrayOrIterable(
$scope,
$sureType[0],
function () use ($sureType): Type {
return $sureType[1];
}
);
}
if (count($specifiedTypes->getSureNotTypes()) > 0) {
throw new \PHPStan\ShouldNotHappenException();
Expand Down Expand Up @@ -325,39 +334,35 @@ private function handleAllNot(
): SpecifiedTypes
{
if ($methodName === 'allNotNull') {
$expr = $node->args[0]->value;
$currentType = $scope->getType($expr);
return $this->arrayOrIterable(
$scope,
$expr,
TypeCombinator::removeNull($currentType->getIterableValueType())
$node->args[0]->value,
function (Type $type): Type {
return TypeCombinator::removeNull($type);
}
);
} elseif ($methodName === 'allNotInstanceOf') {
$classType = $scope->getType($node->args[1]->value);
if (!$classType instanceof ConstantStringType) {
return new SpecifiedTypes([], []);
}

$expr = $node->args[0]->value;
$currentType = $scope->getType($expr);
$objectType = new ObjectType($classType->getValue());
return $this->arrayOrIterable(
$scope,
$expr,
TypeCombinator::remove(
$currentType->getIterableValueType(),
new ObjectType($classType->getValue())
)
$node->args[0]->value,
function (Type $type) use ($objectType): Type {
return TypeCombinator::remove($type, $objectType);
}
);
} elseif ($methodName === 'allNotSame') {
$expr = $node->args[0]->value;
$currentType = $scope->getType($expr);
$valueType = $scope->getType($node->args[1]->value);
return $this->arrayOrIterable(
$scope,
$expr,
TypeCombinator::remove(
$currentType->getIterableValueType(),
$scope->getType($node->args[1]->value)
)
$node->args[0]->value,
function (Type $type) use ($valueType): Type {
return TypeCombinator::remove($type, $valueType);
}
);
}

Expand All @@ -367,14 +372,29 @@ private function handleAllNot(
private function arrayOrIterable(
Scope $scope,
\PhpParser\Node\Expr $expr,
Type $type
\Closure $typeCallback
): SpecifiedTypes
{
$currentType = $scope->getType($expr);
if ((new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($currentType)->yes()) {
$specifiedType = new ArrayType($currentType->getIterableKeyType(), $type);
$arrayTypes = TypeUtils::getArrays($currentType);
if (count($arrayTypes) > 0) {
$newArrayTypes = [];
foreach ($arrayTypes as $arrayType) {
if ($arrayType instanceof ConstantArrayType) {
$builder = ConstantArrayTypeBuilder::createEmpty();
foreach ($arrayType->getKeyTypes() as $i => $keyType) {
$valueType = $arrayType->getValueTypes()[$i];
$builder->setOffsetValueType($keyType, $typeCallback($valueType));
}
$newArrayTypes[] = $builder->getArray();
} else {
$newArrayTypes[] = new ArrayType($arrayType->getKeyType(), $typeCallback($arrayType->getItemType()));
}
}

$specifiedType = TypeCombinator::union(...$newArrayTypes);
} elseif ((new IterableType(new MixedType(), new MixedType()))->isSuperTypeOf($currentType)->yes()) {
$specifiedType = new IterableType($currentType->getIterableKeyType(), $type);
$specifiedType = new IterableType($currentType->getIterableKeyType(), $typeCallback($currentType->getIterableValueType()));
} else {
return new SpecifiedTypes([], []);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public function testExtension(): void
100,
],
[
'Variable $z is: array<0|1|2, 1>',
'Variable $z is: array(1, -2|2, -3|3)',
107,
],
[
Expand Down
4 changes: 2 additions & 2 deletions tests/Type/WebMozartAssert/data/data.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ public function doFoo($a, $b, array $c, iterable $d, $e, $f, $g, $h, $i, $j, $k,
Assert::notSame($y, 1);
$y;

$z = [1, 1, 1];
$z = [1, 2, 3];
if (doFoo()) {
$z = [-1, -1, -1];
$z = [-1, -2, -3];
}
Assert::allNotSame($z, -1);
$z;
Expand Down

0 comments on commit 5954bb8

Please sign in to comment.