Skip to content

Commit

Permalink
[Symfony 5.2] Add PropertyAccessorCreationBooleanToFlagsRector (#4874)
Browse files Browse the repository at this point in the history
  • Loading branch information
simivar authored Dec 13, 2020
1 parent f3decc4 commit a08d26b
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 0 deletions.
4 changes: 4 additions & 0 deletions config/set/symfony52.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Renaming\ValueObject\RenameClassConstant;
use Rector\Symfony5\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector;
use Rector\Symfony5\Rector\StaticCall\BinaryFileResponseCreateToNewInstanceRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
Expand All @@ -28,6 +29,9 @@
]),
]]);

# https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyaccess
$services->set(PropertyAccessorCreationBooleanToFlagsRector::class);

# https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#security
$services->set(RenameClassConstantRector::class)
->call('configure', [[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

declare(strict_types=1);

namespace Rector\Symfony5\Rector\New_;

use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BitwiseOr;
use PhpParser\Node\Expr\New_;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyaccess
* @see \Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\PropertyAccessorCreationBooleanToFlagsRectorTest
*/
final class PropertyAccessorCreationBooleanToFlagsRector extends AbstractRector
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Changes first argument of PropertyAccessor::__construct() to flags from boolean', [
new CodeSample(
<<<'PHP'
class SomeClass
{
public function run()
{
$propertyAccessor = new PropertyAccessor(true);
}
}
PHP
,
<<<'PHP'
class SomeClass
{
public function run()
{
$propertyAccessor = new PropertyAccessor(PropertyAccessor::MAGIC_CALL | PropertyAccessor::MAGIC_GET | PropertyAccessor::MAGIC_SET);
}
}
PHP
),
]);
}

/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [New_::class];
}

/**
* @param New_ $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip($node)) {
return null;
}

$isTrue = $this->isTrue($node->args[0]->value);
$flags = $this->prepareFlags($isTrue);
$node->args[0] = $this->createArg($flags);

return $node;
}

private function prepareFlags(bool $currentValue): BitwiseOr
{
$magicGet = $this->createClassConstFetch('Symfony\Component\PropertyAccess\PropertyAccessor', 'MAGIC_GET');
$magicSet = $this->createClassConstFetch('Symfony\Component\PropertyAccess\PropertyAccessor', 'MAGIC_SET');
if (!$currentValue) {
return new BitwiseOr($magicGet, $magicSet);
}

return new BitwiseOr(
new BitwiseOr(
$this->createClassConstFetch('Symfony\Component\PropertyAccess\PropertyAccessor', 'MAGIC_CALL'),
$magicGet,
),
$magicSet,
);
}

private function shouldSkip(New_ $new_): bool
{
if (! $new_->class instanceof Node\Name) {
return true;
}

if (! $this->isName($new_->class, 'Symfony\Component\PropertyAccess\PropertyAccessor')) {
return true;
}

if (! $this->isBool($new_->args[0]->value)) {
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\Fixture;

use Symfony\Component\PropertyAccess\PropertyAccessor;

class ArgumentFalse
{
public function createPropertyAccessor()
{
return new PropertyAccessor(false);
}
}

?>
-----
<?php

namespace Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\Fixture;

use Symfony\Component\PropertyAccess\PropertyAccessor;

class ArgumentFalse
{
public function createPropertyAccessor()
{
return new PropertyAccessor(\Symfony\Component\PropertyAccess\PropertyAccessor::MAGIC_GET | \Symfony\Component\PropertyAccess\PropertyAccessor::MAGIC_SET);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\Fixture;

use Symfony\Component\PropertyAccess\PropertyAccessor;

class ArgumentFlag
{
public function createPropertyAccessor()
{
return new PropertyAccessor(PropertyAccessor::MAGIC_CALL);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\Fixture;

use Symfony\Component\PropertyAccess\PropertyAccessor;

class ArgumentTrue
{
public function createPropertyAccessor()
{
return new PropertyAccessor(true);
}
}

?>
-----
<?php

namespace Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\Fixture;

use Symfony\Component\PropertyAccess\PropertyAccessor;

class ArgumentTrue
{
public function createPropertyAccessor()
{
return new PropertyAccessor(\Symfony\Component\PropertyAccess\PropertyAccessor::MAGIC_CALL | \Symfony\Component\PropertyAccess\PropertyAccessor::MAGIC_GET | \Symfony\Component\PropertyAccess\PropertyAccessor::MAGIC_SET);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Rector\Symfony5\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector;

use Iterator;
use Rector\Symfony5\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;

final class PropertyAccessorCreationBooleanToFlagsRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}

public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

protected function getRectorClass(): string
{
return PropertyAccessorCreationBooleanToFlagsRector::class;
}
}

0 comments on commit a08d26b

Please sign in to comment.