Skip to content

Commit

Permalink
Fixed ConstantArrayType::accepts()
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed May 3, 2020
1 parent b55208e commit 61cb5aa
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
11 changes: 8 additions & 3 deletions src/Type/Constant/ConstantArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Type\CompoundType;
use PHPStan\Type\ConstantType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateMixedType;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntersectionType;
Expand Down Expand Up @@ -94,8 +95,12 @@ public function getValueTypes(): array

public function accepts(Type $type, bool $strictTypes): TrinaryLogic
{
if (parent::isSuperTypeOf($type)->no()) {
return TrinaryLogic::createNo();
if ($type instanceof MixedType && !$type instanceof TemplateMixedType) {
return $type->isAcceptedBy($this, $strictTypes);
}

if ($type instanceof self && count($this->keyTypes) === 0) {
return TrinaryLogic::createFromBoolean(count($type->keyTypes) === 0);
}

$result = TrinaryLogic::createYes();
Expand All @@ -115,7 +120,7 @@ public function accepts(Type $type, bool $strictTypes): TrinaryLogic
$result = $result->and($acceptsValue);
}

return $result;
return $result->and($type->isArray());
}

public function isSuperTypeOf(Type $type): TrinaryLogic
Expand Down
65 changes: 63 additions & 2 deletions tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use PHPStan\Type\MixedType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\VerbosityLevel;

class ConstantArrayTypeTest extends \PHPStan\Testing\TestCase
Expand Down Expand Up @@ -109,15 +110,75 @@ public function dataAccepts(): iterable
new ConstantArrayType([new ConstantStringType('foo')], [new ConstantStringType('bar')]),
TrinaryLogic::createYes(),
];

yield [
TypeCombinator::union(
new ConstantArrayType([
new ConstantStringType('name'),
], [
new StringType(),
]),
new ConstantArrayType([
new ConstantStringType('name'),
new ConstantStringType('color'),
], [
new StringType(),
new StringType(),
])
),
new ConstantArrayType([
new ConstantStringType('name'),
new ConstantStringType('color'),
new ConstantStringType('year'),
], [
new StringType(),
new StringType(),
new IntegerType(),
]),
TrinaryLogic::createYes(),
];

yield [
new ConstantArrayType([
new ConstantStringType('name'),
new ConstantStringType('color'),
new ConstantStringType('year'),
], [
new StringType(),
new StringType(),
new IntegerType(),
]),
new MixedType(),
TrinaryLogic::createYes(),
];

yield [
TypeCombinator::union(
new ConstantArrayType([], []),
new ConstantArrayType([
new ConstantStringType('name'),
new ConstantStringType('color'),
], [
new StringType(),
new StringType(),
])
),
new ConstantArrayType([
new ConstantStringType('surname'),
], [
new StringType(),
]),
TrinaryLogic::createNo(),
];
}

/**
* @dataProvider dataAccepts
* @param ConstantArrayType $type
* @param Type $type
* @param Type $otherType
* @param TrinaryLogic $expectedResult
*/
public function testAccepts(ConstantArrayType $type, Type $otherType, TrinaryLogic $expectedResult): void
public function testAccepts(Type $type, Type $otherType, TrinaryLogic $expectedResult): void
{
$actualResult = $type->accepts($otherType, true);
$this->assertSame(
Expand Down

0 comments on commit 61cb5aa

Please sign in to comment.