Updated Rector to commit 645071a650fc50d7e084378facaebcc868a52ba1

645071a650 Add test fixture for sprintf number + make use of getArgs() to get always an Arg type (#3822)
This commit is contained in:
Tomas Votruba 2023-05-13 17:20:02 +00:00
parent 900facbf32
commit da149bb5b0
28 changed files with 157 additions and 438 deletions

View File

@ -8,7 +8,7 @@
],
"require": {
"php": "^7.2|^8.0",
"phpstan/phpstan": "^1.10.14"
"phpstan/phpstan": "^1.10.15"
},
"autoload": {
"files": [

View File

@ -11,7 +11,6 @@ use PhpParser\Node\Expr\Variable;
use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
@ -39,18 +38,12 @@ final class PregMatchTypeCorrector
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(BetterNodeFinder $betterNodeFinder, NodeNameResolver $nodeNameResolver, ParentScopeFinder $parentScopeFinder, NodeComparator $nodeComparator, ArgsAnalyzer $argsAnalyzer)
public function __construct(BetterNodeFinder $betterNodeFinder, NodeNameResolver $nodeNameResolver, ParentScopeFinder $parentScopeFinder, NodeComparator $nodeComparator)
{
$this->betterNodeFinder = $betterNodeFinder;
$this->nodeNameResolver = $nodeNameResolver;
$this->parentScopeFinder = $parentScopeFinder;
$this->nodeComparator = $nodeComparator;
$this->argsAnalyzer = $argsAnalyzer;
}
/**
* Special case for "preg_match(), preg_match_all()" - with 3rd argument
@ -74,14 +67,13 @@ final class PregMatchTypeCorrector
if (!$funcCallNode instanceof FuncCall) {
continue;
}
$thirdArg = $funcCallNode->getArgs()[2] ?? null;
if (!$thirdArg instanceof Arg) {
continue;
}
if (!$this->nodeNameResolver->isNames($funcCallNode, ['preg_match', 'preg_match_all'])) {
continue;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($funcCallNode->args, 2)) {
continue;
}
/** @var Arg $thirdArg */
$thirdArg = $funcCallNode->args[2];
// are the same variables
if (!$this->nodeComparator->areNodesEqual($thirdArg->value, $expr)) {
continue;

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
@ -61,7 +60,6 @@ CODE_SAMPLE
if ($args === []) {
return null;
}
/** @var Arg $firstArg */
$firstArg = \array_shift($args);
if ($args === []) {
return null;

View File

@ -4,10 +4,8 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -16,15 +14,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class RemoveSoleValueSprintfRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Remove sprintf() wrapper if not needed', [new CodeSample(<<<'CODE_SAMPLE'
@ -32,8 +21,6 @@ class SomeClass
{
public function run()
{
$value = sprintf('%s', 'hi');
$welcome = 'hello';
$value = sprintf('%s', $welcome);
}
@ -44,8 +31,6 @@ class SomeClass
{
public function run()
{
$value = 'hi';
$welcome = 'hello';
$value = $welcome;
}
@ -68,14 +53,10 @@ CODE_SAMPLE
if (!$this->isName($node, 'sprintf')) {
return null;
}
if (\count($node->args) !== 2) {
if (\count($node->getArgs()) !== 2) {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($node->args, [0, 1])) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$firstArg = $node->getArgs()[0];
$maskArgument = $firstArg->value;
if (!$maskArgument instanceof String_) {
return null;
@ -83,8 +64,7 @@ CODE_SAMPLE
if ($maskArgument->value !== '%s') {
return null;
}
/** @var Arg $secondArg */
$secondArg = $node->args[1];
$secondArg = $node->getArgs()[1];
$valueArgument = $secondArg->value;
$valueType = $this->getType($valueArgument);
if (!$valueType->isString()->yes()) {

View File

@ -16,7 +16,6 @@ use PhpParser\Node\Expr\Cast\Object_;
use PhpParser\Node\Expr\Cast\String_;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -32,15 +31,6 @@ final class SetTypeToCastRector extends AbstractRector
* @var array<string, class-string<Cast>>
*/
private const TYPE_TO_CAST = ['array' => Array_::class, 'bool' => Bool_::class, 'boolean' => Bool_::class, 'double' => Double::class, 'float' => Double::class, 'int' => Int_::class, 'integer' => Int_::class, 'object' => Object_::class, 'string' => String_::class];
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Changes settype() to (type) where possible', [new CodeSample(<<<'CODE_SAMPLE'
@ -82,38 +72,31 @@ CODE_SAMPLE
if (!$this->isName($node, 'settype')) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 1)) {
if ($node->isFirstClassCallable()) {
return null;
}
/** @var Arg $secondArg */
$secondArg = $node->args[1];
$typeNode = $this->valueResolver->getValue($secondArg->value);
if (!\is_string($typeNode)) {
$typeValue = $this->valueResolver->getValue($node->getArgs()[1]->value);
if (!\is_string($typeValue)) {
return null;
}
$typeNode = \strtolower($typeNode);
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$varNode = $firstArg->value;
$typeValue = \strtolower($typeValue);
$variable = $node->getArgs()[0]->value;
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
// result of function or probably used
if ($parentNode instanceof Expr || $parentNode instanceof Arg) {
return null;
}
if (isset(self::TYPE_TO_CAST[$typeNode])) {
$castClass = self::TYPE_TO_CAST[$typeNode];
$castNode = new $castClass($varNode);
if (isset(self::TYPE_TO_CAST[$typeValue])) {
$castClass = self::TYPE_TO_CAST[$typeValue];
$castNode = new $castClass($variable);
if ($parentNode instanceof Expression) {
// bare expression? → assign
return new Assign($varNode, $castNode);
return new Assign($variable, $castNode);
}
return $castNode;
}
if ($typeNode === 'null') {
return new Assign($varNode, $this->nodeFactory->createNull());
if ($typeValue === 'null') {
return new Assign($variable, $this->nodeFactory->createNull());
}
return $node;
}

View File

@ -4,9 +4,7 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -16,15 +14,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class UnwrapSprintfOneArgumentRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('unwrap sprintf() with one argument', [new CodeSample(<<<'CODE_SAMPLE'
@ -47,17 +36,16 @@ CODE_SAMPLE
*/
public function refactor(Node $node) : ?Node
{
if ($node->isFirstClassCallable()) {
return null;
}
if (!$this->isName($node, 'sprintf')) {
return null;
}
if (\count($node->args) > 1) {
if (\count($node->getArgs()) > 1) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$firstArg = $node->getArgs()[0];
if ($firstArg->unpack) {
return null;
}

View File

@ -4,12 +4,10 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\Identical;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -18,15 +16,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class StrlenZeroToIdenticalEmptyStringRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Changes strlen comparison to 0 to direct empty string compare', [new CodeSample(<<<'CODE_SAMPLE'
@ -74,16 +63,13 @@ CODE_SAMPLE
if (!$this->isName($funcCall, 'strlen')) {
return null;
}
if ($funcCall->isFirstClassCallable()) {
return null;
}
if (!$this->valueResolver->isValue($expr, 0)) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($funcCall->args, 0)) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $funcCall->args[0];
/** @var Expr $variable */
$variable = $firstArg->value;
$variable = $funcCall->getArgs()[0]->value;
// Needs string cast if variable type is not string
// see https://github.com/rectorphp/rector/issues/6700
$isStringType = $this->nodeTypeResolver->getNativeType($variable)->isString()->yes();

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\CodingStyle\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\BinaryOp;
@ -17,7 +16,6 @@ use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\PropertyProperty;
use PHPStan\Type\Type;
use Rector\CodingStyle\TypeAnalyzer\IterableTypeAnalyzer;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -40,21 +38,15 @@ final class AddArrayDefaultToArrayPropertyRector extends AbstractRector
* @var \Rector\CodingStyle\TypeAnalyzer\IterableTypeAnalyzer
*/
private $iterableTypeAnalyzer;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
/**
* @readonly
* @var \Rector\Privatization\NodeManipulator\VisibilityManipulator
*/
private $visibilityManipulator;
public function __construct(PropertyFetchAnalyzer $propertyFetchAnalyzer, IterableTypeAnalyzer $iterableTypeAnalyzer, ArgsAnalyzer $argsAnalyzer, VisibilityManipulator $visibilityManipulator)
public function __construct(PropertyFetchAnalyzer $propertyFetchAnalyzer, IterableTypeAnalyzer $iterableTypeAnalyzer, VisibilityManipulator $visibilityManipulator)
{
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
$this->iterableTypeAnalyzer = $iterableTypeAnalyzer;
$this->argsAnalyzer = $argsAnalyzer;
$this->visibilityManipulator = $visibilityManipulator;
}
public function getRuleDefinition() : RuleDefinition
@ -179,12 +171,7 @@ CODE_SAMPLE
if (!$this->isName($node, 'count')) {
return \false;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
return \false;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$countedArgument = $firstArg->value;
$countedArgument = $node->getArgs()[0]->value;
if (!$countedArgument instanceof PropertyFetch) {
return \false;
}

View File

@ -11,7 +11,6 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use Rector\CodingStyle\NodeFactory\ArrayCallableToMethodCallFactory;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
@ -30,15 +29,9 @@ final class CallUserFuncArrayToVariadicRector extends AbstractRector implements
* @var \Rector\CodingStyle\NodeFactory\ArrayCallableToMethodCallFactory
*/
private $arrayCallableToMethodCallFactory;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArrayCallableToMethodCallFactory $arrayCallableToMethodCallFactory, ArgsAnalyzer $argsAnalyzer)
public function __construct(ArrayCallableToMethodCallFactory $arrayCallableToMethodCallFactory)
{
$this->arrayCallableToMethodCallFactory = $arrayCallableToMethodCallFactory;
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
@ -77,15 +70,11 @@ CODE_SAMPLE
if (!$this->isName($node, 'call_user_func_array')) {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($node->args, [0, 1])) {
if ($node->isFirstClassCallable()) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->getArgs()[0];
$firstArgValue = $firstArg->value;
/** @var Arg $secondArg */
$secondArg = $node->getArgs()[1];
$secondArgValue = $secondArg->value;
$firstArgValue = $node->getArgs()[0]->value;
$secondArgValue = $node->getArgs()[1]->value;
if ($firstArgValue instanceof String_) {
$functionName = $this->valueResolver->getValue($firstArgValue);
return $this->createFuncCall($secondArgValue, $functionName);
@ -102,8 +91,7 @@ CODE_SAMPLE
}
private function createFuncCall(Expr $expr, string $functionName) : FuncCall
{
$args = [];
$args[] = $this->createUnpackedArg($expr);
$args = [$this->createUnpackedArg($expr)];
return $this->nodeFactory->createFuncCall($functionName, $args);
}
private function createMethodCall(Array_ $array, Expr $secondExpr) : ?MethodCall

View File

@ -7,7 +7,6 @@ use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -24,15 +23,9 @@ final class ConsistentImplodeRector extends AbstractRector
* @var \Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(StringTypeAnalyzer $stringTypeAnalyzer, ArgsAnalyzer $argsAnalyzer)
public function __construct(StringTypeAnalyzer $stringTypeAnalyzer)
{
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
@ -43,8 +36,6 @@ class SomeClass
{
$itemsAsStrings = implode($items);
$itemsAsStrings = implode($items, '|');
$itemsAsStrings = implode('|', $items);
}
}
CODE_SAMPLE
@ -55,8 +46,6 @@ class SomeClass
{
$itemsAsStrings = implode('', $items);
$itemsAsStrings = implode('|', $items);
$itemsAsStrings = implode('|', $items);
}
}
CODE_SAMPLE
@ -77,32 +66,24 @@ CODE_SAMPLE
if (!$this->isName($node, 'implode')) {
return null;
}
if (\count($node->args) === 1) {
if (\count($node->getArgs()) === 1) {
// complete default value ''
$node->args[1] = $node->args[0];
$node->args[1] = $node->getArgs()[0];
$node->args[0] = new Arg(new String_(''));
return $node;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
return null;
}
/** @var Arg $arg0 */
$arg0 = $node->args[0];
$firstArgumentValue = $arg0->value;
$firstArg = $node->getArgs()[0];
$firstArgumentValue = $firstArg->value;
$firstArgumentType = $this->getType($firstArgumentValue);
if ($firstArgumentType->isString()->yes()) {
return null;
}
if (\count($node->args) !== 2) {
if (\count($node->getArgs()) !== 2) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 1)) {
return null;
}
/** @var Arg $arg1 */
$arg1 = $node->args[1];
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($arg1->value)) {
$node->args = \array_reverse($node->args);
$secondArg = $node->getArgs()[1];
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($secondArg->value)) {
$node->args = \array_reverse($node->getArgs());
return $node;
}
return null;

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\CodingStyle\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp\Greater;
@ -18,7 +17,6 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Util\PhpVersionFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -37,15 +35,9 @@ final class VersionCompareFuncCallToConstantRector extends AbstractRector
* @var \Rector\Core\Util\PhpVersionFactory
*/
private $phpVersionFactory;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(PhpVersionFactory $phpVersionFactory, ArgsAnalyzer $argsAnalyzer)
public function __construct(PhpVersionFactory $phpVersionFactory)
{
$this->phpVersionFactory = $phpVersionFactory;
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
@ -84,23 +76,22 @@ CODE_SAMPLE
if (!$this->isName($node, 'version_compare')) {
return null;
}
if (\count($node->args) !== 3) {
if ($node->isFirstClassCallable()) {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($node->args, [0, 1, 2])) {
if (\count($node->getArgs()) !== 3) {
return null;
}
/** @var Arg[] $args */
$args = $node->args;
$args = $node->getArgs();
if (!$this->isPhpVersionConstant($args[0]->value) && !$this->isPhpVersionConstant($args[1]->value)) {
return null;
}
$left = $this->getNewNodeForArg($args[0]->value);
$right = $this->getNewNodeForArg($args[1]->value);
if ($left === null) {
if (!$left instanceof Expr) {
return null;
}
if ($right === null) {
if (!$right instanceof Expr) {
return null;
}
/** @var String_ $operator */

View File

@ -8,7 +8,6 @@ use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Php55\RegexMatcher;
@ -33,16 +32,10 @@ final class PregReplaceEModifierRector extends AbstractRector implements MinPhpV
* @var \Rector\Php55\RegexMatcher
*/
private $regexMatcher;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(AnonymousFunctionFactory $anonymousFunctionFactory, RegexMatcher $regexMatcher, ArgsAnalyzer $argsAnalyzer)
public function __construct(AnonymousFunctionFactory $anonymousFunctionFactory, RegexMatcher $regexMatcher)
{
$this->anonymousFunctionFactory = $anonymousFunctionFactory;
$this->regexMatcher = $regexMatcher;
$this->argsAnalyzer = $argsAnalyzer;
}
public function provideMinPhpVersion() : int
{
@ -87,11 +80,13 @@ CODE_SAMPLE
if (!$this->isName($node, 'preg_replace')) {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($node->args, [0, 1])) {
if ($node->isFirstClassCallable()) {
return null;
}
/** @var Arg $firstArgument */
$firstArgument = $node->args[0];
if (\count($node->getArgs()) < 2) {
return null;
}
$firstArgument = $node->getArgs()[0];
$firstArgumentValue = $firstArgument->value;
$patternWithoutEExpr = $this->regexMatcher->resolvePatternExpressionWithoutEIfFound($firstArgumentValue);
if ($patternWithoutEExpr === null) {

View File

@ -4,10 +4,8 @@ declare (strict_types=1);
namespace Rector\Php56\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp\Pow;
use PhpParser\Node\Expr\FuncCall;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
@ -18,15 +16,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class PowToExpRector extends AbstractRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Changes pow(val, val2) to ** (exp) parameter', [new CodeSample('pow(1, 2);', '1**2;')]);
@ -46,17 +35,12 @@ final class PowToExpRector extends AbstractRector implements MinPhpVersionInterf
if (!$this->isName($node, 'pow')) {
return null;
}
if (\count($node->args) !== 2) {
if ($node->isFirstClassCallable()) {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($node->args, [0, 1])) {
return null;
}
/** @var Arg $firstArgument */
$firstArgument = $node->args[0];
/** @var Arg $secondArgument */
$secondArgument = $node->args[1];
return new Pow($firstArgument->value, $secondArgument->value);
$firstExpr = $node->getArgs()[0]->value;
$secondExpr = $node->getArgs()[1]->value;
return new Pow($firstExpr, $secondExpr);
}
public function provideMinPhpVersion() : int
{

View File

@ -14,7 +14,6 @@ use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -38,15 +37,9 @@ final class EregToPregMatchRector extends AbstractRector implements MinPhpVersio
* @var \Rector\Php70\EregToPcreTransformer
*/
private $eregToPcreTransformer;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(EregToPcreTransformer $eregToPcreTransformer, ArgsAnalyzer $argsAnalyzer)
public function __construct(EregToPcreTransformer $eregToPcreTransformer)
{
$this->eregToPcreTransformer = $eregToPcreTransformer;
$this->argsAnalyzer = $argsAnalyzer;
}
public function provideMinPhpVersion() : int
{
@ -73,8 +66,7 @@ final class EregToPregMatchRector extends AbstractRector implements MinPhpVersio
}
/** @var string $functionName */
$functionName = $this->getName($node);
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$firstArg = $node->getArgs()[0];
$patternNode = $firstArg->value;
if ($patternNode instanceof String_) {
$this->processStringPattern($node, $patternNode, $functionName);
@ -101,15 +93,14 @@ final class EregToPregMatchRector extends AbstractRector implements MinPhpVersio
if (!isset(self::OLD_NAMES_TO_NEW_ONES[$functionName])) {
return \true;
}
return !$this->argsAnalyzer->isArgInstanceInArgsPosition($funcCall->args, 0);
return !isset($funcCall->getArgs()[0]);
}
private function processStringPattern(FuncCall $funcCall, String_ $string, string $functionName) : void
{
$pattern = $string->value;
$pattern = $this->eregToPcreTransformer->transform($pattern, $this->isCaseInsensitiveFunction($functionName));
/** @var Arg $arg */
$arg = $funcCall->args[0];
$arg->value = new String_($pattern);
$firstArg = $funcCall->getArgs()[0];
$firstArg->value = new String_($pattern);
}
private function processVariablePattern(FuncCall $funcCall, Variable $variable, string $functionName) : void
{

View File

@ -17,7 +17,6 @@ use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Php\ReservedKeywordAnalyzer;
use Rector\Core\PhpParser\Parser\InlineCodeParser;
use Rector\Core\Rector\AbstractRector;
@ -48,17 +47,11 @@ final class CreateFunctionToAnonymousFunctionRector extends AbstractRector imple
* @var \Rector\Core\Php\ReservedKeywordAnalyzer
*/
private $reservedKeywordAnalyzer;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(InlineCodeParser $inlineCodeParser, AnonymousFunctionFactory $anonymousFunctionFactory, ReservedKeywordAnalyzer $reservedKeywordAnalyzer, ArgsAnalyzer $argsAnalyzer)
public function __construct(InlineCodeParser $inlineCodeParser, AnonymousFunctionFactory $anonymousFunctionFactory, ReservedKeywordAnalyzer $reservedKeywordAnalyzer)
{
$this->inlineCodeParser = $inlineCodeParser;
$this->anonymousFunctionFactory = $anonymousFunctionFactory;
$this->reservedKeywordAnalyzer = $reservedKeywordAnalyzer;
$this->argsAnalyzer = $argsAnalyzer;
}
public function provideMinPhpVersion() : int
{
@ -104,15 +97,16 @@ CODE_SAMPLE
if (!$this->isName($node, 'create_function')) {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($node->args, [0, 1])) {
if ($node->isFirstClassCallable()) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
/** @var Arg $secondArg */
$secondArg = $node->args[1];
$params = $this->createParamsFromString($firstArg->value);
$stmts = $this->parseStringToBody($secondArg->value);
if (\count($node->getArgs()) < 2) {
return null;
}
$firstExpr = $node->getArgs()[0]->value;
$secondExpr = $node->getArgs()[1]->value;
$params = $this->createParamsFromString($firstExpr);
$stmts = $this->parseStringToBody($secondExpr);
$refactored = $this->anonymousFunctionFactory->create($params, $stmts, null);
foreach ($refactored->uses as $key => $use) {
$variableName = $this->getName($use->var);
@ -144,7 +138,7 @@ CODE_SAMPLE
return $function->params;
}
/**
* @return Expression[]|Stmt[]
* @return Stmt[]
*/
private function parseStringToBody(Expr $expr) : array
{

View File

@ -10,7 +10,6 @@ use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PHPStan\Type\ObjectType;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
@ -23,15 +22,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class ExportToReflectionFunctionRector extends AbstractRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::EXPORT_TO_REFLECTION_FUNCTION;
@ -70,17 +60,15 @@ CODE_SAMPLE
if (!$this->isName($node->name, 'export')) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
$firstArg = $node->getArgs()[0] ?? null;
if (!$firstArg instanceof Arg) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$new = new New_($node->class, [new Arg($firstArg->value)]);
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 1)) {
$secondArg = $node->getArgs()[1] ?? null;
if (!$secondArg instanceof Arg) {
return $new;
}
/** @var Arg $secondArg */
$secondArg = $node->args[1];
if ($this->valueResolver->isTrue($secondArg->value)) {
return new String_($new);
}

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\Php80\MatchAndRefactor\StrStartsWithMatchAndRefactor;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotEqual;
@ -12,7 +11,6 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\Php80\Contract\StrStartWithMatchAndRefactorInterface;
@ -45,18 +43,12 @@ final class StrncmpMatchAndRefactor implements StrStartWithMatchAndRefactorInter
* @var \Rector\Php80\NodeFactory\StrStartsWithFuncCallFactory
*/
private $strStartsWithFuncCallFactory;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(NodeNameResolver $nodeNameResolver, StrStartsWithFactory $strStartsWithFactory, NodeComparator $nodeComparator, StrStartsWithFuncCallFactory $strStartsWithFuncCallFactory, ArgsAnalyzer $argsAnalyzer)
public function __construct(NodeNameResolver $nodeNameResolver, StrStartsWithFactory $strStartsWithFactory, NodeComparator $nodeComparator, StrStartsWithFuncCallFactory $strStartsWithFuncCallFactory)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->strStartsWithFactory = $strStartsWithFactory;
$this->nodeComparator = $nodeComparator;
$this->strStartsWithFuncCallFactory = $strStartsWithFuncCallFactory;
$this->argsAnalyzer = $argsAnalyzer;
}
/**
* @param \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\Equal|\PhpParser\Node\Expr\BinaryOp\NotEqual $binaryOp
@ -89,43 +81,35 @@ final class StrncmpMatchAndRefactor implements StrStartWithMatchAndRefactorInter
{
$strncmpFuncCall = $strStartsWith->getFuncCall();
$needleExpr = $strStartsWith->getNeedleExpr();
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($strncmpFuncCall->args, 2)) {
if ($strncmpFuncCall->isFirstClassCallable()) {
return \false;
}
/** @var Arg $thirdArg */
$thirdArg = $strncmpFuncCall->args[2];
$secondArgumentValue = $thirdArg->value;
if (!$secondArgumentValue instanceof FuncCall) {
if (\count($strncmpFuncCall->getArgs()) < 2) {
return \false;
}
if (!$this->nodeNameResolver->isName($secondArgumentValue, 'strlen')) {
$thirdArg = $strncmpFuncCall->getArgs()[2];
$thirdArgExpr = $thirdArg->value;
if (!$thirdArgExpr instanceof FuncCall) {
return \false;
}
/** @var FuncCall $strlenFuncCall */
$strlenFuncCall = $thirdArg->value;
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($strlenFuncCall->args, 0)) {
if (!$this->nodeNameResolver->isName($thirdArgExpr, 'strlen')) {
return \false;
}
/** @var Arg $firstArg */
$firstArg = $strlenFuncCall->args[0];
$strlenArgumentValue = $firstArg->value;
return $this->nodeComparator->areNodesEqual($needleExpr, $strlenArgumentValue);
$strlenFuncCall = $thirdArgExpr;
$strlenExpr = $strlenFuncCall->getArgs()[0]->value;
return $this->nodeComparator->areNodesEqual($needleExpr, $strlenExpr);
}
private function isHardcodedStringWithLNumberLength(StrStartsWith $strStartsWith) : bool
{
$strncmpFuncCall = $strStartsWith->getFuncCall();
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($strncmpFuncCall->args, [1, 2])) {
if (\count($strncmpFuncCall->getArgs()) < 2) {
return \false;
}
/** @var Arg $secondArg */
$secondArg = $strncmpFuncCall->args[1];
$hardcodedStringNeedle = $secondArg->value;
$hardcodedStringNeedle = $strncmpFuncCall->getArgs()[1]->value;
if (!$hardcodedStringNeedle instanceof String_) {
return \false;
}
/** @var Arg $thirdArg */
$thirdArg = $strncmpFuncCall->args[2];
$lNumberLength = $thirdArg->value;
$lNumberLength = $strncmpFuncCall->getArgs()[2]->value;
if (!$lNumberLength instanceof LNumber) {
return \false;
}

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\Php80\MatchAndRefactor\StrStartsWithMatchAndRefactor;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Identical;
@ -13,7 +12,6 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\Php80\Contract\StrStartWithMatchAndRefactorInterface;
@ -36,17 +34,11 @@ final class StrposMatchAndRefactor implements StrStartWithMatchAndRefactorInterf
* @var \Rector\Php80\NodeFactory\StrStartsWithFuncCallFactory
*/
private $strStartsWithFuncCallFactory;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(NodeNameResolver $nodeNameResolver, ValueResolver $valueResolver, StrStartsWithFuncCallFactory $strStartsWithFuncCallFactory, ArgsAnalyzer $argsAnalyzer)
public function __construct(NodeNameResolver $nodeNameResolver, ValueResolver $valueResolver, StrStartsWithFuncCallFactory $strStartsWithFuncCallFactory)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->strStartsWithFuncCallFactory = $strStartsWithFuncCallFactory;
$this->argsAnalyzer = $argsAnalyzer;
}
/**
* @param \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\Equal|\PhpParser\Node\Expr\BinaryOp\NotEqual $binaryOp
@ -81,15 +73,14 @@ final class StrposMatchAndRefactor implements StrStartWithMatchAndRefactorInterf
}
/** @var FuncCall $funcCall */
$funcCall = $binaryOp->left;
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($funcCall->args, [0, 1])) {
if ($funcCall->isFirstClassCallable()) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $funcCall->args[0];
$haystack = $firstArg->value;
/** @var Arg $secondArg */
$secondArg = $funcCall->args[1];
$needle = $secondArg->value;
if (\count($funcCall->getArgs()) < 2) {
return null;
}
$haystack = $funcCall->getArgs()[0]->value;
$needle = $funcCall->getArgs()[1]->value;
return new StrStartsWith($funcCall, $haystack, $needle, $isPositive);
}
private function processBinaryOpRight(BinaryOp $binaryOp, bool $isPositive) : ?StrStartsWith
@ -99,15 +90,11 @@ final class StrposMatchAndRefactor implements StrStartWithMatchAndRefactorInterf
}
/** @var FuncCall $funcCall */
$funcCall = $binaryOp->right;
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($funcCall->args, [0, 1])) {
if (\count($funcCall->getArgs()) < 2) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $funcCall->args[0];
$haystack = $firstArg->value;
/** @var Arg $secondArg */
$secondArg = $funcCall->args[1];
$needle = $secondArg->value;
$haystack = $funcCall->getArgs()[0]->value;
$needle = $funcCall->getArgs()[1]->value;
return new StrStartsWith($funcCall, $haystack, $needle, $isPositive);
}
}

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\Php80\MatchAndRefactor\StrStartsWithMatchAndRefactor;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotEqual;
@ -12,7 +11,6 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NodeNameResolver\NodeNameResolver;
@ -41,18 +39,12 @@ final class SubstrMatchAndRefactor implements StrStartWithMatchAndRefactorInterf
* @var \Rector\Php80\NodeFactory\StrStartsWithFuncCallFactory
*/
private $strStartsWithFuncCallFactory;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(NodeNameResolver $nodeNameResolver, ValueResolver $valueResolver, NodeComparator $nodeComparator, StrStartsWithFuncCallFactory $strStartsWithFuncCallFactory, ArgsAnalyzer $argsAnalyzer)
public function __construct(NodeNameResolver $nodeNameResolver, ValueResolver $valueResolver, NodeComparator $nodeComparator, StrStartsWithFuncCallFactory $strStartsWithFuncCallFactory)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->nodeComparator = $nodeComparator;
$this->strStartsWithFuncCallFactory = $strStartsWithFuncCallFactory;
$this->argsAnalyzer = $argsAnalyzer;
}
/**
* @param \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\Equal|\PhpParser\Node\Expr\BinaryOp\NotEqual $binaryOp
@ -63,23 +55,13 @@ final class SubstrMatchAndRefactor implements StrStartWithMatchAndRefactorInterf
if ($binaryOp->left instanceof FuncCall && $this->nodeNameResolver->isName($binaryOp->left, 'substr')) {
/** @var FuncCall $funcCall */
$funcCall = $binaryOp->left;
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($funcCall->args, 0)) {
return null;
}
/** @var Arg $arg */
$arg = $funcCall->args[0];
$haystack = $arg->value;
$haystack = $funcCall->getArgs()[0]->value;
return new StrStartsWith($funcCall, $haystack, $binaryOp->right, $isPositive);
}
if ($binaryOp->right instanceof FuncCall && $this->nodeNameResolver->isName($binaryOp->right, 'substr')) {
/** @var FuncCall $funcCall */
$funcCall = $binaryOp->right;
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($funcCall->args, 0)) {
return null;
}
/** @var Arg $arg */
$arg = $funcCall->args[0];
$haystack = $arg->value;
$haystack = $funcCall->getArgs()[0]->value;
return new StrStartsWith($funcCall, $haystack, $binaryOp->left, $isPositive);
}
return null;
@ -97,58 +79,40 @@ final class SubstrMatchAndRefactor implements StrStartWithMatchAndRefactorInterf
private function isStrlenWithNeedleExpr(StrStartsWith $strStartsWith) : bool
{
$substrFuncCall = $strStartsWith->getFuncCall();
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($substrFuncCall->args, 1)) {
$firstArg = $substrFuncCall->getArgs()[1];
if (!$this->valueResolver->isValue($firstArg->value, 0)) {
return \false;
}
/** @var Arg $arg1 */
$arg1 = $substrFuncCall->args[1];
if (!$this->valueResolver->isValue($arg1->value, 0)) {
return \false;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($substrFuncCall->args, 2)) {
return \false;
}
/** @var Arg $arg2 */
$arg2 = $substrFuncCall->args[2];
$secondFuncCallArgValue = $arg2->value;
$secondFuncCallArgValue = $substrFuncCall->getArgs()[2]->value;
if (!$secondFuncCallArgValue instanceof FuncCall) {
return \false;
}
if (!$this->nodeNameResolver->isName($secondFuncCallArgValue, 'strlen')) {
return \false;
}
/** @var FuncCall $strlenFuncCall */
$strlenFuncCall = $arg2->value;
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($strlenFuncCall->args, 0)) {
return \false;
}
/** @var Arg $arg0 */
$arg0 = $strlenFuncCall->args[0];
$needleExpr = $arg0->value;
$strlenFuncCall = $secondFuncCallArgValue;
$needleExpr = $strlenFuncCall->getArgs()[0]->value;
$comparedNeedleExpr = $strStartsWith->getNeedleExpr();
return $this->nodeComparator->areNodesEqual($needleExpr, $comparedNeedleExpr);
}
private function isHardcodedStringWithLNumberLength(StrStartsWith $strStartsWith) : bool
{
$substrFuncCall = $strStartsWith->getFuncCall();
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($substrFuncCall->args, 1)) {
return \false;
}
/** @var Arg $arg1 */
$arg1 = $substrFuncCall->args[1];
if (!$this->valueResolver->isValue($arg1->value, 0)) {
$secondArg = $substrFuncCall->getArgs()[1];
if (!$this->valueResolver->isValue($secondArg->value, 0)) {
return \false;
}
$hardcodedStringNeedle = $strStartsWith->getNeedleExpr();
if (!$hardcodedStringNeedle instanceof String_) {
return \false;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($substrFuncCall->args, 2)) {
if ($substrFuncCall->isFirstClassCallable()) {
return \false;
}
/** @var Arg $arg2 */
$arg2 = $substrFuncCall->args[2];
$lNumberLength = $arg2->value;
if (\count($substrFuncCall->getArgs()) < 3) {
return \false;
}
$lNumberLength = $substrFuncCall->getArgs()[2]->value;
if (!$lNumberLength instanceof LNumber) {
return \false;
}

View File

@ -19,7 +19,6 @@ use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\If_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
@ -66,17 +65,12 @@ final class TokenManipulator
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver, NodesToRemoveCollector $nodesToRemoveCollector, ValueResolver $valueResolver, NodeComparator $nodeComparator, ArgsAnalyzer $argsAnalyzer, BetterNodeFinder $betterNodeFinder)
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver, NodesToRemoveCollector $nodesToRemoveCollector, ValueResolver $valueResolver, NodeComparator $nodeComparator, BetterNodeFinder $betterNodeFinder)
{
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->nodeNameResolver = $nodeNameResolver;
@ -84,7 +78,6 @@ final class TokenManipulator
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
$this->valueResolver = $valueResolver;
$this->nodeComparator = $nodeComparator;
$this->argsAnalyzer = $argsAnalyzer;
$this->betterNodeFinder = $betterNodeFinder;
}
/**
@ -194,11 +187,10 @@ final class TokenManipulator
if (!$this->nodeNameResolver->isName($node, 'is_array')) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
if ($node->isFirstClassCallable()) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$firstArg = $node->getArgs()[0];
if (!$this->nodeComparator->areNodesEqual($firstArg->value, $singleTokenVariable)) {
return null;
}
@ -253,11 +245,10 @@ final class TokenManipulator
if (!$this->nodeNameResolver->isName($node, 'token_name')) {
return null;
}
if (!$this->argsAnalyzer->isArgInstanceInArgsPosition($node->args, 0)) {
$firstArg = $node->getArgs()[0] ?? null;
if (!$firstArg instanceof Arg) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$possibleTokenArray = $firstArg->value;
if (!$possibleTokenArray instanceof ArrayDimFetch) {
return null;

View File

@ -16,7 +16,6 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\UnaryMinus;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Core\NodeAnalyzer\BinaryOpAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\FuncCallAndExpr;
@ -36,15 +35,9 @@ final class StrEndsWithRector extends AbstractRector implements MinPhpVersionInt
* @var \Rector\Core\NodeAnalyzer\BinaryOpAnalyzer
*/
private $binaryOpAnalyzer;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(BinaryOpAnalyzer $binaryOpAnalyzer, ArgsAnalyzer $argsAnalyzer)
public function __construct(BinaryOpAnalyzer $binaryOpAnalyzer)
{
$this->binaryOpAnalyzer = $binaryOpAnalyzer;
$this->argsAnalyzer = $argsAnalyzer;
}
public function provideMinPhpVersion() : int
{
@ -129,17 +122,17 @@ CODE_SAMPLE
} else {
return null;
}
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($substrFuncCall->args, [0, 1])) {
if ($substrFuncCall->isFirstClassCallable()) {
return null;
}
/** @var Arg $secondArg */
$secondArg = $substrFuncCall->args[1];
if (!$this->isUnaryMinusStrlenFuncCallArgValue($secondArg->value, $comparedNeedleExpr) && !$this->isHardCodedLNumberAndString($secondArg->value, $comparedNeedleExpr)) {
if (\count($substrFuncCall->getArgs()) < 2) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $substrFuncCall->args[0];
$haystack = $firstArg->value;
$needle = $substrFuncCall->getArgs()[1]->value;
if (!$this->isUnaryMinusStrlenFuncCallArgValue($needle, $comparedNeedleExpr) && !$this->isHardCodedLNumberAndString($needle, $comparedNeedleExpr)) {
return null;
}
$haystack = $substrFuncCall->getArgs()[0]->value;
$isPositive = $binaryOp instanceof Identical || $binaryOp instanceof Equal;
return $this->buildReturnNode($haystack, $comparedNeedleExpr, $isPositive);
}
@ -157,18 +150,12 @@ CODE_SAMPLE
return null;
}
$substrCompareFuncCall = $funcCallAndExpr->getFuncCall();
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($substrCompareFuncCall->args, [0, 1, 2])) {
if (\count($substrCompareFuncCall->getArgs()) < 2) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $substrCompareFuncCall->args[0];
$haystack = $firstArg->value;
/** @var Arg $secondArg */
$secondArg = $substrCompareFuncCall->args[1];
$needle = $secondArg->value;
/** @var Arg $thirdArg */
$thirdArg = $substrCompareFuncCall->args[2];
$thirdArgValue = $thirdArg->value;
$haystack = $substrCompareFuncCall->getArgs()[0]->value;
$needle = $substrCompareFuncCall->getArgs()[1]->value;
$thirdArgValue = $substrCompareFuncCall->getArgs()[2]->value;
if (!$this->isUnaryMinusStrlenFuncCallArgValue($thirdArgValue, $needle) && !$this->isHardCodedLNumberAndString($thirdArgValue, $needle)) {
return null;
}

View File

@ -3,32 +3,17 @@
declare (strict_types=1);
namespace Rector\Php80\ValueObjectFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
use Rector\Php80\ValueObject\StrStartsWith;
final class StrStartsWithFactory
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer;
public function __construct(ArgsAnalyzer $argsAnalyzer)
{
$this->argsAnalyzer = $argsAnalyzer;
}
public function createFromFuncCall(FuncCall $funcCall, bool $isPositive) : ?StrStartsWith
{
if (!$this->argsAnalyzer->isArgsInstanceInArgsPositions($funcCall->args, [0, 1])) {
if (\count($funcCall->getArgs()) < 2) {
return null;
}
/** @var Arg $firstArg */
$firstArg = $funcCall->args[0];
$haystack = $firstArg->value;
/** @var Arg $secondArg */
$secondArg = $funcCall->args[1];
$needle = $secondArg->value;
$haystack = $funcCall->getArgs()[0]->value;
$needle = $funcCall->getArgs()[1]->value;
return new StrStartsWith($funcCall, $haystack, $needle, $isPositive);
}
}

View File

@ -17,7 +17,6 @@ use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '6dea82deb1e64a47c0284a86b1b448dc8b1fc05f';
public const PACKAGE_VERSION = '645071a650fc50d7e084378facaebcc868a52ba1';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-05-13 16:45:12';
public const RELEASE_DATE = '2023-05-13 17:16:07';
/**
* @var int
*/

View File

@ -5,22 +5,22 @@ namespace Rector\Core\NodeAnalyzer;
use PhpParser\Node\Arg;
use PhpParser\Node\Identifier;
use PhpParser\Node\VariadicPlaceholder;
final class ArgsAnalyzer
{
/**
* @param Arg[]|VariadicPlaceholder[] $args
* @api
* @deprecated Use $node->getArgs()[x] instead
* @param Arg[] $args
*/
public function isArgInstanceInArgsPosition(array $args, int $position) : bool
{
if (!isset($args[$position])) {
return \false;
}
return $args[$position] instanceof Arg;
return isset($args[$position]);
}
/**
* @param Arg[]|VariadicPlaceholder[] $args
* @api
* @param Arg[] $args
* @param int[] $positions
* @deprecated use count($node->getArgs() < X instead
*/
public function isArgsInstanceInArgsPositions(array $args, array $positions) : bool
{
@ -28,10 +28,6 @@ final class ArgsAnalyzer
if (!isset($args[$position])) {
return \false;
}
if ($args[$position] instanceof Arg) {
continue;
}
return \false;
}
return \true;
}

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInita0b651f3450034e02afaa1bf3f06ce1f::getLoader();
return ComposerAutoloaderInit2febda954f156b62ed0020df63598e12::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInita0b651f3450034e02afaa1bf3f06ce1f
class ComposerAutoloaderInit2febda954f156b62ed0020df63598e12
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInita0b651f3450034e02afaa1bf3f06ce1f
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInita0b651f3450034e02afaa1bf3f06ce1f', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit2febda954f156b62ed0020df63598e12', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInita0b651f3450034e02afaa1bf3f06ce1f', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit2febda954f156b62ed0020df63598e12', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit2febda954f156b62ed0020df63598e12::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit2febda954f156b62ed0020df63598e12::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f
class ComposerStaticInit2febda954f156b62ed0020df63598e12
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -3111,9 +3111,9 @@ class ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInita0b651f3450034e02afaa1bf3f06ce1f::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit2febda954f156b62ed0020df63598e12::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit2febda954f156b62ed0020df63598e12::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit2febda954f156b62ed0020df63598e12::$classMap;
}, null, ClassLoader::class);
}