Skip to content

Commit d07c200

Browse files
committed
analyseExpr - guard against multiple analyses
1 parent 9c60d07 commit d07c200

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

src/Analyser/Generator/GeneratorNodeScopeResolver.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPStan\Analyser\StatementContext;
1313
use PHPStan\DependencyInjection\Container;
1414
use PHPStan\NeverException;
15+
use PHPStan\Node\Printer\ExprPrinter;
1516
use PHPStan\ShouldNotHappenException;
1617
use function array_map;
1718
use function array_merge;
@@ -62,6 +63,7 @@ final class GeneratorNodeScopeResolver
6263
{
6364

6465
public function __construct(
66+
private ExprPrinter $exprPrinter,
6567
private Container $container,
6668
)
6769
{
@@ -271,6 +273,10 @@ private function analyseStmt(Stmt $stmt, GeneratorScope $scope, StatementContext
271273
*/
272274
private function analyseExpr(ExprAnalysisResultStorage $storage, Stmt $stmt, Expr $expr, GeneratorScope $scope, ExpressionContext $context, ?callable $alternativeNodeCallback): Generator
273275
{
276+
if ($storage->lookupExprAnalysisResult($expr) !== null) {
277+
throw new ShouldNotHappenException(sprintf('Expr %s on line %d has already been analysed', $this->exprPrinter->printExpr($expr), $expr->getStartLine()));
278+
}
279+
274280
if ($alternativeNodeCallback === null) {
275281
yield new NodeCallbackRequest($expr, $scope);
276282
} else {

tests/PHPStan/Analyser/Generator/GeneratorNodeScopeResolverRuleTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
7+
use PHPStan\Node\Printer\ExprPrinter;
78
use PHPStan\Rules\IdentifierRuleError;
89
use PHPStan\Rules\Rule;
910
use PHPStan\Rules\RuleErrorBuilder;
@@ -108,7 +109,10 @@ public function testRule(callable $ruleCallback, array $expectedErrors): void
108109

109110
protected function createNodeScopeResolver(): GeneratorNodeScopeResolver
110111
{
111-
return new GeneratorNodeScopeResolver(self::getContainer());
112+
return new GeneratorNodeScopeResolver(
113+
self::getContainer()->getByType(ExprPrinter::class),
114+
self::getContainer(),
115+
);
112116
}
113117

114118
}

tests/PHPStan/Analyser/Generator/GeneratorNodeScopeResolverTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Analyser\Generator;
44

5+
use PHPStan\Node\Printer\ExprPrinter;
56
use PHPStan\Testing\TypeInferenceTestCase;
67
use PHPUnit\Framework\Attributes\DataProvider;
78
use PHPUnit\Framework\Attributes\RequiresPhp;
@@ -30,7 +31,10 @@ public function testFileAsserts(
3031

3132
protected static function createNodeScopeResolver(): GeneratorNodeScopeResolver
3233
{
33-
return new GeneratorNodeScopeResolver(self::getContainer());
34+
return new GeneratorNodeScopeResolver(
35+
self::getContainer()->getByType(ExprPrinter::class),
36+
self::getContainer(),
37+
);
3438
}
3539

3640
public static function getAdditionalConfigFiles(): array

0 commit comments

Comments
 (0)