%PDF- %PDF-
Direktori : /home2/vacivi36/code/vendor/rector/rector/src/Exclusion/ |
Current File : //home2/vacivi36/code/vendor/rector/rector/src/Exclusion/ExclusionManager.php |
<?php declare (strict_types=1); namespace Rector\Core\Exclusion; use PhpParser\Node; use PhpParser\Node\Const_; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\PropertyProperty; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\Core\Contract\Rector\PhpRectorInterface; use Rector\Core\Contract\Rector\RectorInterface; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\Util\StringUtils; use Rector\NodeTypeResolver\Node\AttributeKey; /** * @see \Rector\Core\Tests\Exclusion\ExclusionManagerTest */ final class ExclusionManager { /** * @var string * @see https://regex101.com/r/DKW6RE/1 */ private const NO_RECTOR_START_REGEX = '#@noRector$#'; /** * @readonly * @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory */ private $phpDocInfoFactory; public function __construct(PhpDocInfoFactory $phpDocInfoFactory) { $this->phpDocInfoFactory = $phpDocInfoFactory; } /** * @param class-string<PhpRectorInterface> $rectorClass */ public function isNodeSkippedByRector(Node $node, string $rectorClass) : bool { if ($node instanceof PropertyProperty || $node instanceof Const_) { $node = $node->getAttribute(AttributeKey::PARENT_NODE); if (!$node instanceof Node) { return \false; } } if ($this->hasNoRectorPhpDocTagMatch($node, $rectorClass)) { return \true; } if ($node instanceof Stmt) { return \false; } // recurse up until a Stmt node is found since it might contain a noRector $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE); if (!$parentNode instanceof Node) { return \false; } return $this->isNodeSkippedByRector($parentNode, $rectorClass); } /** * @param class-string<PhpRectorInterface> $rectorClass */ private function hasNoRectorPhpDocTagMatch(Node $node, string $rectorClass) : bool { $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); /** @var PhpDocTagNode[] $noRectorTags */ $noRectorTags = \array_merge($phpDocInfo->getTagsByName('noRector'), $phpDocInfo->getTagsByName('norector')); if ($this->matchesNoRectorTag($noRectorTags, $rectorClass)) { return \true; } return $this->matchesNoRectorComment($node, $rectorClass); } /** * @param PhpDocTagNode[] $noRectorPhpDocTagNodes * @param class-string<RectorInterface> $rectorClass */ private function matchesNoRectorTag(array $noRectorPhpDocTagNodes, string $rectorClass) : bool { foreach ($noRectorPhpDocTagNodes as $noRectorPhpDocTagNode) { if (!$noRectorPhpDocTagNode->value instanceof GenericTagValueNode) { throw new ShouldNotHappenException(); } $description = $noRectorPhpDocTagNode->value->value; if ($description === '') { return \true; } $description = \ltrim($description, '\\'); if ($description === $rectorClass) { return \true; } if (!\is_a($description, RectorInterface::class, \true)) { return \true; } } return \false; } /** * @param class-string<RectorInterface> $rectorClass */ private function matchesNoRectorComment(Node $node, string $rectorClass) : bool { foreach ($node->getComments() as $comment) { if (StringUtils::isMatch($comment->getText(), self::NO_RECTOR_START_REGEX)) { return \true; } $noRectorWithRule = '#@noRector \\\\?' . \preg_quote($rectorClass, '#') . '$#'; if (StringUtils::isMatch($comment->getText(), $noRectorWithRule)) { return \true; } } return \false; } }