Skip to content

Commit

Permalink
DateTime|DateTimeInterface union accepts DateTimeInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet authored Jul 30, 2021
1 parent 419bc0d commit f3d449f
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/Rules/RuleLevelHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp
$acceptedType = TypeCombinator::removeNull($acceptedType);
}

if ($acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
$accepts = $acceptingType->accepts($acceptedType, $strictTypes);
if (!$accepts->yes() && $acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
foreach ($acceptingType->getTypes() as $innerType) {
if (self::accepts($innerType, $acceptedType, $strictTypes)) {
return true;
Expand Down Expand Up @@ -103,8 +104,6 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp
);
}

$accepts = $acceptingType->accepts($acceptedType, $strictTypes);

return $this->checkUnionTypes ? $accepts->yes() : !$accepts->no();
}

Expand Down
10 changes: 10 additions & 0 deletions src/Type/UnionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ public function getReferencedClasses(): array

public function accepts(Type $type, bool $strictTypes): TrinaryLogic
{
if (
$type->equals(new ObjectType(\DateTimeInterface::class))
&& $this->accepts(
new UnionType([new ObjectType(\DateTime::class), new ObjectType(\DateTimeImmutable::class)]),
$strictTypes
)->yes()
) {
return TrinaryLogic::createYes();
}

if ($type instanceof CompoundType && !$type instanceof CallableType) {
return CompoundTypeHelper::accepts($type, $this, $strictTypes);
}
Expand Down
8 changes: 8 additions & 0 deletions tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ public function testCallMethods(): void
'Parameter #1 $test of method Test\NumericStringParam::sayHello() expects string&numeric, \'abc\' given.',
1658,
],
[
'Parameter #1 $date of method Test\HelloWorld3::sayHello() expects array<DateTime|DateTimeImmutable>|int, DateTimeInterface given.',
1732,
],
]);
}

Expand Down Expand Up @@ -767,6 +771,10 @@ public function testCallMethodsOnThisOnly(): void
'Parameter #1 $test of method Test\NumericStringParam::sayHello() expects string&numeric, \'abc\' given.',
1658,
],
[
'Parameter #1 $date of method Test\HelloWorld3::sayHello() expects array<DateTime|DateTimeImmutable>|int, DateTimeInterface given.',
1732,
],
]);
}

Expand Down
54 changes: 54 additions & 0 deletions tests/PHPStan/Rules/Methods/data/call-methods.php
Original file line number Diff line number Diff line change
Expand Up @@ -1678,3 +1678,57 @@ public function openStatically(): void
}

}

class HelloWorld
{
/**
* @param \DateTime|\DateTimeImmutable|int $date
*/
public function sayHello($date): void
{
}

/**
* @param \DateTimeInterface|int $d
*/
public function foo($d): void
{
$this->sayHello($d);
}
}

class HelloWorld2
{
/**
* @param \DateTime|\DateTimeImmutable $date
*/
public function sayHello($date): void
{
}

/**
* @param \DateTimeInterface $d
*/
public function foo($d): void
{
$this->sayHello($d);
}
}

class HelloWorld3
{
/**
* @param array<\DateTime|\DateTimeImmutable>|int $date
*/
public function sayHello($date): void
{
}

/**
* @param \DateTimeInterface $d
*/
public function foo($d): void
{
$this->sayHello($d);
}
}

0 comments on commit f3d449f

Please sign in to comment.