mirror of https://github.com/rectorphp/rector.git
Updated Rector to commit 205df9013af5e05034441aa6088599532f5fef05
205df9013a
[TypeDeclaration] Add Encapsed string support to AlwaysStrictScalarExprAnalyzer (#4382)
This commit is contained in:
parent
f77ffbaf00
commit
5db0586b82
|
@ -45,7 +45,23 @@ final class RegexMatcher
|
|||
return null;
|
||||
}
|
||||
$delimiter = $pattern[0];
|
||||
$delimiter = $delimiter === '(' ? ')' : ($delimiter === '{' ? '}' : ($delimiter === '[' ? ']' : ($delimiter === '<' ? '>' : $delimiter)));
|
||||
switch ($delimiter) {
|
||||
case '(':
|
||||
$delimiter = ')';
|
||||
break;
|
||||
case '{':
|
||||
$delimiter = '}';
|
||||
break;
|
||||
case '[':
|
||||
$delimiter = ']';
|
||||
break;
|
||||
case '<':
|
||||
$delimiter = '>';
|
||||
break;
|
||||
default:
|
||||
$delimiter = $delimiter;
|
||||
break;
|
||||
}
|
||||
/** @var string $modifiers */
|
||||
$modifiers = $this->resolveModifiers((string) Strings::after($pattern, $delimiter, -1));
|
||||
if (\strpos($modifiers, 'e') === \false) {
|
||||
|
|
|
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitacdeb8f05f5810ff3c4be5a432921110::getLoader();
|
||||
return ComposerAutoloaderInit270aad27721263e728d3e03b2ead6200::getLoader();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitacdeb8f05f5810ff3c4be5a432921110
|
||||
class ComposerAutoloaderInit270aad27721263e728d3e03b2ead6200
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -22,17 +22,17 @@ class ComposerAutoloaderInitacdeb8f05f5810ff3c4be5a432921110
|
|||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitacdeb8f05f5810ff3c4be5a432921110', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit270aad27721263e728d3e03b2ead6200', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitacdeb8f05f5810ff3c4be5a432921110', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit270aad27721263e728d3e03b2ead6200', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit270aad27721263e728d3e03b2ead6200::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110::$files;
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit270aad27721263e728d3e03b2ead6200::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110
|
||||
class ComposerStaticInit270aad27721263e728d3e03b2ead6200
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
|
@ -3098,9 +3098,9 @@ class ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110
|
|||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitacdeb8f05f5810ff3c4be5a432921110::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit270aad27721263e728d3e03b2ead6200::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit270aad27721263e728d3e03b2ead6200::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit270aad27721263e728d3e03b2ead6200::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
|
|
@ -1982,12 +1982,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/rectorphp\/rector-downgrade-php.git",
|
||||
"reference": "06c6448c8ad38cf94a07de5a1471bb7ee448169d"
|
||||
"reference": "57ad03c027f04921edea6e081c7346f21d23d104"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/06c6448c8ad38cf94a07de5a1471bb7ee448169d",
|
||||
"reference": "06c6448c8ad38cf94a07de5a1471bb7ee448169d",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/57ad03c027f04921edea6e081c7346f21d23d104",
|
||||
"reference": "57ad03c027f04921edea6e081c7346f21d23d104",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2011,7 +2011,7 @@
|
|||
"tomasvotruba\/type-coverage": "^0.2",
|
||||
"tomasvotruba\/unused-public": "^0.1"
|
||||
},
|
||||
"time": "2023-06-26T07:33:54+00:00",
|
||||
"time": "2023-06-30T11:54:35+00:00",
|
||||
"default-branch": true,
|
||||
"type": "rector-extension",
|
||||
"extra": {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main fc2dbbd'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 06c6448'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main c6bf48b'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 30b651c'));
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main fc2dbbd'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 57ad03c'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main c6bf48b'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 30b651c'));
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -602,7 +602,18 @@ Downgrade `match()` to `switch()`
|
|||
- 400 => 'not found',
|
||||
- default => 'unknown status code',
|
||||
- };
|
||||
+ $message = ($statusCode === 200 || $statusCode === 300 ? null : $statusCode === 400 ? 'not found' : 'unknown status code';
|
||||
+ switch ($statusCode) {
|
||||
+ case 200:
|
||||
+ case 300:
|
||||
+ $message = null;
|
||||
+ break;
|
||||
+ case 400:
|
||||
+ $message = 'not found';
|
||||
+ break;
|
||||
+ default:
|
||||
+ $message = 'unknown status code';
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -954,6 +965,19 @@ Remove Json constant that available only in php 7.3
|
|||
```diff
|
||||
-json_encode($content, JSON_THROW_ON_ERROR);
|
||||
+json_encode($content, 0);
|
||||
+if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
+ throw new \Exception(json_last_error_msg());
|
||||
+}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
```diff
|
||||
-$content = json_decode($json, null, 512, JSON_THROW_ON_ERROR);
|
||||
+$content = json_decode($json, null, 512, 0);
|
||||
+if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
+ throw new \Exception(json_last_error_msg());
|
||||
+}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
|
|
@ -215,7 +215,17 @@ CODE_SAMPLE
|
|||
if (!$subNode instanceof Node) {
|
||||
continue;
|
||||
}
|
||||
$found = \true === $subNode instanceof BitwiseOr ? $this->hasConstFetchInBitwiseOr($subNode, $constName) : (\true === $subNode instanceof ConstFetch ? $this->getName($subNode) === $constName : \false);
|
||||
switch (\true) {
|
||||
case $subNode instanceof BitwiseOr:
|
||||
$found = $this->hasConstFetchInBitwiseOr($subNode, $constName);
|
||||
break;
|
||||
case $subNode instanceof ConstFetch:
|
||||
$found = $this->getName($subNode) === $constName;
|
||||
break;
|
||||
default:
|
||||
$found = \false;
|
||||
break;
|
||||
}
|
||||
if ($found) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -4,18 +4,31 @@ declare (strict_types=1);
|
|||
namespace Rector\DowngradePhp80\Rector\Expression;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||
use PhpParser\Node\Expr\BinaryOp\Identical;
|
||||
use PhpParser\Node\Expr\ConstFetch;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Expr\ArrowFunction;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\CallLike;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\Match_;
|
||||
use PhpParser\Node\Expr\Ternary;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\NullsafeMethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Throw_;
|
||||
use PhpParser\Node\Name;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersion;
|
||||
use PhpParser\Node\MatchArm;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Break_;
|
||||
use PhpParser\Node\Stmt\Case_;
|
||||
use PhpParser\Node\Stmt\Echo_;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PhpParser\Node\Stmt\Switch_;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use Rector\Core\Rector\AbstractScopeAwareRector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Php72\NodeFactory\AnonymousFunctionFactory;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
|
@ -23,16 +36,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*
|
||||
* @see \Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeMatchToSwitchRector\DowngradeMatchToSwitchRectorTest
|
||||
*/
|
||||
final class DowngradeMatchToSwitchRector extends AbstractRector
|
||||
final class DowngradeMatchToSwitchRector extends AbstractScopeAwareRector
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\Php\PhpVersionProvider
|
||||
* @var \Rector\Php72\NodeFactory\AnonymousFunctionFactory
|
||||
*/
|
||||
private $phpVersionProvider;
|
||||
public function __construct(PhpVersionProvider $phpVersionProvider)
|
||||
private $anonymousFunctionFactory;
|
||||
public function __construct(AnonymousFunctionFactory $anonymousFunctionFactory)
|
||||
{
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
$this->anonymousFunctionFactory = $anonymousFunctionFactory;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
|
@ -54,7 +67,18 @@ class SomeClass
|
|||
{
|
||||
public function run()
|
||||
{
|
||||
$message = ($statusCode === 200 || $statusCode === 300 ? null : $statusCode === 400 ? 'not found' : 'unknown status code';
|
||||
switch ($statusCode) {
|
||||
case 200:
|
||||
case 300:
|
||||
$message = null;
|
||||
break;
|
||||
case 400:
|
||||
$message = 'not found';
|
||||
break;
|
||||
default:
|
||||
$message = 'unknown status code';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
@ -65,57 +89,171 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Match_::class];
|
||||
return [Echo_::class, Expression::class, Return_::class];
|
||||
}
|
||||
/**
|
||||
* @param Match_ $node
|
||||
* @param Echo_|Expression|Return_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Ternary
|
||||
public function refactorWithScope(Node $node, Scope $scope) : ?Node
|
||||
{
|
||||
$reversedMatchArms = \array_reverse($node->arms);
|
||||
$defaultExpr = $this->matchDefaultExpr($node);
|
||||
$defaultExpr = $defaultExpr ?: new ConstFetch(new Name('null'));
|
||||
// @see https://wiki.php.net/rfc/throw_expression
|
||||
// throws expr is not allowed → replace temporarily
|
||||
if ($defaultExpr instanceof Throw_ && $this->phpVersionProvider->provide() < PhpVersion::PHP_80) {
|
||||
$defaultExpr = new ConstFetch(new Name('null'));
|
||||
}
|
||||
$currentTernary = null;
|
||||
foreach ($reversedMatchArms as $reversedMatchArm) {
|
||||
if ($reversedMatchArm->conds === null) {
|
||||
continue;
|
||||
/** @var Match_|null $match */
|
||||
$match = null;
|
||||
$hasChanged = \false;
|
||||
$this->traverseNodesWithCallable($node, function (Node $subNode) use($node, &$match, &$hasChanged, $scope) {
|
||||
if ($subNode instanceof ArrayItem && $subNode->value instanceof Match_ && $this->isEqualScope($subNode->value, $scope)) {
|
||||
$switchCases = $this->createSwitchCasesFromMatchArms($node, $subNode->value);
|
||||
$switch = new Switch_($subNode->value->cond, $switchCases);
|
||||
$subNode->value = new FuncCall($this->anonymousFunctionFactory->create([], [$switch], null));
|
||||
$hasChanged = \true;
|
||||
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
}
|
||||
$cond = $this->createCond($reversedMatchArm->conds, $node);
|
||||
$currentTernary = new Ternary($cond, $reversedMatchArm->body, $currentTernary ?: $defaultExpr);
|
||||
if ($subNode instanceof Arg && $subNode->value instanceof ArrowFunction && $subNode->value->expr instanceof Match_) {
|
||||
$refactoredNode = $this->refactorInArrowFunction($subNode, $subNode->value, $subNode->value->expr);
|
||||
if ($refactoredNode instanceof Node) {
|
||||
$hasChanged = \true;
|
||||
}
|
||||
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
}
|
||||
if ($subNode instanceof Assign && $subNode->expr instanceof ArrowFunction && $subNode->expr->expr instanceof Match_) {
|
||||
$refactoredNode = $this->refactorInArrowFunction($subNode, $subNode->expr, $subNode->expr->expr);
|
||||
if ($refactoredNode instanceof Node) {
|
||||
$hasChanged = \true;
|
||||
}
|
||||
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
}
|
||||
if ($subNode instanceof Expression && $subNode->expr instanceof ArrowFunction && $subNode->expr->expr instanceof Match_) {
|
||||
$refactoredNode = $this->refactorInArrowFunction($subNode, $subNode->expr, $subNode->expr->expr);
|
||||
if ($refactoredNode instanceof Node) {
|
||||
$hasChanged = \true;
|
||||
}
|
||||
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
}
|
||||
if ($subNode instanceof Return_ && $subNode->expr instanceof ArrowFunction && $subNode->expr->expr instanceof Match_) {
|
||||
$refactoredNode = $this->refactorInArrowFunction($subNode, $subNode->expr, $subNode->expr->expr);
|
||||
if ($refactoredNode instanceof Node) {
|
||||
$hasChanged = \true;
|
||||
}
|
||||
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
}
|
||||
if ($subNode instanceof FuncCall && $subNode->name instanceof ArrowFunction && $subNode->name->expr instanceof Match_) {
|
||||
$refactoredNode = $this->refactorInArrowFunction($subNode, $subNode->name, $subNode->name->expr);
|
||||
if ($refactoredNode instanceof Node) {
|
||||
$hasChanged = \true;
|
||||
}
|
||||
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
}
|
||||
if ($subNode instanceof Match_) {
|
||||
$match = $subNode;
|
||||
return NodeTraverser::STOP_TRAVERSAL;
|
||||
}
|
||||
});
|
||||
if ($hasChanged) {
|
||||
return $node;
|
||||
}
|
||||
return $currentTernary;
|
||||
if (!$match instanceof Match_) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isEqualScope($match, $scope)) {
|
||||
return null;
|
||||
}
|
||||
$switchCases = $this->createSwitchCasesFromMatchArms($node, $match);
|
||||
$switch = new Switch_($match->cond, $switchCases);
|
||||
return $switch;
|
||||
}
|
||||
private function matchDefaultExpr(Match_ $match) : ?Expr
|
||||
private function isEqualScope(Match_ $match, ?Scope $containerScope) : bool
|
||||
{
|
||||
foreach ($match->arms as $matchArm) {
|
||||
if ($matchArm->conds === null) {
|
||||
return $matchArm->body;
|
||||
}
|
||||
$matchScope = $match->getAttribute(AttributeKey::SCOPE);
|
||||
if (!$matchScope instanceof Scope) {
|
||||
return \false;
|
||||
}
|
||||
if (!$containerScope instanceof Scope) {
|
||||
return \false;
|
||||
}
|
||||
return $matchScope->getParentScope() === $containerScope->getParentScope();
|
||||
}
|
||||
/**
|
||||
* @param \PhpParser\Node\Arg|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\Assign|\PhpParser\Node\Stmt\Expression|\PhpParser\Node\Stmt\Return_ $containerArrowFunction
|
||||
* @return \PhpParser\Node\Arg|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\Assign|\PhpParser\Node\Stmt\Expression|\PhpParser\Node\Stmt\Return_|null
|
||||
*/
|
||||
private function refactorInArrowFunction($containerArrowFunction, ArrowFunction $arrowFunction, Match_ $match)
|
||||
{
|
||||
$containerArrowFunctionScope = $containerArrowFunction->getAttribute(AttributeKey::SCOPE);
|
||||
if (!$this->isEqualScope($match, $containerArrowFunctionScope)) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Yes, Pass Match_ object itself to Return_
|
||||
* Let the Rule revisit the Match_ after the ArrowFunction converted to Closure_
|
||||
*/
|
||||
$stmts = [new Return_($match)];
|
||||
$closure = $this->anonymousFunctionFactory->create($arrowFunction->params, $stmts, $arrowFunction->returnType, $arrowFunction->static);
|
||||
if ($containerArrowFunction instanceof Arg && $containerArrowFunction->value === $arrowFunction) {
|
||||
$containerArrowFunction->value = $closure;
|
||||
return $containerArrowFunction;
|
||||
}
|
||||
if (($containerArrowFunction instanceof Assign || $containerArrowFunction instanceof Expression || $containerArrowFunction instanceof Return_) && $containerArrowFunction->expr === $arrowFunction) {
|
||||
$containerArrowFunction->expr = $closure;
|
||||
return $containerArrowFunction;
|
||||
}
|
||||
if ($containerArrowFunction instanceof FuncCall && $containerArrowFunction->name === $arrowFunction) {
|
||||
$containerArrowFunction->name = $closure;
|
||||
return $containerArrowFunction;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @param Expr[] $condExprs
|
||||
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\BinaryOp\BooleanOr
|
||||
* @return Case_[]
|
||||
* @param \PhpParser\Node\Stmt\Echo_|\PhpParser\Node\Stmt\Expression|\PhpParser\Node\Stmt\Return_ $node
|
||||
*/
|
||||
private function createCond(array $condExprs, Match_ $match)
|
||||
private function createSwitchCasesFromMatchArms($node, Match_ $match) : array
|
||||
{
|
||||
$cond = null;
|
||||
foreach ($condExprs as $condExpr) {
|
||||
if ($cond instanceof Node) {
|
||||
$cond = new BooleanOr($cond, new Identical($match->cond, $condExpr));
|
||||
$switchCases = [];
|
||||
$parentNode = $match->getAttribute(AttributeKey::PARENT_NODE);
|
||||
foreach ($match->arms as $matchArm) {
|
||||
if (\count((array) $matchArm->conds) > 1) {
|
||||
$lastCase = null;
|
||||
foreach ((array) $matchArm->conds as $matchArmCond) {
|
||||
$lastCase = new Case_($matchArmCond);
|
||||
$switchCases[] = $lastCase;
|
||||
}
|
||||
/** @var Case_ $lastCase */
|
||||
$lastCase->stmts = $this->createSwitchStmts($node, $matchArm, $parentNode);
|
||||
} else {
|
||||
$cond = new Identical($match->cond, $condExpr);
|
||||
$stmts = $this->createSwitchStmts($node, $matchArm, $parentNode);
|
||||
$switchCases[] = new Case_($matchArm->conds[0] ?? null, $stmts);
|
||||
}
|
||||
}
|
||||
if (!$cond instanceof Expr) {
|
||||
throw new ShouldNotHappenException();
|
||||
return $switchCases;
|
||||
}
|
||||
/**
|
||||
* @return Stmt[]
|
||||
* @param \PhpParser\Node\Stmt\Echo_|\PhpParser\Node\Stmt\Expression|\PhpParser\Node\Stmt\Return_ $node
|
||||
*/
|
||||
private function createSwitchStmts($node, MatchArm $matchArm, ?Node $parentNode) : array
|
||||
{
|
||||
$stmts = [];
|
||||
if ($parentNode instanceof ArrayItem) {
|
||||
$stmts[] = new Return_($matchArm->body);
|
||||
} elseif ($matchArm->body instanceof Throw_) {
|
||||
$stmts[] = new Expression($matchArm->body);
|
||||
} elseif ($node instanceof Return_) {
|
||||
$stmts[] = new Return_($matchArm->body);
|
||||
} elseif ($node instanceof Echo_) {
|
||||
$stmts[] = new Echo_([$matchArm->body]);
|
||||
$stmts[] = new Break_();
|
||||
} elseif ($node->expr instanceof Assign) {
|
||||
$stmts[] = new Expression(new Assign($node->expr->var, $matchArm->body));
|
||||
$stmts[] = new Break_();
|
||||
} elseif ($node->expr instanceof Match_) {
|
||||
$stmts[] = new Expression($matchArm->body);
|
||||
$stmts[] = new Break_();
|
||||
} elseif ($node->expr instanceof CallLike) {
|
||||
/** @var FuncCall|MethodCall|New_|NullsafeMethodCall|StaticCall $call */
|
||||
$call = clone $node->expr;
|
||||
$call->args = [new Arg($matchArm->body)];
|
||||
$stmts[] = new Expression($call);
|
||||
$stmts[] = new Break_();
|
||||
}
|
||||
return $cond;
|
||||
return $stmts;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,22 @@ public function NAME(): string
|
|||
throw new \LogicException('The node was expected to be an ArrayNode. This Configuration includes an edge case not supported yet.');
|
||||
}
|
||||
foreach ($node->getChildren() as $child) {
|
||||
\true === $child instanceof ScalarNode ? $this->handleScalarNode($child, $class) : (\true === $child instanceof PrototypedArrayNode ? $this->handlePrototypedArrayNode($child, $class, $namespace) : (\true === $child instanceof VariableNode ? $this->handleVariableNode($child, $class) : (\true === $child instanceof ArrayNode ? $this->handleArrayNode($child, $class, $namespace) : null)));
|
||||
switch (\true) {
|
||||
case $child instanceof ScalarNode:
|
||||
$this->handleScalarNode($child, $class);
|
||||
break;
|
||||
case $child instanceof PrototypedArrayNode:
|
||||
$this->handlePrototypedArrayNode($child, $class, $namespace);
|
||||
break;
|
||||
case $child instanceof VariableNode:
|
||||
$this->handleVariableNode($child, $class);
|
||||
break;
|
||||
case $child instanceof ArrayNode:
|
||||
$this->handleArrayNode($child, $class, $namespace);
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException(\sprintf('Unknown node "%s".', \get_class($child)));
|
||||
}
|
||||
}
|
||||
}
|
||||
private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $namespace) : void
|
||||
|
|
|
@ -97,7 +97,24 @@ class XmlReferenceDumper
|
|||
if ($prototype->hasDefaultValue()) {
|
||||
$prototypeValue = $prototype->getDefaultValue();
|
||||
} else {
|
||||
$prototypeValue = \get_class($prototype) === ScalarNode::class ? 'scalar value' : ($prototype::class === FloatNode::class || $prototype::class === IntegerNode::class ? 'numeric value' : ($prototype::class === BooleanNode::class ? 'true|false' : ($prototype::class === EnumNode::class ? $prototype->getPermissibleValues('|') : 'value')));
|
||||
switch (\get_class($prototype)) {
|
||||
case ScalarNode::class:
|
||||
$prototypeValue = 'scalar value';
|
||||
break;
|
||||
case FloatNode::class:
|
||||
case IntegerNode::class:
|
||||
$prototypeValue = 'numeric value';
|
||||
break;
|
||||
case BooleanNode::class:
|
||||
$prototypeValue = 'true|false';
|
||||
break;
|
||||
case EnumNode::class:
|
||||
$prototypeValue = $prototype->getPermissibleValues('|');
|
||||
break;
|
||||
default:
|
||||
$prototypeValue = 'value';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,18 @@ class DefinitionFileLoader extends FileLoader
|
|||
if (!$reflectionType instanceof \ReflectionNamedType) {
|
||||
throw new \InvalidArgumentException(\sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s").', $parameter->getName(), $path, DefinitionConfigurator::class));
|
||||
}
|
||||
$arguments[] = $reflectionType->getName() === DefinitionConfigurator::class ? $configurator : ($reflectionType->getName() === TreeBuilder::class ? $this->treeBuilder : ($reflectionType->getName() === FileLoader::class || $reflectionType->getName() === self::class ? $this : null));
|
||||
switch ($reflectionType->getName()) {
|
||||
case DefinitionConfigurator::class:
|
||||
$arguments[] = $configurator;
|
||||
break;
|
||||
case TreeBuilder::class:
|
||||
$arguments[] = $this->treeBuilder;
|
||||
break;
|
||||
case FileLoader::class:
|
||||
case self::class:
|
||||
$arguments[] = $this;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$callback(...$arguments);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,17 @@ final class DumpCompletionCommand extends Command
|
|||
$commandName = \basename($fullCommand);
|
||||
$fullCommand = @\realpath($fullCommand) ?: $fullCommand;
|
||||
$shell = $this->guessShell();
|
||||
[$rcFile, $completionFile] = $shell === 'fish' ? ['~/.config/fish/config.fish', "/etc/fish/completions/{$commandName}.fish"] : ($shell === 'zsh' ? ['~/.zshrc', '$fpath[1]/_' . $commandName] : ['~/.bashrc', "/etc/bash_completion.d/{$commandName}"]);
|
||||
switch ($shell) {
|
||||
case 'fish':
|
||||
[$rcFile, $completionFile] = ['~/.config/fish/config.fish', "/etc/fish/completions/{$commandName}.fish"];
|
||||
break;
|
||||
case 'zsh':
|
||||
[$rcFile, $completionFile] = ['~/.zshrc', '$fpath[1]/_' . $commandName];
|
||||
break;
|
||||
default:
|
||||
[$rcFile, $completionFile] = ['~/.bashrc', "/etc/bash_completion.d/{$commandName}"];
|
||||
break;
|
||||
}
|
||||
$supportedShells = \implode(', ', $this->getSupportedShells());
|
||||
$this->setHelp(<<<EOH
|
||||
The <info>%command.name%</> command dumps the shell completion script required
|
||||
|
|
|
@ -31,7 +31,25 @@ abstract class Descriptor implements DescriptorInterface
|
|||
public function describe(OutputInterface $output, object $object, array $options = []) : void
|
||||
{
|
||||
$this->output = $output;
|
||||
\true === $object instanceof InputArgument ? $this->describeInputArgument($object, $options) : (\true === $object instanceof InputOption ? $this->describeInputOption($object, $options) : (\true === $object instanceof InputDefinition ? $this->describeInputDefinition($object, $options) : (\true === $object instanceof Command ? $this->describeCommand($object, $options) : (\true === $object instanceof Application ? $this->describeApplication($object, $options) : null))));
|
||||
switch (\true) {
|
||||
case $object instanceof InputArgument:
|
||||
$this->describeInputArgument($object, $options);
|
||||
break;
|
||||
case $object instanceof InputOption:
|
||||
$this->describeInputOption($object, $options);
|
||||
break;
|
||||
case $object instanceof InputDefinition:
|
||||
$this->describeInputDefinition($object, $options);
|
||||
break;
|
||||
case $object instanceof Command:
|
||||
$this->describeCommand($object, $options);
|
||||
break;
|
||||
case $object instanceof Application:
|
||||
$this->describeApplication($object, $options);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException(\sprintf('Object of type "%s" is not describable.', \get_debug_type($object)));
|
||||
}
|
||||
}
|
||||
protected function write(string $content, bool $decorated = \false) : void
|
||||
{
|
||||
|
|
|
@ -48,7 +48,18 @@ final class Dumper
|
|||
};
|
||||
} else {
|
||||
$this->handler = function ($var) : string {
|
||||
return \true === (null === $var) ? 'null' : (\true === (\true === $var) ? 'true' : (\true === (\false === $var) ? 'false' : (\true === \is_string($var) ? '"' . $var . '"' : \rtrim(\print_r($var, \true)))));
|
||||
switch (\true) {
|
||||
case null === $var:
|
||||
return 'null';
|
||||
case \true === $var:
|
||||
return 'true';
|
||||
case \false === $var:
|
||||
return 'false';
|
||||
case \is_string($var):
|
||||
return '"' . $var . '"';
|
||||
default:
|
||||
return \rtrim(\print_r($var, \true));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -511,7 +511,16 @@ final class ProgressBar
|
|||
}
|
||||
private function determineBestFormat() : string
|
||||
{
|
||||
return $this->output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE ? $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX : ($this->output->getVerbosity() === OutputInterface::VERBOSITY_VERY_VERBOSE ? $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX : ($this->output->getVerbosity() === OutputInterface::VERBOSITY_DEBUG ? $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX : ($this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX)));
|
||||
switch ($this->output->getVerbosity()) {
|
||||
case OutputInterface::VERBOSITY_VERBOSE:
|
||||
return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX;
|
||||
case OutputInterface::VERBOSITY_VERY_VERBOSE:
|
||||
return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX;
|
||||
case OutputInterface::VERBOSITY_DEBUG:
|
||||
return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX;
|
||||
default:
|
||||
return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX;
|
||||
}
|
||||
}
|
||||
private static function initPlaceholderFormatters() : array
|
||||
{
|
||||
|
|
|
@ -181,7 +181,15 @@ class ProgressIndicator
|
|||
}
|
||||
private function determineBestFormat() : string
|
||||
{
|
||||
return $this->output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE ? $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi' : ($this->output->getVerbosity() === OutputInterface::VERBOSITY_VERY_VERBOSE || $this->output->getVerbosity() === OutputInterface::VERBOSITY_DEBUG ? $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi' : ($this->output->isDecorated() ? 'normal' : 'normal_no_ansi'));
|
||||
switch ($this->output->getVerbosity()) {
|
||||
case OutputInterface::VERBOSITY_VERBOSE:
|
||||
return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
|
||||
case OutputInterface::VERBOSITY_VERY_VERBOSE:
|
||||
case OutputInterface::VERBOSITY_DEBUG:
|
||||
return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
|
||||
default:
|
||||
return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Overwrites a previous message to the output.
|
||||
|
|
|
@ -32,11 +32,25 @@ class AnsiColorMode
|
|||
$r = $color >> 16 & 255;
|
||||
$g = $color >> 8 & 255;
|
||||
$b = $color & 255;
|
||||
return $this === self::Ansi4 ? (string) $this->convertFromRGB($r, $g, $b) : ($this === self::Ansi8 ? '8;5;' . (string) $this->convertFromRGB($r, $g, $b) : ($this === self::Ansi24 ? \sprintf('8;2;%d;%d;%d', $r, $g, $b) : null));
|
||||
switch ($this) {
|
||||
case self::Ansi4:
|
||||
return (string) $this->convertFromRGB($r, $g, $b);
|
||||
case self::Ansi8:
|
||||
return '8;5;' . (string) $this->convertFromRGB($r, $g, $b);
|
||||
case self::Ansi24:
|
||||
return \sprintf('8;2;%d;%d;%d', $r, $g, $b);
|
||||
}
|
||||
}
|
||||
private function convertFromRGB(int $r, int $g, int $b) : int
|
||||
{
|
||||
return $this === self::Ansi4 ? $this->degradeHexColorToAnsi4($r, $g, $b) : ($this === self::Ansi8 ? $this->degradeHexColorToAnsi8($r, $g, $b) : null);
|
||||
switch ($this) {
|
||||
case self::Ansi4:
|
||||
return $this->degradeHexColorToAnsi4($r, $g, $b);
|
||||
case self::Ansi8:
|
||||
return $this->degradeHexColorToAnsi8($r, $g, $b);
|
||||
default:
|
||||
throw new InvalidArgumentException("RGB cannot be converted to {$this->name}.");
|
||||
}
|
||||
}
|
||||
private function degradeHexColorToAnsi4(int $r, int $g, int $b) : int
|
||||
{
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -43,7 +43,14 @@ class ServiceLocator extends BaseServiceLocator
|
|||
*/
|
||||
public function get(string $id)
|
||||
{
|
||||
return \count($this->serviceMap[$id] ?? []) === 0 ? parent::get($id) : (\count($this->serviceMap[$id] ?? []) === 1 ? $this->serviceMap[$id][0] : ($this->factory)(...$this->serviceMap[$id]));
|
||||
switch (\count($this->serviceMap[$id] ?? [])) {
|
||||
case 0:
|
||||
return parent::get($id);
|
||||
case 1:
|
||||
return $this->serviceMap[$id][0];
|
||||
default:
|
||||
return ($this->factory)(...$this->serviceMap[$id]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -39,8 +39,31 @@ class Autowire
|
|||
throw new LogicException('#[Autowire] attribute must declare exactly one of $service, $expression, or $value.');
|
||||
}
|
||||
if (null !== $value && \strncmp($value, '@', \strlen('@')) === 0) {
|
||||
\true === (\strncmp($value, '@@', \strlen('@@')) === 0) ? $value = \substr($value, 1) : (\true === (\strncmp($value, '@=', \strlen('@=')) === 0) ? $expression = \substr($value, 2) : ($service = \substr($value, 1)));
|
||||
switch (\true) {
|
||||
case \strncmp($value, '@@', \strlen('@@')) === 0:
|
||||
$value = \substr($value, 1);
|
||||
break;
|
||||
case \strncmp($value, '@=', \strlen('@=')) === 0:
|
||||
$expression = \substr($value, 2);
|
||||
break;
|
||||
default:
|
||||
$service = \substr($value, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (\true) {
|
||||
case null !== $service:
|
||||
$this->value = new Reference($service);
|
||||
break;
|
||||
case null !== $expression:
|
||||
if (!\class_exists(Expression::class)) {
|
||||
throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
|
||||
}
|
||||
$this->value = new Expression($expression);
|
||||
break;
|
||||
case null !== $value:
|
||||
$this->value = $value;
|
||||
break;
|
||||
}
|
||||
$this->value = \true === (null !== $service) ? new Reference($service) : (\true === (null !== $expression) ? \class_exists(Expression::class) ? new Expression($expression) : throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".') : (\true === (null !== $value) ? $value : null));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,20 @@ class IniFileLoader extends FileLoader
|
|||
$value = '""' === \substr_replace($v, '', 1, -1) ? \substr($v, 1, -1) : $v;
|
||||
}
|
||||
$lowercaseValue = \strtolower($value);
|
||||
return \true === \defined($value) ? \constant($value) : (\true === ('yes' === $lowercaseValue) || \true === ('on' === $lowercaseValue) ? \true : (\true === ('no' === $lowercaseValue) || \true === ('off' === $lowercaseValue) || \true === ('none' === $lowercaseValue) ? \false : (\true === (isset($value[1]) && ("'" === $value[0] && "'" === $value[\strlen($value) - 1] || '"' === $value[0] && '"' === $value[\strlen($value) - 1])) ? \substr($value, 1, -1) : XmlUtils::phpize($value))));
|
||||
switch (\true) {
|
||||
case \defined($value):
|
||||
return \constant($value);
|
||||
case 'yes' === $lowercaseValue:
|
||||
case 'on' === $lowercaseValue:
|
||||
return \true;
|
||||
case 'no' === $lowercaseValue:
|
||||
case 'off' === $lowercaseValue:
|
||||
case 'none' === $lowercaseValue:
|
||||
return \false;
|
||||
case isset($value[1]) && ("'" === $value[0] && "'" === $value[\strlen($value) - 1] || '"' === $value[0] && '"' === $value[\strlen($value) - 1]):
|
||||
return \substr($value, 1, -1);
|
||||
default:
|
||||
return XmlUtils::phpize($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,7 +438,14 @@ class XmlFileLoader extends FileLoader
|
|||
} else {
|
||||
$arg = $this->getArgumentsAsPhp($arg, $name, $file);
|
||||
}
|
||||
$arguments[$key] = $type === 'service_closure' ? new ServiceClosureArgument($arg) : ($type === 'closure' ? (new Definition('Closure'))->setFactory(['Closure', 'fromCallable'])->addArgument($arg) : null);
|
||||
switch ($type) {
|
||||
case 'service_closure':
|
||||
$arguments[$key] = new ServiceClosureArgument($arg);
|
||||
break;
|
||||
case 'closure':
|
||||
$arguments[$key] = (new Definition('Closure'))->setFactory(['Closure', 'fromCallable'])->addArgument($arg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'service_locator':
|
||||
$arg = $this->getArgumentsAsPhp($arg, $name, $file);
|
||||
|
|
|
@ -51,6 +51,19 @@ class Comparator
|
|||
*/
|
||||
public function test($test) : bool
|
||||
{
|
||||
return $this->operator === '>' ? $test > $this->target : ($this->operator === '>=' ? $test >= $this->target : ($this->operator === '<' ? $test < $this->target : ($this->operator === '<=' ? $test <= $this->target : ($this->operator === '!=' ? $test != $this->target : $test == $this->target))));
|
||||
switch ($this->operator) {
|
||||
case '>':
|
||||
return $test > $this->target;
|
||||
case '>=':
|
||||
return $test >= $this->target;
|
||||
case '<':
|
||||
return $test < $this->target;
|
||||
case '<=':
|
||||
return $test <= $this->target;
|
||||
case '!=':
|
||||
return $test != $this->target;
|
||||
default:
|
||||
return $test == $this->target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,13 @@ class ProcessTimedOutException extends RuntimeException
|
|||
}
|
||||
public function getExceededTimeout() : ?float
|
||||
{
|
||||
return $this->timeoutType === self::TYPE_GENERAL ? $this->process->getTimeout() : ($this->timeoutType === self::TYPE_IDLE ? $this->process->getIdleTimeout() : null);
|
||||
switch ($this->timeoutType) {
|
||||
case self::TYPE_GENERAL:
|
||||
return $this->process->getTimeout();
|
||||
case self::TYPE_IDLE:
|
||||
return $this->process->getIdleTimeout();
|
||||
default:
|
||||
throw new \LogicException(\sprintf('Unknown timeout type "%d".', $this->timeoutType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue