Skip to content
Open
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 @@ -152,7 +152,7 @@ private function isAllowedExpr(Expr $expr, Scope $scope): bool
return false;
}

$type = $this->allAssignNodePropertyTypeInferer->inferProperty($property, $classReflection, $this->file);
$type = $this->allAssignNodePropertyTypeInferer->inferProperty($property, $classReflection, $this->getFile());
if (! $type instanceof Type) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public function refactor(Node $node): ?Node
}

$oldTokens = $this->file->getOldTokens();

if ($this->isIfConditionFollowedByOpeningCurlyBracket($node, $oldTokens)) {
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion rules/CodeQuality/Rector/NotEqual/CommonNotEqualRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public function refactor(Node $node): ?NotEqual
$tokenEndPos = $node->getEndTokenPos();

for ($i = $tokenStartPos; $i < $tokenEndPos; ++$i) {
$token = $this->file->getOldTokens()[$i];
$token = $this->getFile()
->getOldTokens()[$i];

if ((string) $token === '<>') {
$token->text = '!=';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public function getNodeTypes(): array
public function refactor(Node $node): ?Node
{
$hasVariableBeenWrapped = false;
$oldTokens = $this->file->getOldTokens();
$oldTokens = $this->getFile()
->getOldTokens();

foreach ($node->parts as $index => $nodePart) {
if ($nodePart instanceof Variable && $nodePart->getStartTokenPos() >= 0) {
Expand Down
3 changes: 2 additions & 1 deletion rules/DeadCode/Rector/Concat/RemoveConcatAutocastRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ private function removeStringCast(Expr $expr): Expr
}

$targetExpr = $expr->expr;
$tokens = $this->file->getOldTokens();
$tokens = $this->getFile()
->getOldTokens();

if ($expr->expr instanceof BinaryOp) {
$castStartTokenPos = $expr->getStartTokenPos();
Expand Down
3 changes: 2 additions & 1 deletion rules/Php53/Rector/Ternary/TernaryToElvisRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ public function provideMinPhpVersion(): int

private function isParenthesized(Expr $ifExpr, Expr $elseExpr): bool
{
$tokens = $this->file->getOldTokens();
$tokens = $this->getFile()
->getOldTokens();

$ifExprTokenEnd = $ifExpr->getEndTokenPos();
$elseExprTokenStart = $elseExpr->getStartTokenPos();
Expand Down
3 changes: 2 additions & 1 deletion rules/Php54/Rector/Array_/LongArrayToShortArrayRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public function refactor(Node $node): ?Node

$node->setAttribute(AttributeKey::KIND, Array_::KIND_SHORT);

$tokens = $this->file->getOldTokens();
$tokens = $this->getFile()
->getOldTokens();

$startTokenPos = $node->getStartTokenPos();
$endTokenPos = $node->getEndTokenPos();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
if (! $this->isFollowedByCurlyBracket($this->file, $node)) {
if (! $this->isFollowedByCurlyBracket($this->getFile(), $node)) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function refactor(Node $node): ?Node
return null;
}

if ($this->parenthesizedNestedTernaryAnalyzer->isParenthesized($this->file, $node)) {
if ($this->parenthesizedNestedTernaryAnalyzer->isParenthesized($this->getFile(), $node)) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
$oldTokens = $this->file->getOldTokens();
$oldTokens = $this->getFile()
->getOldTokens();
$hasChanged = false;

foreach ($node->parts as $part) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public function refactor(Node $node): ?Node
return null;
}

$oldTokens = $this->file->getOldTokens();
$oldTokens = $this->getFile()
->getOldTokens();

$loop = 1;
while (isset($oldTokens[$node->var->getStartTokenPos() + $loop])) {
Expand Down
58 changes: 27 additions & 31 deletions rules/Php85/Rector/ArrayDimFetch/ArrayFirstLastRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,90 +80,90 @@ public function provideMinPhpVersion(): int
return PhpVersionFeature::ARRAY_FIRST_LAST;
}

private function refactorArrayKeyPattern(ArrayDimFetch $node): ?FuncCall
private function refactorArrayKeyPattern(ArrayDimFetch $arrayDimFetch): ?FuncCall
{
if (! $node->dim instanceof FuncCall) {
if (! $arrayDimFetch->dim instanceof FuncCall) {
return null;
}

if (! $this->isNames($node->dim, [self::ARRAY_KEY_FIRST, self::ARRAY_KEY_LAST])) {
if (! $this->isNames($arrayDimFetch->dim, [self::ARRAY_KEY_FIRST, self::ARRAY_KEY_LAST])) {
return null;
}

if ($node->dim->isFirstClassCallable()) {
if ($arrayDimFetch->dim->isFirstClassCallable()) {
return null;
}

if (count($node->dim->getArgs()) !== 1) {
if (count($arrayDimFetch->dim->getArgs()) !== 1) {
return null;
}

if (! $this->nodeComparator->areNodesEqual($node->var, $node->dim->getArgs()[0]->value)) {
if (! $this->nodeComparator->areNodesEqual($arrayDimFetch->var, $arrayDimFetch->dim->getArgs()[0]->value)) {
return null;
}

if ($this->shouldSkip($node, $node->var)) {
if ($this->shouldSkip($arrayDimFetch, $arrayDimFetch->var)) {
return null;
}

$functionName = $this->isName($node->dim, self::ARRAY_KEY_FIRST)
$functionName = $this->isName($arrayDimFetch->dim, self::ARRAY_KEY_FIRST)
? 'array_first'
: 'array_last';

return $this->nodeFactory->createFuncCall($functionName, [$node->var]);
return $this->nodeFactory->createFuncCall($functionName, [$arrayDimFetch->var]);
}

private function refactorArrayValuesPattern(ArrayDimFetch $node): ?FuncCall
private function refactorArrayValuesPattern(ArrayDimFetch $arrayDimFetch): ?FuncCall
{
if (! $node->var instanceof FuncCall) {
if (! $arrayDimFetch->var instanceof FuncCall) {
return null;
}

if (! $this->isName($node->var, 'array_values')) {
if (! $this->isName($arrayDimFetch->var, 'array_values')) {
return null;
}

if ($node->var->isFirstClassCallable()) {
if ($arrayDimFetch->var->isFirstClassCallable()) {
return null;
}

if (count($node->var->getArgs()) !== 1) {
if (count($arrayDimFetch->var->getArgs()) !== 1) {
return null;
}

if ($this->shouldSkip($node, $node)) {
if ($this->shouldSkip($arrayDimFetch, $arrayDimFetch)) {
return null;
}

$arrayArg = $node->var->getArgs()[0]
$arrayArg = $arrayDimFetch->var->getArgs()[0]
->value;

if ($node->dim instanceof Int_ && $node->dim->value === 0) {
if ($arrayDimFetch->dim instanceof Int_ && $arrayDimFetch->dim->value === 0) {
return $this->nodeFactory->createFuncCall('array_first', [$arrayArg]);
}

if ($node->dim instanceof Minus) {
if (! $node->dim->left instanceof FuncCall) {
if ($arrayDimFetch->dim instanceof Minus) {
if (! $arrayDimFetch->dim->left instanceof FuncCall) {
return null;
}

if (! $this->isName($node->dim->left, 'count')) {
if (! $this->isName($arrayDimFetch->dim->left, 'count')) {
return null;
}

if ($node->dim->left->isFirstClassCallable()) {
if ($arrayDimFetch->dim->left->isFirstClassCallable()) {
return null;
}

if (count($node->dim->left->getArgs()) !== 1) {
if (count($arrayDimFetch->dim->left->getArgs()) !== 1) {
return null;
}

if (! $node->dim->right instanceof Int_ || $node->dim->right->value !== 1) {
if (! $arrayDimFetch->dim->right instanceof Int_ || $arrayDimFetch->dim->right->value !== 1) {
return null;
}

if (! $this->nodeComparator->areNodesEqual($arrayArg, $node->dim->left->getArgs()[0]->value)) {
if (! $this->nodeComparator->areNodesEqual($arrayArg, $arrayDimFetch->dim->left->getArgs()[0]->value)) {
return null;
}

Expand All @@ -173,17 +173,13 @@ private function refactorArrayValuesPattern(ArrayDimFetch $node): ?FuncCall
return null;
}

private function shouldSkip(ArrayDimFetch $node, Node $scopeNode): bool
private function shouldSkip(ArrayDimFetch $arrayDimFetch, Node $scopeNode): bool
{
$scope = ScopeFetcher::fetch($scopeNode);
if ($scope->isInExpressionAssign($node)) {
if ($scope->isInExpressionAssign($arrayDimFetch)) {
return true;
}

if ($node->getAttribute(AttributeKey::IS_UNSET_VAR)) {
return true;
}

return false;
return (bool) $arrayDimFetch->getAttribute(AttributeKey::IS_UNSET_VAR);
}
}
3 changes: 2 additions & 1 deletion rules/Php85/Rector/Switch_/ColonAfterSwitchCaseRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public function getNodeTypes(): array
public function refactor(Node $node): ?Node
{
$hasChanged = false;
$oldTokens = $this->file->getOldTokens();
$oldTokens = $this->getFile()
->getOldTokens();

foreach ($node->cases as $key => $case) {
$cond = $case->cond;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public function refactor(Node $node): ?Node
$inferredType = $this->allAssignNodePropertyTypeInferer->inferProperty(
$property,
$classReflection,
$this->file
$this->getFile()
);
if (! $inferredType instanceof Type) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function someFunction(int $number)
public function refactor(Node $node): ?FileNode
{
// shebang files cannot have declare strict types
if ($this->file->hasShebang()) {
if ($this->getFile()->hasShebang()) {
return null;
}

Expand Down
3 changes: 2 additions & 1 deletion src/PostRector/Rector/AbstractPostRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ protected function addRectorClassWithLine(Node $node): void
Assert::isInstanceOf($this->file, File::class);

$rectorWithLineChange = new RectorWithLineChange(static::class, $node->getStartLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);
$this->getFile()
->addRectorClassWithLine($rectorWithLineChange);
}
}
49 changes: 32 additions & 17 deletions src/Rector/AbstractRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
use Rector\Skipper\Skipper\Skipper;
use Rector\ValueObject\Application\File;

/**
* @property-read File $file @deprecated Use $this->getFile() instead
*/
abstract class AbstractRector extends NodeVisitorAbstract implements RectorInterface
{
private const string EMPTY_NODE_ARRAY_MESSAGE = <<<CODE_SAMPLE
Expand All @@ -56,8 +59,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements RectorInter

protected NodeComparator $nodeComparator;

protected File $file;

protected Skipper $skipper;

private ChangedNodeScopeRefresher $changedNodeScopeRefresher;
Expand All @@ -70,6 +71,16 @@ abstract class AbstractRector extends NodeVisitorAbstract implements RectorInter

private CreatedByRuleDecorator $createdByRuleDecorator;

public function __get(string $name): mixed
{
if ($name === 'file') {
return $this->getFile();
}

// fallback to default behavior
return $this->{$name};
}

public function autowire(
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
Expand All @@ -96,23 +107,12 @@ public function autowire(

/**
* @final Avoid override to prevent unintended side-effects. Use enterNode() or @see \Rector\Contract\PhpParser\DecoratingNodeVisitorInterface instead.
*
* @internal
*
* @return Node[]|null
*/
public function beforeTraverse(array $nodes): ?array
{
// workaround for file around refactor()
$file = $this->currentFileProvider->getFile();
if (! $file instanceof File) {
throw new ShouldNotHappenException(
'File object is missing. Make sure you call $this->currentFileProvider->setFile(...) before traversing.'
);
}

$this->file = $file;

return null;
}

Expand All @@ -121,11 +121,12 @@ public function beforeTraverse(array $nodes): ?array
*/
final public function enterNode(Node $node): int|Node|null|array
{
if (is_a($this, HTMLAverseRectorInterface::class, true) && $this->file->containsHTML()) {
if (is_a($this, HTMLAverseRectorInterface::class, true) && $this->getFile()->containsHTML()) {
return null;
}

$filePath = $this->file->getFilePath();
$filePath = $this->getFile()
->getFilePath();
if ($this->skipper->shouldSkipCurrentNode($this, $filePath, static::class, $node)) {
return null;
}
Expand Down Expand Up @@ -158,7 +159,8 @@ final public function enterNode(Node $node): int|Node|null|array

// notify this rule changed code
$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getStartLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);
$this->getFile()
->addRectorClassWithLine($rectorWithLineChange);

return $refactoredNodeOrState;
}
Expand All @@ -174,6 +176,18 @@ final public function leaveNode(Node $node): array|int|Node|null
return null;
}

protected function getFile(): File
{
$file = $this->currentFileProvider->getFile();
if (! $file instanceof File) {
throw new ShouldNotHappenException(
'File object is missing. Make sure you call $this->currentFileProvider->setFile(...) before traversing.'
);
}

return $file;
}

protected function isName(Node $node, string $name): bool
{
return $this->nodeNameResolver->isName($node, $name);
Expand Down Expand Up @@ -248,7 +262,8 @@ private function postRefactorProcess(
$this->createdByRuleDecorator->decorate($refactoredNode, $originalNode, static::class);

$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getStartLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);
$this->getFile()
->addRectorClassWithLine($rectorWithLineChange);

/** @var MutatingScope|null $currentScope */
$currentScope = $node->getAttribute(AttributeKey::SCOPE);
Expand Down