Skip to content

Commit

Permalink
Fix native static return typehint when entering class method
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 3, 2021
1 parent ae50bb4 commit baa371e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -2595,7 +2595,7 @@ public function enterClassMethod(
return TemplateTypeHelper::toArgument($type);
}, $phpDocParameterTypes),
$this->getRealParameterDefaultValues($classMethod),
$this->getFunctionType($classMethod->returnType, $classMethod->returnType === null, false),
$this->transformStaticType($this->getFunctionType($classMethod->returnType, $classMethod->returnType === null, false)),
$phpDocReturnType !== null ? TemplateTypeHelper::toArgument($phpDocReturnType) : null,
$throwType,
$deprecatedDescription,
Expand All @@ -2608,6 +2608,25 @@ public function enterClassMethod(
);
}

private function transformStaticType(Type $type): Type
{
return TypeTraverser::map($type, function (Type $type, callable $traverse): Type {
if (!$this->isInClass()) {
return $type;
}
if ($type instanceof StaticType) {
$classReflection = $this->getClassReflection();
$changedType = $type->changeBaseClass($classReflection);
if ($classReflection->isFinal()) {
$changedType = $changedType->getStaticObjectType();
}
return $traverse($changedType);
}

return $traverse($type);
});
}

/**
* @param Node\FunctionLike $functionLike
* @return Type[]
Expand Down
8 changes: 8 additions & 0 deletions tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -477,4 +477,12 @@ public function testBug3118(): void
]);
}

public function testBug4795(): void
{
if (PHP_VERSION_ID < 80000 && !self::$useStaticReflectionProvider) {
$this->markTestSkipped('Test requires PHP 8.0');
}
$this->analyse([__DIR__ . '/data/bug-4795.php'], []);
}

}
47 changes: 47 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-4795.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php // lint >= 8.0

namespace Bug4795;

abstract class BaseDTO
{

final protected static function create(): static
{
$class = static::class;

return new $class();
}

abstract public static function parse(): static;

}

final class ConcreteDTO extends BaseDTO
{

public string $foo;

public static function parse(): static
{
$instance = self::create();

$instance->foo = 'bar';

return $instance;
}
}

class NonFinalConcreteDTO extends BaseDTO
{

public string $foo;

public static function parse(): static
{
$instance = self::create();

$instance->foo = 'bar';

return $instance;
}
}

0 comments on commit baa371e

Please sign in to comment.