Skip to content
Merged

Misc #1866

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\Type;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeAnalyzer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PHPStan\Type\IterableType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
use Rector\PhpParser\Node\Manipulator\PropertyFetchManipulator;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
Expand All @@ -34,9 +35,17 @@ final class AddArrayDefaultToArrayPropertyRector extends AbstractRector
*/
private $docBlockManipulator;

public function __construct(DocBlockManipulator $docBlockManipulator)
{
/**
* @var PropertyFetchManipulator
*/
private $propertyFetchManipulator;

public function __construct(
DocBlockManipulator $docBlockManipulator,
PropertyFetchManipulator $propertyFetchManipulator
) {
$this->docBlockManipulator = $docBlockManipulator;
$this->propertyFetchManipulator = $propertyFetchManipulator;
}

public function getDefinition(): RectorDefinition
Expand Down Expand Up @@ -102,22 +111,6 @@ public function refactor(Node $node): ?Node
return $node;
}

/**
* @param string[] $changedProperties
*/
private function isLocalPropertyFetchOfNames(Expr $expr, array $changedProperties): bool
{
if (! $expr instanceof PropertyFetch) {
return false;
}

if (! $this->isName($expr->var, 'this')) {
return false;
}

return $this->isNames($expr->name, $changedProperties);
}

/**
* @return string[]
*/
Expand Down Expand Up @@ -187,11 +180,15 @@ private function replaceNullComparisonOfArrayPropertiesWithArrayComparison(
return null;
}

