22
33namespace PHPStan \Rules \TooWideTypehints ;
44
5+ use PhpParser \Node \Expr \ConstFetch ;
56use PHPStan \Analyser \Scope ;
67use PHPStan \DependencyInjection \AutowiredParameter ;
78use PHPStan \DependencyInjection \AutowiredService ;
1314use PHPStan \Rules \IdentifierRuleError ;
1415use PHPStan \Rules \Properties \PropertyReflectionFinder ;
1516use PHPStan \Rules \RuleErrorBuilder ;
17+ use PHPStan \TrinaryLogic ;
1618use PHPStan \Type \Constant \ConstantBooleanType ;
1719use PHPStan \Type \MixedType ;
1820use PHPStan \Type \NullType ;
2527use PHPStan \Type \VerbosityLevel ;
2628use PHPStan \Type \VoidType ;
2729use function count ;
30+ use function in_array ;
2831use function lcfirst ;
2932use function sprintf ;
33+ use function strtolower ;
3034
3135#[AutowiredService]
3236final class TooWideTypeCheck
@@ -176,24 +180,25 @@ public function checkFunctionReturnType(
176180 if (count ($ returnStatements ) === 0 ) {
177181 return [];
178182 }
179- if (
180- count ($ returnStatements ) === 1
181- && (
182- $ nativeFunctionReturnType ->isBoolean ()->yes ()
183- || $ phpDocFunctionReturnType ->isBoolean ()->yes ()
184- )
185- ) {
186- return [];
187- }
188183
189184 $ returnTypes = [];
185+ $ returnsLiteralTrueFalse = [];
190186 foreach ($ returnStatements as $ returnStatement ) {
191187 $ returnNode = $ returnStatement ->getReturnNode ();
192188 if ($ returnNode ->expr === null ) {
193189 $ returnTypes [] = new VoidType ();
194190 continue ;
195191 }
196192
193+ if (
194+ $ returnNode ->expr instanceof ConstFetch
195+ && in_array (strtolower ($ returnNode ->expr ->name ->toString ()), ['true ' , 'false ' ], true )
196+ ) {
197+ $ returnsLiteralTrueFalse [] = TrinaryLogic::createYes ();
198+ } else {
199+ $ returnsLiteralTrueFalse [] = TrinaryLogic::createNo ();
200+ }
201+ 197202 $ returnTypes [] = $ returnStatement ->getScope ()->getType ($ returnNode ->expr );
198203 }
199204
@@ -214,6 +219,18 @@ public function checkFunctionReturnType(
214219
215220 $ returnType = TypeCombinator::union (...$ returnTypes );
216221
222+ if (
223+ count ($ returnStatements ) === 1
224+ && $ returnsLiteralTrueFalse !== []
225+ && TrinaryLogic::extremeIdentity (...$ returnsLiteralTrueFalse )->yes ()
226+ && (
227+ $ nativeFunctionReturnType ->isBoolean ()->yes ()
228+ || $ phpDocFunctionReturnType ->isBoolean ()->yes ()
229+ )
230+ ) {
231+ return [];
232+ }
233+ 217234 $ unionMessagePattern = sprintf ('%s never returns %%s so it can be removed from the return type. ' , $ functionDescription );
218235 $ boolMessagePattern = sprintf ('%s never returns %%s so the return type can be changed to %%s. ' , $ functionDescription );
219236
0 commit comments