Skip to content

Commit 5adafcb

Browse files
authored
Fix too wide bool in trivial methods
1 parent d194c2c commit 5adafcb

File tree

4 files changed

+98
-33
lines changed

4 files changed

+98
-33
lines changed

src/Rules/TooWideTypehints/TooWideTypeCheck.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Rules\TooWideTypehints;
44

5+
use PhpParser\Node\Expr\ConstFetch;
56
use PHPStan\Analyser\Scope;
67
use PHPStan\DependencyInjection\AutowiredParameter;
78
use PHPStan\DependencyInjection\AutowiredService;
@@ -25,8 +26,10 @@
2526
use PHPStan\Type\VerbosityLevel;
2627
use PHPStan\Type\VoidType;
2728
use function count;
29+
use function in_array;
2830
use function lcfirst;
2931
use function sprintf;
32+
use function strtolower;
3033

3134
#[AutowiredService]
3235
final class TooWideTypeCheck
@@ -205,6 +208,18 @@ public function checkFunctionReturnType(
205208

206209
$returnType = TypeCombinator::union(...$returnTypes);
207210

211+
if (
212+
count($returnStatements) === 1
213+
&& $returnStatements[0]->getReturnNode()->expr instanceof ConstFetch
214+
&& in_array(strtolower($returnStatements[0]->getReturnNode()->expr->name->toString()), ['true', 'false'], true)
215+
&& (
216+
$nativeFunctionReturnType->isBoolean()->yes()
217+
|| $phpDocFunctionReturnType->isBoolean()->yes()
218+
)
219+
) {
220+
return [];
221+
}
222+
208223
$unionMessagePattern = sprintf('%s never returns %%s so it can be removed from the return type.', $functionDescription);
209224
$boolMessagePattern = sprintf('%s never returns %%s so the return type can be changed to %%s.', $functionDescription);
210225

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,23 +1107,15 @@ public function testBug8376(): void
11071107
public function testAssertDocblock(): void
11081108
{
11091109
$errors = $this->runAnalyse(__DIR__ . '/nsrt/assert-docblock.php');
1110-
$this->assertCount(8, $errors);
1111-
$this->assertSame('Function AssertDocblock\validateStringArrayIfTrue() never returns false so the return type can be changed to true.', $errors[0]->getMessage());
1112-
$this->assertSame(17, $errors[0]->getLine());
1113-
$this->assertSame('Function AssertDocblock\validateStringArrayIfFalse() never returns true so the return type can be changed to false.', $errors[1]->getMessage());
1114-
$this->assertSame(25, $errors[1]->getLine());
1115-
$this->assertSame('Function AssertDocblock\validateStringOrIntArray() never returns true so the return type can be changed to false.', $errors[2]->getMessage());
1116-
$this->assertSame(34, $errors[2]->getLine());
1117-
$this->assertSame('Function AssertDocblock\validateStringOrNonEmptyIntArray() never returns true so the return type can be changed to false.', $errors[3]->getMessage());
1118-
$this->assertSame(44, $errors[3]->getLine());
1119-
$this->assertSame('Call to method AssertDocblock\A::testInt() with string will always evaluate to false.', $errors[4]->getMessage());
1120-
$this->assertSame(218, $errors[4]->getLine());
1121-
$this->assertSame('Call to method AssertDocblock\A::testNotInt() with string will always evaluate to true.', $errors[5]->getMessage());
1122-
$this->assertSame(224, $errors[5]->getLine());
1123-
$this->assertSame('Call to method AssertDocblock\A::testInt() with int will always evaluate to true.', $errors[6]->getMessage());
1124-
$this->assertSame(232, $errors[6]->getLine());
1125-
$this->assertSame('Call to method AssertDocblock\A::testNotInt() with int will always evaluate to false.', $errors[7]->getMessage());
1126-
$this->assertSame(238, $errors[7]->getLine());
1110+
$this->assertCount(4, $errors);
1111+
$this->assertSame('Call to method AssertDocblock\A::testInt() with string will always evaluate to false.', $errors[0]->getMessage());
1112+
$this->assertSame(218, $errors[0]->getLine());
1113+
$this->assertSame('Call to method AssertDocblock\A::testNotInt() with string will always evaluate to true.', $errors[1]->getMessage());
1114+
$this->assertSame(224, $errors[1]->getLine());
1115+
$this->assertSame('Call to method AssertDocblock\A::testInt() with int will always evaluate to true.', $errors[2]->getMessage());
1116+
$this->assertSame(232, $errors[2]->getLine());
1117+
$this->assertSame('Call to method AssertDocblock\A::testNotInt() with int will always evaluate to false.', $errors[3]->getMessage());
1118+
$this->assertSame(238, $errors[3]->getLine());
11271119
}
11281120

11291121
#[RequiresPhp('>= 8.0')]

tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ public function testBug13384cPhp82(): void
9494
'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.',
9595
100,
9696
],
97+
[
98+
'Function Bug13384c\returnsTrueUnionReturn() never returns int so it can be removed from the return type.',
99+
130,
100+
],
101+
[
102+
'Function Bug13384c\returnsTruePhpdocUnionReturn() never returns int so it can be removed from the return type.',
103+
137,
104+
],
97105
]);
98106
}
99107

