Merge pull request #103 from RectorPHP/umpirsky-upgrade-fixer

Umpirsky upgrade fixer - Symfony 3.0
This commit is contained in:
Tomáš Votruba 2017-10-20 23:10:19 +02:00 committed by GitHub
commit 09762bd552
31 changed files with 796 additions and 32 deletions

View File

@ -144,6 +144,20 @@ You can:
'renderFormBegin': ['Nette\Bridges\FormsLatte\Runtime', 'renderFormBegin']
```
- **change class constant name**
```yml
# symfony30.yml
rectors:
Rector\Rector\Dynamic\ClassConstantReplacerRector:
# class:
# OLD_CONSTANT: NEW_CONSTANT
'Symfony\Component\Form\FormEvents':
'PRE_BIND': 'PRE_SUBMIT'
'BIND': 'SUBMIT'
'POST_BIND': 'POST_SUBMIT'
```
- or **replace underscore naming `_` with namespaces `\`**
```yml

View File

@ -0,0 +1,40 @@
<?php declare(strict_types=1);
namespace Rector\NodeTypeResolver\NodeVisitor;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\NodeVisitorAbstract;
use Rector\Node\Attribute;
/**
* Add attribute 'methodName' with current class name.
*/
final class MethodResolver extends NodeVisitorAbstract
{
/**
* @var string|null
*/
private $methodName;
/**
* @param Node[] $nodes
*/
public function beforeTraverse(array $nodes): void
{
$this->methodName = null;
}
public function enterNode(Node $node): void
{
if ($node instanceof ClassMethod) {
$this->methodName = $node->name->toString();
}
if ($this->methodName === null) {
return;
}
$node->setAttribute(Attribute::METHOD_NAME, $this->methodName);
}
}

View File

@ -49,6 +49,11 @@ final class Attribute
*/
public const CLASS_NAME = 'className';
/**
* @var string
*/
public const METHOD_NAME = 'methodName';
/**
* @var string
*/

View File

@ -18,6 +18,7 @@ use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Declare_;
@ -105,7 +106,7 @@ final class NodeFactory
*/
public function createMethodCall(string $variableName, string $methodName): MethodCall
{
$variableNode = new Variable($variableName);
$variableNode = $this->createVariable($variableName);
return new MethodCall($variableNode, $methodName);
}
@ -283,4 +284,18 @@ final class NodeFactory
{
return new PropertyFetch($propertyFetchNode->var, $propertyFetchNode->name);
}
public function createParam(string $name, string $type): Param
{
return new Param(
$this->createVariable($name),
null,
$type
);
}
public function createVariable(string $name): Variable
{
return new Variable($name);
}
}

View File

@ -12,41 +12,60 @@ final class ClassConstAnalyzer
/**
* @param string[] $constantNames
*/
public function isClassConstFetchOfClassAndConstantNames(Node $node, string $class, array $constantNames): bool
public function isTypeAndNames(Node $node, string $type, array $constantNames): bool
{
if (! $this->isType($node, $type)) {
return false;
}
/** @var ClassConstFetch $node */
return $this->isNames($node, $constantNames);
}
/**
* @param string[] $types
*/
public function matchTypes(Node $node, array $types): ?string
{
if (! $node instanceof ClassConstFetch) {
return null;
}
$class = $this->resolveType($node);
return in_array($class, $types, true) ? $class : null;
}
private function isType(Node $node, string $type): bool
{
if (! $node instanceof ClassConstFetch) {
return false;
}
if (! $this->isClassName($node, $class)) {
return false;
}
$nodeClass = $this->resolveType($node);
return $this->isConstantName($node, $constantNames);
}
private function isClassName(ClassConstFetch $classConstFetchNode, string $className): bool
{
/** @var FullyQualified $className */
$classFullyQualifiedName = $classConstFetchNode->class->getAttribute(Attribute::RESOLVED_NAME);
if ($classFullyQualifiedName instanceof FullyQualified) {
return $classFullyQualifiedName->toString() === $className;
}
// e.g. "$form::FILLED"
$nodeClassName = $classConstFetchNode->class->getAttribute(Attribute::CLASS_NAME);
return $nodeClassName === $className;
return $nodeClass === $type;
}
/**
* @param string[] $constantNames
* @param string[] $names
*/
private function isConstantName(ClassConstFetch $node, array $constantNames): bool
private function isNames(ClassConstFetch $node, array $names): bool
{
$nodeConstantName = $node->name->name;
return in_array($nodeConstantName, $constantNames, true);
return in_array($nodeConstantName, $names, true);
}
private function resolveType(ClassConstFetch $classConstFetchNode): string
{
$classFullyQualifiedName = $classConstFetchNode->class->getAttribute(Attribute::RESOLVED_NAME);
if ($classFullyQualifiedName instanceof FullyQualified) {
return $classFullyQualifiedName->toString();
}
// e.g. "$form::FILLED"
return (string) $classConstFetchNode->class->getAttribute(Attribute::CLASS_NAME);
}
}

