minor #32812 [ErrorHandler] Added type declarations where possible (Tobias Weichart)

This PR was squashed before being merged into the 4.4 branch (closes #32812).

Discussion
----------

[ErrorHandler] Added type declarations where possible

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

I've added type declarations where possible (method parameters & return types). DocBlocks were replaced too if the type declarations made them redundant.
Void returns were replaced whenever necessary.
Also on one occasion the setting of the exceptionHandler was replaced by a function call, which did practically the same thing.

Commits
-------

ab6aae1a29 [ErrorHandler] Added type declarations where possible
This commit is contained in:
Nicolas Grekas 2019-07-31 17:58:23 +02:00
commit 67d7dda736
7 changed files with 43 additions and 59 deletions

View File

@ -22,12 +22,12 @@ class BufferingLogger extends AbstractLogger
{
private $logs = [];
public function log($level, $message, array $context = [])
public function log($level, $message, array $context = []): void
{
$this->logs[] = [$level, $message, $context];
}
public function cleanLogs()
public function cleanLogs(): array
{
$logs = $this->logs;
$this->logs = [];

View File

@ -24,11 +24,8 @@ class Debug
* Enables the debug tools.
*
* This method registers an error handler and an exception handler.
*
* @param int $errorReportingLevel The level of error reporting you want
* @param bool $displayErrors Whether to display errors (for development) or just log them (for production)
*/
public static function enable($errorReportingLevel = E_ALL, $displayErrors = true)
public static function enable(int $errorReportingLevel = E_ALL, bool $displayErrors = true): void
{
if (static::$enabled) {
return;

View File

@ -75,7 +75,7 @@ class DebugClassLoader
*
* @return callable The wrapped class loader
*/
public function getClassLoader()
public function getClassLoader(): callable
{
return $this->classLoader;
}
@ -83,7 +83,7 @@ class DebugClassLoader
/**
* Wraps all autoloaders.
*/
public static function enable()
public static function enable(): void
{
// Ensures we don't hit https://bugs.php.net/42098
class_exists('Symfony\Component\ErrorHandler\ErrorHandler');
@ -109,7 +109,7 @@ class DebugClassLoader
/**
* Disables the wrapping.
*/
public static function disable()
public static function disable(): void
{
if (!\is_array($functions = spl_autoload_functions())) {
return;
@ -128,29 +128,24 @@ class DebugClassLoader
}
}
/**
* @return string|null
*/
public function findFile($class)
public function findFile(string $class): ?string
{
return $this->isFinder ? $this->classLoader[0]->findFile($class) ?: null : null;
return $this->isFinder ? ($this->classLoader[0]->findFile($class) ?: null) : null;
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
*
* @throws \RuntimeException
*/
public function loadClass($class)
public function loadClass(string $class): void
{
$e = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
try {
if ($this->isFinder && !isset($this->loaded[$class])) {
$this->loaded[$class] = true;
if (!$file = $this->classLoader[0]->findFile($class) ?: false) {
if (!$file = $this->classLoader[0]->findFile($class) ?: '') {
// no-op
} elseif (\function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file)) {
include $file;
@ -161,7 +156,7 @@ class DebugClassLoader
}
} else {
($this->classLoader)($class);
$file = false;
$file = '';
}
} finally {
error_reporting($e);
@ -170,7 +165,7 @@ class DebugClassLoader
$this->checkClass($class, $file);
}
private function checkClass($class, $file = null)
private function checkClass(string $class, string $file = null): void
{
$exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);
@ -218,7 +213,7 @@ class DebugClassLoader
}
}
public function checkAnnotations(\ReflectionClass $refl, $class)
public function checkAnnotations(\ReflectionClass $refl, string $class): array
{
$deprecations = [];
@ -395,7 +390,7 @@ class DebugClassLoader
return $deprecations;
}
public function checkCase(\ReflectionClass $refl, $file, $class)
public function checkCase(\ReflectionClass $refl, string $file, string $class): ?array
{
$real = explode('\\', $class.strrchr($file, '.'));
$tail = explode(\DIRECTORY_SEPARATOR, str_replace('/', \DIRECTORY_SEPARATOR, $file));
@ -411,7 +406,7 @@ class DebugClassLoader
array_splice($tail, 0, $i + 1);
if (!$tail) {
return;
return null;
}
$tail = \DIRECTORY_SEPARATOR.implode(\DIRECTORY_SEPARATOR, $tail);
@ -427,12 +422,14 @@ class DebugClassLoader
) {
return [substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)];
}
return null;
}
/**
* `realpath` on MacOSX doesn't normalize the case of characters.
*/
private function darwinRealpath($real)
private function darwinRealpath(string $real): string
{
$i = 1 + strrpos($real, '/');
$file = substr($real, $i);
@ -504,7 +501,7 @@ class DebugClassLoader
*
* @return string[]
*/
private function getOwnInterfaces($class, $parent)
private function getOwnInterfaces(string $class, $parent): array
{
$ownInterfaces = class_implements($class, false);

View File

@ -98,20 +98,15 @@ class ErrorHandler
private $bootstrappingLogger;
private static $reservedMemory;
private static $toStringException = null;
private static $toStringException;
private static $silencedErrorCache = [];
private static $silencedErrorCount = 0;
private static $exitCode = 0;
/**
* Registers the error handler.
*
* @param self|null $handler The handler to register
* @param bool $replace Whether to replace or not any existing handler
*
* @return self The registered error handler
*/
public static function register(self $handler = null, $replace = true)
public static function register(self $handler = null, bool $replace = true): self
{
if (null === self::$reservedMemory) {
self::$reservedMemory = str_repeat('x', 10240);
@ -175,7 +170,7 @@ class ErrorHandler
* @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
* @param bool $replace Whether to replace or not any existing logger
*/
public function setDefaultLogger(LoggerInterface $logger, $levels = E_ALL, $replace = false)
public function setDefaultLogger(LoggerInterface $logger, $levels = E_ALL, bool $replace = false): void
{
$loggers = [];
@ -209,7 +204,7 @@ class ErrorHandler
*
* @throws \InvalidArgumentException
*/
public function setLoggers(array $loggers)
public function setLoggers(array $loggers): array
{
$prevLogged = $this->loggedErrors;
$prev = $this->loggers;
@ -256,11 +251,11 @@ class ErrorHandler
/**
* Sets a user exception handler.
*
* @param callable $handler A handler that will be called on Exception
* @param callable|null $handler A handler that will be called on Exception
*
* @return callable|null The previous exception handler
*/
public function setExceptionHandler(callable $handler = null)
public function setExceptionHandler(?callable $handler): ?callable
{
$prev = $this->exceptionHandler;
$this->exceptionHandler = $handler;
@ -276,7 +271,7 @@ class ErrorHandler
*
* @return int The previous value
*/
public function throwAt($levels, $replace = false)
public function throwAt(int $levels, bool $replace = false): int
{
$prev = $this->thrownErrors;
$this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
@ -296,7 +291,7 @@ class ErrorHandler
*
* @return int The previous value
*/
public function scopeAt($levels, $replace = false)
public function scopeAt(int $levels, bool $replace = false): int
{
$prev = $this->scopedErrors;
$this->scopedErrors = (int) $levels;
@ -315,7 +310,7 @@ class ErrorHandler
*
* @return int The previous value
*/
public function traceAt($levels, $replace = false)
public function traceAt(int $levels, bool $replace = false): int
{
$prev = $this->tracedErrors;
$this->tracedErrors = (int) $levels;
@ -334,7 +329,7 @@ class ErrorHandler
*
* @return int The previous value
*/
public function screamAt($levels, $replace = false)
public function screamAt(int $levels, bool $replace = false): int
{
$prev = $this->screamedErrors;
$this->screamedErrors = (int) $levels;
@ -348,7 +343,7 @@ class ErrorHandler
/**
* Re-registers as a PHP error handler if levels changed.
*/
private function reRegister($prev)
private function reRegister(int $prev): void
{
if ($prev !== $this->thrownErrors | $this->loggedErrors) {
$handler = set_error_handler('var_dump');
@ -368,18 +363,13 @@ class ErrorHandler
/**
* Handles errors by filtering then logging them according to the configured bit fields.
*
* @param int $type One of the E_* constants
* @param string $message
* @param string $file
* @param int $line
*
* @return bool Returns false when no handling happens so that the PHP engine can handle the error itself
*
* @throws \ErrorException When $this->thrownErrors requests so
*
* @internal
*/
public function handleError($type, $message, $file, $line)
public function handleError(int $type, string $message, string $file, int $line): bool
{
// @deprecated to be removed in Symfony 5.0
if (\PHP_VERSION_ID >= 70300 && $message && '"' === $message[0] && 0 === strpos($message, '"continue') && preg_match('/^"continue(?: \d++)?" targeting switch is equivalent to "break(?: \d++)?"\. Did you mean to use "continue(?: \d++)?"\?$/', $message)) {
@ -442,7 +432,7 @@ class ErrorHandler
self::$silencedErrorCache[$id][$message] = $errorAsException;
}
if (null === $lightTrace) {
return;
return true;
}
} else {
$errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line);
@ -590,11 +580,11 @@ class ErrorHandler
/**
* Shutdown registered function for handling PHP fatal errors.
*
* @param array $error An array as returned by error_get_last()
* @param array|null $error An array as returned by error_get_last()
*
* @internal
*/
public static function handleFatalError(array $error = null)
public static function handleFatalError(array $error = null): void
{
if (null === self::$reservedMemory) {
return;
@ -674,7 +664,7 @@ class ErrorHandler
*
* @return FatalErrorHandlerInterface[] An array of FatalErrorHandlerInterface
*/
protected function getFatalErrorHandlers()
protected function getFatalErrorHandlers(): array
{
return [
new UndefinedFunctionFatalErrorHandler(),
@ -686,7 +676,7 @@ class ErrorHandler
/**
* Cleans the trace by removing function arguments and the frames added by the error handler and DebugClassLoader.
*/
private function cleanTrace($backtrace, $type, $file, $line, $throw)
private function cleanTrace(array $backtrace, int $type, string $file, int $line, bool $throw): array
{
$lightTrace = $backtrace;

View File

@ -68,7 +68,7 @@ class FatalErrorException extends \ErrorException
}
}
protected function setTrace($trace)
protected function setTrace(array $trace): void
{
$traceReflector = new \ReflectionProperty('Exception', 'trace');
$traceReflector->setAccessible(true);

View File

@ -34,27 +34,27 @@ class SilencedErrorContext implements \JsonSerializable
$this->count = $count;
}
public function getSeverity()
public function getSeverity(): int
{
return $this->severity;
}
public function getFile()
public function getFile(): string
{
return $this->file;
}
public function getLine()
public function getLine(): int
{
return $this->line;
}
public function getTrace()
public function getTrace(): array
{
return $this->trace;
}
public function JsonSerialize()
public function jsonSerialize(): array
{
return [
'severity' => $this->severity,

View File

@ -6,7 +6,7 @@ use Symfony\Component\ErrorHandler\BufferingLogger;
class LoggerThatSetAnErrorHandler extends BufferingLogger
{
public function log($level, $message, array $context = [])
public function log($level, $message, array $context = []): void
{
set_error_handler('is_string');
parent::log($level, $message, $context);