Skip to content

Commit

Permalink
Fixed universal object crate classes not respecting @Property annotat…
Browse files Browse the repository at this point in the history
…ions.
  • Loading branch information
mad-briller committed Oct 3, 2022
1 parent 8778350 commit 081d438
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 8 deletions.
Expand Up @@ -2,6 +2,7 @@

namespace PHPStan\Reflection\Php;

use PHPSTan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\PropertiesClassReflectionExtension;
Expand All @@ -16,7 +17,11 @@ class UniversalObjectCratesClassReflectionExtension
/**
* @param string[] $classes
*/
public function __construct(private ReflectionProvider $reflectionProvider, private array $classes)
public function __construct(
private ReflectionProvider $reflectionProvider,
private array $classes,
private AnnotationsPropertiesClassReflectionExtension $annotationClassReflection
)
{
}

Expand Down Expand Up @@ -56,6 +61,10 @@ public static function isUniversalObjectCrate(

public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection
{
if ($this->annotationClassReflection->hasProperty($classReflection, $propertyName)) {
return $this->annotationClassReflection->getProperty($classReflection, $propertyName);
}

if ($classReflection->hasNativeMethod('__get')) {
$readableType = ParametersAcceptorSelector::selectSingle($classReflection->getNativeMethod('__get')->getVariants())->getReturnType();
} else {
Expand Down
Expand Up @@ -2,6 +2,7 @@

namespace PHPStan\Reflection\Php;

use PHPStan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension;
use PHPStan\Testing\PHPStanTestCase;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StringType;
Expand All @@ -13,10 +14,11 @@ class UniversalObjectCratesClassReflectionExtensionTest extends PHPStanTestCase
public function testNonexistentClass(): void
{
$reflectionProvider = $this->createReflectionProvider();
$extension = new UniversalObjectCratesClassReflectionExtension($reflectionProvider, [
'NonexistentClass',
'stdClass',
]);
$extension = new UniversalObjectCratesClassReflectionExtension(
$reflectionProvider,
['NonexistentClass', 'stdClass'],
new AnnotationsPropertiesClassReflectionExtension()
);
$this->assertTrue($extension->hasProperty($reflectionProvider->getClass(stdClass::class), 'foo'));
}

Expand All @@ -25,9 +27,11 @@ public function testDifferentGetSetType(): void
require_once __DIR__ . '/data/universal-object-crates.php';

$reflectionProvider = $this->createReflectionProvider();
$extension = new UniversalObjectCratesClassReflectionExtension($reflectionProvider, [
'UniversalObjectCreates\DifferentGetSetTypes',
]);
$extension = new UniversalObjectCratesClassReflectionExtension(
$reflectionProvider,
['UniversalObjectCreates\DifferentGetSetTypes'],
new AnnotationsPropertiesClassReflectionExtension()
);

$this->assertEquals(
new ObjectType('UniversalObjectCreates\DifferentGetSetTypesValue'),
Expand All @@ -43,4 +47,30 @@ public function testDifferentGetSetType(): void
);
}

public function testAnnotationOverrides(): void
{
require_once __DIR__ . '/data/universal-object-crates-annotations.php';
$className = 'UniversalObjectCratesAnnotations\Model';

$reflectionProvider = $this->createReflectionProvider();
$extension = new UniversalObjectCratesClassReflectionExtension(
$reflectionProvider,
[$className],
new AnnotationsPropertiesClassReflectionExtension()
);

$this->assertEquals(
new StringType(),
$extension
->getProperty($reflectionProvider->getClass($className), 'foo')
->getReadableType(),
);
$this->assertEquals(
new StringType(),
$extension
->getProperty($reflectionProvider->getClass($className), 'foo')
->getWritableType(),
);
}

}
@@ -0,0 +1,12 @@
<?php declare(strict_types = 1);

namespace UniversalObjectCratesAnnotations;

use StdClass;

/**
* @property string $foo
*/
class Model extends StdClass
{
}

0 comments on commit 081d438

Please sign in to comment.