Skip to content

Commit

Permalink
[Core] Apply auto fallback to use Scope from File when Node both does…
Browse files Browse the repository at this point in the history
…not has parent Node and Scope (#2587)

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Jun 29, 2022
1 parent 1d037d1 commit d180768
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,13 @@ private function processIdenticalOrNotIdentical(Node $node, FuncCall $funcCall,
if (($node instanceof Identical || $node instanceof NotIdentical) && $node->right instanceof LNumber && $node->right->value === 0) {
$this->removeNode($funcCall);
$node->right = new Array_([]);
$node->right->setAttribute(AttributeKey::SCOPE, $node->getAttribute(AttributeKey::SCOPE));

return $expr;
}

if (($node instanceof Identical || $node instanceof NotIdentical) && $node->left instanceof LNumber && $node->left->value === 0) {
$this->removeNode($funcCall);
$node->left = new Array_([]);
$node->left->setAttribute(AttributeKey::SCOPE, $node->getAttribute(AttributeKey::SCOPE));

return $expr;
}
Expand Down
12 changes: 3 additions & 9 deletions src/NodeAnalyzer/ScopeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Namespace_;
use PHPStan\Analyser\MutatingScope;
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\NodeTypeResolver\Node\AttributeKey;

final class ScopeAnalyzer
{
Expand All @@ -21,11 +19,6 @@ final class ScopeAnalyzer
*/
private const NO_SCOPE_NODES = [Name::class, Identifier::class, Param::class, Arg::class];

/**
* @var array<class-string<Stmt>>
*/
private const RESOLVABLE_FROM_FILE_NODES = [Namespace_::class, FileWithoutNamespace::class];

public function hasScope(Node $node): bool
{
foreach (self::NO_SCOPE_NODES as $noScopeNode) {
Expand All @@ -43,6 +36,7 @@ public function isScopeResolvableFromFile(Node $node, ?MutatingScope $mutatingSc
return false;
}

return in_array($node::class, self::RESOLVABLE_FROM_FILE_NODES, true);
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
return ! $parent instanceof Node;
}
}
4 changes: 0 additions & 4 deletions src/NodeManipulator/ClassInsertManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\ValueObject\PropertyMetadata;

final class ClassInsertManipulator
Expand All @@ -32,9 +31,6 @@ public function __construct(

public function addAsFirstMethod(Class_ $class, Property | ClassConst | ClassMethod $stmt): void
{
$scope = $class->getAttribute(AttributeKey::SCOPE);
$stmt->setAttribute(AttributeKey::SCOPE, $scope);

if ($this->isSuccessToInsertBeforeFirstMethod($class, $stmt)) {
return;
}
Expand Down
12 changes: 11 additions & 1 deletion src/Rector/AbstractRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Exclusion\ExclusionManager;
use Rector\Core\Logging\CurrentRectorProvider;
use Rector\Core\NodeAnalyzer\ScopeAnalyzer;
use Rector\Core\NodeDecorator\CreatedByRuleDecorator;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
Expand All @@ -37,6 +38,7 @@
use Rector\NodeRemoval\NodeRemover;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\PHPStan\Scope\ScopeFactory;
use Rector\PostRector\Collector\NodesToAddCollector;
use Rector\PostRector\Collector\NodesToRemoveCollector;
use Rector\StaticTypeMapper\StaticTypeMapper;
Expand Down Expand Up @@ -97,6 +99,10 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn

protected ChangedNodeScopeRefresher $changedNodeScopeRefresher;

protected ScopeAnalyzer $scopeAnalyzer;

protected ScopeFactory $scopeFactory;

private SimpleCallableNodeTraverser $simpleCallableNodeTraverser;

private ExclusionManager $exclusionManager;
Expand Down Expand Up @@ -142,7 +148,9 @@ public function autowire(
RectifiedAnalyzer $rectifiedAnalyzer,
CreatedByRuleDecorator $createdByRuleDecorator,
ChangedNodeScopeRefresher $changedNodeScopeRefresher,
RectorOutputStyle $rectorOutputStyle
RectorOutputStyle $rectorOutputStyle,
ScopeAnalyzer $scopeAnalyzer,
ScopeFactory $scopeFactory
): void {
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
$this->nodesToAddCollector = $nodesToAddCollector;
Expand All @@ -165,6 +173,8 @@ public function autowire(
$this->createdByRuleDecorator = $createdByRuleDecorator;
$this->changedNodeScopeRefresher = $changedNodeScopeRefresher;
$this->rectorOutputStyle = $rectorOutputStyle;
$this->scopeAnalyzer = $scopeAnalyzer;
$this->scopeFactory = $scopeFactory;
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/Rector/AbstractScopeAwareRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ abstract class AbstractScopeAwareRector extends AbstractRector implements ScopeA
public function refactor(Node $node)
{
$scope = $node->getAttribute(AttributeKey::SCOPE);

if ($this->scopeAnalyzer->isScopeResolvableFromFile($node, $scope)) {
$smartFileInfo = $this->file->getSmartFileInfo();
$scope = $this->scopeFactory->createFromFile($smartFileInfo);

$this->changedNodeScopeRefresher->refresh($node, $scope, $smartFileInfo);
}

if (! $scope instanceof Scope) {
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);

Expand Down

0 comments on commit d180768

Please sign in to comment.