Skip to content

Commit 133a54f

Browse files
github-actions[bot]phpstan-bot
authored andcommitted
Fix crash on first-class callable in do-while condition
- Added printer methods for MethodCallableNode, FunctionCallableNode, StaticMethodCallableNode, and InstantiationCallableNode to Printer - These nodes delegate to printing their original AST node - The crash occurred because filterByTruthyValue/filterByFalseyValue tried to print callable nodes that had no printer method - New regression test in tests/PHPStan/Analyser/data/bug-12246.php Closes phpstan/phpstan#12246
1 parent 3222c52 commit 133a54f

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

src/Node/Printer/Printer.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
use PHPStan\Node\Expr\SetOffsetValueTypeExpr;
2424
use PHPStan\Node\Expr\TypeExpr;
2525
use PHPStan\Node\Expr\UnsetOffsetExpr;
26+
use PHPStan\Node\FunctionCallableNode;
27+
use PHPStan\Node\InstantiationCallableNode;
2628
use PHPStan\Node\IssetExpr;
29+
use PHPStan\Node\MethodCallableNode;
30+
use PHPStan\Node\StaticMethodCallableNode;
2731
use PHPStan\Type\VerbosityLevel;
2832
use function sprintf;
2933

@@ -134,4 +138,24 @@ protected function pPHPStan_Node_BooleanAndNode(BooleanAndNode $expr): string //
134138
return sprintf('__phpstanBooleanAnd(%s, %s)', $this->p($expr->getOriginalNode()->left), $this->p($expr->getOriginalNode()->right));
135139
}
136140

141+
protected function pPHPStan_Node_FunctionCallableNode(FunctionCallableNode $expr): string // phpcs:ignore
142+
{
143+
return $this->p($expr->getOriginalNode());
144+
}
145+
146+
protected function pPHPStan_Node_MethodCallableNode(MethodCallableNode $expr): string // phpcs:ignore
147+
{
148+
return $this->p($expr->getOriginalNode());
149+
}
150+
151+
protected function pPHPStan_Node_StaticMethodCallableNode(StaticMethodCallableNode $expr): string // phpcs:ignore
152+
{
153+
return $this->p($expr->getOriginalNode());
154+
}
155+
156+
protected function pPHPStan_Node_InstantiationCallableNode(InstantiationCallableNode $expr): string // phpcs:ignore
157+
{
158+
return $this->p($expr->getOriginalNode());
159+
}
160+
137161
}

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,14 @@ public function testBug13945Two(): void
16561656
$this->assertNoErrors($errors);
16571657
}
16581658

1659+
public function testBug12246(): void
1660+
{
1661+
$errors = $this->runAnalyse(__DIR__ . '/data/bug-12246.php');
1662+
$this->assertCount(1, $errors);
1663+
$this->assertSame('Do-while loop condition is always true.', $errors[0]->getMessage());
1664+
$this->assertSame(11, $errors[0]->getLine());
1665+
}
1666+
16591667
public function testBigPhpdocArrayShape(): void
16601668
{
16611669
$errors = $this->runAnalyse(__DIR__ . '/nsrt/bug-14012b.php');
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12246;
4+
5+
final class SkipFirstClassCallableInDo
6+
{
7+
public function getSubscribedEvents(): void
8+
{
9+
do {
10+
11+
} while ($this->textElement(...));
12+
}
13+
14+
public function textElement(): int
15+
{
16+
return 1;
17+
}
18+
}

0 commit comments

Comments
 (0)