Skip to content

Commit

Permalink
Fix TypeUtils::getDirectClassNames for nested type (#1380)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Jun 2, 2022
1 parent 1232186 commit 0bc75d9
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 4 deletions.
6 changes: 2 additions & 4 deletions src/Type/TypeUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,9 @@ public static function getDirectClassNames(Type $type): array
if ($type instanceof UnionType || $type instanceof IntersectionType) {
$classNames = [];
foreach ($type->getTypes() as $innerType) {
if (!$innerType instanceof TypeWithClassName) {
continue;
foreach (self::getDirectClassNames($innerType) as $n) {
$classNames[] = $n;
}

$classNames[] = $innerType->getClassName();
}

return $classNames;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function dataAsserts(): iterable

yield from $this->gatherAssertTypes(__DIR__ . '/data/dynamic-method-return-compound-types.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/dynamic-method-return-getsingle-conditional.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7344.php');
}

/**
Expand Down
31 changes: 31 additions & 0 deletions tests/PHPStan/Analyser/data/TestDynamicReturnTypeExtensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@

namespace PHPStan\Tests;

use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\Dummy\ChangedTypeMethodReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\ResolvedMethodReflection;
use PHPStan\Reflection\Type\CalledOnTypeUnresolvedMethodPrototypeReflection;
use PHPStan\Reflection\Type\UnionTypeMethodReflection;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\NeverType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;

class GetByPrimaryDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
Expand Down Expand Up @@ -209,3 +218,25 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
}

}

class Bug7344DynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return \Bug7344\Model::class;
}

public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'getModel';
}

public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
return new IntegerType();
}

}
56 changes: 56 additions & 0 deletions tests/PHPStan/Analyser/data/bug-7344.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Bug7344;

use Exception;
use function PHPStan\Testing\assertType;

interface PhpdocTypeInterface
{
/**
* Interface for phpdoc type for Phpstan only
*
* @return never
*/
public function neverImplement(): void;
}

interface IsEntity extends PhpdocTypeInterface
{
}

class Model
{

public function getModel(bool $allowOnModel = false): self
{
return $this;
}
}

class Person extends Model
{
}

class Female extends Person
{
}

class Male extends Person
{
}

class Foo
{

/** @param Male|Female $maleOrFemale */
public function doFoo($maleOrFemale): void
{
if (!$maleOrFemale instanceof IsEntity) {
return;
}

assertType('(Bug7344\Female&Bug7344\IsEntity)|(Bug7344\IsEntity&Bug7344\Male)', $maleOrFemale);
assertType('int', $maleOrFemale->getModel());
}
}
4 changes: 4 additions & 0 deletions tests/PHPStan/Analyser/dynamic-return-type.neon
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ services:
class: PHPStan\Tests\ConditionalGetSingle
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
-
class: PHPStan\Tests\Bug7344DynamicReturnTypeExtension
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

0 comments on commit 0bc75d9

Please sign in to comment.