diff --git a/rules/nette/src/NodeAnalyzer/RenderMethodAnalyzer.php b/rules/nette/src/NodeAnalyzer/RenderMethodAnalyzer.php new file mode 100644 index 000000000000..8130e12c72ee --- /dev/null +++ b/rules/nette/src/NodeAnalyzer/RenderMethodAnalyzer.php @@ -0,0 +1,88 @@ +simpleCallableNodeTraverser = $simpleCallableNodeTraverser; + $this->nodeNameResolver = $nodeNameResolver; + $this->scopeNestingComparator = $scopeNestingComparator; + } + + public function hasConditionalTemplateAssigns(ClassMethod $classMethod): bool + { + $hasConditionalAssigns = false; + + $this->simpleCallableNodeTraverser->traverseNodesWithCallable( + $classMethod, + function (Node $node) use (&$hasConditionalAssigns): int { + if (! $node instanceof Assign) { + return null; + } + + if (! $this->isThisTemplatePropertyFetch($node->var)) { + return null; + } + + if ($this->scopeNestingComparator->isNodeConditionallyScoped($node)) { + $hasConditionalAssigns = true; + return NodeTraverser::STOP_TRAVERSAL; + } + + return null; + } + ); + + return $hasConditionalAssigns; + } + + private function isThisTemplatePropertyFetch(Expr $expr): bool + { + if (! $expr instanceof PropertyFetch) { + return false; + } + + if (! $expr->var instanceof PropertyFetch) { + return false; + } + + $nestedPropertyFetch = $expr->var; + if (! $this->nodeNameResolver->isName($nestedPropertyFetch->var, 'this')) { + return false; + } + + return $this->nodeNameResolver->isName($nestedPropertyFetch->name, 'template'); + } +} diff --git a/rules/nette/src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php b/rules/nette/src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php index 9285ac131545..82439fcfb61e 100644 --- a/rules/nette/src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php +++ b/rules/nette/src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php @@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Return_; use Rector\Core\Rector\AbstractRector; +use Rector\Nette\NodeAnalyzer\RenderMethodAnalyzer; use Rector\Nette\NodeFactory\ActionRenderFactory; use Rector\Nette\TemplatePropertyAssignCollector; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -31,12 +32,19 @@ final class TemplateMagicAssignToExplicitVariableArrayRector extends AbstractRec */ private $actionRenderFactory; + /** + * @var RenderMethodAnalyzer + */ + private $renderMethodAnalyzer; + public function __construct( ActionRenderFactory $actionRenderFactory, - TemplatePropertyAssignCollector $templatePropertyAssignCollector + TemplatePropertyAssignCollector $templatePropertyAssignCollector, + RenderMethodAnalyzer $renderMethodAnalyzer ) { $this->templatePropertyAssignCollector = $templatePropertyAssignCollector; $this->actionRenderFactory = $actionRenderFactory; + $this->renderMethodAnalyzer = $renderMethodAnalyzer; } public function getRuleDefinition(): RuleDefinition @@ -126,6 +134,6 @@ private function shouldSkip(ClassMethod $classMethod): bool return true; } - return ! $classMethod->isPublic(); + return $this->renderMethodAnalyzer->hasConditionalTemplateAssigns($classMethod); } }