View File

@ -0,0 +1,48 @@
<?php declare(strict_types=1);
namespace Rector\NodeAnalyzer\Contrib;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\PrettyPrinter\Standard;
use Rector\Node\Attribute;
final class ControllerMethodAnalyzer
{
/**
* @var Standard
*/
private $standardPrinter;
public function __construct(Standard $standardPrinter)
{
$this->standardPrinter = $standardPrinter;
}
/**
* Detect if is <some>Action() in Controller
*/
public function isAction(Node $node): bool
{
if (! $node instanceof ClassMethod) {
return false;
}
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
$controllerClass = 'Symfony\Bundle\FrameworkBundle\Controller\Controller';
if ($parentClassName !== $controllerClass) {
return false;
}
return Strings::endsWith($node->name->toString(), 'Action');
}
public function doesNodeContain(ClassMethod $classMethodNode, string $part): bool
{
$methodInString = $this->standardPrinter->prettyPrint([$classMethodNode]);
return Strings::contains($methodInString, $part);
}
}

View File

@ -1,6 +1,6 @@
<?php declare(strict_types=1);
namespace Rector\NodeAnalyzer;
namespace Rector\NodeAnalyzer\Contrib;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;

View File

@ -48,7 +48,7 @@ final class FormNegativeRulesRector extends AbstractRector
return false;
}
return $this->classConstAnalyzer->isClassConstFetchOfClassAndConstantNames(
return $this->classConstAnalyzer->isTypeAndNames(
$node->expr,
self::FORM_CLASS,
self::RULE_NAMES

View File

@ -11,7 +11,7 @@ use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
use Rector\Naming\PropertyNaming;
use Rector\Node\Attribute;
use Rector\Node\NodeFactory;
use Rector\NodeAnalyzer\SymfonyContainerCallsAnalyzer;
use Rector\NodeAnalyzer\Contrib\SymfonyContainerCallsAnalyzer;
use Rector\Rector\AbstractRector;
/**

View File

@ -47,7 +47,7 @@ final class ConsoleExceptionToErrorEventConstantRector extends AbstractRector
public function isCandidate(Node $node): bool
{
if ($this->classConstAnalyzer->isClassConstFetchOfClassAndConstantNames(
if ($this->classConstAnalyzer->isTypeAndNames(
$node,
self::CONSOLE_EVENTS_CLASS,
['EXCEPTION']

View File

@ -0,0 +1,97 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony\Form;
use PhpParser\Node;
use PhpParser\Node\Scalar\String_;
use Rector\Node\Attribute;
use Rector\Node\NodeFactory;
use Rector\Rector\AbstractRector;
/**
* Converts all:
* - getParent() {
* return 'some_string';
* }
*
* into:
* - getParent() {
* return CollectionType::class;
* }
*/
final class FormTypeGetParentRector extends AbstractRector
{
/**
* @var string[]
*/
private $nameToClassMap = [
'birthday' => 'Symfony\Component\Form\Extension\Core\Type\BirthdayType',
'checkbox' => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
'collection' => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
'country' => 'Symfony\Component\Form\Extension\Core\Type\CountryType',
'currency' => 'Symfony\Component\Form\Extension\Core\Type\CurrencyType',
'date' => 'Symfony\Component\Form\Extension\Core\Type\DateType',
'datetime' => 'Symfony\Component\Form\Extension\Core\Type\DatetimeType',
'email' => 'Symfony\Component\Form\Extension\Core\Type\EmailType',
'file' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
'hidden' => 'Symfony\Component\Form\Extension\Core\Type\HiddenType',
'integer' => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
'language' => 'Symfony\Component\Form\Extension\Core\Type\LanguageType',
'locale' => 'Symfony\Component\Form\Extension\Core\Type\LocaleType',
'money' => 'Symfony\Component\Form\Extension\Core\Type\MoneyType',
'number' => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
'password' => 'Symfony\Component\Form\Extension\Core\Type\PasswordType',
'percent' => 'Symfony\Component\Form\Extension\Core\Type\PercentType',
'radio' => 'Symfony\Component\Form\Extension\Core\Type\RadioType',
'range' => 'Symfony\Component\Form\Extension\Core\Type\RangeType',
'repeated' => 'Symfony\Component\Form\Extension\Core\Type\RepeatedType',
'search' => 'Symfony\Component\Form\Extension\Core\Type\SearchType',
'textarea' => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
'text' => 'Symfony\Component\Form\Extension\Core\Type\TextType',
'time' => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
'timezone' => 'Symfony\Component\Form\Extension\Core\Type\TimezoneType',
'url' => 'Symfony\Component\Form\Extension\Core\Type\UrlType',
'button' => 'Symfony\Component\Form\Extension\Core\Type\ButtonType',
'submit' => 'Symfony\Component\Form\Extension\Core\Type\SubmitType',
'reset' => 'Symfony\Component\Form\Extension\Core\Type\ResetType',
];
/**
* @var NodeFactory
*/
private $nodeFactory;
public function __construct(NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
public function isCandidate(Node $node): bool
{
if (! $node instanceof String_ || ! isset($this->nameToClassMap[$node->value])) {
return false;
}
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
if ($parentClassName !== 'Symfony\Component\Form\AbstractType') {
return false;
}
$methodName = $node->getAttribute(Attribute::METHOD_NAME);
if ($methodName !== 'getParent') {
return false;
}
return true;
}
/**
* @param String_ $stringNode
*/
public function refactor(Node $stringNode): ?Node
{
$class = $this->nameToClassMap[$stringNode->value];
return $this->nodeFactory->createClassConstantReference($class);
}
}

View File

@ -0,0 +1,61 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony\Form;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use Rector\Node\Attribute;
use Rector\Rector\AbstractRector;
/**
* Converts all:
* - $builder->add('...', ['precision' => '...', 'virtual' => '...'];
*
*
* into:
* - $builder->add('...', ['scale' => '...', 'inherit_data' => '...'];
*/
final class OptionNameRector extends AbstractRector
{
/**
* @var string
*/
private $oldToNewOption = [
'precision' => 'scale',
'virtual' => 'inherit_data',
];
public function isCandidate(Node $node): bool
{
if (! $node instanceof String_) {
return false;
}
if (! isset($this->oldToNewOption[$node->value])) {
return false;
}
$arrayItemParentNode = $node->getAttribute(Attribute::PARENT_NODE);
if (! $arrayItemParentNode instanceof ArrayItem) {
return false;
}
$arrayParentNode = $arrayItemParentNode->getAttribute(Attribute::PARENT_NODE);
$argParentNode = $arrayParentNode->getAttribute(Attribute::PARENT_NODE);
/** @var MethodCall $methodCallNode */
$methodCallNode = $argParentNode->getAttribute(Attribute::PARENT_NODE);
return $methodCallNode->name->toString() === 'add';
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
return new String_($this->oldToNewOption[$node->value]);
}
}

View File

@ -69,11 +69,11 @@ final class StringFormTypeToClassRector extends AbstractRector
}
/**
* @param String_ $node
* @param String_ $stringNode
*/
public function refactor(Node $node): ?Node
public function refactor(Node $stringNode): ?Node
{
$class = $this->nameToClassMap[$node->value];
$class = $this->nameToClassMap[$stringNode->value];
return $this->nodeFactory->createClassConstantReference($class);
}

View File

@ -0,0 +1,110 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony\HttpKernel;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Node\Attribute;
use Rector\Node\NodeFactory;
use Rector\NodeAnalyzer\Contrib\ControllerMethodAnalyzer;
use Rector\NodeAnalyzer\MethodCallAnalyzer;
use Rector\Rector\AbstractRector;
/**
* Converts all:
* public action()
* {
* $this->getRequest()->...();
*
* into:
* public action(Request $request)
* {
* $request->...();
* }
*/
final class GetRequestRector extends AbstractRector
{
/**
* @var ControllerMethodAnalyzer
*/
private $controllerMethodAnalyzer;
/**
* @var NodeFactory
*/
private $nodeFactory;
/**
* @var MethodCallAnalyzer
*/
private $methodCallAnalyzer;
public function __construct(
ControllerMethodAnalyzer $controllerMethodAnalyzer,
MethodCallAnalyzer $methodCallAnalyzer,
NodeFactory $nodeFactory
) {
$this->controllerMethodAnalyzer = $controllerMethodAnalyzer;
$this->nodeFactory = $nodeFactory;
$this->methodCallAnalyzer = $methodCallAnalyzer;
}
public function isCandidate(Node $node): bool
{
if ($this->isActionWithGetRequestInBody($node)) {
return true;
}
if ($this->isGetRequestInAction($node)) {
return true;
}
return false;
}
/**
* @param ClassMethod|MethodCall $classMethodOrMethodCallNode
*/
public function refactor(Node $classMethodOrMethodCallNode): ?Node
{
if ($classMethodOrMethodCallNode instanceof ClassMethod) {
$requestParam = $this->nodeFactory->createParam('request', 'Symfony\Component\HttpFoundation\Request');
$classMethodOrMethodCallNode->params[] = $requestParam;
return $classMethodOrMethodCallNode;
}
return $this->nodeFactory->createVariable('request');
}
private function isActionWithGetRequestInBody(Node $node): bool
{
if (! $this->controllerMethodAnalyzer->isAction($node)) {
return false;
}
/** @var ClassMethod $node */
if (! $this->controllerMethodAnalyzer->doesNodeContain($node, '$this->getRequest()')) {
return false;
}
return true;
}
private function isGetRequestInAction(Node $node): bool
{
if (! $this->methodCallAnalyzer->isMethod($node, 'getRequest')) {
return false;
}
$scopeNode = $node->getAttribute(Attribute::SCOPE_NODE);
if (! $this->controllerMethodAnalyzer->isAction($scopeNode)) {
return false;
}
return true;
}
}

View File

@ -9,7 +9,7 @@ use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
use Rector\Naming\PropertyNaming;
use Rector\Node\Attribute;
use Rector\Node\NodeFactory;
use Rector\NodeAnalyzer\SymfonyContainerCallsAnalyzer;
use Rector\NodeAnalyzer\Contrib\SymfonyContainerCallsAnalyzer;
use Rector\Rector\AbstractRector;
/**

View File

@ -0,0 +1,83 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Dynamic;
use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Identifier;
use Rector\NodeAnalyzer\ClassConstAnalyzer;
use Rector\Rector\AbstractRector;
final class ClassConstantReplacerRector extends AbstractRector
{
/**
* class => [
* OLD_CONSTANT => NEW_CONSTANT
* ]
*
* @var string[]
*/
private $oldToNewConstantsByClass = [];
/**
* @var ClassConstAnalyzer
*/
private $classConstAnalyzer;
/**
* @var string
*/
private $activeType;
/**
* @param string[] $oldToNewConstantsByClass
*/
public function __construct(array $oldToNewConstantsByClass, ClassConstAnalyzer $classConstAnalyzer)
{
$this->oldToNewConstantsByClass = $oldToNewConstantsByClass;
$this->classConstAnalyzer = $classConstAnalyzer;
}
public function isCandidate(Node $node): bool
{
$this->activeType = null;
foreach ($this->oldToNewConstantsByClass as $type => $oldToNewConstants) {
$matchedType = $this->classConstAnalyzer->matchTypes($node, $this->getTypes());
if ($matchedType) {
$this->activeType = $matchedType;
return true;
}
}
return false;
}
/**
* @param ClassConstFetch $classConstFetchNode
*/
public function refactor(Node $classConstFetchNode): ?Node
{
$configuration = $this->oldToNewConstantsByClass[$this->activeType];
$constantName = $classConstFetchNode->name->toString();
if (! isset($configuration[$constantName])) {
return $classConstFetchNode;
}
$newConstantName = $configuration[$constantName];
$classConstFetchNode->name = new Identifier($newConstantName);
return $classConstFetchNode;
}
/**
* @return string[]
*/
private function getTypes(): array
{
return array_keys($this->oldToNewConstantsByClass);
}
}

View File

@ -0,0 +1,27 @@
rectors:
Rector\Rector\Contrib\Symfony\HttpKernel\GetRequestRector: ~
Rector\Rector\Contrib\Symfony\Form\FormTypeGetParentRector: ~
Rector\Rector\Contrib\Symfony\Form\OptionNameRector: ~
Rector\Rector\Dynamic\ClassConstantReplacerRector:
# form
'Symfony\Component\Form\FormEvents':
'PRE_BIND': 'PRE_SUBMIT'
'BIND': 'SUBMIT'
'POST_BIND': 'POST_SUBMIT'
Rector\Rector\Dynamic\MethodNameReplacerRector:
# form
'Symfony\Component\Form\AbstractType':
'setDefaultOptions': 'configureOptions'
'Symfony\Component\Form\FormTypeInterface':
'getName': 'getBlockPrefix'
# property access
Symfony\Component\PropertyAccess\PropertyAccess:
'getPropertyAccessor': 'createPropertyAccessor'
Rector\Rector\Dynamic\ClassReplacerRector:
# console
'Symfony\Component\Console\Helper\ProgressHelper': 'Symfony\Component\Console\Helper\ProgressBar'
# form
'Symfony\Component\Form\Util\VirtualFormAwareIterator': 'Symfony\Component\Form\Util\InheritDataAwareIterator'

View File

@ -18,6 +18,8 @@ services:
- ['addNodeVisitor', ['@Rector\NodeVisitor\NodeConnector']]
# adds current class to all nodes via attribute
- ['addNodeVisitor', ['@Rector\NodeTypeResolver\NodeVisitor\ClassResolver']]
# adds current method to all nodes via attribute
- ['addNodeVisitor', ['@Rector\NodeTypeResolver\NodeVisitor\MethodResolver']]
# adds type to variable and property nodes via attribute
- ['addNodeVisitor', ['@Rector\NodeTypeResolver\NodeVisitor\TypeResolver']]
# adds current namespace to all nodes via attribute

View File

@ -0,0 +1,16 @@
<?php declare (strict_types=1);
use Symfony\Component\Form\AbstractType;
class PermissionCollectionType extends AbstractType
{
public function getName()
{
return 'some_name';
}
public function getParent()
{
return \Symfony\Component\Form\Extension\Core\Type\CollectionType::class;
}
}

View File

@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\Symfony\Form\FormTypeGetParentRector;
use Rector\Rector\Contrib\Symfony\Form\FormTypeGetParentRector;
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 [FormTypeGetParentRector::class];
}
}

