Merge pull request #14 from TomasVotruba/symfony-form-type-string-to-class

[Symfony] add StringFormTypeToClassRector
This commit is contained in:
Tomáš Votruba 2017-09-01 00:39:24 +02:00 committed by GitHub
commit 5bbc0443fa
9 changed files with 131 additions and 8 deletions

View File

@ -14,11 +14,12 @@
"nette/utils": "^2.4"
},
"require-dev": {
"phpunit/phpunit": "^6.2",
"phpstan/phpstan": "^0.8",
"tracy/tracy": "^2.4",
"phpunit/phpunit": "^6.2",
"slam/php-cs-fixer-extensions": "^1.4",
"symfony/form": "^3.3",
"symplify/easy-coding-standard": "^2.2",
"slam/php-cs-fixer-extensions": "^1.4"
"tracy/tracy": "^2.4"
},
"autoload": {
"psr-4": {

View File

@ -26,6 +26,11 @@ checkers:
# Class should be Final or Abstract
- SlamCsFixer\FinalInternalClassFixer
Symplify\CodingStandard\Sniffs\DependencyInjection\NoClassInstantiationSniff:
extraAllowedClasses:
- 'PhpParser\Node\*'
- 'PhpParser\Comment\Doc'
parameters:
exclude_checkers:
# Excluded from symfony-checkers.neon
@ -39,6 +44,7 @@ parameters:
Symplify\CodingStandard\Fixer\Php\ClassStringToClassConstantFixer:
# classes might not exist
- */src/Rector/Contrib/Nette/*Rector.php
- src/Rector/Contrib/Symfony/StringFormTypeToClassRector.php
Symplify\CodingStandard\Sniffs\Debug\CommentedOutCodeSniff:
# examples of code to be found
- src/Rector/Contrib/Symfony/GetterToPropertyRector.php

View File

@ -7,9 +7,8 @@ use PhpParser\NodeVisitor\CloningVisitor;
final class CloningNodeTraverser extends NodeTraverser
{
public function __construct()
public function __construct(CloningVisitor $cloningVisitor)
{
// note: probably have to be recreated to clear cache
$this->addVisitor(new CloningVisitor);
$this->addVisitor($cloningVisitor);
}
}

View File

@ -22,9 +22,9 @@ final class StandaloneTraverseNodeTraverser
*/
private $nodeVisitors = [];
public function __construct()
public function __construct(NodeTraverser $nativeNodeTraverser)
{
$this->nativeNodeTraverser = new NodeTraverser;
$this->nativeNodeTraverser = $nativeNodeTraverser;
}
public function addNodeVisitor(NodeVisitor $nodeVisitor): void

View File

@ -0,0 +1,83 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony;
use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\String_;
use Rector\Deprecation\SetNames;
use Rector\Rector\AbstractRector;
/**
* Converts all:
* $form->add('name', 'form.type.text');
*
* into:
* $form->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class);
*
* Ref: https://github.com/symfony/symfony/blob/master/UPGRADE-4.0.md#frameworkbundle
*/
final class StringFormTypeToClassRector extends AbstractRector
{
/**
* @var string[]
*/
private $nameToClassMap = [
'form.type.birthday' => 'Symfony\Component\Form\Extension\Core\Type\BirthdayType',
'form.type.checkbox' => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
'form.type.collection' => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
'form.type.country' => 'Symfony\Component\Form\Extension\Core\Type\CountryType',
'form.type.currency' => 'Symfony\Component\Form\Extension\Core\Type\CurrencyType',
'form.type.date' => 'Symfony\Component\Form\Extension\Core\Type\DateType',
'form.type.datetime' => 'Symfony\Component\Form\Extension\Core\Type\DatetimeType',
'form.type.email' => 'Symfony\Component\Form\Extension\Core\Type\EmailType',
'form.type.file' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
'form.type.hidden' => 'Symfony\Component\Form\Extension\Core\Type\HiddenType',
'form.type.integer' => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
'form.type.language' => 'Symfony\Component\Form\Extension\Core\Type\LanguageType',
'form.type.locale' => 'Symfony\Component\Form\Extension\Core\Type\LocaleType',
'form.type.money' => 'Symfony\Component\Form\Extension\Core\Type\MoneyType',
'form.type.number' => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
'form.type.password' => 'Symfony\Component\Form\Extension\Core\Type\PasswordType',
'form.type.percent' => 'Symfony\Component\Form\Extension\Core\Type\PercentType',
'form.type.radio' => 'Symfony\Component\Form\Extension\Core\Type\RadioType',
'form.type.range' => 'Symfony\Component\Form\Extension\Core\Type\RangeType',
'form.type.repeated' => 'Symfony\Component\Form\Extension\Core\Type\RepeatedType',
'form.type.search' => 'Symfony\Component\Form\Extension\Core\Type\SearchType',
'form.type.textarea' => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
'form.type.text' => 'Symfony\Component\Form\Extension\Core\Type\TextType',
'form.type.time' => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
'form.type.timezone' => 'Symfony\Component\Form\Extension\Core\Type\TimezoneType',
'form.type.url' => 'Symfony\Component\Form\Extension\Core\Type\UrlType',
'form.type.button' => 'Symfony\Component\Form\Extension\Core\Type\ButtonType',
'form.type.submit' => 'Symfony\Component\Form\Extension\Core\Type\SubmitType',
'form.type.reset' => 'Symfony\Component\Form\Extension\Core\Type\ResetType',
];
public function getSetName(): string
{
return SetNames::SYMFONY;
}
public function sinceVersion(): float
{
return 4.0;
}
public function isCandidate(Node $node): bool
{
return $node instanceof String_ && isset($this->nameToClassMap[$node->value]);
}
/**
* @param String_ $node
*/
public function refactor(Node $node): ?Node
{
$class = $this->nameToClassMap[$node->value];
$nameNode = new Name('\\' . $class);
return new ClassConstFetch($nameNode, 'class');
}
}

View File

@ -36,6 +36,7 @@ services:
PhpParser\ParserFactory: ~
PhpParser\BuilderFactory: ~
PhpParser\NodeVisitor\CloningVisitor:
PhpParser\NodeVisitor\NameResolver:
arguments:
$options:

View File

@ -0,0 +1,4 @@
<?php declare (strict_types=1);
$formBuilder = new Symfony\Component\Form\FormBuilder;
$formBuilder->add('task', \Symfony\Component\Form\Extension\Core\Type\TextType::class);

View File

@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\Symfony\StringFormTypeToClassRector;
use Rector\Rector\Contrib\Symfony\StringFormTypeToClassRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class Test extends AbstractRectorTestCase
{
public function test(): void
{
$this->doTestFileMatchesExpectedContent(
__DIR__ . '/Wrong/wrong.php.inc',
__DIR__ . '/Correct/correct.php.inc'
);
}
/**
* @return string[]
*/
protected function getRectorClasses(): array
{
return [StringFormTypeToClassRector::class];
}
}

View File

@ -0,0 +1,4 @@
<?php declare (strict_types=1);
$formBuilder = new Symfony\Component\Form\FormBuilder;
$formBuilder->add('task', 'form.type.text');