diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 603035e2d1..2a0f622fb5 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -3653,31 +3653,6 @@ static function (): void { } else { $classReflection = $this->reflectionProvider->getAnonymousClassReflection($expr->class, $scope); // populates $expr->class->name - $constructorResult = null; - $this->processStmtNode($expr->class, $scope, static function (Node $node, Scope $scope) use ($nodeCallback, $classReflection, &$constructorResult): void { - $nodeCallback($node, $scope); - if (!$node instanceof MethodReturnStatementsNode) { - return; - } - if ($constructorResult !== null) { - return; - } - $currentClassReflection = $node->getClassReflection(); - if ($currentClassReflection->getName() !== $classReflection->getName()) { - return; - } - if (!$currentClassReflection->hasConstructor()) { - return; - } - if ($currentClassReflection->getConstructor()->getName() !== $node->getMethodReflection()->getName()) { - return; - } - $constructorResult = $node; - }, StatementContext::createTopLevel()); - if ($constructorResult !== null) { - $throwPoints = array_merge($throwPoints, $constructorResult->getStatementResult()->getThrowPoints()); - $impurePoints = array_merge($impurePoints, $constructorResult->getImpurePoints()); - } if ($classReflection->hasConstructor()) { $constructorReflection = $classReflection->getConstructor(); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( @@ -3686,6 +3661,54 @@ static function (): void { $constructorReflection->getVariants(), $constructorReflection->getNamedArgumentsVariants(), ); + + if ($constructorReflection->getDeclaringClass()->getName() === $classReflection->getName()) { + $constructorResult = null; + $this->processStmtNode($expr->class, $scope, static function (Node $node, Scope $scope) use ($nodeCallback, $classReflection, &$constructorResult): void { + $nodeCallback($node, $scope); + if (!$node instanceof MethodReturnStatementsNode) { + return; + } + if ($constructorResult !== null) { + return; + } + $currentClassReflection = $node->getClassReflection(); + if ($currentClassReflection->getName() !== $classReflection->getName()) { + return; + } + if (!$currentClassReflection->hasConstructor()) { + return; + } + if ($currentClassReflection->getConstructor()->getName() !== $node->getMethodReflection()->getName()) { + return; + } + $constructorResult = $node; + }, StatementContext::createTopLevel()); + if ($constructorResult !== null) { + $throwPoints = $constructorResult->getStatementResult()->getThrowPoints(); + $impurePoints = $constructorResult->getImpurePoints(); + } + } else { + $this->processStmtNode($expr->class, $scope, $nodeCallback, StatementContext::createTopLevel()); + $declaringClass = $constructorReflection->getDeclaringClass(); + $constructorThrowPoint = $this->getConstructorThrowPoint($constructorReflection, $parametersAcceptor, $classReflection, $expr, new Name\FullyQualified($declaringClass->getName()), $expr->getArgs(), $scope); + if ($constructorThrowPoint !== null) { + $throwPoints[] = $constructorThrowPoint; + } + + if (!$constructorReflection->hasSideEffects()->no()) { + $certain = $constructorReflection->isPure()->no(); + $impurePoints[] = new ImpurePoint( + $scope, + $expr, + 'new', + sprintf('instantiation of class %s', $declaringClass->getDisplayName()), + $certain, + ); + } + } + } else { + $this->processStmtNode($expr->class, $scope, $nodeCallback, StatementContext::createTopLevel()); } } diff --git a/tests/PHPStan/Rules/DeadCode/NoopRuleTest.php b/tests/PHPStan/Rules/DeadCode/NoopRuleTest.php index 5750c03c3e..4937c46546 100644 --- a/tests/PHPStan/Rules/DeadCode/NoopRuleTest.php +++ b/tests/PHPStan/Rules/DeadCode/NoopRuleTest.php @@ -158,4 +158,18 @@ public function testBug13067(): void $this->analyse([__DIR__ . '/data/bug-13067.php'], []); } + public function testBug13698(): void + { + $this->analyse([__DIR__ . '/data/bug-13698.php'], [ + [ + 'Expression "new class extends \Bug13698\NoConstructorClass…" on a separate line does not do anything.', + 47, + ], + [ + 'Expression "new class…" on a separate line does not do anything.', + 50, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/DeadCode/data/bug-13698.php b/tests/PHPStan/Rules/DeadCode/data/bug-13698.php new file mode 100644 index 0000000000..89d0b2f84a --- /dev/null +++ b/tests/PHPStan/Rules/DeadCode/data/bug-13698.php @@ -0,0 +1,52 @@ +