Skip to content

Commit 20a5164

Browse files
committed
Report bool properties as too wide when only used with true/false
1 parent bd10157 commit 20a5164

File tree

6 files changed

+140
-2
lines changed

6 files changed

+140
-2
lines changed

src/Php/PhpVersions.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ public function supportsNamedArgumentAfterUnpackedArgument(): TrinaryLogic
4343
return IntegerRangeType::fromInterval(80100, null)->isSuperTypeOf($this->phpVersions)->result;
4444
}
4545

46+
public function supportsTrueAndFalseStandaloneType(): TrinaryLogic
47+
{
48+
return IntegerRangeType::fromInterval(80200, null)->isSuperTypeOf($this->phpVersions)->result;
49+
}
50+
4651
}

src/Rules/TooWideTypehints/TooWidePropertyTypeRule.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,15 @@ public function processNode(Node $node, Scope $scope): array
6060
$propertyReflection = $classReflection->getNativeProperty($propertyName);
6161
$propertyType = $propertyReflection->getWritableType();
6262
if (!$propertyType instanceof UnionType) {
63-
continue;
63+
if (
64+
!$propertyReflection->getNativeReflection()->hasType() ||
65+
!$propertyType->isBoolean()->yes() ||
66+
!$scope->getPhpVersion()->supportsTrueAndFalseStandaloneType()->yes()
67+
) {
68+
continue;
69+
}
6470
}
71+
6572
foreach ($this->extensionProvider->getExtensions() as $extension) {
6673
if ($extension->isAlwaysRead($propertyReflection, $propertyName)) {
6774
continue 2;
@@ -101,7 +108,9 @@ public function processNode(Node $node, Scope $scope): array
101108
$assignedType = TypeCombinator::union(...$assignedTypes);
102109
$propertyDescription = $this->describePropertyByName($propertyReflection, $propertyName);
103110
$verbosityLevel = VerbosityLevel::getRecommendedLevelByType($propertyType, $assignedType);
104-
foreach ($propertyType->getTypes() as $type) {
111+
112+
$propertyTypes = $propertyType instanceof UnionType ? $propertyType->getTypes() : $propertyType->getFiniteTypes();
113+
foreach ($propertyTypes as $type) {
105114
if (!$type->isSuperTypeOf($assignedType)->no()) {
106115
continue;
107116
}

tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,15 @@ public function testBug8926(): void
182182
$this->analyse([__DIR__ . '/data/bug-8926.php'], []);
183183
}
184184

185+
public function testBug13384b(): void
186+
{
187+
$this->treatPhpDocTypesAsCertain = true;
188+
$this->analyse([__DIR__ . '/../TooWideTypehints/data/bug-13384b.php'], [
189+
[
190+
'If condition is always false.',
191+
23,
192+
],
193+
]);
194+
}
195+
185196
}

tests/PHPStan/Rules/TooWideTypehints/TooWidePropertyTypeRuleTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,30 @@ public function testBug11667(): void
5858
$this->analyse([__DIR__ . '/data/bug-11667.php'], []);
5959
}
6060

61+
#[RequiresPhp('>= 8.2')]
62+
public function testBug13384(): void
63+
{
64+
$this->analyse([__DIR__ . '/data/bug-13384.php'], [
65+
[
66+
'Static property Bug13384\ShutdownHandlerFalseDefault::$registered (bool) is never assigned true so it can be removed from the property type.',
67+
9,
68+
],
69+
[
70+
'Static property Bug13384\ShutdownHandlerTrueDefault::$registered (bool) is never assigned false so it can be removed from the property type.',
71+
34,
72+
],
73+
]);
74+
}
75+
76+
#[RequiresPhp('< 8.2')]
77+
public function testBug13384NoStandaloneTrueFalse(): void
78+
{
79+
$this->analyse([__DIR__ . '/data/bug-13384.php'], []);
80+
}
81+
82+
public function testBug13384b(): void
83+
{
84+
$this->analyse([__DIR__ . '/data/bug-13384b.php'], []);
85+
}
86+
6187
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Bug13384;
4+
5+
use function register_shutdown_function;
6+
7+
final class ShutdownHandlerFalseDefault
8+
{
9+
private static bool $registered = false;
10+
private static string $message = '';
11+
12+
public static function setMessage(string $message): void
13+
{
14+
self::register();
15+
16+
self::$message = $message;
17+
}
18+
19+
private static function register(): void
20+
{
21+
if (self::$registered) {
22+
return;
23+
}
24+
25+
register_shutdown_function(static function (): void
26+
{
27+
print self::$message;
28+
});
29+
}
30+
}
31+
32+
final class ShutdownHandlerTrueDefault
33+
{
34+
private static bool $registered = true;
35+
private static string $message = '';
36+
37+
public static function setMessage(string $message): void
38+
{
39+
self::register();
40+
41+
self::$message = $message;
42+
}
43+
44+
private static function register(): void
45+
{
46+
if (self::$registered) {
47+
return;
48+
}
49+
50+
register_shutdown_function(static function (): void
51+
{
52+
print self::$message;
53+
});
54+
}
55+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php // lint >= 8.2
2+
3+
declare(strict_types=1);
4+
5+
namespace Bug13384b;
6+
7+
use function register_shutdown_function;
8+
9+
final class ShutdownHandlerFooBar
10+
{
11+
private static false $registered = false;
12+
private static string $message = '';
13+
14+
public static function setMessage(string $message): void
15+
{
16+
self::register();
17+
18+
self::$message = $message;
19+
}
20+
21+
private static function register(): void
22+
{
23+
if (self::$registered) {
24+
return;
25+
}
26+
27+
register_shutdown_function(static function (): void
28+
{
29+
print self::$message;
30+
});
31+
}
32+
}

0 commit comments

Comments
 (0)