Skip to content

Commit

Permalink
Remove parent node fetch (#4143)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
TomasVotruba and actions-user committed Jun 9, 2023
1 parent ebfe96b commit 5ba083c
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 127 deletions.

This file was deleted.

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

namespace Rector\Tests\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector\Fixture;

trait SkipTrait
{
public ?string $name;
}
90 changes: 56 additions & 34 deletions rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ final class ArgumentAdderRector extends AbstractRector implements ConfigurableRe
*/
private array $addedArguments = [];

private bool $haveArgumentsChanged = false;
private bool $hasChanged = false;

public function __construct(
private readonly ArgumentAddingScope $argumentAddingScope,
Expand Down Expand Up @@ -83,9 +83,14 @@ public function someMethod($value = true)
CODE_SAMPLE
,
[
new ArgumentAdder('SomeExampleClass', 'someMethod', 0, 'someArgument', true, new ObjectType(
'SomeType'
)),
new ArgumentAdder(
'SomeExampleClass',
'someMethod',
0,
'someArgument',
true,
new ObjectType('SomeType')
),
]
),
]
Expand All @@ -97,29 +102,25 @@ public function someMethod($value = true)
*/
public function getNodeTypes(): array
{
return [MethodCall::class, StaticCall::class, ClassMethod::class];
return [MethodCall::class, StaticCall::class, Class_::class];
}

