Skip to content

Commit

Permalink
Fix DatePeriod constructor extension in subclasses
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 1, 2022
1 parent 1789915 commit 0c82b3a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Type/Php/DatePeriodConstructorReturnTypeExtension.php
Expand Up @@ -6,6 +6,7 @@
use DateTime;
use DateTimeInterface;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
Expand All @@ -15,6 +16,7 @@
use PHPStan\Type\ObjectType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use function strtolower;

class DatePeriodConstructorReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension
{
Expand All @@ -35,6 +37,15 @@ public function getTypeFromStaticMethodCall(MethodReflection $methodReflection,
return new ObjectType(DatePeriod::class);
}

if (!$methodCall->class instanceof Name) {
return new ObjectType(DatePeriod::class);
}

$className = $scope->resolveName($methodCall->class);
if (strtolower($className) !== 'dateperiod') {
return new ObjectType($className);
}

$firstArgType = $scope->getType($methodCall->getArgs()[0]->value);
if ((new StringType())->isSuperTypeOf($firstArgType)->yes()) {
$firstArgType = new ObjectType(DateTime::class);
Expand Down
2 changes: 2 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -678,6 +678,8 @@ public function dataFileAsserts(): iterable
} else {
yield from $this->gatherAssertTypes(__DIR__ . '/data/hash-functions-74.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6500.php');
}

/**
Expand Down
14 changes: 14 additions & 0 deletions tests/PHPStan/Analyser/data/bug-6500.php
@@ -0,0 +1,14 @@
<?php

namespace Bug6500;

use function PHPStan\Testing\assertType;

class DatePeriodExample extends \DatePeriod {

public static function test(): void {
$self = new self(new \DateTimeImmutable('2022-01-01'), new \DateInterval('P1M'), new \DateTimeImmutable('2022-01-31'));
assertType(self::class, $self);
}

}

0 comments on commit 0c82b3a

Please sign in to comment.