if ($this->isLocalPropertyFetchOfNames($node->left, $propertyNames) && $this->isNull($node->right)) {
if ($this->propertyFetchManipulator->isLocalPropertyOfNames($node->left, $propertyNames) && $this->isNull(
$node->right
)) {
$node->right = new Array_();
}

if ($this->isLocalPropertyFetchOfNames($node->right, $propertyNames) && $this->isNull($node->left)) {
if ($this->propertyFetchManipulator->isLocalPropertyOfNames($node->right, $propertyNames) && $this->isNull(
$node->left
)) {
$node->left = new Array_();
}

Expand All @@ -204,7 +201,7 @@ private function replaceNullComparisonOfArrayPropertiesWithArrayComparison(
*/
private function clearNotNullBeforeCount(Class_ $class, array $propertyNames): void
{
$this->traverseNodesWithCallable($class, function (Node $node) use ($propertyNames) {
$this->traverseNodesWithCallable($class, function (Node $node) use ($propertyNames): ?Expr {
if (! $node instanceof BooleanAnd) {
return null;
}
Expand Down Expand Up @@ -254,11 +251,15 @@ private function isLocalPropertyOfNamesNotIdenticalToNull(Expr $expr, array $pro
return false;
}

if ($this->isLocalPropertyFetchOfNames($expr->left, $propertyNames) && $this->isNull($expr->right)) {
if ($this->propertyFetchManipulator->isLocalPropertyOfNames($expr->left, $propertyNames) && $this->isNull(
$expr->right
)) {
return true;
}

if ($this->isLocalPropertyFetchOfNames($expr->right, $propertyNames) && $this->isNull($expr->left)) {
if ($this->propertyFetchManipulator->isLocalPropertyOfNames($expr->right, $propertyNames) && $this->isNull(
$expr->left
)) {
return true;
}

Expand Down
37 changes: 10 additions & 27 deletions packages/DeadCode/src/Analyzer/SetterOnlyMethodAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
namespace Rector\DeadCode\Analyzer;

use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use Rector\DeadCode\Doctrine\DoctrineEntityManipulator;
use Rector\NodeContainer\ParsedNodesByType;
use Rector\PhpParser\Node\Manipulator\AssignManipulator;
use Rector\PhpParser\Node\Manipulator\ClassManipulator;
use Rector\PhpParser\Node\Resolver\NameResolver;
use Rector\PhpParser\NodeTraverser\CallableNodeTraverser;
Expand Down Expand Up @@ -52,18 +51,25 @@ final class SetterOnlyMethodAnalyzer
*/
private $isSetterOnlyPropertiesAndMethodsByTypeAnalyzed = false;

/**
* @var AssignManipulator
*/
private $assignManipulator;

public function __construct(
ParsedNodesByType $parsedNodesByType,
ClassManipulator $classManipulator,
NameResolver $nameResolver,
CallableNodeTraverser $callableNodeTraverser,
DoctrineEntityManipulator $doctrineEntityManipulator
DoctrineEntityManipulator $doctrineEntityManipulator,
AssignManipulator $assignManipulator
) {
$this->parsedNodesByType = $parsedNodesByType;
$this->classManipulator = $classManipulator;
$this->nameResolver = $nameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
$this->doctrineEntityManipulator = $doctrineEntityManipulator;
$this->assignManipulator = $assignManipulator;
}

/**
Expand Down Expand Up @@ -158,29 +164,6 @@ private function isClassMethodWithSinglePropertyAssignOfNames(Node $node, array

$onlyStmt = $onlyExpression->expr;

return $this->isPropertyAssignWithPropertyNames($onlyStmt, $propertyNames);
}

/**
* Is: "$this->value = <$value>"
*
* @param string[] $propertyNames
*/
private function isPropertyAssignWithPropertyNames(Node $node, array $propertyNames): bool
{
if (! $node instanceof Assign) {
return false;
}

if (! $node->var instanceof PropertyFetch) {
return false;
}

$propertyFetch = $node->var;
if (! $this->nameResolver->isName($propertyFetch->var, 'this')) {
return false;
}

return $this->nameResolver->isNames($propertyFetch->name, $propertyNames);
return $this->assignManipulator->isLocalPropertyAssignWithPropertyNames($onlyStmt, $propertyNames);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Case_;
use PhpParser\Node\Stmt\Catch_;
Expand Down Expand Up @@ -68,7 +69,7 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
if (! $node->var instanceof Variable && ! $node->var instanceof PropertyFetch) {
if (! $node->var instanceof Variable && ! $node->var instanceof PropertyFetch && ! $node->var instanceof StaticPropertyFetch) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use Rector\DeadCode\Analyzer\SetterOnlyMethodAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PhpParser\Node\Manipulator\AssignManipulator;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
Expand All @@ -27,9 +27,17 @@ final class RemoveSetterOnlyPropertyAndMethodCallRector extends AbstractRector
*/
private $setterOnlyMethodAnalyzer;

public function __construct(SetterOnlyMethodAnalyzer $setterOnlyMethodAnalyzer)
{
/**
* @var AssignManipulator
*/
private $assignManipulator;

public function __construct(
SetterOnlyMethodAnalyzer $setterOnlyMethodAnalyzer,
AssignManipulator $assignManipulator
) {
$this->setterOnlyMethodAnalyzer = $setterOnlyMethodAnalyzer;
$this->assignManipulator = $assignManipulator;
}

public function getDefinition(): RectorDefinition
Expand Down Expand Up @@ -149,7 +157,7 @@ private function processClassStmts(Node $node, array $setterOnlyPropertiesAndMet
}

// 2. remove class inner assigns
if ($this->isThisVariableAssign($node)) {
if ($this->assignManipulator->isLocalPropertyAssign($node)) {
/** @var Assign $node */
$propertyFetch = $node->var;
/** @var PropertyFetch $propertyFetch */
Expand All @@ -165,25 +173,4 @@ private function processClassStmts(Node $node, array $setterOnlyPropertiesAndMet
}
}
}

/**
* Checks:
* $this->x = y;
*/
private function isThisVariableAssign(Node $node): bool
{
if (! $node instanceof Assign) {
return false;
}

if (! $node->var instanceof PropertyFetch) {
return false;
}

if (! $node->var->var instanceof Variable) {
return false;
}

return $this->isName($node->var->var, 'this');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\PostInc;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
Expand Down Expand Up @@ -167,7 +168,7 @@ private function processFieldToFieldDirect(Assign $assign, FuncCall $funcCall):
foreach ($this->fieldToFieldDirect as $funcName => $property) {
if ($this->isName($funcCall, $funcName)) {
$parentNode = $funcCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof PropertyFetch) {
if ($parentNode instanceof PropertyFetch || $parentNode instanceof StaticPropertyFetch) {
continue;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/NodeTypeResolver/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ services:

Rector\NodeTypeResolver\:
resource: '../src'
exclude: '../src/{Contract,Php/*Info.php,PHPStanOverride/*}'
# "Type" is because the file is needed for PHPStan container only
exclude: '../src/{Contract,Php/*Info.php,PHPStanOverride/*,Type}'

Rector\Php\TypeAnalyzer: ~
Rector\FileSystem\FilesFinder: ~
Expand Down
4 changes: 4 additions & 0 deletions packages/NodeTypeResolver/config/phpstan/type-extensions.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
-
class: Rector\NodeTypeResolver\Type\TypeExtension\StaticContainerGetDynamicMethodReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public function __construct()
$additionalConfigFiles[] = $phpstanPhpunitExtensionConfig;
}

$additionalConfigFiles[] = __DIR__ . '/../../config/phpstan/type-extensions.neon';

$this->container = $containerFactory->create(sys_get_temp_dir(), $additionalConfigFiles, []);
}

Expand Down
5 changes: 3 additions & 2 deletions packages/NodeTypeResolver/src/NodeTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\String_;
Expand Down Expand Up @@ -252,7 +253,7 @@ public function isArrayType(Node $node): bool
return true;
}

if ($node instanceof PropertyFetch) {
if ($node instanceof PropertyFetch || $node instanceof StaticPropertyFetch) {
// PHPStan false positive, when variable has type[] docblock, but default array is missing
if ($this->isPropertyFetchWithArrayDefault($node) === false) {
return false;
Expand Down Expand Up @@ -527,7 +528,7 @@ private function isIntersectionArrayType(Type $nodeType): bool
*/
private function isPropertyFetchWithArrayDefault(Node $node): bool
{
if (! $node instanceof PropertyFetch) {
if (! $node instanceof PropertyFetch && ! $node instanceof StaticPropertyFetch) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,6 @@ private function isClassAnonymous(Node $node): bool
}

// PHPStan polution
return Strings::startsWith($node->name->toString(), 'AnonymousClass');
return (bool) Strings::match($node->name->toString(), '#^AnonymousClass\w+#');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php declare(strict_types=1);

namespace Rector\NodeTypeResolver\Type\TypeExtension;

use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Psr\Container\ContainerInterface;
use Rector\Exception\ShouldNotHappenException;

final class StaticContainerGetDynamicMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return ContainerInterface::class;
}

public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'get';
}

public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
$valueType = $scope->getType($methodCall->args[0]->value);

if ($valueType instanceof ConstantStringType) {
return new ObjectType($valueType->getValue());
}

throw new ShouldNotHappenException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public function refactor(Node $node): ?Node
return null;
}

/** @var Node|null $nextNode */
$nextNode = $expression->getAttribute(AttributeKey::NEXT_NODE);
if ($nextNode === null) {
return null;
Expand Down
Loading