/**
* @param MethodCall|StaticCall|ClassMethod $node
* @param MethodCall|StaticCall|Class_ $node
*/
public function refactor(Node $node): MethodCall | StaticCall | ClassMethod | null
public function refactor(Node $node): MethodCall | StaticCall | Class_ | null
{
$this->haveArgumentsChanged = false;
$this->hasChanged = false;

foreach ($this->addedArguments as $addedArgument) {
if (! $this->isName($node->name, $addedArgument->getMethod())) {
continue;
}

if (! $this->isObjectTypeMatch($node, $addedArgument->getObjectType())) {
continue;
if ($node instanceof MethodCall || $node instanceof StaticCall) {
$this->refactorCall($node);
} else {
foreach ($node->getMethods() as $classMethod) {
$this->refactorClassMethod($node, $classMethod);
}

$this->processPositionWithDefaultValues($node, $addedArgument);
}

if ($this->haveArgumentsChanged) {
if ($this->hasChanged) {
return $node;
}

Expand All @@ -135,22 +136,13 @@ public function configure(array $configuration): void
$this->addedArguments = $configuration;
}

private function isObjectTypeMatch(MethodCall | StaticCall | ClassMethod $node, ObjectType $objectType): bool
private function isObjectTypeMatch(MethodCall | StaticCall $call, ObjectType $objectType): bool
{
if ($node instanceof MethodCall) {
return $this->isObjectType($node->var, $objectType);
}

if ($node instanceof StaticCall) {
return $this->isObjectType($node->class, $objectType);
if ($call instanceof MethodCall) {
return $this->isObjectType($call->var, $objectType);
}

$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return false;
}

return $this->isObjectType($classLike, $objectType);
return $this->isObjectType($call->class, $objectType);
}

private function processPositionWithDefaultValues(
Expand Down Expand Up @@ -189,7 +181,7 @@ private function processMethodCall(MethodCall $methodCall, mixed $defaultValue,
$this->fillGapBetweenWithDefaultValue($methodCall, $position);

$methodCall->args[$position] = $arg;
$this->haveArgumentsChanged = true;
$this->hasChanged = true;
}

private function fillGapBetweenWithDefaultValue(MethodCall | StaticCall $node, int $position): void
Expand Down Expand Up @@ -281,7 +273,7 @@ private function addClassMethodParam(
}

$classMethod->params[$position] = $param;
$this->haveArgumentsChanged = true;
$this->hasChanged = true;
}

private function processStaticCall(StaticCall $staticCall, int $position, ArgumentAdder $argumentAdder): void
Expand All @@ -302,6 +294,36 @@ private function processStaticCall(StaticCall $staticCall, int $position, Argume
$this->fillGapBetweenWithDefaultValue($staticCall, $position);

$staticCall->args[$position] = new Arg(new Variable($argumentName));
$this->haveArgumentsChanged = true;
$this->hasChanged = true;
}

private function refactorCall(StaticCall|MethodCall $call): void
{
foreach ($this->addedArguments as $addedArgument) {
if (! $this->isName($call->name, $addedArgument->getMethod())) {
continue;
}

if (! $this->isObjectTypeMatch($call, $addedArgument->getObjectType())) {
continue;
}

$this->processPositionWithDefaultValues($call, $addedArgument);
}
}

private function refactorClassMethod(Class_ $class, ClassMethod $classMethod): void
{
foreach ($this->addedArguments as $addedArgument) {
if (! $this->isName($classMethod, $addedArgument->getMethod())) {
continue;
}

if (! $this->isObjectType($class, $addedArgument->getObjectType())) {
continue;
}

$this->processPositionWithDefaultValues($classMethod, $addedArgument);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,40 @@ class SomeClass
*/
public function getNodeTypes(): array
{
return [Property::class];
return [Class_::class];
}

/**
* @param Property $node
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip($node)) {
return null;
$hasChanged = false;

foreach ($node->getProperties() as $property) {
if ($this->shouldSkip($property, $node)) {
continue;
}

$onlyProperty = $property->props[0];
$onlyProperty->default = $this->nodeFactory->createNull();

$hasChanged = true;
}

$onlyProperty = $node->props[0];
$onlyProperty->default = $this->nodeFactory->createNull();
if ($hasChanged) {
return $node;
}

return $node;
return null;
}

public function provideMinPhpVersion(): int
{
return PhpVersionFeature::TYPED_PROPERTIES;
}

private function shouldSkip(Property $property): bool
private function shouldSkip(Property $property, Class_ $class): bool
{
if ($property->type === null) {
return true;
Expand All @@ -102,14 +112,6 @@ private function shouldSkip(Property $property): bool

// is variable assigned in constructor
$propertyName = $this->getName($property);
$classLike = $this->betterNodeFinder->findParentType($property, Class_::class);

// a trait can be used in multiple context, we don't know whether it is assigned in __construct or not
// so it needs to has null default
if (! $classLike instanceof Class_) {
return false;
}

return $this->constructorAssignDetector->isPropertyAssigned($classLike, $propertyName);
return $this->constructorAssignDetector->isPropertyAssigned($class, $propertyName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,38 +69,50 @@ private function getSome()
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
return [Class_::class];
}

/**
* @param MethodCall $node
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
if (! $node->var instanceof Variable) {
return null;
}
$class = $node;
$hasChanged = false;

if (! $this->nodeNameResolver->isName($node->var, 'this')) {
return null;
}
$this->traverseNodesWithCallable($node, function (Node $node) use ($class, &$hasChanged): ?PropertyFetch {
if (! $node instanceof MethodCall) {
return null;
}

$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}
if (! $node->var instanceof Variable) {
return null;
}

$methodName = $this->getName($node->name);
if ($methodName === null) {
return null;
}
if (! $this->nodeNameResolver->isName($node->var, 'this')) {
return null;
}

$classMethod = $classLike->getMethod($methodName);
if (! $classMethod instanceof ClassMethod) {
return null;
$methodName = $this->getName($node->name);
if ($methodName === null) {
return null;
}

$classMethod = $class->getMethod($methodName);
if (! $classMethod instanceof ClassMethod) {
return null;
}

$hasChanged = true;

return $this->matchLocalPropertyFetchInGetterMethod($classMethod);
});

if ($hasChanged) {
return $node;
}

return $this->matchLocalPropertyFetchInGetterMethod($classMethod);
return null;
}

private function matchLocalPropertyFetchInGetterMethod(ClassMethod $classMethod): ?PropertyFetch
Expand Down
Loading

0 comments on commit 5ba083c

Please sign in to comment.