Skip to content

Commit c427740

Browse files
Fix ConstantArrayType::isCallable
1 parent 5e3a364 commit c427740

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,19 @@ public function isCallable(): TrinaryLogic
468468
$typeAndMethods,
469469
);
470470

471-
return TrinaryLogic::createYes()->and(...$results);
471+
$isCallable = TrinaryLogic::createYes()->and(...$results);
472+
if ($isCallable->yes()) {
473+
$callableArray = $this->getClassOrObjectAndMethods();
474+
if ($callableArray !== []) {
475+
[$classOrObject, $methods] = $callableArray;
476+
477+
if (count($methods->getConstantStrings()) !== count($typeAndMethods)) {
478+
return TrinaryLogic::createMaybe();
479+
}
480+
}
481+
}
482+
483+
return $isCallable;
472484
}
473485

474486
public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array

tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,4 +1102,11 @@ public function testAlwaysTruePregMatch(): void
11021102
$this->analyse([__DIR__ . '/data/always-true-preg-match.php'], []);
11031103
}
11041104

1105+
public function testBug12063(): void
1106+
{
1107+
$this->checkAlwaysTrueCheckTypeFunctionCall = true;
1108+
$this->treatPhpDocTypesAsCertain = true;
1109+
$this->analyse([__DIR__ . '/data/bug-12063.php'], []);
1110+
}
1111+
11051112
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php declare(strict_types=1); // lint >= 7.4
2+
3+
namespace Bug12063;
4+
5+
use BadFunctionCallException;
6+
7+
final class View
8+
{
9+
public function existingMethod(): void
10+
{
11+
}
12+
}
13+
14+
final class TwigExtension
15+
{
16+
private View $viewFunctions;
17+
18+
public function __construct(View $viewFunctions)
19+
{
20+
$this->viewFunctions = $viewFunctions;
21+
}
22+
23+
public function iterateFunctions(): void
24+
{
25+
$functionMappings = [
26+
'i_exist' => 'existingMethod',
27+
'i_dont_exist' => 'nonExistingMethod'
28+
];
29+
30+
$functions = [];
31+
foreach ($functionMappings as $nameFrom => $nameTo) {
32+
$callable = [$this->viewFunctions, $nameTo];
33+
if (!is_callable($callable)) {
34+
throw new BadFunctionCallException("Function $nameTo does not exist in view functions");
35+
}
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)