mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 21:38:22 +01:00
Merge pull request #726 from rectorphp/sensitive-naming
Sensitive naming
This commit is contained in:
commit
d24aea7c85
@ -66,7 +66,7 @@ final class NodeTypeResolver
|
||||
// complete parent types - parent classes, interfaces and traits
|
||||
foreach ($types as $i => $type) {
|
||||
// remove scalar types and other non-existing ones
|
||||
if ($type === 'null') {
|
||||
if ($type === 'null' || $type === null) {
|
||||
unset($types[$i]);
|
||||
continue;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ CODE_SAMPLE
|
||||
$this->processClassMethodStatementsForParentConstructorCalls($node);
|
||||
|
||||
// not PSR-4 constructor
|
||||
if (strtolower((string) $classNode->name) !== strtolower((string) $node->name)) {
|
||||
if (! $this->isNameInsensitive($classNode, (string) $node->name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ CODE_SAMPLE
|
||||
}
|
||||
|
||||
// it's not a parent PHP 4 constructor call
|
||||
if (strtolower($parentClassName) !== strtolower($this->getName($node))) {
|
||||
if (! $this->isNameInsensitive($node, $parentClassName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ CODE_SAMPLE
|
||||
private function processIdentifier(Identifier $identifierNode): Identifier
|
||||
{
|
||||
foreach ($this->reservedKeywordsToReplacements as $reservedKeyword => $replacement) {
|
||||
if (strtolower($identifierNode->name) === strtolower($reservedKeyword)) {
|
||||
if ($this->isNameInsensitive($identifierNode, $reservedKeyword)) {
|
||||
$identifierNode->name = $replacement;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ parameters:
|
||||
- '#Offset string does not exist on string#' # 1
|
||||
- '#Array \(array<array<PhpParser\\Node\\Stmt>>\) does not accept array<PhpParser\\Node\\Stmt|null>#'
|
||||
- '#Property Rector\\DependencyInjection\\Loader\\RectorServiceParametersShifter::\$serviceKeywords \(array<string>\) does not accept ReflectionProperty#'
|
||||
- '#Strict comparison using === between string and null will always evaluate to false#'
|
||||
|
||||
# nette container
|
||||
- '#Method Rector\\NodeTypeResolver\\DependencyInjection\\PHPStanServicesFactory::create(.*?)() should return (.*?) but returns object#'
|
||||
|
@ -1,31 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
|
||||
/**
|
||||
* Read-only utils for MethodCall Node:
|
||||
* $this->"someMethod()"
|
||||
*/
|
||||
final class MethodNameAnalyzer
|
||||
{
|
||||
/**
|
||||
* @param string[] $types
|
||||
*/
|
||||
public function isOverrideOfTypes(Node $node, array $types): bool
|
||||
{
|
||||
if (! $node instanceof Identifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
|
||||
if (! $parentClassName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($parentClassName, $types, true);
|
||||
}
|
||||
}
|
@ -72,8 +72,12 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$resolvedName = $this->getName($node);
|
||||
$newName = $this->oldToNewClasses[$resolvedName] ?? null;
|
||||
$name = $this->getName($node);
|
||||
if (! $name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newName = $this->oldToNewClasses[$name] ?? null;
|
||||
if (! $newName) {
|
||||
return null;
|
||||
}
|
||||
|
@ -34,9 +34,6 @@ final class ClassConstantReplacerRector extends AbstractRector
|
||||
$this->identifierRenamer = $identifierRenamer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo complete list with all possibilities
|
||||
*/
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Replaces defined class constants in their calls.', [
|
||||
@ -73,7 +70,7 @@ final class ClassConstantReplacerRector extends AbstractRector
|
||||
}
|
||||
|
||||
foreach ($oldToNewConstants as $oldConstant => $newConstant) {
|
||||
if (! $this->isName($node, $oldConstant)) {
|
||||
if (! $this->isNameInsensitive($node, $oldConstant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -52,15 +52,14 @@ final class FunctionReplaceRector extends AbstractRector
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$functionName = $this->getName($node);
|
||||
if (! isset($this->oldFunctionToNewFunction[$functionName])) {
|
||||
return null;
|
||||
foreach ($this->oldFunctionToNewFunction as $oldFunction => $newFunction) {
|
||||
if (! $this->isNameInsensitive($node, $oldFunction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->name = new FullyQualified($newFunction);
|
||||
}
|
||||
|
||||
$newFunctionName = $this->oldFunctionToNewFunction[$functionName];
|
||||
|
||||
$node->name = new FullyQualified($newFunctionName);
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,7 @@
|
||||
namespace Rector\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use Rector\Builder\IdentifierRenamer;
|
||||
use Rector\NodeAnalyzer\MethodNameAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\ConfiguredCodeSample;
|
||||
@ -21,34 +18,14 @@ final class MethodNameReplacerRector extends AbstractRector
|
||||
*
|
||||
* @var string[][]
|
||||
*/
|
||||
private $perClassOldToNewMethods = [];
|
||||
private $oldToNewMethodsByClass = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @param string[][] $oldToNewMethodsByClass
|
||||
*/
|
||||
private $activeTypes = [];
|
||||
|
||||
/**
|
||||
* @var MethodNameAnalyzer
|
||||
*/
|
||||
private $methodNameAnalyzer;
|
||||
|
||||
/**
|
||||
* @var IdentifierRenamer
|
||||
*/
|
||||
private $identifierRenamer;
|
||||
|
||||
/**
|
||||
* @param string[][] $perClassOldToNewMethods
|
||||
*/
|
||||
public function __construct(
|
||||
array $perClassOldToNewMethods,
|
||||
MethodNameAnalyzer $methodNameAnalyzer,
|
||||
IdentifierRenamer $identifierRenamer
|
||||
) {
|
||||
$this->perClassOldToNewMethods = $perClassOldToNewMethods;
|
||||
$this->methodNameAnalyzer = $methodNameAnalyzer;
|
||||
$this->identifierRenamer = $identifierRenamer;
|
||||
public function __construct(array $oldToNewMethodsByClass)
|
||||
{
|
||||
$this->oldToNewMethodsByClass = $oldToNewMethodsByClass;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
@ -56,18 +33,18 @@ final class MethodNameReplacerRector extends AbstractRector
|
||||
return new RectorDefinition('Turns method names to new ones.', [
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
$someObject = new SomeClass;
|
||||
$someObject = new SomeExampleClass;
|
||||
$someObject->oldMethod();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$someObject = new SomeClass;
|
||||
$someObject = new SomeExampleClass;
|
||||
$someObject->newMethod();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
'$perClassOldToNewMethods' => [
|
||||
'SomeClass' => [
|
||||
'SomeExampleClass' => [
|
||||
'oldMethod' => 'newMethod',
|
||||
],
|
||||
],
|
||||
@ -81,127 +58,31 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Identifier::class, MethodCall::class];
|
||||
return [Identifier::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Identifier|MethodCall $node
|
||||
* @param Identifier $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($node instanceof Identifier) {
|
||||
return $this->processIdentifierNode($node);
|
||||
}
|
||||
$parentNode = $node->getAttribute(Attribute::PARENT_NODE);
|
||||
|
||||
if ($node instanceof MethodCall) {
|
||||
return $this->processMethodCall($node);
|
||||
}
|
||||
foreach ($this->oldToNewMethodsByClass as $type => $oldToNewMethods) {
|
||||
if (! $this->isType($parentNode, $type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
foreach ($oldToNewMethods as $oldMethod => $newMethod) {
|
||||
if (! $this->isNameInsensitive($node, $oldMethod)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function getClasses(): array
|
||||
{
|
||||
return array_keys($this->perClassOldToNewMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function matchOldToNewMethods(): array
|
||||
{
|
||||
foreach ($this->activeTypes as $activeType) {
|
||||
if (isset($this->perClassOldToNewMethods[$activeType])) {
|
||||
return $this->perClassOldToNewMethods[$activeType];
|
||||
$node->name = $newMethod;
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $types
|
||||
*/
|
||||
private function isMethodName(Node $node, array $types): bool
|
||||
{
|
||||
// already covered by previous methods
|
||||
if (! $node instanceof Identifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parentNode = $node->getAttribute(Attribute::PARENT_NODE);
|
||||
if ($parentNode instanceof MethodCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->methodNameAnalyzer->isOverrideOfTypes($node, $types)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var Identifier $node */
|
||||
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
|
||||
|
||||
/** @var Identifier $node */
|
||||
if (! isset($this->perClassOldToNewMethods[$parentClassName][$node->name])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->activeTypes = [$parentClassName];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveIdentifier(Identifier $node): ?Identifier
|
||||
{
|
||||
$oldToNewMethods = $this->matchOldToNewMethods();
|
||||
|
||||
$methodName = $node->name;
|
||||
if (! isset($oldToNewMethods[$methodName])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->name = $oldToNewMethods[$methodName];
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function processIdentifierNode(Identifier $identifierNode): ?Identifier
|
||||
{
|
||||
$this->activeTypes = [];
|
||||
|
||||
$matchedTypes = $this->matchTypes($identifierNode, $this->getClasses());
|
||||
|
||||
if ($matchedTypes) {
|
||||
$this->activeTypes = $matchedTypes;
|
||||
}
|
||||
|
||||
if (! $this->isMethodName($identifierNode, $this->getClasses())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->resolveIdentifier($identifierNode);
|
||||
}
|
||||
|
||||
private function processMethodCall(MethodCall $node): ?MethodCall
|
||||
{
|
||||
$this->activeTypes = [];
|
||||
$matchedTypes = $this->matchTypes($node, $this->getClasses());
|
||||
if ($matchedTypes) {
|
||||
$this->activeTypes = $matchedTypes;
|
||||
}
|
||||
|
||||
$oldToNewMethods = $this->matchOldToNewMethods();
|
||||
|
||||
$currentMethodName = $this->getName($node);
|
||||
if (! isset($oldToNewMethods[$currentMethodName])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->identifierRenamer->renameNode($node, $oldToNewMethods[$currentMethodName]);
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,6 @@ use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use Rector\Builder\IdentifierRenamer;
|
||||
use Rector\NodeAnalyzer\MethodNameAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\ConfiguredCodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
@ -16,48 +13,39 @@ use Rector\RectorDefinition\RectorDefinition;
|
||||
final class StaticMethodNameReplacerRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string[][]
|
||||
* @var string[][]|string[][][]
|
||||
*/
|
||||
private $perClassOldToNewMethods = [];
|
||||
private $oldToNewMethodByClasses = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @param string[][]|string[][][] $oldToNewMethodByClasses
|
||||
*/
|
||||
private $activeTypes = [];
|
||||
|
||||
/**
|
||||
* @var MethodNameAnalyzer
|
||||
*/
|
||||
private $methodNameAnalyzer;
|
||||
|
||||
/**
|
||||
* @var IdentifierRenamer
|
||||
*/
|
||||
private $identifierRenamer;
|
||||
|
||||
/**
|
||||
* @param string[][] $perClassOldToNewMethods
|
||||
*/
|
||||
public function __construct(
|
||||
array $perClassOldToNewMethods,
|
||||
MethodNameAnalyzer $methodNameAnalyzer,
|
||||
IdentifierRenamer $identifierRenamer
|
||||
) {
|
||||
$this->perClassOldToNewMethods = $perClassOldToNewMethods;
|
||||
$this->methodNameAnalyzer = $methodNameAnalyzer;
|
||||
$this->identifierRenamer = $identifierRenamer;
|
||||
public function __construct(array $oldToNewMethodByClasses)
|
||||
{
|
||||
$this->oldToNewMethodByClasses = $oldToNewMethodByClasses;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Turns method names to new ones.', [
|
||||
new ConfiguredCodeSample(
|
||||
'SomeClass::oldStaticMethod();',
|
||||
'AnotherExampleClass::newStaticMethod();',
|
||||
[
|
||||
'$oldToNewMethodByClasses' => [
|
||||
'SomeClass' => [
|
||||
'oldMethod' => ['AnotherExampleClass', 'newStaticMethod'],
|
||||
],
|
||||
],
|
||||
]
|
||||
),
|
||||
new ConfiguredCodeSample(
|
||||
'SomeClass::oldStaticMethod();',
|
||||
'SomeClass::newStaticMethod();',
|
||||
[
|
||||
'$perClassOldToNewMethods' => [
|
||||
'$oldToNewMethodByClasses' => [
|
||||
'SomeClass' => [
|
||||
'oldMethod' => ['SomeClass', 'newMethod'],
|
||||
'oldMethod' => 'newStaticMethod',
|
||||
],
|
||||
],
|
||||
]
|
||||
@ -70,155 +58,44 @@ final class StaticMethodNameReplacerRector extends AbstractRector
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Identifier::class, StaticCall::class];
|
||||
return [StaticCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Identifier|StaticCall $node
|
||||
* @param StaticCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($node instanceof Identifier) {
|
||||
return $this->processIdentifierNode($node);
|
||||
}
|
||||
foreach ($this->oldToNewMethodByClasses as $type => $oldToNewMethods) {
|
||||
if (! $this->isType($node, $type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof StaticCall) {
|
||||
return $this->processStaticCallNode($node);
|
||||
foreach ($oldToNewMethods as $oldMethod => $newMethod) {
|
||||
if (! $this->isNameInsensitive($node, $oldMethod)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->rename($node, $newMethod);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @param string|string[] $newMethod
|
||||
*/
|
||||
private function getClasses(): array
|
||||
private function rename(StaticCall $staticCallNode, $newMethod): StaticCall
|
||||
{
|
||||
return array_keys($this->perClassOldToNewMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $oldToNewMethods
|
||||
*/
|
||||
private function isClassRename(array $oldToNewMethods): bool
|
||||
{
|
||||
$firstMethodConfiguration = current($oldToNewMethods);
|
||||
|
||||
return is_array($firstMethodConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function matchOldToNewMethods(): array
|
||||
{
|
||||
foreach ($this->activeTypes as $activeType) {
|
||||
if (isset($this->perClassOldToNewMethods[$activeType])) {
|
||||
return $this->perClassOldToNewMethods[$activeType];
|
||||
}
|
||||
if (is_array($newMethod)) {
|
||||
[$newClass, $newMethod] = $newMethod;
|
||||
$staticCallNode->class = new Name($newClass);
|
||||
$staticCallNode->name = new Identifier($newMethod);
|
||||
} else {
|
||||
$staticCallNode->name = new Identifier($newMethod);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $types
|
||||
*/
|
||||
private function isMethodName(Node $node, array $types): bool
|
||||
{
|
||||
// already covered by previous methods
|
||||
if (! $node instanceof Identifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parentNode = $node->getAttribute(Attribute::PARENT_NODE);
|
||||
if ($parentNode instanceof StaticCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->methodNameAnalyzer->isOverrideOfTypes($node, $types)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var Identifier $node */
|
||||
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
|
||||
|
||||
/** @var Identifier $node */
|
||||
if (! isset($this->perClassOldToNewMethods[$parentClassName][$node->name])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->activeTypes = [$parentClassName];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveIdentifier(Identifier $node): ?Identifier
|
||||
{
|
||||
$oldToNewMethods = $this->matchOldToNewMethods();
|
||||
|
||||
$methodName = $node->name;
|
||||
if (! isset($oldToNewMethods[$methodName])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->name = $oldToNewMethods[$methodName];
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $oldToNewMethods
|
||||
*/
|
||||
private function resolveClassRename(StaticCall $staticCallNode, array $oldToNewMethods, string $methodName): Node
|
||||
{
|
||||
[$newClass, $newMethod] = $oldToNewMethods[$methodName];
|
||||
|
||||
$staticCallNode->class = new Name($newClass);
|
||||
$this->identifierRenamer->renameNode($staticCallNode, $newMethod);
|
||||
|
||||
return $staticCallNode;
|
||||
}
|
||||
|
||||
private function processIdentifierNode(Identifier $node): ?Identifier
|
||||
{
|
||||
$this->activeTypes = [];
|
||||
$matchedTypes = $this->matchTypes($node, $this->getClasses());
|
||||
if ($matchedTypes) {
|
||||
$this->activeTypes = $matchedTypes;
|
||||
}
|
||||
|
||||
if (! $this->isMethodName($node, $this->getClasses())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->resolveIdentifier($node);
|
||||
}
|
||||
|
||||
private function processStaticCallNode(StaticCall $node): ?Node
|
||||
{
|
||||
$this->activeTypes = [];
|
||||
$matchedTypes = $this->matchTypes($node, $this->getClasses());
|
||||
if ($matchedTypes) {
|
||||
$this->activeTypes = $matchedTypes;
|
||||
}
|
||||
|
||||
$oldToNewMethods = $this->matchOldToNewMethods();
|
||||
|
||||
/** @var Identifier $identifierNode */
|
||||
$identifierNode = $node->name;
|
||||
|
||||
$methodName = $identifierNode->toString();
|
||||
if (! isset($oldToNewMethods[$methodName])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isClassRename($oldToNewMethods)) {
|
||||
return $this->resolveClassRename($node, $oldToNewMethods, $methodName);
|
||||
}
|
||||
|
||||
$this->identifierRenamer->renameNode($node, $oldToNewMethods[$methodName]);
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,11 @@ trait NameResolverTrait
|
||||
return $this->getName($node) === $name;
|
||||
}
|
||||
|
||||
public function isNameInsensitive(Node $node, string $name): bool
|
||||
{
|
||||
return strtolower($this->getName($node)) === strtolower($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $names
|
||||
*/
|
||||
|
@ -5,7 +5,6 @@ namespace Rector\Rector\Property;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Identifier;
|
||||
use Rector\Builder\IdentifierRenamer;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\ConfiguredCodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
@ -19,25 +18,14 @@ final class PropertyNameReplacerRector extends AbstractRector
|
||||
*
|
||||
* @var string[][]
|
||||
*/
|
||||
private $perClassOldToNewProperties = [];
|
||||
private $oldToNewPropertyByTypes = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @param string[][] $oldToNewPropertyByTypes
|
||||
*/
|
||||
private $activeTypes = [];
|
||||
|
||||
/**
|
||||
* @var IdentifierRenamer
|
||||
*/
|
||||
private $identifierRenamer;
|
||||
|
||||
/**
|
||||
* @param string[][] $perClassOldToNewProperties
|
||||
*/
|
||||
public function __construct(array $perClassOldToNewProperties, IdentifierRenamer $identifierRenamer)
|
||||
public function __construct(array $oldToNewPropertyByTypes)
|
||||
{
|
||||
$this->perClassOldToNewProperties = $perClassOldToNewProperties;
|
||||
$this->identifierRenamer = $identifierRenamer;
|
||||
$this->oldToNewPropertyByTypes = $oldToNewPropertyByTypes;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
@ -47,7 +35,7 @@ final class PropertyNameReplacerRector extends AbstractRector
|
||||
'$someObject->someOldProperty;',
|
||||
'$someObject->someNewProperty;',
|
||||
[
|
||||
'$perClassOldToNewProperties' => [
|
||||
'$oldToNewPropertyByTypes' => [
|
||||
'SomeClass' => [
|
||||
'someOldProperty' => 'someNewProperty',
|
||||
],
|
||||
@ -70,54 +58,20 @@ final class PropertyNameReplacerRector extends AbstractRector
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$this->activeTypes = [];
|
||||
$matchedTypes = $this->matchTypes($node, $this->getClasses());
|
||||
|
||||
if ($matchedTypes) {
|
||||
$this->activeTypes = $matchedTypes;
|
||||
}
|
||||
|
||||
$oldToNewProperties = $this->matchOldToNewProperties();
|
||||
|
||||
/** @var Identifier $identifierNode */
|
||||
$identifierNode = $node->name;
|
||||
|
||||
$propertyName = $identifierNode->toString();
|
||||
|
||||
if (! isset($oldToNewProperties[$propertyName])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($oldToNewProperties as $oldProperty => $newProperty) {
|
||||
if ($propertyName !== $oldProperty) {
|
||||
foreach ($this->oldToNewPropertyByTypes as $type => $oldToNewProperties) {
|
||||
if (! $this->isType($node, $type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->identifierRenamer->renameNode($node, $newProperty);
|
||||
foreach ($oldToNewProperties as $oldProperty => $newProperty) {
|
||||
if (! $this->isNameInsensitive($node, $oldProperty)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->name = new Identifier($newProperty);
|
||||
}
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function getClasses(): array
|
||||
{
|
||||
return array_keys($this->perClassOldToNewProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function matchOldToNewProperties(): array
|
||||
{
|
||||
foreach ($this->activeTypes as $activeType) {
|
||||
if ($this->perClassOldToNewProperties[$activeType]) {
|
||||
return $this->perClassOldToNewProperties[$activeType];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ final class ClassReplacerRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
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'];
|
||||
}
|
||||
|
||||
protected function provideConfig(): string
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
namespace SomeNamespace;
|
||||
|
||||
use \SomeNamespace\NewClassWithoutTypo;
|
||||
|
||||
class MyClass extends \SomeNamespace\NewClassWithoutTypo
|
||||
{
|
||||
public function run(): \SomeNamespace\NewClassWithoutTypo
|
||||
{
|
||||
$oldClassWithTypo = new \SomeNamespace\NewClassWithoutTypo;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Rector\Class_\ClassReplacerRector\Source;
|
||||
|
||||
class OldClassWithTypo
|
||||
{
|
||||
|
||||
}
|
13
tests/Rector/Class_/ClassReplacerRector/Wrong/wrong3.php.inc
Normal file
13
tests/Rector/Class_/ClassReplacerRector/Wrong/wrong3.php.inc
Normal file
@ -0,0 +1,13 @@
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
namespace SomeNamespace;
|
||||
|
||||
use Rector\Tests\Rector\Class_\ClassReplacerRector\Source\OldClassWithTypo;
|
||||
|
||||
class MyClass extends OldClassWithTypO
|
||||
{
|
||||
public function run(): OLDClassWithTYPO
|
||||
{
|
||||
$oldClassWithTypo = new OldClassWithTYPO;
|
||||
}
|
||||
}
|
@ -2,4 +2,4 @@ services:
|
||||
Rector\Rector\Class_\ClassReplacerRector:
|
||||
'SomeNamespace\OldClass': 'Rector\Tests\Rector\Class_\ClassReplacerRector\Source\NewClass'
|
||||
'PhpParser\BuilderAbstract': 'PhpParser\Builder'
|
||||
|
||||
Rector\Tests\Rector\Class_\ClassReplacerRector\Source\OldClassWithTypo: 'SomeNamespace\NewClassWithoutTypo'
|
||||
|
@ -9,6 +9,7 @@ class SomeClass
|
||||
public function subscribe()
|
||||
{
|
||||
return [
|
||||
LocalFormEvents::PRE_SUBMIT,
|
||||
LocalFormEvents::PRE_SUBMIT
|
||||
];
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ class SomeClass
|
||||
public function subscribe()
|
||||
{
|
||||
return [
|
||||
LocalFormEvents::PRE_BIND
|
||||
LocalFormEvents::PRE_BIND,
|
||||
LocalFormEvents::PRE_Bind
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,7 @@ class SomeClass
|
||||
'parameters > directories_to_repositories',
|
||||
'monorepo-builder.yml'
|
||||
));
|
||||
|
||||
$this->setName(\Safe\sprintf('One %s', 'two'));
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,7 @@ class SomeClass
|
||||
'parameters > directories_to_repositories',
|
||||
'monorepo-builder.yml'
|
||||
));
|
||||
|
||||
$this->setName(sprINTf('One %s', 'two'));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
use Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\AbstractType;
|
||||
use Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\Something;
|
||||
|
||||
class MyType6 extends AbstractType
|
||||
{
|
||||
public function configureOptions(SomeResolver $resolver)
|
||||
{
|
||||
$something = new Something();
|
||||
$something->setDefaultOptions();
|
||||
|
||||
parent::configureOptions($resolver);
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ final class MethodNameReplacerRectorTest extends AbstractRectorTestCase
|
||||
yield [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/correct3.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong4.php.inc', __DIR__ . '/Correct/correct4.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong5.php.inc', __DIR__ . '/Correct/correct5.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong6.php.inc', __DIR__ . '/Correct/correct6.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/SomeClass.php', __DIR__ . '/Correct/SomeClass.php'];
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
<?php declare (strict_types=1);
|
||||
|
||||
use Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\AbstractType;
|
||||
use Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\Something;
|
||||
|
||||
class MyType6 extends AbstractType
|
||||
{
|
||||
public function setDefaultOptions(SomeResolver $resolver)
|
||||
{
|
||||
$something = new Something();
|
||||
$something->setDefaultOptions();
|
||||
|
||||
parent::setDEFAULTOptions($resolver);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
services:
|
||||
Rector\Rector\MethodCall\MethodNameReplacerRector:
|
||||
'Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\AbstractType':
|
||||
'setDefaultOptions': 'configureOptions'
|
||||
'Nette\Utils\Html':
|
||||
'add': 'addHtml'
|
||||
'Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\FormMacros':
|
||||
'renderFormBegin': ['Nette\Bridges\FormsLatte\Runtime', 'renderFormBegin']
|
||||
Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\AbstractType:
|
||||
setDefaultOptions: 'configureOptions'
|
||||
Nette\Utils\Html:
|
||||
add: 'addHtml'
|
||||
Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\FormMacros:
|
||||
renderFormBegin: ['Nette\Bridges\FormsLatte\Runtime', 'renderFormBegin']
|
||||
|
@ -3,3 +3,4 @@
|
||||
use Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\FormMacros;
|
||||
|
||||
$result = Nette\Bridges\FormsLatte\Runtime::renderFormBegin($someArgs);
|
||||
$result = Nette\Bridges\FormsLatte\Runtime::renderFormBegin($someArgs);
|
||||
|
@ -3,3 +3,4 @@
|
||||
use Rector\Tests\Rector\MethodCall\MethodNameReplacerRector\Source\FormMacros;
|
||||
|
||||
$result = FormMacros::renderFormBegin($someArgs);
|
||||
$result = FormMACROS::renderFormBEGIN($someArgs);
|
||||
|
@ -2,3 +2,4 @@
|
||||
|
||||
$someService = new SomeClass;
|
||||
$someService->newProperty = 5;
|
||||
$someService->anotherNewProperty = 5;
|
||||
|
@ -2,3 +2,4 @@
|
||||
|
||||
$someService = new SomeClass;
|
||||
$someService->oldProperty = 5;
|
||||
$someService->anotherOLDProperty = 5;
|
||||
|
@ -1,4 +1,5 @@
|
||||
services:
|
||||
Rector\Rector\Property\PropertyNameReplacerRector:
|
||||
'SomeClass':
|
||||
'oldProperty': 'newProperty'
|
||||
SomeClass:
|
||||
oldProperty: 'newProperty'
|
||||
anotherOldProperty: 'anotherNewProperty'
|
||||
|
Loading…
x
Reference in New Issue
Block a user