View File

@ -0,0 +1,16 @@
<?php declare (strict_types=1);
use Symfony\Component\Form\AbstractType;
class PermissionCollectionType extends AbstractType
{
public function getName()
{
return 'some_name';
}
public function getParent()
{
return 'collection';
}
}

View File

@ -0,0 +1,26 @@
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text', array('label' => 'form.name'))
->add('price1', 'text', array(
'label' => 'form.price1',
'scale' => 3,
))
->add('price2', 'text', array(
'scale' => 3,
))
->add('discount', 'integer', [
'label' => 'form.email',
'inherit_data' => true,
])
->add('password', 'password')
;
}
}

View File

@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\Symfony\Form\OptionNameRector;
use Rector\Rector\Contrib\Symfony\Form\OptionNameRector;
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 [OptionNameRector::class];
}
}

View File

@ -0,0 +1,26 @@
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text', array('label' => 'form.name'))
->add('price1', 'text', array(
'label' => 'form.price1',
'precision' => 3,
))
->add('price2', 'text', array(
'precision' => 3,
))
->add('discount', 'integer', [
'label' => 'form.email',
'virtual' => true,
])
->add('password', 'password')
;
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ClassWithNamedService extends Controller
{
public function someAction(Symfony\Component\HttpFoundation\Request $request)
{
$request->getSomething();
}
}

