|
6 | 6 | use PhpParser\Node; |
7 | 7 | use PhpParser\Node\Arg; |
8 | 8 | use PhpParser\Node\Expr; |
9 | | -use PhpParser\Node\Expr\BinaryOp; |
10 | 9 | use PhpParser\Node\Expr\FuncCall; |
11 | 10 | use PhpParser\Node\Expr\MethodCall; |
12 | 11 | use PhpParser\Node\Expr\PropertyFetch; |
|
19 | 18 | use PHPStan\Analyser\ExpressionResult; |
20 | 19 | use PHPStan\Analyser\ExpressionResultStorage; |
21 | 20 | use PHPStan\Analyser\ExprHandler; |
| 21 | +use PHPStan\Analyser\ExprHandler\Helper\OutputBufferHelper; |
22 | 22 | use PHPStan\Analyser\ExprHandler\Helper\VoidToNullTypeTransformer; |
23 | 23 | use PHPStan\Analyser\ImpurePoint; |
24 | 24 | use PHPStan\Analyser\InternalThrowPoint; |
|
53 | 53 | use PHPStan\Type\ClosureType; |
54 | 54 | use PHPStan\Type\Constant\ConstantArrayType; |
55 | 55 | use PHPStan\Type\Constant\ConstantArrayTypeBuilder; |
56 | | -use PHPStan\Type\Constant\ConstantIntegerType; |
57 | 56 | use PHPStan\Type\ErrorType; |
58 | 57 | use PHPStan\Type\GeneralizePrecision; |
59 | 58 | use PHPStan\Type\Generic\TemplateTypeHelper; |
@@ -572,29 +571,18 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex |
572 | 571 | $scope = $scope->afterOpenSslCall($functionReflection->getName()); |
573 | 572 | } |
574 | 573 |
|
575 | | - if ($functionReflection !== null) { |
576 | | - $functionName = $functionReflection->getName(); |
577 | | - if ($functionName === 'ob_start') { |
578 | | - $outputBufferDelta = 1; |
579 | | - } elseif (in_array($functionName, ['ob_get_clean', 'ob_get_flush', 'ob_end_clean', 'ob_end_flush'], true)) { |
580 | | - $outputBufferDelta = -1; |
581 | | - } else { |
582 | | - $outputBufferDelta = 0; |
583 | | - } |
584 | | - if ($outputBufferDelta !== 0) { |
585 | | - $obGetLevelCall = new FuncCall(new Name('ob_get_level'), []); |
586 | | - $scope = $scope->assignExpression( |
587 | | - $obGetLevelCall, |
588 | | - $scope->getType(new BinaryOp\Plus( |
589 | | - new TypeExpr($scope->getType($obGetLevelCall)), |
590 | | - new TypeExpr(new ConstantIntegerType($outputBufferDelta)), |
591 | | - )), |
592 | | - $scope->getType(new BinaryOp\Plus( |
593 | | - new TypeExpr($scope->getNativeType($obGetLevelCall)), |
594 | | - new TypeExpr(new ConstantIntegerType($outputBufferDelta)), |
595 | | - )), |
596 | | - ); |
597 | | - } |
| 574 | + $outputBufferDelta = $functionReflection !== null ? OutputBufferHelper::getLevelDelta($functionReflection->getName()) : 0; |
| 575 | + if ($outputBufferDelta !== 0) { |
| 576 | + $scope = OutputBufferHelper::applyLevelDelta($scope, $outputBufferDelta); |
| 577 | + } |
| 578 | + |
| 579 | + $pureCallable = $parametersAcceptor instanceof CallableParametersAcceptor |
| 580 | + && count($parametersAcceptor->getImpurePoints()) === 0; |
| 581 | + if ( |
| 582 | + ($functionReflection !== null && !$functionReflection->isBuiltin() && !$functionReflection->hasSideEffects()->no()) |
| 583 | + || ($functionReflection === null && !$pureCallable) |
| 584 | + ) { |
| 585 | + $scope = $scope->invalidateVolatileExpressions(); |
598 | 586 | } |
599 | 587 |
|
600 | 588 | return new ExpressionResult( |
|
0 commit comments