mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-20 23:41:57 +02:00
Updated Rector to commit e74ecfb6599f75dbd1463a6ac0b43d99c6dad466
e74ecfb659
[TypeDeclaration] Handle crash on func call not found on BoolReturnTypeFromBooleanStrictReturnsRector (#6327)
This commit is contained in:
parent
5095dcdca5
commit
569cb9f7eb
@ -165,7 +165,11 @@ CODE_SAMPLE
|
||||
if (!\is_string($functionName)) {
|
||||
return \false;
|
||||
}
|
||||
$functionReflection = $this->reflectionProvider->getFunction(new Name($functionName), null);
|
||||
$name = new Name($functionName);
|
||||
if (!$this->reflectionProvider->hasFunction($name, null)) {
|
||||
return \false;
|
||||
}
|
||||
$functionReflection = $this->reflectionProvider->getFunction($name, null);
|
||||
if (!$functionReflection->isBuiltin()) {
|
||||
return \false;
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '398b04db9fe8df75fd3b9d32805425a0b8a5ef6b';
|
||||
public const PACKAGE_VERSION = 'e74ecfb6599f75dbd1463a6ac0b43d99c6dad466';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2024-09-23 14:12:46';
|
||||
public const RELEASE_DATE = '2024-09-26 15:23:06';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
1
vendor/composer/autoload_classmap.php
vendored
1
vendor/composer/autoload_classmap.php
vendored
@ -53,6 +53,7 @@ return array(
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTextNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PureUnlessCallableIsImpureTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PureUnlessCallableIsImpureTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireExtendsTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireImplementsTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ReturnTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php',
|
||||
|
1
vendor/composer/autoload_static.php
vendored
1
vendor/composer/autoload_static.php
vendored
@ -272,6 +272,7 @@ class ComposerStaticInitb7f7ba4346a5afcc49f848aa6217e771
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTextNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PureUnlessCallableIsImpureTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PureUnlessCallableIsImpureTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireExtendsTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireImplementsTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ReturnTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php',
|
||||
|
46
vendor/composer/installed.json
vendored
46
vendor/composer/installed.json
vendored
@ -512,17 +512,17 @@
|
||||
},
|
||||
{
|
||||
"name": "illuminate\/container",
|
||||
"version": "v11.23.5",
|
||||
"version_normalized": "11.23.5.0",
|
||||
"version": "v11.24.1",
|
||||
"version_normalized": "11.24.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/illuminate\/container.git",
|
||||
"reference": "66d20471c8c55ef056044dc1ff16da90d7b4d649"
|
||||
"reference": "d6aca7c315d68cb6807c139facd7ea134b4f5104"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/illuminate\/container\/zipball\/66d20471c8c55ef056044dc1ff16da90d7b4d649",
|
||||
"reference": "66d20471c8c55ef056044dc1ff16da90d7b4d649",
|
||||
"url": "https:\/\/api.github.com\/repos\/illuminate\/container\/zipball\/d6aca7c315d68cb6807c139facd7ea134b4f5104",
|
||||
"reference": "d6aca7c315d68cb6807c139facd7ea134b4f5104",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -533,7 +533,7 @@
|
||||
"provide": {
|
||||
"psr\/container-implementation": "1.1|2.0"
|
||||
},
|
||||
"time": "2024-09-11T20:15:17+00:00",
|
||||
"time": "2024-09-20T12:51:05+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@ -569,17 +569,17 @@
|
||||
},
|
||||
{
|
||||
"name": "illuminate\/contracts",
|
||||
"version": "v11.23.5",
|
||||
"version_normalized": "11.23.5.0",
|
||||
"version": "v11.24.1",
|
||||
"version_normalized": "11.24.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/illuminate\/contracts.git",
|
||||
"reference": "5a4c6dcf633c1f69e1b70bbea1ef1b7d2186d3da"
|
||||
"reference": "56312862af937bd6da8e6dc8bbd88188dfb478f8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/illuminate\/contracts\/zipball\/5a4c6dcf633c1f69e1b70bbea1ef1b7d2186d3da",
|
||||
"reference": "5a4c6dcf633c1f69e1b70bbea1ef1b7d2186d3da",
|
||||
"url": "https:\/\/api.github.com\/repos\/illuminate\/contracts\/zipball\/56312862af937bd6da8e6dc8bbd88188dfb478f8",
|
||||
"reference": "56312862af937bd6da8e6dc8bbd88188dfb478f8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -587,7 +587,7 @@
|
||||
"psr\/container": "^1.1.1|^2.0.1",
|
||||
"psr\/simple-cache": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"time": "2024-09-12T15:25:08+00:00",
|
||||
"time": "2024-09-22T15:08:08+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@ -867,17 +867,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan\/phpdoc-parser",
|
||||
"version": "1.31.0",
|
||||
"version_normalized": "1.31.0.0",
|
||||
"version": "1.32.0",
|
||||
"version_normalized": "1.32.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/phpstan\/phpdoc-parser.git",
|
||||
"reference": "249f15fb843bf240cf058372dad29e100cee6c17"
|
||||
"reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpdoc-parser\/zipball\/249f15fb843bf240cf058372dad29e100cee6c17",
|
||||
"reference": "249f15fb843bf240cf058372dad29e100cee6c17",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpdoc-parser\/zipball\/6ca22b154efdd9e3c68c56f5d94670920a1c19a4",
|
||||
"reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -894,7 +894,7 @@
|
||||
"phpunit\/phpunit": "^9.5",
|
||||
"symfony\/process": "^5.2"
|
||||
},
|
||||
"time": "2024-09-22T11:32:18+00:00",
|
||||
"time": "2024-09-26T07:23:32+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -911,7 +911,7 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https:\/\/github.com\/phpstan\/phpdoc-parser\/issues",
|
||||
"source": "https:\/\/github.com\/phpstan\/phpdoc-parser\/tree\/1.31.0"
|
||||
"source": "https:\/\/github.com\/phpstan\/phpdoc-parser\/tree\/1.32.0"
|
||||
},
|
||||
"install-path": "..\/phpstan\/phpdoc-parser"
|
||||
},
|
||||
@ -1811,12 +1811,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/rectorphp\/rector-phpunit.git",
|
||||
"reference": "bffd16339732095ba84bf21475eac749c1c9a154"
|
||||
"reference": "6a33c23cc196081d405cb38cd70af860fc796884"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/bffd16339732095ba84bf21475eac749c1c9a154",
|
||||
"reference": "bffd16339732095ba84bf21475eac749c1c9a154",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/6a33c23cc196081d405cb38cd70af860fc796884",
|
||||
"reference": "6a33c23cc196081d405cb38cd70af860fc796884",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1839,7 +1839,7 @@
|
||||
"tomasvotruba\/class-leak": "^0.2",
|
||||
"tracy\/tracy": "^2.10"
|
||||
},
|
||||
"time": "2024-09-22T19:04:35+00:00",
|
||||
"time": "2024-09-26T07:47:53+00:00",
|
||||
"default-branch": true,
|
||||
"type": "rector-extension",
|
||||
"extra": {
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
3
vendor/illuminate/container/Container.php
vendored
3
vendor/illuminate/container/Container.php
vendored
@ -927,6 +927,9 @@ class Container implements ArrayAccess, ContainerContract
|
||||
if ($parameter->isVariadic()) {
|
||||
return [];
|
||||
}
|
||||
if ($parameter->hasType() && $parameter->allowsNull()) {
|
||||
return null;
|
||||
}
|
||||
$this->unresolvablePrimitive($parameter);
|
||||
}
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace RectorPrefix202409\Illuminate\Contracts\Concurrency;
|
||||
|
||||
use Closure;
|
||||
use RectorPrefix202409\Illuminate\Foundation\Defer\DeferredCallback;
|
||||
use RectorPrefix202409\Illuminate\Support\Defer\DeferredCallback;
|
||||
interface Driver
|
||||
{
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ interface SerializesCastableAttributes
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @param array<string, mixed> $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function serialize(Model $model, string $key, $value, array $attributes);
|
||||
|
@ -13,7 +13,7 @@ interface InvokableRule
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param \Closure(string, ?string = null): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @return void
|
||||
*/
|
||||
public function __invoke(string $attribute, $value, Closure $fail);
|
||||
|
@ -10,7 +10,7 @@ interface ValidationRule
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param \Closure(string, ?string = null): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @return void
|
||||
*/
|
||||
public function validate(string $attribute, $value, Closure $fail) : void;
|
||||
|
@ -93,6 +93,15 @@ class PhpDocNode implements Node
|
||||
return $value instanceof \PHPStan\PhpDocParser\Ast\PhpDoc\ParamClosureThisTagValueNode;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @return PureUnlessCallableIsImpureTagValueNode[]
|
||||
*/
|
||||
public function getPureUnlessCallableIsImpureTagValues(string $tagName = '@pure-unless-callable-is-impure') : array
|
||||
{
|
||||
return array_filter(array_column($this->getTagsByName($tagName), 'value'), static function (\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode $value) : bool {
|
||||
return $value instanceof \PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @return TemplateTagValueNode[]
|
||||
*/
|
||||
|
24
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PureUnlessCallableIsImpureTagValueNode.php
vendored
Normal file
24
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PureUnlessCallableIsImpureTagValueNode.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function trim;
|
||||
class PureUnlessCallableIsImpureTagValueNode implements \PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
use NodeAttributes;
|
||||
/** @var string */
|
||||
public $parameterName;
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
public function __construct(string $parameterName, string $description)
|
||||
{
|
||||
$this->parameterName = $parameterName;
|
||||
$this->description = $description;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return trim("{$this->parameterName} {$this->description}");
|
||||
}
|
||||
}
|
@ -297,6 +297,10 @@ class PhpDocParser
|
||||
case '@phpstan-param-closure-this':
|
||||
$tagValue = $this->parseParamClosureThisTagValue($tokens);
|
||||
break;
|
||||
case '@pure-unless-callable-is-impure':
|
||||
case '@phpstan-pure-unless-callable-is-impure':
|
||||
$tagValue = $this->parsePureUnlessCallableIsImpureTagValue($tokens);
|
||||
break;
|
||||
case '@var':
|
||||
case '@phpstan-var':
|
||||
case '@psalm-var':
|
||||
@ -636,6 +640,12 @@ class PhpDocParser
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
return new Ast\PhpDoc\ParamClosureThisTagValueNode($type, $parameterName, $description);
|
||||
}
|
||||
private function parsePureUnlessCallableIsImpureTagValue(\PHPStan\PhpDocParser\Parser\TokenIterator $tokens) : Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode
|
||||
{
|
||||
$parameterName = $this->parseRequiredVariableName($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($parameterName, $description);
|
||||
}
|
||||
private function parseVarTagValue(\PHPStan\PhpDocParser\Parser\TokenIterator $tokens) : Ast\PhpDoc\VarTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
|
@ -32,6 +32,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
@ -249,6 +250,9 @@ final class Printer
|
||||
if ($node instanceof ParamClosureThisTagValueNode) {
|
||||
return trim("{$node->type} {$node->parameterName} {$node->description}");
|
||||
}
|
||||
if ($node instanceof PureUnlessCallableIsImpureTagValueNode) {
|
||||
return trim("{$node->parameterName} {$node->description}");
|
||||
}
|
||||
if ($node instanceof PropertyTagValueNode) {
|
||||
$type = $this->printType($node->type);
|
||||
return trim("{$type} {$node->propertyName} {$node->description}");
|
||||
|
@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
|
||||
*/
|
||||
final class GeneratedConfig
|
||||
{
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main e75008c'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main cfebdb1'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main bffd163'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 352a84c'));
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main e75008c'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main cfebdb1'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main 6a33c23'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 352a84c'));
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use Rector\VersionBonding\Contract\MinPhpVersionInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\PHPUnit\Tests\Rector\StmtsAwareInterface\WithConsecutiveRector\WithConsecutiveRectorTest
|
||||
* @see \Rector\PHPUnit\Tests\PHPUnit100\Rector\StmtsAwareInterface\WithConsecutiveRector\WithConsecutiveRectorTest
|
||||
*/
|
||||
final class WithConsecutiveRector extends AbstractRector implements MinPhpVersionInterface
|
||||
{
|
||||
@ -122,28 +122,16 @@ CODE_SAMPLE
|
||||
if ($this->hasWillReturnMapOrWill($node)) {
|
||||
return null;
|
||||
}
|
||||
$firstArg = $withConsecutiveMethodCall->getArgs()[0];
|
||||
$isWithConsecutiveVariadic = $firstArg->unpack;
|
||||
$returnStmts = [];
|
||||
$willReturn = $this->findMethodCall($node, 'willReturn');
|
||||
if ($willReturn instanceof MethodCall) {
|
||||
$args = $willReturn->getArgs();
|
||||
if (\count($args) !== 1 || !$args[0] instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
$returnStmts = [new Return_($args[0]->value)];
|
||||
$returnStmts[] = $this->createWillReturnStmt($willReturn);
|
||||
}
|
||||
$willReturnSelf = $this->findMethodCall($node, 'willReturnSelf');
|
||||
if ($willReturnSelf instanceof MethodCall) {
|
||||
if ($returnStmts !== []) {
|
||||
return null;
|
||||
}
|
||||
$selfVariable = $willReturnSelf;
|
||||
while (\true) {
|
||||
if (!$selfVariable instanceof MethodCall) {
|
||||
break;
|
||||
}
|
||||
$selfVariable = $selfVariable->var;
|
||||
}
|
||||
$returnStmts = [new Return_($selfVariable)];
|
||||
$returnStmts[] = $this->createWillReturnSelfStmts($willReturnSelf);
|
||||
}
|
||||
$willReturnArgument = $this->findMethodCall($node, 'willReturnArgument');
|
||||
if ($willReturnArgument instanceof MethodCall) {
|
||||
@ -151,11 +139,11 @@ CODE_SAMPLE
|
||||
return null;
|
||||
}
|
||||
$parametersVariable = new Variable('parameters');
|
||||
$args = $willReturnArgument->getArgs();
|
||||
if (\count($args) !== 1 || !$args[0] instanceof Arg) {
|
||||
$firstArgs = $willReturnArgument->getArgs()[0];
|
||||
if (!$firstArgs instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
$returnStmts = [new Return_(new ArrayDimFetch($parametersVariable, $args[0]->value))];
|
||||
$returnStmts = [new Return_(new ArrayDimFetch($parametersVariable, $firstArgs->value))];
|
||||
}
|
||||
$willReturnOnConsecutiveCallsArgument = $this->findMethodCall($node, 'willReturnOnConsecutiveCalls');
|
||||
if ($willReturnOnConsecutiveCallsArgument instanceof MethodCall) {
|
||||
@ -176,11 +164,11 @@ CODE_SAMPLE
|
||||
if ($returnStmts !== []) {
|
||||
return null;
|
||||
}
|
||||
$args = $willReturnReferenceArgument->args;
|
||||
if (\count($args) !== 1 || !$args[0] instanceof Arg) {
|
||||
$firstArg = $willReturnReferenceArgument->getArgs()[0] ?? null;
|
||||
if (!$firstArg instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
$referenceVariable = $args[0]->value;
|
||||
$referenceVariable = $firstArg->value;
|
||||
if (!$referenceVariable instanceof Variable) {
|
||||
return null;
|
||||
}
|
||||
@ -191,11 +179,11 @@ CODE_SAMPLE
|
||||
if ($returnStmts !== []) {
|
||||
return null;
|
||||
}
|
||||
$args = $willThrowException->getArgs();
|
||||
if (\count($args) !== 1 || !$args[0] instanceof Arg) {
|
||||
$firstArg = $willThrowException->getArgs()[0] ?? null;
|
||||
if (!$firstArg instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
$returnStmts = [new Throw_($args[0]->value)];
|
||||
$returnStmts = [new Throw_($firstArg->value)];
|
||||
}
|
||||
$this->removeMethodCalls($node, ['willReturn', 'willReturnArgument', 'willReturnSelf', 'willReturnOnConsecutiveCalls', 'willReturnReference', 'willThrowException']);
|
||||
$expectsCall = $this->matchAndRefactorExpectsMethodCall($node);
|
||||
@ -207,31 +195,15 @@ CODE_SAMPLE
|
||||
// 2. does willReturnCallback() exist? just merge
|
||||
$existingWillReturnCallback = $this->findMethodCall($node, 'willReturnCallback');
|
||||
if ($existingWillReturnCallback instanceof MethodCall) {
|
||||
$callbackArg = $existingWillReturnCallback->getArgs()[0];
|
||||
if (!$callbackArg->value instanceof Closure) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
$callbackClosure = $callbackArg->value;
|
||||
$matcherVariable = new Variable('matcher');
|
||||
$parametersVariable = new Variable('parameters');
|
||||
$parametersMatch = $this->withConsecutiveMatchFactory->createParametersMatch($matcherVariable, $withConsecutiveMethodCall, $parametersVariable);
|
||||
$callbackClosure->params[] = new Param($parametersVariable);
|
||||
$callbackClosure->stmts = \array_merge([new Expression($parametersMatch)], $callbackClosure->stmts);
|
||||
$this->removeMethodCalls($node, [self::WITH_CONSECUTIVE_METHOD]);
|
||||
return [$node];
|
||||
return $this->refactorWithExistingWillReturnCallback($existingWillReturnCallback, $withConsecutiveMethodCall, $node);
|
||||
}
|
||||
// 3. rename and replace withConsecutive()
|
||||
return $this->refactorToWillReturnCallback($withConsecutiveMethodCall, $returnStmts, $referenceVariable, $expectsCall, $node);
|
||||
return $this->refactorToWillReturnCallback($withConsecutiveMethodCall, $returnStmts, $referenceVariable, $expectsCall, $node, $isWithConsecutiveVariadic);
|
||||
}
|
||||
public function provideMinPhpVersion() : int
|
||||
{
|
||||
/**
|
||||
* This rule just work for phpunit 10,
|
||||
* And as php 8.1 is the min version supported by phpunit 10, then we decided to let this version as minimum.
|
||||
*
|
||||
* You can see more detail in this issue: https://github.com/rectorphp/rector-phpunit/issues/272
|
||||
*/
|
||||
return PhpVersion::PHP_81;
|
||||
// This rule uses PHP 8.0 match
|
||||
return PhpVersion::PHP_80;
|
||||
}
|
||||
/**
|
||||
* Replace $this->expects(...)
|
||||
@ -284,6 +256,41 @@ CODE_SAMPLE
|
||||
});
|
||||
return $nodesWithWillReturnMap !== [];
|
||||
}
|
||||
/**
|
||||
* @param Stmt[] $returnStmts
|
||||
* @return Stmt[]
|
||||
* @param \PhpParser\Node\Expr|\PhpParser\Node\Expr\Variable|null $referenceVariable
|
||||
* @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall $expectsCall
|
||||
*/
|
||||
private function refactorToWillReturnCallback(MethodCall $withConsecutiveMethodCall, array $returnStmts, $referenceVariable, $expectsCall, Expression $expression, bool $isWithConsecutiveVariadic) : array
|
||||
{
|
||||
$withConsecutiveMethodCall->name = new Identifier('willReturnCallback');
|
||||
$withConsecutiveMethodCall->args = [new Arg($this->withConsecutiveMatchFactory->createClosure($withConsecutiveMethodCall, $returnStmts, $referenceVariable, $isWithConsecutiveVariadic))];
|
||||
$hasExpects = $this->findMethodCall($expression, 'expects') instanceof MethodCall;
|
||||
$matcherVariable = new Variable('matcher');
|
||||
if ($hasExpects === \false) {
|
||||
/** @var MethodCall $mockMethodCall */
|
||||
$mockMethodCall = $expression->expr;
|
||||
$mockMethodCall->var = new MethodCall($mockMethodCall->var, 'expects', [new Arg($matcherVariable)]);
|
||||
}
|
||||
$matcherAssign = new Assign($matcherVariable, $expectsCall);
|
||||
return [new Expression($matcherAssign), $expression];
|
||||
}
|
||||
private function refactorWithExistingWillReturnCallback(MethodCall $existingWillReturnCallback, MethodCall $withConsecutiveMethodCall, Expression $expression) : Expression
|
||||
{
|
||||
$callbackArg = $existingWillReturnCallback->getArgs()[0];
|
||||
if (!$callbackArg->value instanceof Closure) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
$callbackClosure = $callbackArg->value;
|
||||
$matcherVariable = new Variable('matcher');
|
||||
$parametersVariable = new Variable('parameters');
|
||||
$parametersMatch = $this->withConsecutiveMatchFactory->createParametersMatch($matcherVariable, $withConsecutiveMethodCall, $parametersVariable);
|
||||
$callbackClosure->params[] = new Param($parametersVariable);
|
||||
$callbackClosure->stmts = \array_merge([new Expression($parametersMatch)], $callbackClosure->stmts);
|
||||
$this->removeMethodCalls($expression, [self::WITH_CONSECUTIVE_METHOD]);
|
||||
return $expression;
|
||||
}
|
||||
/**
|
||||
* @param string[] $methodNames
|
||||
*/
|
||||
@ -299,17 +306,23 @@ CODE_SAMPLE
|
||||
return $node->var;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param Stmt[] $returnStmts
|
||||
* @return Stmt[]
|
||||
* @param \PhpParser\Node\Expr|\PhpParser\Node\Expr\Variable|null $referenceVariable
|
||||
* @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall $expectsCall
|
||||
*/
|
||||
private function refactorToWillReturnCallback(MethodCall $withConsecutiveMethodCall, array $returnStmts, $referenceVariable, $expectsCall, Expression $expression) : array
|
||||
private function createWillReturnStmt(MethodCall $willReturnMethodCall) : Return_
|
||||
{
|
||||
$withConsecutiveMethodCall->name = new Identifier('willReturnCallback');
|
||||
$withConsecutiveMethodCall->args = [new Arg($this->withConsecutiveMatchFactory->createClosure($withConsecutiveMethodCall, $returnStmts, $referenceVariable))];
|
||||
$matcherAssign = new Assign(new Variable('matcher'), $expectsCall);
|
||||
return [new Expression($matcherAssign), $expression];
|
||||
$firstArg = $willReturnMethodCall->getArgs()[0] ?? null;
|
||||
if (!$firstArg instanceof Arg) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
return new Return_($firstArg->value);
|
||||
}
|
||||
private function createWillReturnSelfStmts(MethodCall $willReturnSelfMethodCall) : Return_
|
||||
{
|
||||
$selfVariable = $willReturnSelfMethodCall;
|
||||
while (\true) {
|
||||
if (!$selfVariable instanceof MethodCall) {
|
||||
break;
|
||||
}
|
||||
$selfVariable = $selfVariable->var;
|
||||
}
|
||||
return new Return_($selfVariable);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ namespace Rector\PHPUnit\NodeFactory;
|
||||
|
||||
use PhpParser\BuilderFactory;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
use PhpParser\Node\Expr\BinaryOp\Minus;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\ClosureUse;
|
||||
use PhpParser\Node\Expr\Match_;
|
||||
@ -46,31 +49,32 @@ final class WithConsecutiveMatchFactory
|
||||
* @param Stmt[] $returnStmts
|
||||
* @param \PhpParser\Node\Expr\Variable|\PhpParser\Node\Expr|null $referenceVariable
|
||||
*/
|
||||
public function createClosure(MethodCall $expectsMethodCall, array $returnStmts, $referenceVariable) : Closure
|
||||
public function createClosure(MethodCall $withConsecutiveMethodCall, array $returnStmts, $referenceVariable, bool $isWithConsecutiveVariadic) : Closure
|
||||
{
|
||||
$byRef = $referenceVariable instanceof Variable;
|
||||
$closure = new Closure(['byRef' => $byRef]);
|
||||
$matcherVariable = new Variable('matcher');
|
||||
$closure->uses[] = new ClosureUse($matcherVariable);
|
||||
$usedVariables = $this->resolveUniqueUsedVariables(\array_merge($expectsMethodCall->getArgs(), $this->resolveUniqueUsedVariables($returnStmts)));
|
||||
foreach ($usedVariables as $usedVariable) {
|
||||
$closureUse = new ClosureUse($usedVariable);
|
||||
if ($byRef && $this->nodeNameResolver->areNamesEqual($usedVariable, $referenceVariable)) {
|
||||
$closureUse->byRef = \true;
|
||||
}
|
||||
$closure->uses[] = $closureUse;
|
||||
}
|
||||
$usedVariables = $this->resolveUsedVariables($withConsecutiveMethodCall, $returnStmts);
|
||||
$isByRef = $this->isByRef($referenceVariable);
|
||||
$uses = $this->createUses($matcherVariable, $usedVariables);
|
||||
$parametersVariable = new Variable('parameters');
|
||||
$match = $this->createParametersMatch($matcherVariable, $expectsMethodCall, $parametersVariable);
|
||||
$closure->params[] = new Param($parametersVariable);
|
||||
$closure->stmts = \array_merge([new Expression($match)], $returnStmts);
|
||||
return $closure;
|
||||
$match = $this->createParametersMatch($matcherVariable, $withConsecutiveMethodCall, $parametersVariable);
|
||||
$parametersParam = new Param($parametersVariable);
|
||||
if ($isWithConsecutiveVariadic) {
|
||||
$parametersParam->variadic = \true;
|
||||
}
|
||||
return new Closure(['byRef' => $isByRef, 'uses' => $uses, 'params' => [$parametersParam], 'stmts' => \array_merge([new Expression($match)], $returnStmts)]);
|
||||
}
|
||||
public function createParametersMatch(Variable $matcherVariable, MethodCall $expectsMethodCall, Variable $parameters) : Match_
|
||||
/**
|
||||
* @return \PhpParser\Node\Expr\Match_|\PhpParser\Node\Expr\MethodCall
|
||||
*/
|
||||
public function createParametersMatch(Variable $matcherVariable, MethodCall $withConsecutiveMethodCall, Variable $parameters)
|
||||
{
|
||||
$firstArg = $withConsecutiveMethodCall->getArgs()[0] ?? null;
|
||||
if ($firstArg instanceof Arg && $firstArg->unpack) {
|
||||
return $this->createAssertSameDimFetch($firstArg, $matcherVariable, $parameters);
|
||||
}
|
||||
$numberOfInvocationsMethodCall = new MethodCall($matcherVariable, new Identifier('numberOfInvocations'));
|
||||
$matchArms = [];
|
||||
foreach ($expectsMethodCall->getArgs() as $key => $arg) {
|
||||
foreach ($withConsecutiveMethodCall->getArgs() as $key => $arg) {
|
||||
$assertEquals = $this->builderFactory->staticCall('self', 'assertEquals', [$arg, $parameters]);
|
||||
$matchArms[] = new MatchArm([new LNumber($key + 1)], $assertEquals);
|
||||
}
|
||||
@ -94,4 +98,39 @@ final class WithConsecutiveMatchFactory
|
||||
}
|
||||
return $uniqueUsedVariables;
|
||||
}
|
||||
private function createAssertSameDimFetch(Arg $firstArg, Variable $matcherVariable, Variable $parameters) : MethodCall
|
||||
{
|
||||
$currentValueArrayDimFetch = new ArrayDimFetch($firstArg->value, new Minus(new MethodCall($matcherVariable, new Identifier('numberOfInvocations')), new LNumber(1)));
|
||||
$compareArgs = [new Arg($currentValueArrayDimFetch), new Arg(new ArrayDimFetch($parameters, new LNumber(0)))];
|
||||
return $this->builderFactory->methodCall(new Variable('this'), 'assertSame', $compareArgs);
|
||||
}
|
||||
/**
|
||||
* @param Stmt[] $returnStmts
|
||||
* @return Variable[]
|
||||
*/
|
||||
private function resolveUsedVariables(MethodCall $withConsecutiveMethodCall, array $returnStmts) : array
|
||||
{
|
||||
$consecutiveArgs = $withConsecutiveMethodCall->getArgs();
|
||||
$stmtVariables = $this->resolveUniqueUsedVariables($returnStmts);
|
||||
return $this->resolveUniqueUsedVariables(\array_merge($consecutiveArgs, $stmtVariables));
|
||||
}
|
||||
/**
|
||||
* @param \PhpParser\Node\Expr|\PhpParser\Node\Expr\Variable|null $referenceVariable
|
||||
*/
|
||||
private function isByRef($referenceVariable) : bool
|
||||
{
|
||||
return $referenceVariable instanceof Variable;
|
||||
}
|
||||
/**
|
||||
* @param Variable[] $usedVariables
|
||||
* @return ClosureUse[]
|
||||
*/
|
||||
private function createUses(Variable $matcherVariable, array $usedVariables) : array
|
||||
{
|
||||
$uses = [new ClosureUse($matcherVariable)];
|
||||
foreach ($usedVariables as $usedVariable) {
|
||||
$uses[] = new ClosureUse($usedVariable);
|
||||
}
|
||||
return $uses;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user