View File

@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\Symfony\HttpKernel\GetRequestRector;
use Rector\Rector\Contrib\Symfony\HttpKernel\GetRequestRector;
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 [GetRequestRector::class];
}
}

View File

@ -0,0 +1,11 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ClassWithNamedService extends Controller
{
public function someAction()
{
$this->getRequest()->getSomething();
}
}

View File

@ -0,0 +1,30 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Dynamic\ClassConstantReplacerRector;
use Rector\Rector\Dynamic\ClassConstantReplacerRector;
use Rector\Testing\PHPUnit\AbstractConfigurableRectorTestCase;
final class Test extends AbstractConfigurableRectorTestCase
{
public function test(): void
{
$this->doTestFileMatchesExpectedContent(
__DIR__ . '/wrong/wrong.php.inc',
__DIR__ . '/correct/correct.php.inc'
);
}
protected function provideConfig(): string
{
return __DIR__ . '/config/rector.yml';
}
/**
* @return string[]
*/
protected function getRectorClasses(): array
{
return [ClassConstantReplacerRector::class];
}
}

View File

@ -0,0 +1,6 @@
rectors:
Rector\Rector\Dynamic\ClassConstantReplacerRector:
'Symfony\Component\Form\FormEvents':
'PRE_BIND': 'PRE_SUBMIT'
'BIND': 'SUBMIT'
'POST_BIND': 'POST_SUBMIT'

View File

@ -0,0 +1,13 @@
<?php declare(strict_types=1);
use Symfony\Component\Form\FormEvents;
class SomeClass
{
public function subscribe()
{
return [
FormEvents::PRE_SUBMIT
];
}
}

View File

@ -0,0 +1,13 @@
<?php declare(strict_types=1);
use Symfony\Component\Form\FormEvents;
class SomeClass
{
public function subscribe()
{
return [
FormEvents::PRE_BIND
];
}
}