diff --git a/src/DependencyInjection/LazyContainerFactory.php b/src/DependencyInjection/LazyContainerFactory.php index 0853f805ac7..07c8b196614 100644 --- a/src/DependencyInjection/LazyContainerFactory.php +++ b/src/DependencyInjection/LazyContainerFactory.php @@ -103,6 +103,7 @@ use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\ContextNodeVisitor; use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\GlobalVariableNodeVisitor; use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\NameNodeVisitor; +use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\PhpVersionConditionNodeVisitor; use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\PropertyOrClassConstDefaultNodeVisitor; use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\StaticVariableNodeVisitor; use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\SymfonyClosureNodeVisitor; @@ -239,6 +240,7 @@ final class LazyContainerFactory */ private const DECORATING_NODE_VISITOR_CLASSES = [ ArgNodeVisitor::class, + PhpVersionConditionNodeVisitor::class, AssignedToNodeVisitor::class, SymfonyClosureNodeVisitor::class, ByRefReturnNodeVisitor::class, diff --git a/src/NodeTypeResolver/Node/AttributeKey.php b/src/NodeTypeResolver/Node/AttributeKey.php index 46f4f41c5c8..fd68ae8b3ac 100644 --- a/src/NodeTypeResolver/Node/AttributeKey.php +++ b/src/NodeTypeResolver/Node/AttributeKey.php @@ -296,4 +296,6 @@ final class AttributeKey public const IS_INSIDE_BYREF_FUNCTION_LIKE = 'is_inside_byref_function_like'; public const CLASS_CONST_FETCH_NAME = 'class_const_fetch_name'; + + public const PHP_VERSION_CONDITIONED = 'php_version_conditioned'; } diff --git a/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/PhpVersionConditionNodeVisitor.php b/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/PhpVersionConditionNodeVisitor.php new file mode 100644 index 00000000000..7127ae5deb2 --- /dev/null +++ b/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/PhpVersionConditionNodeVisitor.php @@ -0,0 +1,52 @@ +hasVersionCompareCond($node)) { + if ($node instanceof Ternary) { + $nodes = [$node->else]; + if ($node->if instanceof \PhpParser\Node) { + $nodes[] = $node->if; + } + } else { + $nodes = $node->stmts; + } + + SimpleNodeTraverser::decorateWithAttributeValue($nodes, AttributeKey::PHP_VERSION_CONDITIONED, true); + } + + return null; + } + + private function hasVersionCompareCond(If_|Ternary $ifOrTernary): bool + { + if (! $ifOrTernary->cond instanceof FuncCall) { + return false; + } + + $versionCompare = $this->conditionResolver->resolveFromExpr($ifOrTernary->cond); + return $versionCompare instanceof VersionCompareCondition; + } +}