@@ -111,12 +119,29 @@ public function testBug13384cPrePhp82(): void
111119
'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.',
112120
100,
113121
],
122+
[
123+
'Function Bug13384c\returnsTrueUnionReturn() never returns int so it can be removed from the return type.',
124+
130,
125+
],
126+
[
127+
'Function Bug13384c\returnsTruePhpdocUnionReturn() never returns int so it can be removed from the return type.',
128+
137,
129+
],
114130
]);
115131
}
116132

117133
public function testBug13384cOff(): void
118134
{
119-
$this->analyse([__DIR__ . '/data/bug-13384c.php'], []);
135+
$this->analyse([__DIR__ . '/data/bug-13384c.php'], [
136+
[
137+
'Function Bug13384c\returnsTrueUnionReturn() never returns int so it can be removed from the return type.',
138+
130,
139+
],
140+
[
141+
'Function Bug13384c\returnsTruePhpdocUnionReturn() never returns int so it can be removed from the return type.',
142+
137,
143+
],
144+
]);
120145
}
121146

122147
public function testNestedTooWideType(): void
Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
<?php
1+
<?php // lint >= 8.0
22

33
namespace Bug13384c;
44

55
function doFoo(): bool {
6-
return false;
6+
return returnsFalse();
77
}
88

99
function doFoo2(): bool {
10-
return true;
10+
return returnsTrue();
1111
}
1212

1313
function doFoo3(): bool {
@@ -20,22 +20,22 @@ function doFoo3(): bool {
2020

2121
class Bug13384c {
2222
public function doBarPublic(): bool {
23-
return false;
23+
return returnsFalse();
2424
}
2525

2626
/**
2727
* @return false
2828
*/
2929
private function doBarPhpdocReturn(): bool {
30-
return false;
30+
return returnsFalse();
3131
}
3232

3333
private function doBar(): bool {
34-
return false;
34+
return returnsFalse();
3535
}
3636

3737
private function doBar2(): bool {
38-
return true;
38+
return returnsTrue();
3939
}
4040

4141
private function doBar3(): bool {
@@ -46,25 +46,25 @@ private function doBar3(): bool {
4646
}
4747

4848
private function doBarMixed() {
49-
return true;
49+
return returnsTrue();
5050
}
5151

5252
/**
5353
* @return bool
5454
*/
5555
private function doBarPhpdoc() {
56-
return true;
56+
return returnsTrue();
5757
}
5858

5959
}
6060

6161
class Bug13384Static {
6262
private static function doBar(): bool {
63-
return false;
63+
return returnsFalse();
6464
}
6565

6666
private static function doBar2(): bool {
67-
return true;
67+
return returnsTrue();
6868
}
6969

7070
private static function doBar3(): bool {
@@ -75,14 +75,14 @@ private static function doBar3(): bool {
7575
}
7676

7777
private static function doBarMixed() {
78-
return true;
78+
return returnsTrue();
7979
}
8080

8181
/**
8282
* @return bool
8383
*/
8484
private static function doBarPhpdoc() {
85-
return true;
85+
return returnsTrue();
8686
}
8787

8888
}
@@ -91,16 +91,49 @@ private static function doBarPhpdoc() {
9191
* @return bool
9292
*/
9393
function doFooPhpdoc() {
94-
return true;
94+
return returnsTrue();
9595
}
9696

9797
/**
9898
* @return bool
9999
*/
100100
function doFooPhpdoc2() {
101-
return false;
101+
return returnsFalse();
102102
}
103103

104104
function doFooMixed() {
105+
return returnsTrue();
106+
}
107+
108+
/**
109+
* @return true
110+
*/
111+
function returnsTrue(): bool {
112+
return true;
113+
}
114+
115+
/**
116+
* @return false
117+
*/
118+
function returnsFalse(): bool {
119+
return false;
120+
}
121+
122+
function returnsTrueNoPhpdoc(): bool {
123+
return true;
124+
}
125+
126+
function returnsFalseNoPhpdoc(): bool {
127+
return false;
128+
}
129+
130+
function returnsTrueUnionReturn(): int|bool {
131+
return true;
132+
}
133+
134+
/**
135+
* @return int|bool
136+
*/
137+
function returnsTruePhpdocUnionReturn() {
105138
return true;
106139
}

0 commit comments

Comments
 (0)