2019-10-13 05:59:52 +00:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2021-02-09 17:25:16 +00:00
|
|
|
namespace Rector\Privatization\NodeManipulator;
|
2018-07-31 08:54:00 +00:00
|
|
|
|
|
|
|
use PhpParser\Node;
|
2021-02-23 01:25:34 +00:00
|
|
|
use PhpParser\Node\Stmt;
|
2018-07-31 08:54:00 +00:00
|
|
|
use PhpParser\Node\Stmt\Class_;
|
2018-07-31 09:15:27 +00:00
|
|
|
use PhpParser\Node\Stmt\ClassConst;
|
2018-07-31 08:54:00 +00:00
|
|
|
use PhpParser\Node\Stmt\ClassMethod;
|
|
|
|
use PhpParser\Node\Stmt\Property;
|
2020-02-06 21:48:18 +00:00
|
|
|
use Rector\Core\Exception\InvalidNodeTypeException;
|
2020-12-24 22:01:30 +00:00
|
|
|
use Rector\Core\ValueObject\Visibility;
|
2021-06-29 00:31:58 +00:00
|
|
|
use RectorPrefix20210629\Webmozart\Assert\Assert;
|
2019-02-27 21:54:39 +00:00
|
|
|
final class VisibilityManipulator
|
2018-07-31 08:54:00 +00:00
|
|
|
{
|
2018-07-31 09:15:27 +00:00
|
|
|
/**
|
2021-02-23 01:25:34 +00:00
|
|
|
* @var array<class-string<Stmt>>
|
2018-07-31 09:15:27 +00:00
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private const ALLOWED_NODE_TYPES = [\PhpParser\Node\Stmt\ClassMethod::class, \PhpParser\Node\Stmt\Property::class, \PhpParser\Node\Stmt\ClassConst::class, \PhpParser\Node\Stmt\Class_::class];
|
2019-02-09 13:22:20 +00:00
|
|
|
/**
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makeStatic(\PhpParser\Node $node) : void
|
2019-02-09 13:22:20 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->addVisibilityFlag($node, \Rector\Core\ValueObject\Visibility::STATIC);
|
2019-02-09 13:22:20 +00:00
|
|
|
}
|
2019-05-26 11:47:23 +00:00
|
|
|
/**
|
|
|
|
* @param ClassMethod|Class_ $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makeAbstract(\PhpParser\Node $node) : void
|
2019-05-26 11:47:23 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->addVisibilityFlag($node, \Rector\Core\ValueObject\Visibility::ABSTRACT);
|
2019-05-26 11:47:23 +00:00
|
|
|
}
|
2020-09-10 07:27:03 +00:00
|
|
|
/**
|
2020-09-17 07:34:27 +00:00
|
|
|
* @param ClassMethod|Property $node
|
2020-09-10 07:27:03 +00:00
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makeNonStatic(\PhpParser\Node $node) : void
|
2020-09-10 07:27:03 +00:00
|
|
|
{
|
2021-05-09 20:15:43 +00:00
|
|
|
if (!$node->isStatic()) {
|
2020-09-17 07:34:27 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
$node->flags -= \PhpParser\Node\Stmt\Class_::MODIFIER_STATIC;
|
2020-09-10 07:27:03 +00:00
|
|
|
}
|
2019-08-25 10:29:15 +00:00
|
|
|
/**
|
|
|
|
* @param Class_|ClassMethod $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makeFinal(\PhpParser\Node $node) : void
|
2019-08-25 10:29:15 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->addVisibilityFlag($node, \Rector\Core\ValueObject\Visibility::FINAL);
|
2019-08-25 10:29:15 +00:00
|
|
|
}
|
2020-12-05 21:33:30 +00:00
|
|
|
/**
|
|
|
|
* @param Class_|ClassMethod $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makeNonFinal(\PhpParser\Node $node) : void
|
2020-12-05 21:33:30 +00:00
|
|
|
{
|
2021-05-09 20:15:43 +00:00
|
|
|
if (!$node->isFinal()) {
|
2020-12-05 21:33:30 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
$node->flags -= \PhpParser\Node\Stmt\Class_::MODIFIER_FINAL;
|
2020-12-05 21:33:30 +00:00
|
|
|
}
|
2020-11-17 10:45:31 +00:00
|
|
|
/**
|
|
|
|
* This way "abstract", "static", "final" are kept
|
|
|
|
*
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function removeVisibility(\PhpParser\Node $node) : void
|
2020-11-17 10:45:31 +00:00
|
|
|
{
|
|
|
|
$this->ensureIsClassMethodOrProperty($node, __METHOD__);
|
|
|
|
// no modifier
|
|
|
|
if ($node->flags === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ($node->isPublic()) {
|
2021-05-10 22:23:08 +00:00
|
|
|
$node->flags -= \PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC;
|
2020-11-17 10:45:31 +00:00
|
|
|
}
|
|
|
|
if ($node->isProtected()) {
|
2021-05-10 22:23:08 +00:00
|
|
|
$node->flags -= \PhpParser\Node\Stmt\Class_::MODIFIER_PROTECTED;
|
2020-11-17 10:45:31 +00:00
|
|
|
}
|
|
|
|
if ($node->isPrivate()) {
|
2021-05-10 22:23:08 +00:00
|
|
|
$node->flags -= \PhpParser\Node\Stmt\Class_::MODIFIER_PRIVATE;
|
2020-11-17 10:45:31 +00:00
|
|
|
}
|
|
|
|
}
|
2020-11-27 21:29:40 +00:00
|
|
|
/**
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function changeNodeVisibility(\PhpParser\Node $node, int $visibility) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2021-06-29 00:31:58 +00:00
|
|
|
\RectorPrefix20210629\Webmozart\Assert\Assert::oneOf($visibility, [\Rector\Core\ValueObject\Visibility::PUBLIC, \Rector\Core\ValueObject\Visibility::PROTECTED, \Rector\Core\ValueObject\Visibility::PRIVATE, \Rector\Core\ValueObject\Visibility::STATIC, \Rector\Core\ValueObject\Visibility::ABSTRACT, \Rector\Core\ValueObject\Visibility::FINAL]);
|
2020-12-24 23:18:02 +00:00
|
|
|
$this->replaceVisibilityFlag($node, $visibility);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makePublic(\PhpParser\Node $node) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->replaceVisibilityFlag($node, \Rector\Core\ValueObject\Visibility::PUBLIC);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makeProtected(\PhpParser\Node $node) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->replaceVisibilityFlag($node, \Rector\Core\ValueObject\Visibility::PROTECTED);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function makePrivate(\PhpParser\Node $node) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->replaceVisibilityFlag($node, \Rector\Core\ValueObject\Visibility::PRIVATE);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
public function removeFinal(\PhpParser\Node\Stmt\Class_ $class) : void
|
2021-02-08 21:00:45 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$class->flags -= \PhpParser\Node\Stmt\Class_::MODIFIER_FINAL;
|
2021-02-08 21:00:45 +00:00
|
|
|
}
|
2018-07-31 09:15:27 +00:00
|
|
|
/**
|
2019-05-26 11:47:23 +00:00
|
|
|
* @param Class_|ClassMethod|Property|ClassConst $node
|
2018-07-31 09:15:27 +00:00
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function addVisibilityFlag(\PhpParser\Node $node, int $visibility) : void
|
2018-07-31 09:15:27 +00:00
|
|
|
{
|
|
|
|
$this->ensureIsClassMethodOrProperty($node, __METHOD__);
|
2020-12-24 22:01:30 +00:00
|
|
|
$node->flags |= $visibility;
|
2018-07-31 09:15:27 +00:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
private function ensureIsClassMethodOrProperty(\PhpParser\Node $node, string $location) : void
|
2018-07-31 08:54:00 +00:00
|
|
|
{
|
2020-02-14 23:21:14 +00:00
|
|
|
foreach (self::ALLOWED_NODE_TYPES as $allowedNodeType) {
|
2021-05-09 20:15:43 +00:00
|
|
|
if (\is_a($node, $allowedNodeType, \true)) {
|
2018-07-31 09:15:27 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-07-31 08:54:00 +00:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
throw new \Rector\Core\Exception\InvalidNodeTypeException(\sprintf('"%s" only accepts "%s" types. "%s" given.', $location, \implode('", "', self::ALLOWED_NODE_TYPES), \get_class($node)));
|
2018-07-31 08:54:00 +00:00
|
|
|
}
|
2020-11-30 09:51:11 +00:00
|
|
|
/**
|
|
|
|
* @param ClassMethod|Property|ClassConst $node
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function replaceVisibilityFlag(\PhpParser\Node $node, int $visibility) : void
|
2020-11-30 09:51:11 +00:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
$isStatic = $node instanceof \PhpParser\Node\Stmt\ClassMethod && $node->isStatic();
|
2020-12-23 14:28:30 +00:00
|
|
|
if ($isStatic) {
|
2021-01-30 21:41:25 +00:00
|
|
|
$this->removeVisibility($node);
|
2020-12-23 14:28:30 +00:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($visibility !== \Rector\Core\ValueObject\Visibility::STATIC && $visibility !== \Rector\Core\ValueObject\Visibility::ABSTRACT && $visibility !== \Rector\Core\ValueObject\Visibility::FINAL) {
|
2021-01-30 21:41:25 +00:00
|
|
|
$this->removeVisibility($node);
|
2020-11-30 09:51:11 +00:00
|
|
|
}
|
|
|
|
$this->addVisibilityFlag($node, $visibility);
|
2020-12-23 14:28:30 +00:00
|
|
|
if ($isStatic) {
|
|
|
|
$this->makeStatic($node);
|
|
|
|
}
|
2020-11-30 09:51:11 +00:00
|
|
|
}
|
2018-07-31 08:54:00 +00:00
|
|
|
}
|