mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-19 06:18:07 +01:00
fix StringFormTypeToClassRector
This commit is contained in:
parent
0f2f74ca8a
commit
5c3067c95d
@ -46,8 +46,6 @@ final class DocBlockAnalyzer
|
||||
}
|
||||
|
||||
return Strings::contains($node->getDocComment()->getText(), '@' . $name);
|
||||
// $phpDocInfo = $this->createPhpDocInfoFromNode($node);
|
||||
// return $phpDocInfo->hasTag($name);
|
||||
}
|
||||
|
||||
public function removeParamTagByName(Node $node, string $name): void
|
||||
|
@ -20,9 +20,9 @@ final class ExceptionAnnotationRectorTest extends AbstractRectorTestCase
|
||||
|
||||
public function provideWrongToFixedFiles(): Iterator
|
||||
{
|
||||
// yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'];
|
||||
// yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'];
|
||||
// yield [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/correct3.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/correct3.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong4.php.inc', __DIR__ . '/Correct/correct4.php.inc'];
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,10 @@ final class FormTypeStringToTypeProvider
|
||||
|
||||
public function hasClassForNameWithPrefix(string $name): bool
|
||||
{
|
||||
if (! Strings::startsWith($name, 'form.type.')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->removeFormTypePrefix($name);
|
||||
|
||||
return $this->hasClassForName($name);
|
||||
|
@ -3,9 +3,10 @@
|
||||
namespace Rector\Symfony\Rector\Form;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use Rector\Node\NodeFactory;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\NodeAnalyzer\MethodCallAnalyzer;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
@ -26,9 +27,25 @@ final class StringFormTypeToClassRector extends AbstractRector
|
||||
*/
|
||||
private $formTypeStringToTypeProvider;
|
||||
|
||||
public function __construct(NodeFactory $nodeFactory, FormTypeStringToTypeProvider $formTypeStringToTypeProvider)
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $formBuilderClass;
|
||||
|
||||
/**
|
||||
* @var MethodCallAnalyzer
|
||||
*/
|
||||
private $methodCallAnalyzer;
|
||||
|
||||
public function __construct(
|
||||
NodeFactory $nodeFactory,
|
||||
FormTypeStringToTypeProvider $formTypeStringToTypeProvider,
|
||||
MethodCallAnalyzer $methodCallAnalyzer,
|
||||
string $formBuilderClass = 'Symfony\Component\Form\FormBuilderInterface'
|
||||
) {
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->formBuilderClass = $formBuilderClass;
|
||||
$this->methodCallAnalyzer = $methodCallAnalyzer;
|
||||
$this->formTypeStringToTypeProvider = $formTypeStringToTypeProvider;
|
||||
}
|
||||
|
||||
@ -41,8 +58,15 @@ final class StringFormTypeToClassRector extends AbstractRector
|
||||
'Turns string Form Type references to their CONSTANT alternatives in FormTypes in Form in Symfony',
|
||||
[
|
||||
new CodeSample(
|
||||
'$form->add("name", "form.type.text");',
|
||||
'$form->add("name", \Symfony\Component\Form\Extension\Core\Type\TextType::class);'
|
||||
<<<'CODE_SAMPLE'
|
||||
$formBuilder = new Symfony\Component\Form\FormBuilder;
|
||||
$formBuilder->add('name', 'form.type.text');
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$formBuilder = new Symfony\Component\Form\FormBuilder;
|
||||
$form->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class);
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
@ -53,22 +77,40 @@ final class StringFormTypeToClassRector extends AbstractRector
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [String_::class];
|
||||
return [MethodCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String_ $stringNode
|
||||
* @param MethodCall $methodCallNode
|
||||
*/
|
||||
public function refactor(Node $stringNode): ?Node
|
||||
public function refactor(Node $methodCallNode): ?Node
|
||||
{
|
||||
if (! $this->methodCallAnalyzer->isTypeAndMethod($methodCallNode, $this->formBuilderClass, 'add')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// just one argument
|
||||
if (! isset($methodCallNode->args[1])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// not a string
|
||||
if (! $methodCallNode->args[1]->value instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var String_ $stringNode */
|
||||
$stringNode = $methodCallNode->args[1]->value;
|
||||
|
||||
// not a form type string
|
||||
if (! $this->formTypeStringToTypeProvider->hasClassForNameWithPrefix($stringNode->value)) {
|
||||
return null;
|
||||
}
|
||||
if (((string) $stringNode->getAttribute(Attribute::METHOD_CALL_NAME) === 'add') === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$class = $this->formTypeStringToTypeProvider->getClassForNameWithPrefix($stringNode->value);
|
||||
|
||||
return $this->nodeFactory->createClassConstantReference($class);
|
||||
$methodCallNode->args[1]->value = $this->nodeFactory->createClassConstantReference($class);
|
||||
|
||||
return $methodCallNode;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
$formBuilder = new Symfony\Component\Form\FormBuilder;
|
||||
use Rector\Symfony\Tests\Rector\Form\StringFormTypeToClassRector\Source\FormBuilder;
|
||||
|
||||
$formBuilder = new FormBuilder();
|
||||
$formBuilder->add('task', \Symfony\Component\Form\Extension\Core\Type\TextType::class);
|
||||
|
||||
$variable = 'form.type.text';
|
||||
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\CoreBundle\Form\Type;
|
||||
|
||||
use Rector\Symfony\Tests\Rector\Form\StringFormTypeToClassRector\Source\FormBuilder;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
|
||||
final class ContactType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilder $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('email', EmailType::class, [
|
||||
'label' => 'sylius.ui.email',
|
||||
])
|
||||
;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony\Tests\Rector\Form\StringFormTypeToClassRector\Source;
|
||||
|
||||
final class FormBuilder
|
||||
{
|
||||
|
||||
}
|
@ -21,6 +21,7 @@ final class StringFormTypeToClassRectorTest extends AbstractRectorTestCase
|
||||
public function provideWrongToFixedFiles(): Iterator
|
||||
{
|
||||
yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'];
|
||||
}
|
||||
|
||||
protected function provideConfig(): string
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
$formBuilder = new Symfony\Component\Form\FormBuilder;
|
||||
use Rector\Symfony\Tests\Rector\Form\StringFormTypeToClassRector\Source\FormBuilder;
|
||||
|
||||
$formBuilder = new FormBuilder();
|
||||
$formBuilder->add('task', 'form.type.text');
|
||||
|
||||
$variable = 'form.type.text';
|
||||
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\CoreBundle\Form\Type;
|
||||
|
||||
use Rector\Symfony\Tests\Rector\Form\StringFormTypeToClassRector\Source\FormBuilder;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
|
||||
final class ContactType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilder $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('email', EmailType::class, [
|
||||
'label' => 'sylius.ui.email',
|
||||
])
|
||||
;
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
services:
|
||||
Rector\Symfony\Rector\Form\StringFormTypeToClassRector: ~
|
||||
Rector\Symfony\Rector\Form\StringFormTypeToClassRector:
|
||||
$formBuilderClass: 'Rector\Symfony\Tests\Rector\Form\StringFormTypeToClassRector\Source\FormBuilder'
|
||||
|
@ -7,6 +7,7 @@ use Rector\Configuration\Option;
|
||||
use Rector\FileSystem\FileGuard;
|
||||
use Rector\Utils\FilesystemTweaker;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Should it pass autoload files/directories to PHPStan analyzer?
|
||||
@ -110,7 +111,7 @@ final class AdditionalAutoloader
|
||||
// sometimes tests can include ambiguous classes
|
||||
try {
|
||||
$robotLoader->register();
|
||||
} catch (\Throwable $throwable) {
|
||||
} catch (Throwable $throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,30 +200,7 @@ final class ProcessCommand extends Command
|
||||
$this->consoleStyle->progressStart($totalFiles);
|
||||
|
||||
foreach ($fileInfos as $fileInfo) {
|
||||
try {
|
||||
// php
|
||||
if ($fileInfo->getExtension() === 'php') {
|
||||
$this->processFile($fileInfo);
|
||||
// yml
|
||||
} elseif ($fileInfo->getExtension() === 'yml') {
|
||||
$this->processYamlFile($fileInfo);
|
||||
}
|
||||
} catch (AnalysedCodeException $analysedCodeException) {
|
||||
if ($shouldHideAutoloadErrors) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
'Analyze error: %s Try to include your files in "parameters > autoload_files" or "parameters > autoload_directories".%sSee https://github.com/rectorphp/rector#extra-autoloading',
|
||||
$analysedCodeException->getMessage(),
|
||||
PHP_EOL
|
||||
);
|
||||
|
||||
$this->errors[] = new Error($fileInfo, $message, null);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->errors[] = new Error($fileInfo, $throwable->getMessage(), $throwable->getCode());
|
||||
}
|
||||
|
||||
$this->processFileInfo($fileInfo, $shouldHideAutoloadErrors);
|
||||
$this->consoleStyle->progressAdvance();
|
||||
}
|
||||
|
||||
@ -271,4 +248,31 @@ final class ProcessCommand extends Command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processFileInfo(SplFileInfo $fileInfo, bool $shouldHideAutoloadErrors): void
|
||||
{
|
||||
try {
|
||||
// php
|
||||
if ($fileInfo->getExtension() === 'php') {
|
||||
$this->processFile($fileInfo);
|
||||
// yml
|
||||
} elseif ($fileInfo->getExtension() === 'yml') {
|
||||
$this->processYamlFile($fileInfo);
|
||||
}
|
||||
} catch (AnalysedCodeException $analysedCodeException) {
|
||||
if ($shouldHideAutoloadErrors) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
'Analyze error: %s Try to include your files in "parameters > autoload_files" or "parameters > autoload_directories".%sSee https://github.com/rectorphp/rector#extra-autoloading',
|
||||
$analysedCodeException->getMessage(),
|
||||
PHP_EOL
|
||||
);
|
||||
|
||||
$this->errors[] = new Error($fileInfo, $message, null);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->errors[] = new Error($fileInfo, $throwable->getMessage(), $throwable->getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ final class FilesFinder
|
||||
$finder->filter(function (NativeSplFileInfo $splFileInfo) {
|
||||
// return false to remove file
|
||||
foreach ($this->excludePaths as $excludePath) {
|
||||
if (Strings::match($splFileInfo->getRealPath(), '#' . preg_quote($excludePath, '#') . '#' )) {
|
||||
if (Strings::match($splFileInfo->getRealPath(), '#' . preg_quote($excludePath, '#') . '#')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user