Skip to content

Commit 1064566

Browse files
committed
Allow overriding PHPDoc type of a protected property in a subclass
1 parent 6c1a295 commit 1064566

File tree

5 files changed

+34
-7
lines changed

5 files changed

+34
-7
lines changed

src/Reflection/Php/PhpClassReflectionExtension.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,11 @@ private function createProperty(
430430
&& !$propertyReflection->isStatic()
431431
&& ($classReflection->allowsDynamicProperties() || !$propertyReflection->isPrivate())
432432
&& $this->annotationsPropertiesClassReflectionExtension->hasProperty($classReflection, $propertyName)
433-
&& (!$scope->canReadProperty($nativeProperty) || $nativeProperty->isPublic())
433+
&& (
434+
!$scope->canReadProperty($nativeProperty)
435+
|| $nativeProperty->isPublic()
436+
|| ($scope->isInClass() && $scope->getClassReflection()->getName() !== $declaringClassReflection->getName())
437+
)
434438
) {
435439
$hierarchyDistances = $classReflection->getClassHierarchyDistances();
436440
$annotationProperty = $this->annotationsPropertiesClassReflectionExtension->getProperty($classReflection, $propertyName);

tests/PHPStan/Analyser/nsrt/bug-1216.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Baz extends Foo
3434

3535
public function __construct()
3636
{
37-
assertType('int', $this->foo);
37+
assertType('string', $this->foo);
3838
assertType('string', $this->bar);
3939
assertType('string', $this->untypedBar);
4040
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace OverridingPhpDocTypeOfProtectedProperty;
4+
5+
use stdClass;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
11+
/** @var array|object */
12+
protected $config;
13+
14+
}
15+
16+
/**
17+
* @property stdClass $config
18+
*/
19+
class Bar extends Foo
20+
{
21+
22+
public function doFoo()
23+
{
24+
assertType(stdClass::class, $this->config);
25+
}
26+
27+
}

tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,6 @@ public function testTypesAssignedToProperties(): void
126126
public function testBug1216(): void
127127
{
128128
$this->analyse([__DIR__ . '/data/bug-1216.php'], [
129-
[
130-
'Property Bug1216PropertyTest\Foo::$foo (int) does not accept string.',
131-
36,
132-
],
133129
[
134130
'Property Bug1216PropertyTest\Baz::$untypedBar (string) does not accept int.',
135131
38,

tests/PHPStan/Rules/Properties/data/bug-1216.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Baz extends Foo
3333

3434
public function __construct()
3535
{
36-
$this->foo = 'foo'; // error because property is protected so in this scope "int" type is used
36+
$this->foo = 'foo'; // OK
3737
$this->bar = 'bar'; // OK
3838
$this->untypedBar = 123; // error
3939
}

0 commit comments

Comments
 (0)