update patch 1
This commit is contained in:
+4
-3
@@ -12,10 +12,11 @@
|
||||
namespace Psy\CodeCleaner;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\ArrayItem;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
// @todo Switch to PhpParser\Node\ArrayItem once we drop support for PHP-Parser 4.x
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
// @todo Drop PhpParser\Node\Expr\ArrayItem once we drop support for PHP-Parser 4.x
|
||||
use PhpParser\Node\Expr\ArrayItem as LegacyArrayItem;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\List_;
|
||||
@@ -81,7 +82,7 @@ class ListPass extends CodeCleanerPass
|
||||
*/
|
||||
private static function isValidArrayItem(Node $item): bool
|
||||
{
|
||||
$value = ($item instanceof ArrayItem) ? $item->value : $item;
|
||||
$value = ($item instanceof ArrayItem || $item instanceof LegacyArrayItem) ? $item->value : $item;
|
||||
|
||||
while ($value instanceof ArrayDimFetch || $value instanceof PropertyFetch) {
|
||||
$value = $value->var;
|
||||
|
||||
+9
-2
@@ -13,6 +13,8 @@ namespace Psy\CodeCleaner;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Scalar\DNumber;
|
||||
use PhpParser\Node\Scalar\Float_;
|
||||
use PhpParser\Node\Scalar\Int_;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Stmt\Break_;
|
||||
use PhpParser\Node\Stmt\Continue_;
|
||||
@@ -70,8 +72,13 @@ class LoopContextPass extends CodeCleanerPass
|
||||
throw new FatalErrorException($msg, 0, \E_ERROR, null, $node->getStartLine());
|
||||
}
|
||||
|
||||
// @todo Rename to Int_ and Float_ once we drop support for PHP-Parser 4.x
|
||||
if ($node->num instanceof LNumber || $node->num instanceof DNumber) {
|
||||
// @todo Remove LNumber and DNumber once we drop support for PHP-Parser 4.x
|
||||
if (
|
||||
$node->num instanceof LNumber ||
|
||||
$node->num instanceof DNumber ||
|
||||
$node->num instanceof Int_ ||
|
||||
$node->num instanceof Float_
|
||||
) {
|
||||
$num = $node->num->value;
|
||||
if ($node->num instanceof DNumber || $num < 1) {
|
||||
$msg = \sprintf("'%s' operator accepts only positive numbers", $operator);
|
||||
|
||||
@@ -21,6 +21,7 @@ use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\VariadicPlaceholder;
|
||||
use Psy\Exception\FatalErrorException;
|
||||
|
||||
/**
|
||||
@@ -61,6 +62,10 @@ class PassableByReferencePass extends CodeCleanerPass
|
||||
|
||||
$args = [];
|
||||
foreach ($node->args as $position => $arg) {
|
||||
if ($arg instanceof VariadicPlaceholder) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$args[$arg->name !== null ? $arg->name->name : $position] = $arg;
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -16,6 +16,7 @@ use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\Include_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Name\FullyQualified as FullyQualifiedName;
|
||||
use PhpParser\Node\Scalar\Int_;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use Psy\Exception\ErrorException;
|
||||
use Psy\Exception\FatalErrorException;
|
||||
@@ -49,11 +50,15 @@ class RequirePass extends CodeCleanerPass
|
||||
*
|
||||
* $foo = require \Psy\CodeCleaner\RequirePass::resolve($bar)
|
||||
*/
|
||||
// @todo Rename LNumber to Int_ once we drop support for PHP-Parser 4.x
|
||||
// @todo Remove LNumber once we drop support for PHP-Parser 4.x
|
||||
$arg = \class_exists('PhpParser\Node\Scalar\Int_') ?
|
||||
new Int_($origNode->getStartLine()) :
|
||||
new LNumber($origNode->getStartLine());
|
||||
|
||||
$node->expr = new StaticCall(
|
||||
new FullyQualifiedName(self::class),
|
||||
'resolve',
|
||||
[new Arg($origNode->expr), new Arg(new LNumber($origNode->getStartLine()))],
|
||||
[new Arg($origNode->expr), new Arg($arg)],
|
||||
$origNode->getAttributes()
|
||||
);
|
||||
|
||||
|
||||
+7
-5
@@ -13,6 +13,7 @@ namespace Psy\CodeCleaner;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\DeclareItem;
|
||||
use PhpParser\Node\Scalar\Int_;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Stmt\Declare_;
|
||||
use PhpParser\Node\Stmt\DeclareDeclare;
|
||||
@@ -63,8 +64,8 @@ class StrictTypesPass extends CodeCleanerPass
|
||||
foreach ($node->declares as $declare) {
|
||||
if ($declare->key->toString() === 'strict_types') {
|
||||
$value = $declare->value;
|
||||
// @todo Rename LNumber to Int_ once we drop support for PHP-Parser 4.x
|
||||
if (!$value instanceof LNumber || ($value->value !== 0 && $value->value !== 1)) {
|
||||
// @todo Remove LNumber once we drop support for PHP-Parser 4.x
|
||||
if ((!$value instanceof LNumber && !$value instanceof Int_) || ($value->value !== 0 && $value->value !== 1)) {
|
||||
throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, \E_ERROR, null, $node->getStartLine());
|
||||
}
|
||||
|
||||
@@ -78,10 +79,11 @@ class StrictTypesPass extends CodeCleanerPass
|
||||
$first = \reset($nodes);
|
||||
if (!$first instanceof Declare_) {
|
||||
// @todo Switch to PhpParser\Node\DeclareItem once we drop support for PHP-Parser 4.x
|
||||
// @todo Rename LNumber to Int_ once we drop support for PHP-Parser 4.x
|
||||
// @todo Remove LNumber once we drop support for PHP-Parser 4.x
|
||||
$arg = \class_exists('PhpParser\Node\Scalar\Int_') ? new Int_(1) : new LNumber(1);
|
||||
$declareItem = \class_exists('PhpParser\Node\DeclareItem') ?
|
||||
new DeclareItem('strict_types', new LNumber(1)) :
|
||||
new DeclareDeclare('strict_types', new LNumber(1));
|
||||
new DeclareItem('strict_types', $arg) :
|
||||
new DeclareDeclare('strict_types', $arg);
|
||||
$declare = new Declare_([$declareItem]);
|
||||
\array_unshift($nodes, $declare);
|
||||
}
|
||||
|
||||
+3
-1
@@ -140,9 +140,11 @@ abstract class Command extends BaseCommand
|
||||
$default = '';
|
||||
}
|
||||
|
||||
$name = $argument->getName();
|
||||
$pad = \str_pad('', $max - \strlen($name));
|
||||
$description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $argument->getDescription());
|
||||
|
||||
$messages[] = \sprintf(" <info>%-{$max}s</info> %s%s", $argument->getName(), $description, $default);
|
||||
$messages[] = \sprintf(' <info>%s</info>%s %s%s', $name, $pad, $description, $default);
|
||||
}
|
||||
|
||||
$messages[] = '';
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ class ShowCommand extends ReflectingCommand
|
||||
Show the code for an object, class, constant, method or property, or the context
|
||||
of the last exception.
|
||||
|
||||
<return>cat --ex</return> defaults to showing the lines surrounding the location of the last
|
||||
<return>show --ex</return> defaults to showing the lines surrounding the location of the last
|
||||
exception. Invoking it more than once travels up the exception's stack trace,
|
||||
and providing a number shows the context of the given index of the trace.
|
||||
|
||||
|
||||
Vendored
+10
-10
@@ -63,10 +63,8 @@ class ConfigPaths
|
||||
|
||||
/**
|
||||
* Get the current home directory.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function homeDir()
|
||||
public function homeDir(): ?string
|
||||
{
|
||||
if ($homeDir = $this->getEnv('HOME') ?: $this->windowsHomeDir()) {
|
||||
return \strtr($homeDir, '\\', '/');
|
||||
@@ -75,7 +73,7 @@ class ConfigPaths
|
||||
return null;
|
||||
}
|
||||
|
||||
private function windowsHomeDir()
|
||||
private function windowsHomeDir(): ?string
|
||||
{
|
||||
if (\defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||
$homeDrive = $this->getEnv('HOMEDRIVE');
|
||||
@@ -88,13 +86,16 @@ class ConfigPaths
|
||||
return null;
|
||||
}
|
||||
|
||||
private function homeConfigDir()
|
||||
private function homeConfigDir(): ?string
|
||||
{
|
||||
if ($homeConfigDir = $this->getEnv('XDG_CONFIG_HOME')) {
|
||||
return $homeConfigDir;
|
||||
}
|
||||
|
||||
$homeDir = $this->homeDir();
|
||||
if ($homeDir === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $homeDir === '/' ? $homeDir.'.config' : $homeDir.'/.config';
|
||||
}
|
||||
@@ -130,7 +131,7 @@ class ConfigPaths
|
||||
*
|
||||
* @see self::homeConfigDir
|
||||
*/
|
||||
public function currentConfigDir(): string
|
||||
public function currentConfigDir(): ?string
|
||||
{
|
||||
if ($this->configDir !== null) {
|
||||
return $this->configDir;
|
||||
@@ -144,7 +145,7 @@ class ConfigPaths
|
||||
}
|
||||
}
|
||||
|
||||
return $configDirs[0];
|
||||
return $configDirs[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,10 +232,8 @@ class ConfigPaths
|
||||
* If $PATH is unset/empty it defaults to '/usr/sbin:/usr/bin:/sbin:/bin'.
|
||||
*
|
||||
* @param string $command the executable to locate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function which($command)
|
||||
public function which($command): ?string
|
||||
{
|
||||
foreach ($this->pathDirs() as $path) {
|
||||
$fullpath = $path.\DIRECTORY_SEPARATOR.$command;
|
||||
@@ -259,6 +258,7 @@ class ConfigPaths
|
||||
*/
|
||||
private function allDirNames(array $baseDirs): array
|
||||
{
|
||||
$baseDirs = \array_filter($baseDirs);
|
||||
$dirs = \array_map(function ($dir) {
|
||||
return \strtr($dir, '\\', '/').'/psysh';
|
||||
}, $baseDirs);
|
||||
|
||||
+28
-10
@@ -623,16 +623,18 @@ class Configuration
|
||||
/**
|
||||
* Get the shell's temporary directory location.
|
||||
*
|
||||
* Defaults to `/psysh` inside the system's temp dir unless explicitly
|
||||
* Defaults to `/psysh` inside the system's temp dir unless explicitly
|
||||
* overridden.
|
||||
*
|
||||
* @throws RuntimeException if no temporary directory is set and it is not possible to create one
|
||||
*
|
||||
* @param bool $create False to suppress directory creation if it does not exist
|
||||
*/
|
||||
public function getRuntimeDir(): string
|
||||
public function getRuntimeDir($create = true): string
|
||||
{
|
||||
$runtimeDir = $this->configPaths->runtimeDir();
|
||||
|
||||
if (!\is_dir($runtimeDir)) {
|
||||
if ($create && !\is_dir($runtimeDir)) {
|
||||
if (!@\mkdir($runtimeDir, 0700, true)) {
|
||||
throw new RuntimeException(\sprintf('Unable to create PsySH runtime directory. Make sure PHP is able to write to %s in order to continue.', \dirname($runtimeDir)));
|
||||
}
|
||||
@@ -657,7 +659,7 @@ class Configuration
|
||||
* Defaults to `/history` inside the shell's base config dir unless
|
||||
* explicitly overridden.
|
||||
*/
|
||||
public function getHistoryFile(): string
|
||||
public function getHistoryFile(): ?string
|
||||
{
|
||||
if (isset($this->historyFile)) {
|
||||
return $this->historyFile;
|
||||
@@ -674,7 +676,12 @@ class Configuration
|
||||
$this->setHistoryFile($files[0]);
|
||||
} else {
|
||||
// fallback: create our own history file
|
||||
$this->setHistoryFile($this->configPaths->currentConfigDir().'/psysh_history');
|
||||
$configDir = $this->configPaths->currentConfigDir();
|
||||
if ($configDir === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->setHistoryFile($configDir.'/psysh_history');
|
||||
}
|
||||
|
||||
return $this->historyFile;
|
||||
@@ -1023,7 +1030,11 @@ class Configuration
|
||||
*/
|
||||
public function setErrorLoggingLevel($errorLoggingLevel)
|
||||
{
|
||||
$this->errorLoggingLevel = (\E_ALL | \E_STRICT) & $errorLoggingLevel;
|
||||
if (\PHP_VERSION_ID < 80400) {
|
||||
$this->errorLoggingLevel = (\E_ALL | \E_STRICT) & $errorLoggingLevel;
|
||||
} else {
|
||||
$this->errorLoggingLevel = \E_ALL & $errorLoggingLevel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1263,9 +1274,11 @@ class Configuration
|
||||
// let's not use it by default.
|
||||
//
|
||||
// See https://github.com/bobthecow/psysh/issues/778
|
||||
$link = @\readlink($less);
|
||||
if ($link !== false && \strpos($link, 'busybox') !== false) {
|
||||
return false;
|
||||
if (@\is_link($less)) {
|
||||
$link = @\readlink($less);
|
||||
if ($link !== false && \strpos($link, 'busybox') !== false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->pager = $less.' -R -F -X';
|
||||
@@ -1646,7 +1659,12 @@ class Configuration
|
||||
*/
|
||||
public function getUpdateCheckCacheFile()
|
||||
{
|
||||
return ConfigPaths::touchFileWithMkdir($this->configPaths->currentConfigDir().'/update_check.json');
|
||||
$configDir = $this->configPaths->currentConfigDir();
|
||||
if ($configDir === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ConfigPaths::touchFileWithMkdir($configDir.'/update_check.json');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-4
@@ -37,10 +37,6 @@ class ErrorException extends \ErrorException implements Exception
|
||||
}
|
||||
|
||||
switch ($severity) {
|
||||
case \E_STRICT:
|
||||
$type = 'Strict error';
|
||||
break;
|
||||
|
||||
case \E_NOTICE:
|
||||
case \E_USER_NOTICE:
|
||||
$type = 'Notice';
|
||||
@@ -63,6 +59,10 @@ class ErrorException extends \ErrorException implements Exception
|
||||
break;
|
||||
|
||||
default:
|
||||
if (\PHP_VERSION_ID < 80400 && $severity === \E_STRICT) {
|
||||
$type = 'Strict error';
|
||||
break;
|
||||
}
|
||||
$type = 'Error';
|
||||
break;
|
||||
}
|
||||
|
||||
+4
@@ -48,6 +48,10 @@ class Libedit extends GNUReadline
|
||||
*/
|
||||
public function listHistory(): array
|
||||
{
|
||||
if ($this->historyFile === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$history = \file_get_contents($this->historyFile);
|
||||
if (!$history) {
|
||||
return [];
|
||||
|
||||
Vendored
+55
-11
@@ -50,7 +50,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
class Shell extends Application
|
||||
{
|
||||
const VERSION = 'v0.12.4';
|
||||
const VERSION = 'v0.12.5';
|
||||
|
||||
private $config;
|
||||
private $cleaner;
|
||||
@@ -214,7 +214,7 @@ class Shell extends Application
|
||||
new Command\TraceCommand(),
|
||||
new Command\BufferCommand(),
|
||||
new Command\ClearCommand(),
|
||||
new Command\EditCommand($this->config->getRuntimeDir()),
|
||||
new Command\EditCommand($this->config->getRuntimeDir(false)),
|
||||
// new Command\PsyVersionCommand(),
|
||||
$sudo,
|
||||
$hist,
|
||||
@@ -919,17 +919,58 @@ class Shell extends Application
|
||||
|
||||
$input = new ShellInput(\str_replace('\\', '\\\\', \rtrim($input, " \t\n\r\0\x0B;")));
|
||||
|
||||
if ($input->hasParameterOption(['--help', '-h'])) {
|
||||
$helpCommand = $this->get('help');
|
||||
if (!$helpCommand instanceof Command\HelpCommand) {
|
||||
throw new RuntimeException('Invalid help command instance');
|
||||
}
|
||||
$helpCommand->setCommand($command);
|
||||
if (!$input->hasParameterOption(['--help', '-h'])) {
|
||||
try {
|
||||
return $command->run($input, $this->output);
|
||||
} catch (\Exception $e) {
|
||||
if (!self::needsInputHelp($e)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $helpCommand->run(new StringInput(''), $this->output);
|
||||
$this->writeException($e);
|
||||
|
||||
$this->output->writeln('--');
|
||||
if (!$this->config->theme()->compact()) {
|
||||
$this->output->writeln('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $command->run($input, $this->output);
|
||||
$helpCommand = $this->get('help');
|
||||
if (!$helpCommand instanceof Command\HelpCommand) {
|
||||
throw new RuntimeException('Invalid help command instance');
|
||||
}
|
||||
$helpCommand->setCommand($command);
|
||||
|
||||
return $helpCommand->run(new StringInput(''), $this->output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given input error would benefit from --help.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function needsInputHelp(\Exception $e): bool
|
||||
{
|
||||
if (!($e instanceof \RuntimeException || $e instanceof SymfonyConsoleException)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$inputErrors = [
|
||||
'Not enough arguments',
|
||||
'option does not accept a value',
|
||||
'option does not exist',
|
||||
'option requires a value',
|
||||
];
|
||||
|
||||
$msg = $e->getMessage();
|
||||
foreach ($inputErrors as $errorMsg) {
|
||||
if (\strpos($msg, $errorMsg) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1261,10 +1302,13 @@ class Shell extends Application
|
||||
case \E_USER_NOTICE:
|
||||
case \E_USER_DEPRECATED:
|
||||
case \E_DEPRECATED:
|
||||
case \E_STRICT:
|
||||
return 'warning';
|
||||
|
||||
default:
|
||||
if ((\PHP_VERSION_ID < 80400) && $severity === \E_STRICT) {
|
||||
return 'warning';
|
||||
}
|
||||
|
||||
return 'error';
|
||||
}
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ class AutoCompleter
|
||||
$matches = [];
|
||||
foreach ($this->matchers as $matcher) {
|
||||
if ($matcher->hasMatched($tokens)) {
|
||||
$matches = \array_merge($matcher->getMatches($tokens), $matches);
|
||||
$matches = \array_merge($matcher->getMatches($tokens, $info), $matches);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user