2019-10-13 05:59:52 +00:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2022-06-06 17:12:56 +00:00
|
|
|
namespace Rector\Privatization\NodeManipulator;
|
2018-07-31 08:54:00 +00:00
|
|
|
|
2022-06-06 17:12:56 +00:00
|
|
|
use PhpParser\Node\Param;
|
|
|
|
use PhpParser\Node\Stmt\Class_;
|
|
|
|
use PhpParser\Node\Stmt\ClassConst;
|
|
|
|
use PhpParser\Node\Stmt\ClassMethod;
|
|
|
|
use PhpParser\Node\Stmt\Property;
|
2024-01-02 02:40:38 +00:00
|
|
|
use Rector\ValueObject\Visibility;
|
2024-03-01 20:02:28 +00:00
|
|
|
use RectorPrefix202403\Webmozart\Assert\Assert;
|
2021-12-02 10:13:44 +00:00
|
|
|
/**
|
|
|
|
* @see \Rector\Tests\Privatization\NodeManipulator\VisibilityManipulatorTest
|
|
|
|
*/
|
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
|
|
|
/**
|
2022-05-12 15:51:17 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Param $node
|
2018-07-31 09:15:27 +00:00
|
|
|
*/
|
2021-07-22 23:37:17 +00:00
|
|
|
public function hasVisibility($node, int $visibility) : bool
|
|
|
|
{
|
|
|
|
return (bool) ($node->flags & $visibility);
|
|
|
|
}
|
2019-02-09 13:22:20 +00:00
|
|
|
/**
|
2022-07-15 08:14:37 +00:00
|
|
|
* @api
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
2019-02-09 13:22:20 +00:00
|
|
|
*/
|
2021-06-29 13:37:16 +00:00
|
|
|
public function makeStatic($node) : void
|
2019-02-09 13:22:20 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->addVisibilityFlag($node, Visibility::STATIC);
|
2019-02-09 13:22:20 +00:00
|
|
|
}
|
2022-09-16 18:01:57 +00:00
|
|
|
/**
|
|
|
|
* @api
|
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property $node
|
|
|
|
*/
|
|
|
|
public function makeNonStatic($node) : void
|
|
|
|
{
|
|
|
|
if (!$node->isStatic()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$node->flags -= Class_::MODIFIER_STATIC;
|
|
|
|
}
|
2020-09-10 07:27:03 +00:00
|
|
|
/**
|
2022-07-16 14:24:54 +00:00
|
|
|
* @api
|
2022-09-17 07:19:59 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Class_ $node
|
2020-09-10 07:27:03 +00:00
|
|
|
*/
|
2022-09-16 18:01:57 +00:00
|
|
|
public function makeNonAbstract($node) : void
|
2020-09-10 07:27:03 +00:00
|
|
|
{
|
2022-09-17 07:19:59 +00:00
|
|
|
if (!$node->isAbstract()) {
|
2020-09-17 07:34:27 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-09-16 18:01:57 +00:00
|
|
|
$node->flags -= Class_::MODIFIER_ABSTRACT;
|
2020-09-10 07:27:03 +00:00
|
|
|
}
|
2019-08-25 10:29:15 +00:00
|
|
|
/**
|
2024-01-31 14:27:18 +00:00
|
|
|
* @api
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\ClassConst $node
|
2019-08-25 10:29:15 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
public function makeFinal($node) : void
|
2019-08-25 10:29:15 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->addVisibilityFlag($node, Visibility::FINAL);
|
2019-08-25 10:29:15 +00:00
|
|
|
}
|
2020-12-05 21:33:30 +00:00
|
|
|
/**
|
2022-07-17 01:16:52 +00:00
|
|
|
* @api
|
2021-08-23 00:20:32 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod $node
|
2020-12-05 21:33:30 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
public function makeNonFinal($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;
|
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
$node->flags -= Class_::MODIFIER_FINAL;
|
2020-12-05 21:33:30 +00:00
|
|
|
}
|
2020-11-27 21:29:40 +00:00
|
|
|
/**
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
2020-11-27 21:29:40 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
public function changeNodeVisibility($node, int $visibility) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
Assert::oneOf($visibility, [Visibility::PUBLIC, Visibility::PROTECTED, Visibility::PRIVATE, Visibility::STATIC, Visibility::ABSTRACT, Visibility::FINAL]);
|
2020-12-24 23:18:02 +00:00
|
|
|
$this->replaceVisibilityFlag($node, $visibility);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
|
|
|
/**
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
2020-11-27 21:29:40 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
public function makePublic($node) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->replaceVisibilityFlag($node, Visibility::PUBLIC);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
|
|
|
/**
|
2022-07-16 14:24:54 +00:00
|
|
|
* @api
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
2020-11-27 21:29:40 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
public function makeProtected($node) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->replaceVisibilityFlag($node, Visibility::PROTECTED);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
|
|
|
/**
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
2020-11-27 21:29:40 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
public function makePrivate($node) : void
|
2020-11-27 21:29:40 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->replaceVisibilityFlag($node, Visibility::PRIVATE);
|
2020-11-27 21:29:40 +00:00
|
|
|
}
|
2021-07-22 23:37:17 +00:00
|
|
|
/**
|
2023-05-14 15:57:29 +00:00
|
|
|
* @api
|
2021-08-23 00:20:32 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassConst $node
|
2021-07-22 23:37:17 +00:00
|
|
|
*/
|
|
|
|
public function removeFinal($node) : void
|
2021-02-08 21:00:45 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$node->flags -= Class_::MODIFIER_FINAL;
|
2021-02-08 21:00:45 +00:00
|
|
|
}
|
2018-07-31 09:15:27 +00:00
|
|
|
/**
|
2022-05-12 15:51:17 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node
|
2018-07-31 09:15:27 +00:00
|
|
|
*/
|
2021-07-22 23:37:17 +00:00
|
|
|
public function makeReadonly($node) : void
|
2018-07-31 09:15:27 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->addVisibilityFlag($node, Visibility::READONLY);
|
2021-11-18 19:20:31 +00:00
|
|
|
}
|
|
|
|
/**
|
2023-11-28 20:19:53 +00:00
|
|
|
* @api
|
2022-05-31 21:25:48 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node
|
2021-11-18 19:20:31 +00:00
|
|
|
*/
|
|
|
|
public function isReadonly($node) : bool
|
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
return $this->hasVisibility($node, Visibility::READONLY);
|
2021-11-18 19:20:31 +00:00
|
|
|
}
|
|
|
|
/**
|
2022-05-31 21:25:48 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node
|
2021-11-18 19:20:31 +00:00
|
|
|
*/
|
|
|
|
public function removeReadonly($node) : void
|
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->removeVisibilityFlag($node, Visibility::READONLY);
|
2018-07-31 09:15:27 +00:00
|
|
|
}
|
2023-02-28 20:41:27 +00:00
|
|
|
/**
|
|
|
|
* @param \PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\ClassMethod $node
|
|
|
|
* @return \PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\ClassMethod|null
|
|
|
|
*/
|
|
|
|
public function publicize($node)
|
|
|
|
{
|
|
|
|
// already non-public
|
|
|
|
if (!$node->isPublic()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
// explicitly public
|
|
|
|
if ($this->hasVisibility($node, Visibility::PUBLIC)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
$this->makePublic($node);
|
|
|
|
return $node;
|
|
|
|
}
|
2022-12-23 17:10:25 +00:00
|
|
|
/**
|
|
|
|
* This way "abstract", "static", "final" are kept
|
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
|
|
|
*/
|
|
|
|
private function removeVisibility($node) : void
|
|
|
|
{
|
|
|
|
// no modifier
|
|
|
|
if ($node->flags === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ($node->isPublic()) {
|
|
|
|
$node->flags |= Class_::MODIFIER_PUBLIC;
|
|
|
|
$node->flags -= Class_::MODIFIER_PUBLIC;
|
|
|
|
}
|
|
|
|
if ($node->isProtected()) {
|
|
|
|
$node->flags -= Class_::MODIFIER_PROTECTED;
|
|
|
|
}
|
|
|
|
if ($node->isPrivate()) {
|
|
|
|
$node->flags -= Class_::MODIFIER_PRIVATE;
|
|
|
|
}
|
|
|
|
}
|
2021-07-22 23:37:17 +00:00
|
|
|
/**
|
2022-07-15 08:14:37 +00:00
|
|
|
* @api
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Param $node
|
2021-07-22 23:37:17 +00:00
|
|
|
*/
|
|
|
|
private function addVisibilityFlag($node, int $visibility) : void
|
2018-07-31 08:54:00 +00:00
|
|
|
{
|
2021-07-22 23:37:17 +00:00
|
|
|
$node->flags |= $visibility;
|
2018-07-31 08:54:00 +00:00
|
|
|
}
|
2021-11-18 19:20:31 +00:00
|
|
|
/**
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Param $node
|
2021-11-18 19:20:31 +00:00
|
|
|
*/
|
|
|
|
private function removeVisibilityFlag($node, int $visibility) : void
|
|
|
|
{
|
|
|
|
$node->flags &= ~$visibility;
|
|
|
|
}
|
2020-11-30 09:51:11 +00:00
|
|
|
/**
|
2022-04-26 08:13:18 +00:00
|
|
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
|
2020-11-30 09:51:11 +00:00
|
|
|
*/
|
2021-06-29 14:24:45 +00:00
|
|
|
private function replaceVisibilityFlag($node, int $visibility) : void
|
2020-11-30 09:51:11 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$isStatic = $node instanceof ClassMethod && $node->isStatic();
|
2020-12-23 14:28:30 +00:00
|
|
|
if ($isStatic) {
|
2021-12-02 07:47:15 +00:00
|
|
|
$this->makeNonStatic($node);
|
2020-12-23 14:28:30 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
if ($visibility !== Visibility::STATIC && $visibility !== Visibility::ABSTRACT && $visibility !== 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
|
|
|
}
|