Updated Rector to commit 205df9013af5e05034441aa6088599532f5fef05

205df9013a [TypeDeclaration] Add Encapsed string support to AlwaysStrictScalarExprAnalyzer (#4382)
This commit is contained in:
Tomas Votruba 2023-06-30 11:59:36 +00:00
parent f77ffbaf00
commit 5db0586b82
26 changed files with 560 additions and 87 deletions

View File

@ -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) {

2
vendor/autoload.php vendored
View File

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

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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()
{
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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
{

View File

@ -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));
}
};
}
}

View File

@ -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
{

View File

@ -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.

View File

@ -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

View File

@ -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}

View File

@ -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));
}
}

View File

@ -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);
}
}
}

View File

@ -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);

View 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;
}
}
}

View File

@ -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));
}
}
}