From b8071fb7bc4e641a51ab559f2032518c1da4ec38 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 15 Apr 2021 19:34:49 +0200 Subject: [PATCH] Make use of inline parser over extreme node construction (#6145) Co-authored-by: kaizen-ci --- .../ParsedPropertyFetchNodeCollector.php | 3 +- .../Collector/NodesToAddCollector.php | 9 +- phpunit.xml | 2 +- .../config/configured_rule.php | 1 - .../config/configured_rule.php | 18 ++-- .../CodeQuality/NodeAnalyzer/ForAnalyzer.php | 5 +- .../SimplifyForeachToCoalescingRector.php | 3 +- .../Rector/FuncCall/SetTypeToCastRector.php | 3 +- .../NodeManipulator/LivingCodeManipulator.php | 7 +- .../Assign/RemoveDoubleAssignRector.php | 3 +- .../RemoveDeadZeroAndOneOperationRector.php | 4 +- .../FluentChainMethodCallNodeAnalyzer.php | 7 +- .../FluentChainMethodCallRootExtractor.php | 3 +- .../FuncCall/DowngradeStreamIsattyRector.php | 80 ++++------------ .../snippet/isatty_closure.php.inc | 9 ++ ...owngradeTrailingCommasInParamUseRector.php | 12 +-- rules/Naming/Naming/VariableNaming.php | 5 +- .../NetteFormToSymfonyFormRector.php | 4 - ...DefaultValueForUndefinedVariableRector.php | 12 ++- rules/Php70/NodeAnalyzer/VariableNaming.php | 7 +- .../Rector/FuncCall/RegexDashEscapeRector.php | 1 - .../NodeManipulator/IdentifierManipulator.php | 3 +- .../PseudoNamespaceToNamespaceRector.php | 5 +- .../Assign/GetAndSetToMethodCallRector.php | 92 ++++++++----------- .../ValueObject/GetAndSetToMethodCall.php | 50 ++++++++++ src/NodeAnalyzer/PropertyFetchAnalyzer.php | 16 +++- .../ClassMethodAssignManipulator.php | 3 +- .../ClassMethodPropertyFetchManipulator.php | 3 +- .../MagicPropertyFetchAnalyzer.php | 28 ++++-- src/NodeManipulator/NullsafeManipulator.php | 3 +- src/PhpParser/Parser/InlineCodeParser.php | 35 +++++-- 31 files changed, 230 insertions(+), 206 deletions(-) create mode 100644 rules/Downgrade72/snippet/isatty_closure.php.inc create mode 100644 rules/Transform/ValueObject/GetAndSetToMethodCall.php diff --git a/packages/NodeCollector/NodeCollector/ParsedPropertyFetchNodeCollector.php b/packages/NodeCollector/NodeCollector/ParsedPropertyFetchNodeCollector.php index 1cb74072cc0..2f84d1f2e3c 100644 --- a/packages/NodeCollector/NodeCollector/ParsedPropertyFetchNodeCollector.php +++ b/packages/NodeCollector/NodeCollector/ParsedPropertyFetchNodeCollector.php @@ -13,7 +13,6 @@ use PHPStan\Type\MixedType; use PHPStan\Type\Type; use PHPStan\Type\TypeWithClassName; use PHPStan\Type\UnionType; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\NodeTypeResolver; @@ -55,7 +54,7 @@ final class ParsedPropertyFetchNodeCollector } // make sure name is valid - if (StaticNodeInstanceOf::isOneOf($node->name, [StaticCall::class, MethodCall::class])) { + if ($node->name instanceof StaticCall || $node->name instanceof MethodCall) { return; } diff --git a/packages/PostRector/Collector/NodesToAddCollector.php b/packages/PostRector/Collector/NodesToAddCollector.php index a59a5e4794e..191860aa6ce 100644 --- a/packages/PostRector/Collector/NodesToAddCollector.php +++ b/packages/PostRector/Collector/NodesToAddCollector.php @@ -8,10 +8,10 @@ use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Expression; +use PhpParser\Node\Stmt\Return_; use Rector\ChangesReporting\Collector\RectorChangeCollector; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Node\BetterNodeFinder; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\PostRector\Contract\Collector\NodeCollectorInterface; @@ -128,10 +128,15 @@ final class NodesToAddCollector implements NodeCollectorInterface private function resolveNearestExpressionPosition(Node $node): string { - if (StaticNodeInstanceOf::isOneOf($node, [Expression::class, Stmt::class])) { + if ($node instanceof Expression || $node instanceof Stmt) { return spl_object_hash($node); } + $parent = $node->getAttribute(AttributeKey::PARENT_NODE); + if ($parent instanceof Return_) { + return spl_object_hash($parent); + } + $foundNode = $this->betterNodeFinder->findParentType($node, Expression::class); if (! $foundNode instanceof Expression) { $foundNode = $node; diff --git a/phpunit.xml b/phpunit.xml index 318a7751aad..a26915a50c4 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,7 +1,7 @@ diff --git a/rules-tests/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector/config/configured_rule.php b/rules-tests/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector/config/configured_rule.php index 942f4a369fc..0377982ea0d 100644 --- a/rules-tests/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector/config/configured_rule.php +++ b/rules-tests/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector/config/configured_rule.php @@ -7,6 +7,5 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura return static function (ContainerConfigurator $containerConfigurator): void { $services = $containerConfigurator->services(); - $services->set(NetteFormToSymfonyFormRector::class); }; diff --git a/rules-tests/Transform/Rector/Assign/GetAndSetToMethodCallRector/config/configured_rule.php b/rules-tests/Transform/Rector/Assign/GetAndSetToMethodCallRector/config/configured_rule.php index b11f7348083..a371bc2d532 100644 --- a/rules-tests/Transform/Rector/Assign/GetAndSetToMethodCallRector/config/configured_rule.php +++ b/rules-tests/Transform/Rector/Assign/GetAndSetToMethodCallRector/config/configured_rule.php @@ -1,22 +1,22 @@ services(); + $services->set(GetAndSetToMethodCallRector::class) ->call('configure', [[ - GetAndSetToMethodCallRector::TYPE_TO_METHOD_CALLS => [ - SomeContainer::class => [ - 'get' => 'getService', - 'set' => 'addService', - ], - Klarka::class => [ - 'get' => 'get', - ], - ], + GetAndSetToMethodCallRector::TYPE_TO_METHOD_CALLS => ValueObjectInliner::inline([ + new GetAndSetToMethodCall(SomeContainer::class, 'getService', 'addService'), + new GetAndSetToMethodCall(Klarka::class, 'get', 'set'), + ]), ]]); }; diff --git a/rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php b/rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php index fb5b8f92712..f989f642f6b 100644 --- a/rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php +++ b/rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php @@ -20,7 +20,6 @@ use PhpParser\Node\Stmt\Unset_; use Rector\Core\NodeManipulator\AssignManipulator; use Rector\Core\PhpParser\Comparing\NodeComparator; use Rector\Core\PhpParser\Node\BetterNodeFinder; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -103,9 +102,9 @@ final class ForAnalyzer return false; } - /** @var PreInc|PostInc $prePostInc */ $prePostInc = $loopExprs[0]; - if (StaticNodeInstanceOf::isOneOf($prePostInc, [PreInc::class, PostInc::class])) { + + if ($prePostInc instanceof PreInc || $prePostInc instanceof PostInc) { return $this->nodeNameResolver->isName($prePostInc->var, $keyValueName); } diff --git a/rules/CodeQuality/Rector/Foreach_/SimplifyForeachToCoalescingRector.php b/rules/CodeQuality/Rector/Foreach_/SimplifyForeachToCoalescingRector.php index 9c158010888..b68e2d919cc 100644 --- a/rules/CodeQuality/Rector/Foreach_/SimplifyForeachToCoalescingRector.php +++ b/rules/CodeQuality/Rector/Foreach_/SimplifyForeachToCoalescingRector.php @@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\Return_; use Rector\Core\NodeManipulator\ForeachManipulator; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\Core\ValueObject\PhpVersionFeature; use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -127,7 +126,7 @@ CODE_SAMPLE } $innerNode = $node->stmts[0] instanceof Expression ? $node->stmts[0]->expr : $node->stmts[0]; - if (StaticNodeInstanceOf::isOneOf($innerNode, [Assign::class, Return_::class])) { + if ($innerNode instanceof Assign || $innerNode instanceof Return_) { return $innerNode; } diff --git a/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php b/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php index 804ca55a944..de90f5582b8 100644 --- a/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php +++ b/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php @@ -18,7 +18,6 @@ use PhpParser\Node\Expr\Cast\String_; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Stmt\Expression; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -104,7 +103,7 @@ CODE_SAMPLE $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE); // result of function or probably used - if (StaticNodeInstanceOf::isOneOf($parentNode, [Expr::class, Arg::class])) { + if ($parentNode instanceof Expr || $parentNode instanceof Arg) { return null; } diff --git a/rules/DeadCode/NodeManipulator/LivingCodeManipulator.php b/rules/DeadCode/NodeManipulator/LivingCodeManipulator.php index 531293123aa..18ed27c986d 100644 --- a/rules/DeadCode/NodeManipulator/LivingCodeManipulator.php +++ b/rules/DeadCode/NodeManipulator/LivingCodeManipulator.php @@ -30,7 +30,6 @@ use PhpParser\Node\Expr\UnaryPlus; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Scalar; use PhpParser\Node\Stmt\Expression; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\PostRector\Collector\NodesToAddCollector; final class LivingCodeManipulator @@ -63,7 +62,7 @@ final class LivingCodeManipulator return []; } - if (StaticNodeInstanceOf::isOneOf($expr, [Closure::class, Scalar::class, ConstFetch::class])) { + if ($expr instanceof Closure || $expr instanceof Scalar || $expr instanceof ConstFetch) { return []; } @@ -88,8 +87,8 @@ final class LivingCodeManipulator $this->keepLivingCodeFromExpr($expr->dim) ); } - if (StaticNodeInstanceOf::isOneOf($expr, [ClassConstFetch::class, StaticPropertyFetch::class])) { - /** @var ClassConstFetch|StaticPropertyFetch $expr */ + + if ($expr instanceof ClassConstFetch || $expr instanceof StaticPropertyFetch) { return array_merge( $this->keepLivingCodeFromExpr($expr->class), $this->keepLivingCodeFromExpr($expr->name) diff --git a/rules/DeadCode/Rector/Assign/RemoveDoubleAssignRector.php b/rules/DeadCode/Rector/Assign/RemoveDoubleAssignRector.php index b2a1658a859..5f7d1555bdd 100644 --- a/rules/DeadCode/Rector/Assign/RemoveDoubleAssignRector.php +++ b/rules/DeadCode/Rector/Assign/RemoveDoubleAssignRector.php @@ -15,7 +15,6 @@ use PhpParser\Node\Expr\StaticPropertyFetch; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Stmt\Expression; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNestingScope\ScopeNestingComparator; use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -100,7 +99,7 @@ CODE_SAMPLE private function isCall(Expr $expr): bool { - return StaticNodeInstanceOf::isOneOf($expr, [FuncCall::class, StaticCall::class, MethodCall::class]); + return $expr instanceof FuncCall || $expr instanceof StaticCall || $expr instanceof MethodCall; } private function shouldSkipForDifferentScope(Assign $assign, Expression $expression): bool diff --git a/rules/DeadCode/Rector/Plus/RemoveDeadZeroAndOneOperationRector.php b/rules/DeadCode/Rector/Plus/RemoveDeadZeroAndOneOperationRector.php index 69c8cb6495a..ca1e3ea9716 100644 --- a/rules/DeadCode/Rector/Plus/RemoveDeadZeroAndOneOperationRector.php +++ b/rules/DeadCode/Rector/Plus/RemoveDeadZeroAndOneOperationRector.php @@ -18,7 +18,6 @@ use PhpParser\Node\Expr\BinaryOp\Mul; use PhpParser\Node\Expr\BinaryOp\Plus; use PhpParser\Node\Expr\UnaryMinus; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -139,8 +138,7 @@ CODE_SAMPLE private function processBinaryOp(Node $node): ?Expr { - if (StaticNodeInstanceOf::isOneOf($node, [Plus::class, Minus::class])) { - /** @var Plus|Minus $node */ + if ($node instanceof Plus || $node instanceof Minus) { return $this->processBinaryPlusAndMinus($node); } diff --git a/rules/Defluent/NodeAnalyzer/FluentChainMethodCallNodeAnalyzer.php b/rules/Defluent/NodeAnalyzer/FluentChainMethodCallNodeAnalyzer.php index b51ee9d5fba..6bdf0665a46 100644 --- a/rules/Defluent/NodeAnalyzer/FluentChainMethodCallNodeAnalyzer.php +++ b/rules/Defluent/NodeAnalyzer/FluentChainMethodCallNodeAnalyzer.php @@ -16,7 +16,6 @@ use PHPStan\Analyser\MutatingScope; use PHPStan\Type\MixedType; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\Defluent\Reflection\MethodCallToClassMethodParser; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -239,7 +238,11 @@ final class FluentChainMethodCallNodeAnalyzer private function isCall(Expr $expr): bool { - return StaticNodeInstanceOf::isOneOf($expr, [MethodCall::class, StaticCall::class]); + if ($expr instanceof MethodCall) { + return true; + } + + return $expr instanceof StaticCall; } private function isMethodCallCreatingNewInstance(MethodCall $methodCall): bool diff --git a/rules/Defluent/NodeAnalyzer/FluentChainMethodCallRootExtractor.php b/rules/Defluent/NodeAnalyzer/FluentChainMethodCallRootExtractor.php index be3474b75e5..9a49ae00895 100644 --- a/rules/Defluent/NodeAnalyzer/FluentChainMethodCallRootExtractor.php +++ b/rules/Defluent/NodeAnalyzer/FluentChainMethodCallRootExtractor.php @@ -13,7 +13,6 @@ use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Return_; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Node\BetterNodeFinder; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\Defluent\ValueObject\AssignAndRootExpr; use Rector\Defluent\ValueObject\FluentCallsKind; use Rector\Naming\Naming\PropertyNaming; @@ -86,7 +85,7 @@ final class FluentChainMethodCallRootExtractor } foreach ($methodCalls as $methodCall) { - if (StaticNodeInstanceOf::isOneOf($methodCall->var, [Variable::class, PropertyFetch::class])) { + if ($methodCall->var instanceof Variable || $methodCall->var instanceof PropertyFetch) { return $this->createAssignAndRootExprForVariableOrPropertyFetch($methodCall); } if ($methodCall->var instanceof New_) { diff --git a/rules/Downgrade72/Rector/FuncCall/DowngradeStreamIsattyRector.php b/rules/Downgrade72/Rector/FuncCall/DowngradeStreamIsattyRector.php index 6210ece584c..4fbd59e407e 100644 --- a/rules/Downgrade72/Rector/FuncCall/DowngradeStreamIsattyRector.php +++ b/rules/Downgrade72/Rector/FuncCall/DowngradeStreamIsattyRector.php @@ -5,26 +5,15 @@ declare(strict_types=1); namespace Rector\Downgrade72\Rector\FuncCall; use PhpParser\Node; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\Assign; -use PhpParser\Node\Expr\BinaryOp\BitwiseAnd; -use PhpParser\Node\Expr\BinaryOp\Identical; use PhpParser\Node\Expr\Closure; -use PhpParser\Node\Expr\ConstFetch; -use PhpParser\Node\Expr\ErrorSuppress; use PhpParser\Node\Expr\FuncCall; -use PhpParser\Node\Expr\Ternary; use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Param; -use PhpParser\Node\Scalar\LNumber; -use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Expression; -use PhpParser\Node\Stmt\If_; -use PhpParser\Node\Stmt\Return_; +use Rector\Core\Exception\ShouldNotHappenException; +use Rector\Core\PhpParser\Parser\InlineCodeParser; use Rector\Core\Rector\AbstractRector; -use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -36,9 +25,14 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; final class DowngradeStreamIsattyRector extends AbstractRector { /** - * @var string + * @var InlineCodeParser */ - private const STAT = 'stat'; + private $inlineCodeParser; + + public function __construct(InlineCodeParser $inlineCodeParser) + { + $this->inlineCodeParser = $inlineCodeParser; + } public function getRuleDefinition(): RuleDefinition { @@ -92,59 +86,25 @@ CODE_SAMPLE return null; } - $function = $this->createClosure($node); + $function = $this->createClosure(); $assign = new Assign(new Variable('streamIsatty'), $function); - $parent = $node->getAttribute(AttributeKey::PARENT_NODE); - if ($parent instanceof Return_) { - $this->addNodeBeforeNode($assign, $parent); - } else { - $this->addNodeBeforeNode($assign, $node); - } - + $this->addNodeBeforeNode($assign, $node); return new FuncCall(new Variable('streamIsatty'), $node->args); } - private function createIf(Expr $expr): If_ + private function createClosure(): Closure { - $constFetch = new ConstFetch(new FullyQualified('DIRECTORY_SEPARATOR')); - $identical = new Identical(new String_('\\'), $constFetch); + $stmts = $this->inlineCodeParser->parse(__DIR__ . '/../../snippet/isatty_closure.php.inc'); - $if = new If_($identical); - $statAssign = new Assign( - new Variable(self::STAT), - new ErrorSuppress($this->nodeFactory->createFuncCall('fstat', [$expr])) - ); - $if->stmts[] = new Expression($statAssign); + /** @var Expression $expression */ + $expression = $stmts[0]; - $arrayDimFetch = new ArrayDimFetch(new Variable(self::STAT), new String_('mode')); - $bitwiseAnd = new BitwiseAnd( - $arrayDimFetch, - new LNumber(0170000, [ - AttributeKey::KIND => LNumber::KIND_OCT, - ]) - ); + $expr = $expression->expr; + if (! $expr instanceof Closure) { + throw new ShouldNotHappenException(); + } - $identical = new Identical(new LNumber(020000, [ - AttributeKey::KIND => LNumber::KIND_OCT, - ]), $bitwiseAnd); - - $ternary = new Ternary(new Variable(self::STAT), $identical, $this->nodeFactory->createFalse()); - $if->stmts[] = new Return_($ternary); - - return $if; - } - - private function createClosure(FuncCall $funcCall): Closure - { - $if = $this->createIf($funcCall->args[0]->value); - - $function = new Closure(); - $function->params[] = new Param(new Variable('stream')); - $function->stmts[] = $if; - - $posixIsatty = $this->nodeFactory->createFuncCall('posix_isatty', [$funcCall->args[0]->value]); - $function->stmts[] = new Return_(new ErrorSuppress($posixIsatty)); - return $function; + return $expr; } } diff --git a/rules/Downgrade72/snippet/isatty_closure.php.inc b/rules/Downgrade72/snippet/isatty_closure.php.inc new file mode 100644 index 00000000000..bc8394d5527 --- /dev/null +++ b/rules/Downgrade72/snippet/isatty_closure.php.inc @@ -0,0 +1,9 @@ +processArgs($node); } diff --git a/rules/Naming/Naming/VariableNaming.php b/rules/Naming/Naming/VariableNaming.php index 48aa3facf14..2eb0b7adcee 100644 --- a/rules/Naming/Naming/VariableNaming.php +++ b/rules/Naming/Naming/VariableNaming.php @@ -22,7 +22,6 @@ use PHPStan\Type\ThisType; use PHPStan\Type\Type; use Rector\Core\Exception\NotImplementedYetException; use Rector\Core\PhpParser\Node\Value\ValueResolver; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\NodeTypeResolver; use Stringy\Stringy; @@ -89,9 +88,7 @@ final class VariableNaming return $this->resolveFromPropertyFetch($node); } - if ($node !== null && StaticNodeInstanceOf::isOneOf( - $node, - [MethodCall::class, NullsafeMethodCall::class, StaticCall::class])) { + if ($node !== null && ($node instanceof MethodCall || $node instanceof NullsafeMethodCall || $node instanceof StaticCall)) { return $this->resolveFromMethodCall($node); } diff --git a/rules/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector.php b/rules/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector.php index 43d758e857f..3e5a596b13c 100644 --- a/rules/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector.php +++ b/rules/NetteToSymfony/Rector/MethodCall/NetteFormToSymfonyFormRector.php @@ -65,7 +65,6 @@ class SomePresenter extends UI\Presenter { $form = new UI\Form; $form->addText('name', 'Name:'); - $form->addPassword('password', 'Password:'); $form->addSubmit('login', 'Sign up'); } } @@ -82,9 +81,6 @@ class SomePresenter extends UI\Presenter $form->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, [ 'label' => 'Name:' ]); - $form->add('password', \Symfony\Component\Form\Extension\Core\Type\PasswordType::class, [ - 'label' => 'Password:' - ]); $form->add('login', \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, [ 'label' => 'Sign up' ]); diff --git a/rules/Php56/Rector/FunctionLike/AddDefaultValueForUndefinedVariableRector.php b/rules/Php56/Rector/FunctionLike/AddDefaultValueForUndefinedVariableRector.php index a9dbc9a1807..ff28df93ba6 100644 --- a/rules/Php56/Rector/FunctionLike/AddDefaultValueForUndefinedVariableRector.php +++ b/rules/Php56/Rector/FunctionLike/AddDefaultValueForUndefinedVariableRector.php @@ -27,7 +27,6 @@ use PhpParser\Node\Stmt\Unset_; use PhpParser\NodeTraverser; use PHPStan\Analyser\Scope; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -213,7 +212,8 @@ CODE_SAMPLE )) { return true; } - if (StaticNodeInstanceOf::isOneOf($parentNode, [Unset_::class, UnsetCast::class])) { + + if ($parentNode instanceof Unset_ || $parentNode instanceof UnsetCast) { return true; } @@ -252,7 +252,11 @@ CODE_SAMPLE private function isListAssign(Node $node): bool { - $parentParentNode = $node->getAttribute(AttributeKey::PARENT_NODE); - return StaticNodeInstanceOf::isOneOf($parentParentNode, [List_::class, Array_::class]); + $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE); + if ($parentNode instanceof List_) { + return true; + } + + return $parentNode instanceof Array_; } } diff --git a/rules/Php70/NodeAnalyzer/VariableNaming.php b/rules/Php70/NodeAnalyzer/VariableNaming.php index 575035035f5..72f7d036aa6 100644 --- a/rules/Php70/NodeAnalyzer/VariableNaming.php +++ b/rules/Php70/NodeAnalyzer/VariableNaming.php @@ -25,7 +25,6 @@ use PHPStan\Type\ThisType; use PHPStan\Type\Type; use Rector\Core\Exception\NotImplementedYetException; use Rector\Core\PhpParser\Node\Value\ValueResolver; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\NodeTypeResolver; use Stringy\Stringy; @@ -181,11 +180,7 @@ final class VariableNaming return $this->resolveFromPropertyFetch($node); } - if ($node !== null && StaticNodeInstanceOf::isOneOf( - $node, - [MethodCall::class, NullsafeMethodCall::class, StaticCall::class])) { - - /** @var MethodCall|NullsafeMethodCall|StaticCall $node */ + if ($node instanceof MethodCall || $node instanceof NullsafeMethodCall || $node instanceof StaticCall) { return $this->resolveFromMethodCall($node); } diff --git a/rules/Php73/Rector/FuncCall/RegexDashEscapeRector.php b/rules/Php73/Rector/FuncCall/RegexDashEscapeRector.php index 39762c23c8d..7958845cf5d 100644 --- a/rules/Php73/Rector/FuncCall/RegexDashEscapeRector.php +++ b/rules/Php73/Rector/FuncCall/RegexDashEscapeRector.php @@ -21,7 +21,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; */ final class RegexDashEscapeRector extends AbstractRector { - /** * @var string * @see https://regex101.com/r/iQbGgZ/1 diff --git a/rules/Renaming/NodeManipulator/IdentifierManipulator.php b/rules/Renaming/NodeManipulator/IdentifierManipulator.php index 6fdbdcaffc1..db5b0b2a582 100644 --- a/rules/Renaming/NodeManipulator/IdentifierManipulator.php +++ b/rules/Renaming/NodeManipulator/IdentifierManipulator.php @@ -12,7 +12,6 @@ use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Identifier; use PhpParser\Node\Stmt\ClassMethod; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Webmozart\Assert\Assert; @@ -81,7 +80,7 @@ final class IdentifierManipulator */ private function resolveOldMethodName(Node $node): ?string { - if (StaticNodeInstanceOf::isOneOf($node, [StaticCall::class, MethodCall::class])) { + if ($node instanceof StaticCall || $node instanceof MethodCall) { return $this->nodeNameResolver->getName($node->name); } diff --git a/rules/Renaming/Rector/FileWithoutNamespace/PseudoNamespaceToNamespaceRector.php b/rules/Renaming/Rector/FileWithoutNamespace/PseudoNamespaceToNamespaceRector.php index 1d4ba806257..d449ca95f9f 100644 --- a/rules/Renaming/Rector/FileWithoutNamespace/PseudoNamespaceToNamespaceRector.php +++ b/rules/Renaming/Rector/FileWithoutNamespace/PseudoNamespaceToNamespaceRector.php @@ -17,7 +17,6 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\PhpDoc\PhpDocTypeRenamer; use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace; @@ -138,9 +137,7 @@ CODE_SAMPLE private function refactorStmts(array $stmts): array { $this->traverseNodesWithCallable($stmts, function (Node $node): ?Node { - if (! StaticNodeInstanceOf::isOneOf( - $node, - [Name::class, Identifier::class, Property::class, FunctionLike::class])) { + if (! $node instanceof Name && ! $node instanceof Identifier && ! $node instanceof Property && ! $node instanceof FunctionLike) { return null; } diff --git a/rules/Transform/Rector/Assign/GetAndSetToMethodCallRector.php b/rules/Transform/Rector/Assign/GetAndSetToMethodCallRector.php index b6c9d4cd895..00bf96c4cd8 100644 --- a/rules/Transform/Rector/Assign/GetAndSetToMethodCallRector.php +++ b/rules/Transform/Rector/Assign/GetAndSetToMethodCallRector.php @@ -9,17 +9,17 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; -use PhpParser\Node\Expr\StaticPropertyFetch; use PhpParser\Node\Expr\Variable; use PHPStan\Type\ObjectType; use Rector\Core\Contract\Rector\ConfigurableRectorInterface; use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer; use Rector\Core\NodeManipulator\MagicPropertyFetchAnalyzer; use Rector\Core\Rector\AbstractRector; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\Node\AttributeKey; +use Rector\Transform\ValueObject\GetAndSetToMethodCall; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; +use Webmozart\Assert\Assert; /** * @see \Rector\Tests\Transform\Rector\Assign\GetAndSetToMethodCallRector\GetAndSetToMethodCallRectorTest @@ -32,14 +32,9 @@ final class GetAndSetToMethodCallRector extends AbstractRector implements Config public const TYPE_TO_METHOD_CALLS = 'type_to_method_calls'; /** - * @var string + * @var GetAndSetToMethodCall[] */ - private const GET = 'get'; - - /** - * @var string[][] - */ - private $typeToMethodCalls = []; + private $getAndSetToMethodCalls = []; /** * @var PropertyFetchAnalyzer @@ -75,28 +70,7 @@ CODE_SAMPLE , [ self::TYPE_TO_METHOD_CALLS => [ - 'SomeContainer' => [ - 'set' => 'addService', - ], - ], - ] - ), - new ConfiguredCodeSample( - <<<'CODE_SAMPLE' -$container = new SomeContainer; -$someService = $container->someService; -CODE_SAMPLE - , - <<<'CODE_SAMPLE' -$container = new SomeContainer; -$someService = $container->getService("someService"); -CODE_SAMPLE - , - [ - self::TYPE_TO_METHOD_CALLS => [ - 'SomeContainer' => [ - self::GET => 'getService', - ], + new GetAndSetToMethodCall('SomeContainer', 'addService', 'getService'), ], ] ), @@ -117,35 +91,39 @@ CODE_SAMPLE public function refactor(Node $node): ?Node { if ($node instanceof Assign) { - if (StaticNodeInstanceOf::isOneOf($node->var, [PropertyFetch::class, StaticPropertyFetch::class])) { - return $this->processMagicSet($node); + if ($node->var instanceof PropertyFetch) { + return $this->processMagicSet($node->expr, $node->var); } + return null; } return $this->processPropertyFetch($node); } + /** + * @param array $configuration + */ public function configure(array $configuration): void { - $this->typeToMethodCalls = $configuration[self::TYPE_TO_METHOD_CALLS] ?? []; + $getAndSetToMethodCalls = $configuration[self::TYPE_TO_METHOD_CALLS] ?? []; + Assert::allIsAOf($getAndSetToMethodCalls, GetAndSetToMethodCall::class); + + $this->getAndSetToMethodCalls = $getAndSetToMethodCalls; } - private function processMagicSet(Assign $assign): ?Node + private function processMagicSet(Expr $expr, PropertyFetch $propertyFetch): ?Node { - /** @var PropertyFetch $propertyFetchNode */ - $propertyFetchNode = $assign->var; - - foreach ($this->typeToMethodCalls as $type => $transformation) { - $objectType = new ObjectType($type); - if ($this->shouldSkipPropertyFetch($propertyFetchNode, $objectType)) { + foreach ($this->getAndSetToMethodCalls as $getAndSetToMethodCall) { + $objectType = $getAndSetToMethodCall->getObjectType(); + if ($this->shouldSkipPropertyFetch($propertyFetch, $objectType)) { continue; } return $this->createMethodCallNodeFromAssignNode( - $propertyFetchNode, - $assign->expr, - $transformation['set'] + $propertyFetch, + $expr, + $getAndSetToMethodCall->getSetMethod() ); } @@ -154,21 +132,27 @@ CODE_SAMPLE private function processPropertyFetch(PropertyFetch $propertyFetch): ?MethodCall { - foreach ($this->typeToMethodCalls as $type => $transformation) { - $objectType = new ObjectType($type); - if ($this->shouldSkipPropertyFetch($propertyFetch, $objectType)) { + $parentNode = $propertyFetch->getAttribute(AttributeKey::PARENT_NODE); + + foreach ($this->getAndSetToMethodCalls as $getAndSetToMethodCall) { + if ($this->shouldSkipPropertyFetch($propertyFetch, $getAndSetToMethodCall->getObjectType())) { continue; } // setter, skip - $parentNode = $propertyFetch->getAttribute(AttributeKey::PARENT_NODE); if (! $parentNode instanceof Assign) { - return $this->createMethodCallNodeFromPropertyFetchNode($propertyFetch, $transformation[self::GET]); + return $this->createMethodCallNodeFromPropertyFetchNode( + $propertyFetch, + $getAndSetToMethodCall->getGetMethod() + ); } + if ($parentNode->var !== $propertyFetch) { - return $this->createMethodCallNodeFromPropertyFetchNode($propertyFetch, $transformation[self::GET]); + return $this->createMethodCallNodeFromPropertyFetchNode( + $propertyFetch, + $getAndSetToMethodCall->getGetMethod() + ); } - continue; } return null; @@ -192,10 +176,8 @@ CODE_SAMPLE Expr $expr, string $method ): MethodCall { - /** @var Variable $variableNode */ - $variableNode = $propertyFetch->var; - - return $this->nodeFactory->createMethodCall($variableNode, $method, [$this->getName($propertyFetch), $expr]); + $propertyName = $this->getName($propertyFetch->name); + return $this->nodeFactory->createMethodCall($propertyFetch->var, $method, [$propertyName, $expr]); } private function createMethodCallNodeFromPropertyFetchNode( diff --git a/rules/Transform/ValueObject/GetAndSetToMethodCall.php b/rules/Transform/ValueObject/GetAndSetToMethodCall.php new file mode 100644 index 00000000000..575c6090637 --- /dev/null +++ b/rules/Transform/ValueObject/GetAndSetToMethodCall.php @@ -0,0 +1,50 @@ +classType = $classType; + $this->getMethod = $getMethod; + $this->setMethod = $setMethod; + } + + public function getGetMethod(): string + { + return $this->getMethod; + } + + public function getSetMethod(): string + { + return $this->setMethod; + } + + public function getObjectType(): ObjectType + { + return new ObjectType($this->classType); + } +} diff --git a/src/NodeAnalyzer/PropertyFetchAnalyzer.php b/src/NodeAnalyzer/PropertyFetchAnalyzer.php index b6878fc3e45..f90b1155c56 100644 --- a/src/NodeAnalyzer/PropertyFetchAnalyzer.php +++ b/src/NodeAnalyzer/PropertyFetchAnalyzer.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Rector\Core\NodeAnalyzer; use PhpParser\Node; +use PhpParser\Node\Expr; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; @@ -72,19 +73,26 @@ final class PropertyFetchAnalyzer }); } - public function isPropertyToSelf(PropertyFetch $propertyFetch): bool + /** + * @param PropertyFetch|StaticPropertyFetch $expr + */ + public function isPropertyToSelf(Expr $expr): bool { - if (! $this->nodeNameResolver->isName($propertyFetch->var, 'this')) { + if ($expr instanceof PropertyFetch && ! $this->nodeNameResolver->isName($expr->var, 'this')) { return false; } - $classLike = $propertyFetch->getAttribute(AttributeKey::CLASS_NODE); + if ($expr instanceof StaticPropertyFetch && ! $this->nodeNameResolver->isName($expr->class, 'self')) { + return false; + } + + $classLike = $expr->getAttribute(AttributeKey::CLASS_NODE); if (! $classLike instanceof Class_) { return false; } foreach ($classLike->getProperties() as $property) { - if (! $this->nodeNameResolver->areNamesEqual($property->props[0], $propertyFetch)) { + if (! $this->nodeNameResolver->areNamesEqual($property->props[0], $expr)) { continue; } diff --git a/src/NodeManipulator/ClassMethodAssignManipulator.php b/src/NodeManipulator/ClassMethodAssignManipulator.php index 416124146f3..ce51746e3ac 100644 --- a/src/NodeManipulator/ClassMethodAssignManipulator.php +++ b/src/NodeManipulator/ClassMethodAssignManipulator.php @@ -27,7 +27,6 @@ use Rector\Core\PhpParser\Comparing\NodeComparator; use Rector\Core\PhpParser\Node\BetterNodeFinder; use Rector\Core\PhpParser\Node\NodeFactory; use Rector\Core\PHPStan\Reflection\CallReflectionResolver; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser; @@ -307,7 +306,7 @@ final class ClassMethodAssignManipulator return false; } - if (StaticNodeInstanceOf::isOneOf($node, [Arg::class, ClosureUse::class, Param::class])) { + if ($node instanceof Arg || $node instanceof ClosureUse || $node instanceof Param) { return $node->byRef; } diff --git a/src/NodeManipulator/ClassMethodPropertyFetchManipulator.php b/src/NodeManipulator/ClassMethodPropertyFetchManipulator.php index 7420e9dccec..ec181d3b22b 100644 --- a/src/NodeManipulator/ClassMethodPropertyFetchManipulator.php +++ b/src/NodeManipulator/ClassMethodPropertyFetchManipulator.php @@ -11,7 +11,6 @@ use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Param; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\NodeTraverser; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeNameResolver\NodeNameResolver; use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser; @@ -59,7 +58,7 @@ final class ClassMethodPropertyFetchManipulator return null; } - if (StaticNodeInstanceOf::isOneOf($node->expr, [MethodCall::class, StaticCall::class])) { + if ($node->expr instanceof MethodCall || $node->expr instanceof StaticCall) { return null; } diff --git a/src/NodeManipulator/MagicPropertyFetchAnalyzer.php b/src/NodeManipulator/MagicPropertyFetchAnalyzer.php index fe9e31b23bd..48cd6a877e6 100644 --- a/src/NodeManipulator/MagicPropertyFetchAnalyzer.php +++ b/src/NodeManipulator/MagicPropertyFetchAnalyzer.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace Rector\Core\NodeManipulator; use PhpParser\Node; +use PhpParser\Node\Expr; use PhpParser\Node\Expr\PropertyFetch; +use PhpParser\Node\Expr\StaticPropertyFetch; use PHPStan\Analyser\Scope; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Type\ErrorType; @@ -48,9 +50,12 @@ final class MagicPropertyFetchAnalyzer $this->reflectionProvider = $reflectionProvider; } - public function isMagicOnType(PropertyFetch $propertyFetch, Type $type): bool + /** + * @param PropertyFetch|Node\Expr\StaticPropertyFetch $expr + */ + public function isMagicOnType(Expr $expr, Type $type): bool { - $varNodeType = $this->nodeTypeResolver->resolve($propertyFetch); + $varNodeType = $this->nodeTypeResolver->resolve($expr); if ($varNodeType instanceof ErrorType) { return true; @@ -64,22 +69,30 @@ final class MagicPropertyFetchAnalyzer return false; } - $nodeName = $this->nodeNameResolver->getName($propertyFetch); + $nodeName = $this->nodeNameResolver->getName($expr->name); if ($nodeName === null) { return false; } - return ! $this->hasPublicProperty($propertyFetch, $nodeName); + return ! $this->hasPublicProperty($expr, $nodeName); } - private function hasPublicProperty(PropertyFetch $propertyFetch, string $propertyName): bool + /** + * @param PropertyFetch|StaticPropertyFetch $expr + */ + private function hasPublicProperty(Expr $expr, string $propertyName): bool { - $scope = $propertyFetch->getAttribute(AttributeKey::SCOPE); + $scope = $expr->getAttribute(AttributeKey::SCOPE); if (! $scope instanceof Scope) { throw new ShouldNotHappenException(); } - $propertyFetchType = $scope->getType($propertyFetch->var); + if ($expr instanceof PropertyFetch) { + $propertyFetchType = $scope->getType($expr->var); + } else { + $propertyFetchType = $this->nodeTypeResolver->resolve($expr->class); + } + if (! $propertyFetchType instanceof TypeWithClassName) { return false; } @@ -95,7 +108,6 @@ final class MagicPropertyFetchAnalyzer } $propertyReflection = $classReflection->getProperty($propertyName, $scope); - return $propertyReflection->isPublic(); } } diff --git a/src/NodeManipulator/NullsafeManipulator.php b/src/NodeManipulator/NullsafeManipulator.php index b1b464dd44b..c195ab93667 100644 --- a/src/NodeManipulator/NullsafeManipulator.php +++ b/src/NodeManipulator/NullsafeManipulator.php @@ -10,7 +10,6 @@ use PhpParser\Node\Expr\NullsafeMethodCall; use PhpParser\Node\Expr\NullsafePropertyFetch; use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Identifier; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\Node\AttributeKey; final class NullsafeManipulator @@ -36,7 +35,7 @@ final class NullsafeManipulator $parentIdentifier = $nextExprIdentifier->getAttribute(AttributeKey::PARENT_NODE); - if (StaticNodeInstanceOf::isOneOf($parentIdentifier, [MethodCall::class, NullsafeMethodCall::class])) { + if ($parentIdentifier instanceof MethodCall || $parentIdentifier instanceof NullsafeMethodCall) { return new NullsafeMethodCall($expr, $nextExprIdentifier); } diff --git a/src/PhpParser/Parser/InlineCodeParser.php b/src/PhpParser/Parser/InlineCodeParser.php index 78b06d877a1..fd05adcd544 100644 --- a/src/PhpParser/Parser/InlineCodeParser.php +++ b/src/PhpParser/Parser/InlineCodeParser.php @@ -16,8 +16,8 @@ use PhpParser\Node\Stmt; use PhpParser\Parser; use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Printer\BetterStandardPrinter; -use Rector\Core\Util\StaticNodeInstanceOf; use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator; +use Symplify\SmartFileSystem\SmartFileSystem; final class InlineCodeParser { @@ -33,6 +33,18 @@ final class InlineCodeParser */ private const CURLY_BRACKET_WRAPPER_REGEX = "#'{(\\\$.*?)}'#"; + /** + * @var string + * @see https://regex101.com/r/TBlhoR/1 + */ + private const OPEN_PHP_TAG_REGEX = '#^\<\?php\s+#'; + + /** + * @var string + * @see https://regex101.com/r/TUWwKw/1/ + */ + private const ENDING_SEMI_COLON_REGEX = '#;(\s+)?$#'; + /** * @var Parser */ @@ -48,14 +60,21 @@ final class InlineCodeParser */ private $betterStandardPrinter; + /** + * @var SmartFileSystem + */ + private $smartFileSystem; + public function __construct( BetterStandardPrinter $betterStandardPrinter, NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator, - Parser $parser + Parser $parser, + SmartFileSystem $smartFileSystem ) { $this->parser = $parser; $this->betterStandardPrinter = $betterStandardPrinter; $this->nodeScopeAndMetadataDecorator = $nodeScopeAndMetadataDecorator; + $this->smartFileSystem = $smartFileSystem; } /** @@ -63,12 +82,16 @@ final class InlineCodeParser */ public function parse(string $content): array { + // to cover files too + if (is_file($content)) { + $content = $this->smartFileSystem->readFile($content); + } + // wrap code so php-parser can interpret it - $content = Strings::startsWith($content, 'parser->parse($content); - return $this->nodeScopeAndMetadataDecorator->decorateNodesFromString($nodes); } @@ -91,7 +114,7 @@ final class InlineCodeParser return $this->stringify($expr->left) . $this->stringify($expr->right); } - if (StaticNodeInstanceOf::isOneOf($expr, [Variable::class, PropertyFetch::class, StaticPropertyFetch::class])) { + if ($expr instanceof Variable || $expr instanceof PropertyFetch || $expr instanceof StaticPropertyFetch) { return $this->betterStandardPrinter->print($expr); }