Skip to content

Commit

Permalink
[Php81] Allow normal variable in trait on NullToStrictStringFuncCallA…
Browse files Browse the repository at this point in the history
…rgRector (#3181)

* [Php81] Allow normal variable in trait on NullToStrictStringFuncCallArgRector

* update fixture

* Fixed 🎉

* cs clean

* phpstan

* rename fixture for skip method call mixed object on trait -a

* rollback property assigned in trait construct

* rollback

* clean up

* [ci-review] Rector Rectify

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Dec 10, 2022
1 parent e1f7637 commit e479114
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 65 deletions.

This file was deleted.

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

namespace Rector\Tests\CodingStyle\Rector\Property\AddFalseDefaultToBoolPropertyRector\Fixture;

trait SkipAssignInConstruct2
{
/**
* @var bool
*/
private $property;

public function __construct(bool $property)
{
$this->property = $property;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Rector\Tests\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector\Fixture;

trait NormalVariableInTrait
{
public function getTitle($title)
{
return trim($title);
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector\Fixture;

trait NormalVariableInTrait
{
public function getTitle($title)
{
return trim((string) $title);
}
}

?>
38 changes: 22 additions & 16 deletions rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\Encapsed;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Trait_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\Native\NativeFunctionReflection;
use PHPStan\Type\ErrorType;
use PHPStan\Type\MixedType;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;
Expand Down Expand Up @@ -331,7 +331,8 @@ final class NullToStrictStringFuncCallArgRector extends AbstractScopeAwareRector

public function __construct(
private readonly ReflectionResolver $reflectionResolver,
private readonly ArgsAnalyzer $argsAnalyzer
private readonly ArgsAnalyzer $argsAnalyzer,
private readonly PropertyFetchAnalyzer $propertyFetchAnalyzer
) {
}

Expand Down Expand Up @@ -378,7 +379,7 @@ public function getNodeTypes(): array
*/
public function refactorWithScope(Node $node, Scope $scope): ?Node
{
if ($this->shouldSkip($node, $scope)) {
if ($this->shouldSkip($node)) {
return null;
}

Expand All @@ -391,9 +392,12 @@ public function refactorWithScope(Node $node, Scope $scope): ?Node
return null;
}

$classReflection = $scope->getClassReflection();
$isTrait = $classReflection instanceof ClassReflection && $classReflection->isTrait();

$isChanged = false;
foreach ($positions as $position) {
$result = $this->processNullToStrictStringOnNodePosition($node, $args, $position);
$result = $this->processNullToStrictStringOnNodePosition($node, $args, $position, $isTrait);
if ($result instanceof Node) {
$node = $result;
$isChanged = true;
Expand Down Expand Up @@ -443,7 +447,8 @@ private function resolveNamedPositions(FuncCall $funcCall, array $args): array
private function processNullToStrictStringOnNodePosition(
FuncCall $funcCall,
array $args,
int|string $position
int|string $position,
bool $isTrait
): ?FuncCall {
if (! isset($args[$position])) {
return null;
Expand Down Expand Up @@ -471,11 +476,8 @@ private function processNullToStrictStringOnNodePosition(
return null;
}

if ($args[$position]->value instanceof MethodCall) {
$trait = $this->betterNodeFinder->findParentType($funcCall, Trait_::class);
if ($trait instanceof Trait_) {
return null;
}
if ($this->shouldSkipTrait($argValue, $isTrait)) {
return null;
}

if ($this->isCastedReassign($argValue)) {
Expand All @@ -488,6 +490,15 @@ private function processNullToStrictStringOnNodePosition(
return $funcCall;
}

private function shouldSkipTrait(Expr $expr, bool $isTrait): bool
{
if (! $expr instanceof MethodCall) {
return $isTrait && $this->propertyFetchAnalyzer->isLocalPropertyFetch($expr);
}

return $isTrait;
}

private function isCastedReassign(Expr $expr): bool
{
return (bool) $this->betterNodeFinder->findFirstPrevious($expr, function (Node $subNode) use ($expr): bool {
Expand Down Expand Up @@ -551,18 +562,13 @@ private function resolveOriginalPositions(FuncCall $funcCall): array
return $positions;
}

private function shouldSkip(FuncCall $funcCall, Scope $scope): bool
private function shouldSkip(FuncCall $funcCall): bool
{
$functionNames = array_keys(self::ARG_POSITION_NAME_NULL_TO_STRICT_STRING);
if (! $this->nodeNameResolver->isNames($funcCall, $functionNames)) {
return true;
}

$classReflection = $scope->getClassReflection();
if ($classReflection instanceof ClassReflection && $classReflection->isTrait()) {
return true;
}

return $funcCall->isFirstClassCallable();
}
}
15 changes: 5 additions & 10 deletions src/NodeAnalyzer/PropertyFetchAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
Expand All @@ -53,14 +52,6 @@ public function isLocalPropertyFetch(Node $node): bool
return false;
}

$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
/**
* Property Fetch on Trait currently doesn't has Parent Node, so fallback to use this, self, static name instead
*/
if (! $parentNode instanceof Node) {
return $this->isTraitLocalPropertyFetch($node);
}

$variableType = $node instanceof PropertyFetch
? $this->nodeTypeResolver->getType($node->var)
: $this->nodeTypeResolver->getType($node->class);
Expand All @@ -74,7 +65,11 @@ public function isLocalPropertyFetch(Node $node): bool
return false;
}

return $variableType instanceof ThisType;
if (! $variableType instanceof ThisType) {
return $this->isTraitLocalPropertyFetch($node);
}

return true;
}

public function isLocalPropertyFetchName(Node $node, string $desiredPropertyName): bool
Expand Down

0 comments on commit e479114

Please sign in to comment.