diff --git a/rules/CodeQuality/Rector/Empty_/SimplifyEmptyCheckOnEmptyArrayRector.php b/rules/CodeQuality/Rector/Empty_/SimplifyEmptyCheckOnEmptyArrayRector.php index efb58b3dfd7..693523e6359 100644 --- a/rules/CodeQuality/Rector/Empty_/SimplifyEmptyCheckOnEmptyArrayRector.php +++ b/rules/CodeQuality/Rector/Empty_/SimplifyEmptyCheckOnEmptyArrayRector.php @@ -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; } diff --git a/rules/CodeQuality/Rector/If_/CompleteMissingIfElseBracketRector.php b/rules/CodeQuality/Rector/If_/CompleteMissingIfElseBracketRector.php index 1b950cc5ebb..98be3b72816 100644 --- a/rules/CodeQuality/Rector/If_/CompleteMissingIfElseBracketRector.php +++ b/rules/CodeQuality/Rector/If_/CompleteMissingIfElseBracketRector.php @@ -69,6 +69,7 @@ public function refactor(Node $node): ?Node } $oldTokens = $this->file->getOldTokens(); + if ($this->isIfConditionFollowedByOpeningCurlyBracket($node, $oldTokens)) { return null; } diff --git a/rules/CodeQuality/Rector/NotEqual/CommonNotEqualRector.php b/rules/CodeQuality/Rector/NotEqual/CommonNotEqualRector.php index f443f49b641..cea0b7c876d 100644 --- a/rules/CodeQuality/Rector/NotEqual/CommonNotEqualRector.php +++ b/rules/CodeQuality/Rector/NotEqual/CommonNotEqualRector.php @@ -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 = '!='; diff --git a/rules/CodingStyle/Rector/Encapsed/WrapEncapsedVariableInCurlyBracesRector.php b/rules/CodingStyle/Rector/Encapsed/WrapEncapsedVariableInCurlyBracesRector.php index 160abb10e17..3d039823d08 100644 --- a/rules/CodingStyle/Rector/Encapsed/WrapEncapsedVariableInCurlyBracesRector.php +++ b/rules/CodingStyle/Rector/Encapsed/WrapEncapsedVariableInCurlyBracesRector.php @@ -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) { diff --git a/rules/DeadCode/Rector/Concat/RemoveConcatAutocastRector.php b/rules/DeadCode/Rector/Concat/RemoveConcatAutocastRector.php index 2ab1a6b09f7..6205fe4c468 100644 --- a/rules/DeadCode/Rector/Concat/RemoveConcatAutocastRector.php +++ b/rules/DeadCode/Rector/Concat/RemoveConcatAutocastRector.php @@ -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(); diff --git a/rules/Php53/Rector/Ternary/TernaryToElvisRector.php b/rules/Php53/Rector/Ternary/TernaryToElvisRector.php index 15e04e21f06..83b5ead1a5b 100644 --- a/rules/Php53/Rector/Ternary/TernaryToElvisRector.php +++ b/rules/Php53/Rector/Ternary/TernaryToElvisRector.php @@ -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(); diff --git a/rules/Php54/Rector/Array_/LongArrayToShortArrayRector.php b/rules/Php54/Rector/Array_/LongArrayToShortArrayRector.php index 59a5d8b3c9c..a0409e3af0a 100644 --- a/rules/Php54/Rector/Array_/LongArrayToShortArrayRector.php +++ b/rules/Php54/Rector/Array_/LongArrayToShortArrayRector.php @@ -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(); diff --git a/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php b/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php index 9e3bed6a019..a83d0a2c69e 100644 --- a/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php +++ b/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php @@ -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; } diff --git a/rules/Php74/Rector/Ternary/ParenthesizeNestedTernaryRector.php b/rules/Php74/Rector/Ternary/ParenthesizeNestedTernaryRector.php index 2752fad0cfc..f84e0e31f24 100644 --- a/rules/Php74/Rector/Ternary/ParenthesizeNestedTernaryRector.php +++ b/rules/Php74/Rector/Ternary/ParenthesizeNestedTernaryRector.php @@ -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; } diff --git a/rules/Php82/Rector/Encapsed/VariableInStringInterpolationFixerRector.php b/rules/Php82/Rector/Encapsed/VariableInStringInterpolationFixerRector.php index 354a989f4fe..3adf2a8cf47 100644 --- a/rules/Php82/Rector/Encapsed/VariableInStringInterpolationFixerRector.php +++ b/rules/Php82/Rector/Encapsed/VariableInStringInterpolationFixerRector.php @@ -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) { diff --git a/rules/Php84/Rector/MethodCall/NewMethodCallWithoutParenthesesRector.php b/rules/Php84/Rector/MethodCall/NewMethodCallWithoutParenthesesRector.php index bcc1d2ce61e..b559a7b1539 100644 --- a/rules/Php84/Rector/MethodCall/NewMethodCallWithoutParenthesesRector.php +++ b/rules/Php84/Rector/MethodCall/NewMethodCallWithoutParenthesesRector.php @@ -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])) { diff --git a/rules/Php85/Rector/ArrayDimFetch/ArrayFirstLastRector.php b/rules/Php85/Rector/ArrayDimFetch/ArrayFirstLastRector.php index 9f461243539..57f655e5bd2 100644 --- a/rules/Php85/Rector/ArrayDimFetch/ArrayFirstLastRector.php +++ b/rules/Php85/Rector/ArrayDimFetch/ArrayFirstLastRector.php @@ -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; } @@ -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); } } diff --git a/rules/Php85/Rector/Switch_/ColonAfterSwitchCaseRector.php b/rules/Php85/Rector/Switch_/ColonAfterSwitchCaseRector.php index 910f961640e..da74a4273ef 100644 --- a/rules/Php85/Rector/Switch_/ColonAfterSwitchCaseRector.php +++ b/rules/Php85/Rector/Switch_/ColonAfterSwitchCaseRector.php @@ -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; diff --git a/rules/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector.php b/rules/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector.php index bbfe3fbf536..076f5a00b35 100644 --- a/rules/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector.php +++ b/rules/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector.php @@ -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; diff --git a/rules/TypeDeclaration/Rector/StmtsAwareInterface/DeclareStrictTypesRector.php b/rules/TypeDeclaration/Rector/StmtsAwareInterface/DeclareStrictTypesRector.php index 7cb04dfe14e..db8e89ffd3a 100644 --- a/rules/TypeDeclaration/Rector/StmtsAwareInterface/DeclareStrictTypesRector.php +++ b/rules/TypeDeclaration/Rector/StmtsAwareInterface/DeclareStrictTypesRector.php @@ -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; } diff --git a/src/PostRector/Rector/AbstractPostRector.php b/src/PostRector/Rector/AbstractPostRector.php index 341100666b9..18736f9fbb3 100644 --- a/src/PostRector/Rector/AbstractPostRector.php +++ b/src/PostRector/Rector/AbstractPostRector.php @@ -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); } } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index e7d0db63273..472f131cbd3 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -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 = <<getFile(); + } + + // fallback to default behavior + return $this->{$name}; + } + public function autowire( NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver, @@ -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; } @@ -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; } @@ -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; } @@ -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); @@ -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);