/home/smartonegroup/www/system/vendor/rector/rector/src/ProcessAnalyzer/RectifiedAnalyzer.php
<?php

declare (strict_types=1);
namespace Rector\Core\ProcessAnalyzer;

use PhpParser\Node;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\ValueObject\RectifiedNode;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
 * This service verify if the Node already rectified with same Rector rule before current Rector rule with condition
 *
 *        Same Rector Rule <-> Same Node <-> Same File
 *
 *  For both non-consecutive or consecutive order.
 */
final class RectifiedAnalyzer
{
    /**
     * @var array<string, RectifiedNode|null>
     */
    private $previousFileWithNodes = [];
    /**
     * @readonly
     * @var \Rector\Core\PhpParser\Comparing\NodeComparator
     */
    private $nodeComparator;
    public function __construct(NodeComparator $nodeComparator)
    {
        $this->nodeComparator = $nodeComparator;
    }
    /**
     * @param class-string<RectorInterface> $rectorClass
     */
    public function verify(string $rectorClass, Node $node, string $filePath) : ?RectifiedNode
    {
        $originalNode = $node->getAttribute(AttributeKey::ORIGINAL_NODE);
        if ($this->hasCreatedByRule($rectorClass, $node, $originalNode)) {
            return new RectifiedNode($rectorClass, $node);
        }
        if (!isset($this->previousFileWithNodes[$filePath])) {
            $this->previousFileWithNodes[$filePath] = new RectifiedNode($rectorClass, $node);
            return null;
        }
        /** @var RectifiedNode $rectifiedNode */
        $rectifiedNode = $this->previousFileWithNodes[$filePath];
        if ($this->shouldContinue($rectifiedNode, $rectorClass, $node, $originalNode)) {
            return null;
        }
        if ($this->previousFileWithNodes[$filePath]->getNode() === $node) {
            // re-set to refill next
            $this->previousFileWithNodes[$filePath] = null;
        }
        return $rectifiedNode;
    }
    /**
     * @param class-string<RectorInterface> $rectorClass
     */
    private function hasCreatedByRule(string $rectorClass, Node $node, ?Node $originalNode) : bool
    {
        if (!$originalNode instanceof Node) {
            $createdByRule = $node->getAttribute(AttributeKey::CREATED_BY_RULE) ?? [];
            \end($createdByRule);
            $lastRectorRuleKey = \key($createdByRule);
            if ($lastRectorRuleKey === null) {
                return \false;
            }
            return $createdByRule[$lastRectorRuleKey] === $rectorClass;
        }
        $createdByRule = $originalNode->getAttribute(AttributeKey::CREATED_BY_RULE) ?? [];
        return \in_array($rectorClass, $createdByRule, \true);
    }
    /**
     * @param class-string<RectorInterface> $rectorClass
     */
    private function shouldContinue(RectifiedNode $rectifiedNode, string $rectorClass, Node $node, ?Node $originalNode) : bool
    {
        $rectifiedNodeClass = $rectifiedNode->getRectorClass();
        $rectifiedNodeNode = $rectifiedNode->getNode();
        if ($rectifiedNodeClass === $rectorClass && $rectifiedNodeNode === $node) {
            /**
             * allow to revisit the Node with same Rector rule if Node is changed by other rule
             */
            return !$this->nodeComparator->areNodesEqual($originalNode, $node);
        }
        if ($originalNode instanceof Node) {
            return \true;
        }
        $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
        if (!$parentNode instanceof Node) {
            return \true;
        }
        $parentOriginalNode = $parentNode->getAttribute(AttributeKey::ORIGINAL_NODE);
        if ($parentOriginalNode instanceof Node) {
            return \true;
        }
        /**
         * Start token pos must be < 0 to continue, as the node and parent node just re-printed
         *
         * - Node's original node is null
         * - Parent Node's original node is null
         */
        $startTokenPos = $node->getStartTokenPos();
        return $startTokenPos < 0;
    }
}