[
  {
    "path": ".gitattributes",
    "content": "/Tests export-ignore\n/phpunit.xml.dist export-ignore\n/.gitattributes export-ignore\n/.gitignore export-ignore\n"
  },
  {
    "path": ".gitignore",
    "content": "vendor/\ncomposer.lock\nphpunit.xml\n"
  },
  {
    "path": "BufferingLogger.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug;\n\nuse Psr\\Log\\AbstractLogger;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', BufferingLogger::class, \\Symfony\\Component\\ErrorHandler\\BufferingLogger::class), \\E_USER_DEPRECATED);\n\n/**\n * A buffering logger that stacks logs for later.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\BufferingLogger instead.\n */\nclass BufferingLogger extends AbstractLogger\n{\n    private $logs = [];\n\n    /**\n     * @return void\n     */\n    public function log($level, $message, array $context = [])\n    {\n        $this->logs[] = [$level, $message, $context];\n    }\n\n    public function cleanLogs()\n    {\n        $logs = $this->logs;\n        $this->logs = [];\n\n        return $logs;\n    }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "CHANGELOG\n=========\n\n4.4.0\n-----\n\n * deprecated `FlattenException`, use the `FlattenException` of the `ErrorHandler` component\n * deprecated the whole component in favor of the `ErrorHandler` component\n\n4.3.0\n-----\n\n * made the `ErrorHandler` and `ExceptionHandler` classes final\n * added `Exception\\FlattenException::getAsString` and\n   `Exception\\FlattenException::getTraceAsString` to increase compatibility to php\n   exception objects\n\n4.0.0\n-----\n\n * removed the symfony_debug extension\n * removed `ContextErrorException`\n\n3.4.0\n-----\n\n * deprecated `ErrorHandler::stackErrors()` and `ErrorHandler::unstackErrors()`\n\n3.3.0\n-----\n\n * deprecated the `ContextErrorException` class: use \\ErrorException directly now\n\n3.2.0\n-----\n\n * `FlattenException::getTrace()` now returns additional type descriptions\n   `integer` and `float`.\n\n3.0.0\n-----\n\n * removed classes, methods and interfaces deprecated in 2.x\n\n2.8.0\n-----\n\n * added BufferingLogger for errors that happen before a proper logger is configured\n * allow throwing from `__toString()` with `return trigger_error($e, E_USER_ERROR);`\n * deprecate ExceptionHandler::createResponse\n\n2.7.0\n-----\n\n * added deprecations checking for parent interfaces/classes to DebugClassLoader\n * added ZTS support to symfony_debug extension\n * added symfony_debug_backtrace() to symfony_debug extension\n   to track the backtrace of fatal errors\n\n2.6.0\n-----\n\n * generalized ErrorHandler and ExceptionHandler,\n   with some new methods and others deprecated\n * enhanced error messages for uncaught exceptions\n\n2.5.0\n-----\n\n * added ExceptionHandler::setHandler()\n * added UndefinedMethodFatalErrorHandler\n * deprecated DummyException\n\n2.4.0\n-----\n\n * added a DebugClassLoader able to wrap any autoloader providing a findFile method\n * improved error messages for not found classes and functions\n\n2.3.0\n-----\n\n * added the component\n"
  },
  {
    "path": "Debug.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', Debug::class, \\Symfony\\Component\\ErrorHandler\\Debug::class), \\E_USER_DEPRECATED);\n\n/**\n * Registers all the debug tools.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Debug instead.\n */\nclass Debug\n{\n    private static $enabled = false;\n\n    /**\n     * Enables the debug tools.\n     *\n     * This method registers an error handler and an exception handler.\n     *\n     * @param int  $errorReportingLevel The level of error reporting you want\n     * @param bool $displayErrors       Whether to display errors (for development) or just log them (for production)\n     */\n    public static function enable($errorReportingLevel = \\E_ALL, $displayErrors = true)\n    {\n        if (static::$enabled) {\n            return;\n        }\n\n        static::$enabled = true;\n\n        if (null !== $errorReportingLevel) {\n            error_reporting($errorReportingLevel);\n        } else {\n            error_reporting(\\E_ALL);\n        }\n\n        if (!\\in_array(\\PHP_SAPI, ['cli', 'phpdbg'], true)) {\n            ini_set('display_errors', 0);\n            ExceptionHandler::register();\n        } elseif ($displayErrors && (!filter_var(\\ini_get('log_errors'), \\FILTER_VALIDATE_BOOLEAN) || \\ini_get('error_log'))) {\n            // CLI - display errors only if they're not already logged to STDERR\n            ini_set('display_errors', 1);\n        }\n        if ($displayErrors) {\n            ErrorHandler::register(new ErrorHandler(new BufferingLogger()));\n        } else {\n            ErrorHandler::register()->throwAt(0, true);\n        }\n\n        DebugClassLoader::enable();\n    }\n}\n"
  },
  {
    "path": "DebugClassLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug;\n\nuse PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', DebugClassLoader::class, \\Symfony\\Component\\ErrorHandler\\DebugClassLoader::class), \\E_USER_DEPRECATED);\n\n/**\n * Autoloader checking if the class is really defined in the file found.\n *\n * The ClassLoader will wrap all registered autoloaders\n * and will throw an exception if a file is found but does\n * not declare the class.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Christophe Coevoet <stof@notk.org>\n * @author Nicolas Grekas <p@tchwork.com>\n * @author Guilhem Niot <guilhem.niot@gmail.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\DebugClassLoader instead.\n */\nclass DebugClassLoader\n{\n    private $classLoader;\n    private $isFinder;\n    private $loaded = [];\n    private static $caseCheck;\n    private static $checkedClasses = [];\n    private static $final = [];\n    private static $finalMethods = [];\n    private static $deprecated = [];\n    private static $internal = [];\n    private static $internalMethods = [];\n    private static $annotatedParameters = [];\n    private static $darwinCache = ['/' => ['/', []]];\n    private static $method = [];\n\n    public function __construct(callable $classLoader)\n    {\n        $this->classLoader = $classLoader;\n        $this->isFinder = \\is_array($classLoader) && method_exists($classLoader[0], 'findFile');\n\n        if (!isset(self::$caseCheck)) {\n            $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), \\DIRECTORY_SEPARATOR);\n            $i = strrpos($file, \\DIRECTORY_SEPARATOR);\n            $dir = substr($file, 0, 1 + $i);\n            $file = substr($file, 1 + $i);\n            $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);\n            $test = realpath($dir.$test);\n\n            if (false === $test || false === $i) {\n                // filesystem is case sensitive\n                self::$caseCheck = 0;\n            } elseif (substr($test, -\\strlen($file)) === $file) {\n                // filesystem is case insensitive and realpath() normalizes the case of characters\n                self::$caseCheck = 1;\n            } elseif (false !== stripos(\\PHP_OS, 'darwin')) {\n                // on MacOSX, HFS+ is case insensitive but realpath() doesn't normalize the case of characters\n                self::$caseCheck = 2;\n            } else {\n                // filesystem case checks failed, fallback to disabling them\n                self::$caseCheck = 0;\n            }\n        }\n    }\n\n    /**\n     * Gets the wrapped class loader.\n     *\n     * @return callable The wrapped class loader\n     */\n    public function getClassLoader()\n    {\n        return $this->classLoader;\n    }\n\n    /**\n     * Wraps all autoloaders.\n     */\n    public static function enable()\n    {\n        // Ensures we don't hit https://bugs.php.net/42098\n        class_exists(\\Symfony\\Component\\Debug\\ErrorHandler::class);\n        class_exists(\\Psr\\Log\\LogLevel::class);\n\n        if (!\\is_array($functions = spl_autoload_functions())) {\n            return;\n        }\n\n        foreach ($functions as $function) {\n            spl_autoload_unregister($function);\n        }\n\n        foreach ($functions as $function) {\n            if (!\\is_array($function) || !$function[0] instanceof self) {\n                $function = [new static($function), 'loadClass'];\n            }\n\n            spl_autoload_register($function);\n        }\n    }\n\n    /**\n     * Disables the wrapping.\n     */\n    public static function disable()\n    {\n        if (!\\is_array($functions = spl_autoload_functions())) {\n            return;\n        }\n\n        foreach ($functions as $function) {\n            spl_autoload_unregister($function);\n        }\n\n        foreach ($functions as $function) {\n            if (\\is_array($function) && $function[0] instanceof self) {\n                $function = $function[0]->getClassLoader();\n            }\n\n            spl_autoload_register($function);\n        }\n    }\n\n    /**\n     * @return string|null\n     */\n    public function findFile($class)\n    {\n        return $this->isFinder ? $this->classLoader[0]->findFile($class) ?: null : null;\n    }\n\n    /**\n     * Loads the given class or interface.\n     *\n     * @param string $class The name of the class\n     *\n     * @throws \\RuntimeException\n     */\n    public function loadClass($class)\n    {\n        $e = error_reporting(error_reporting() | \\E_PARSE | \\E_ERROR | \\E_CORE_ERROR | \\E_COMPILE_ERROR);\n\n        try {\n            if ($this->isFinder && !isset($this->loaded[$class])) {\n                $this->loaded[$class] = true;\n                if (!$file = $this->classLoader[0]->findFile($class) ?: false) {\n                    // no-op\n                } elseif (\\function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file)) {\n                    include $file;\n\n                    return;\n                } elseif (false === include $file) {\n                    return;\n                }\n            } else {\n                ($this->classLoader)($class);\n                $file = false;\n            }\n        } finally {\n            error_reporting($e);\n        }\n\n        $this->checkClass($class, $file);\n    }\n\n    private function checkClass(string $class, string $file = null)\n    {\n        $exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);\n\n        if (null !== $file && $class && '\\\\' === $class[0]) {\n            $class = substr($class, 1);\n        }\n\n        if ($exists) {\n            if (isset(self::$checkedClasses[$class])) {\n                return;\n            }\n            self::$checkedClasses[$class] = true;\n\n            $refl = new \\ReflectionClass($class);\n            if (null === $file && $refl->isInternal()) {\n                return;\n            }\n            $name = $refl->getName();\n\n            if ($name !== $class && 0 === strcasecmp($name, $class)) {\n                throw new \\RuntimeException(sprintf('Case mismatch between loaded and declared class names: \"%s\" vs \"%s\".', $class, $name));\n            }\n\n            $deprecations = $this->checkAnnotations($refl, $name);\n\n            foreach ($deprecations as $message) {\n                @trigger_error($message, \\E_USER_DEPRECATED);\n            }\n        }\n\n        if (!$file) {\n            return;\n        }\n\n        if (!$exists) {\n            if (false !== strpos($class, '/')) {\n                throw new \\RuntimeException(sprintf('Trying to autoload a class with an invalid name \"%s\". Be careful that the namespace separator is \"\\\" in PHP, not \"/\".', $class));\n            }\n\n            throw new \\RuntimeException(sprintf('The autoloader expected class \"%s\" to be defined in file \"%s\". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));\n        }\n\n        if (self::$caseCheck && $message = $this->checkCase($refl, $file, $class)) {\n            throw new \\RuntimeException(sprintf('Case mismatch between class and real file names: \"%s\" vs \"%s\" in \"%s\".', $message[0], $message[1], $message[2]));\n        }\n    }\n\n    public function checkAnnotations(\\ReflectionClass $refl, $class)\n    {\n        $deprecations = [];\n\n        // Don't trigger deprecations for classes in the same vendor\n        if (2 > $len = 1 + (strpos($class, '\\\\') ?: strpos($class, '_'))) {\n            $len = 0;\n            $ns = '';\n        } else {\n            $ns = str_replace('_', '\\\\', substr($class, 0, $len));\n        }\n\n        // Detect annotations on the class\n        if (false !== $doc = $refl->getDocComment()) {\n            foreach (['final', 'deprecated', 'internal'] as $annotation) {\n                if (false !== strpos($doc, $annotation) && preg_match('#\\n\\s+\\* @'.$annotation.'(?:( .+?)\\.?)?\\r?\\n\\s+\\*(?: @|/$|\\r?\\n)#s', $doc, $notice)) {\n                    self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\\.?\\r?\\n( \\*)? *(?= |\\r?\\n|$)#', '', $notice[1]) : '';\n                }\n            }\n\n            if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\\n \\* @method\\s+(static\\s+)?+(?:[\\w\\|&\\[\\]\\\\\\]+\\s+)?(\\w+(?:\\s*\\([^\\)]*\\))?)+(.+?([[:punct:]]\\s*)?)?(?=\\r?\\n \\*(?: @|/$|\\r?\\n))#', $doc, $notice, \\PREG_SET_ORDER)) {\n                foreach ($notice as $method) {\n                    $static = '' !== $method[1];\n                    $name = $method[2];\n                    $description = $method[3] ?? null;\n                    if (false === strpos($name, '(')) {\n                        $name .= '()';\n                    }\n                    if (null !== $description) {\n                        $description = trim($description);\n                        if (!isset($method[4])) {\n                            $description .= '.';\n                        }\n                    }\n                    self::$method[$class][] = [$class, $name, $static, $description];\n                }\n            }\n        }\n\n        $parent = get_parent_class($class);\n        $parentAndOwnInterfaces = $this->getOwnInterfaces($class, $parent ?: null);\n        if ($parent) {\n            $parentAndOwnInterfaces[$parent] = $parent;\n\n            if (!isset(self::$checkedClasses[$parent])) {\n                $this->checkClass($parent);\n            }\n\n            if (isset(self::$final[$parent])) {\n                $deprecations[] = sprintf('The \"%s\" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from \"%s\".', $parent, self::$final[$parent], $class);\n            }\n        }\n\n        // Detect if the parent is annotated\n        foreach ($parentAndOwnInterfaces + class_uses($class, false) as $use) {\n            if (!isset(self::$checkedClasses[$use])) {\n                $this->checkClass($use);\n            }\n            if (isset(self::$deprecated[$use]) && strncmp($ns, str_replace('_', '\\\\', $use), $len) && !isset(self::$deprecated[$class])) {\n                $type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');\n                $verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');\n\n                $deprecations[] = sprintf('The \"%s\" %s %s \"%s\" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);\n            }\n            if (isset(self::$internal[$use]) && strncmp($ns, str_replace('_', '\\\\', $use), $len)) {\n                $deprecations[] = sprintf('The \"%s\" %s is considered internal%s. It may change without further notice. You should not use it from \"%s\".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);\n            }\n            if (isset(self::$method[$use])) {\n                if ($refl->isAbstract()) {\n                    if (isset(self::$method[$class])) {\n                        self::$method[$class] = array_merge(self::$method[$class], self::$method[$use]);\n                    } else {\n                        self::$method[$class] = self::$method[$use];\n                    }\n                } elseif (!$refl->isInterface()) {\n                    $hasCall = $refl->hasMethod('__call');\n                    $hasStaticCall = $refl->hasMethod('__callStatic');\n                    foreach (self::$method[$use] as $method) {\n                        [$interface, $name, $static, $description] = $method;\n                        if ($static ? $hasStaticCall : $hasCall) {\n                            continue;\n                        }\n                        $realName = substr($name, 0, strpos($name, '('));\n                        if (!$refl->hasMethod($realName) || !($methodRefl = $refl->getMethod($realName))->isPublic() || ($static && !$methodRefl->isStatic()) || (!$static && $methodRefl->isStatic())) {\n                            $deprecations[] = sprintf('Class \"%s\" should implement method \"%s::%s\"%s', $class, ($static ? 'static ' : '').$interface, $name, null == $description ? '.' : ': '.$description);\n                        }\n                    }\n                }\n            }\n        }\n\n        if (trait_exists($class)) {\n            return $deprecations;\n        }\n\n        // Inherit @final, @internal and @param annotations for methods\n        self::$finalMethods[$class] = [];\n        self::$internalMethods[$class] = [];\n        self::$annotatedParameters[$class] = [];\n        foreach ($parentAndOwnInterfaces as $use) {\n            foreach (['finalMethods', 'internalMethods', 'annotatedParameters'] as $property) {\n                if (isset(self::${$property}[$use])) {\n                    self::${$property}[$class] = self::${$property}[$class] ? self::${$property}[$use] + self::${$property}[$class] : self::${$property}[$use];\n                }\n            }\n        }\n\n        foreach ($refl->getMethods(\\ReflectionMethod::IS_PUBLIC | \\ReflectionMethod::IS_PROTECTED) as $method) {\n            if ($method->class !== $class) {\n                continue;\n            }\n\n            if ($parent && isset(self::$finalMethods[$parent][$method->name])) {\n                [$declaringClass, $message] = self::$finalMethods[$parent][$method->name];\n                $deprecations[] = sprintf('The \"%s::%s()\" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from \"%s\".', $declaringClass, $method->name, $message, $class);\n            }\n\n            if (isset(self::$internalMethods[$class][$method->name])) {\n                [$declaringClass, $message] = self::$internalMethods[$class][$method->name];\n                if (strncmp($ns, $declaringClass, $len)) {\n                    $deprecations[] = sprintf('The \"%s::%s()\" method is considered internal%s. It may change without further notice. You should not extend it from \"%s\".', $declaringClass, $method->name, $message, $class);\n                }\n            }\n\n            // To read method annotations\n            $doc = $method->getDocComment();\n\n            if (isset(self::$annotatedParameters[$class][$method->name])) {\n                $definedParameters = [];\n                foreach ($method->getParameters() as $parameter) {\n                    $definedParameters[$parameter->name] = true;\n                }\n\n                foreach (self::$annotatedParameters[$class][$method->name] as $parameterName => $deprecation) {\n                    if (!isset($definedParameters[$parameterName]) && !($doc && preg_match(\"/\\\\n\\\\s+\\\\* @param +((?(?!callable *\\().*?|callable *\\(.*\\).*?))(?<= )\\\\\\${$parameterName}\\\\b/\", $doc))) {\n                        $deprecations[] = sprintf($deprecation, $class);\n                    }\n                }\n            }\n\n            if (!$doc) {\n                continue;\n            }\n\n            $finalOrInternal = false;\n\n            foreach (['final', 'internal'] as $annotation) {\n                if (false !== strpos($doc, $annotation) && preg_match('#\\n\\s+\\* @'.$annotation.'(?:( .+?)\\.?)?\\r?\\n\\s+\\*(?: @|/$|\\r?\\n)#s', $doc, $notice)) {\n                    $message = isset($notice[1]) ? preg_replace('#\\.?\\r?\\n( \\*)? *(?= |\\r?\\n|$)#', '', $notice[1]) : '';\n                    self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message];\n                    $finalOrInternal = true;\n                }\n            }\n\n            if ($finalOrInternal || $method->isConstructor() || false === strpos($doc, '@param') || StatelessInvocation::class === $class) {\n                continue;\n            }\n            if (!preg_match_all('#\\n\\s+\\* @param +((?(?!callable *\\().*?|callable *\\(.*\\).*?))(?<= )\\$([a-zA-Z0-9_\\x7f-\\xff]++)#', $doc, $matches, \\PREG_SET_ORDER)) {\n                continue;\n            }\n            if (!isset(self::$annotatedParameters[$class][$method->name])) {\n                $definedParameters = [];\n                foreach ($method->getParameters() as $parameter) {\n                    $definedParameters[$parameter->name] = true;\n                }\n            }\n            foreach ($matches as [, $parameterType, $parameterName]) {\n                if (!isset($definedParameters[$parameterName])) {\n                    $parameterType = trim($parameterType);\n                    self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The \"%%s::%s()\" method will require a new \"%s$%s\" argument in the next major version of its %s \"%s\", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($class) ? 'interface' : 'parent class', $method->class);\n                }\n            }\n        }\n\n        return $deprecations;\n    }\n\n    /**\n     * @param string $file\n     * @param string $class\n     *\n     * @return array|null\n     */\n    public function checkCase(\\ReflectionClass $refl, $file, $class)\n    {\n        $real = explode('\\\\', $class.strrchr($file, '.'));\n        $tail = explode(\\DIRECTORY_SEPARATOR, str_replace('/', \\DIRECTORY_SEPARATOR, $file));\n\n        $i = \\count($tail) - 1;\n        $j = \\count($real) - 1;\n\n        while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {\n            --$i;\n            --$j;\n        }\n\n        array_splice($tail, 0, $i + 1);\n\n        if (!$tail) {\n            return null;\n        }\n\n        $tail = \\DIRECTORY_SEPARATOR.implode(\\DIRECTORY_SEPARATOR, $tail);\n        $tailLen = \\strlen($tail);\n        $real = $refl->getFileName();\n\n        if (2 === self::$caseCheck) {\n            $real = $this->darwinRealpath($real);\n        }\n\n        if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)\n            && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)\n        ) {\n            return [substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)];\n        }\n\n        return null;\n    }\n\n    /**\n     * `realpath` on MacOSX doesn't normalize the case of characters.\n     */\n    private function darwinRealpath(string $real): string\n    {\n        $i = 1 + strrpos($real, '/');\n        $file = substr($real, $i);\n        $real = substr($real, 0, $i);\n\n        if (isset(self::$darwinCache[$real])) {\n            $kDir = $real;\n        } else {\n            $kDir = strtolower($real);\n\n            if (isset(self::$darwinCache[$kDir])) {\n                $real = self::$darwinCache[$kDir][0];\n            } else {\n                $dir = getcwd();\n\n                if (!@chdir($real)) {\n                    return $real.$file;\n                }\n\n                $real = getcwd().'/';\n                chdir($dir);\n\n                $dir = $real;\n                $k = $kDir;\n                $i = \\strlen($dir) - 1;\n                while (!isset(self::$darwinCache[$k])) {\n                    self::$darwinCache[$k] = [$dir, []];\n                    self::$darwinCache[$dir] = &self::$darwinCache[$k];\n\n                    while ('/' !== $dir[--$i]) {\n                    }\n                    $k = substr($k, 0, ++$i);\n                    $dir = substr($dir, 0, $i--);\n                }\n            }\n        }\n\n        $dirFiles = self::$darwinCache[$kDir][1];\n\n        if (!isset($dirFiles[$file]) && ') : eval()\\'d code' === substr($file, -17)) {\n            // Get the file name from \"file_name.php(123) : eval()'d code\"\n            $file = substr($file, 0, strrpos($file, '(', -17));\n        }\n\n        if (isset($dirFiles[$file])) {\n            return $real.$dirFiles[$file];\n        }\n\n        $kFile = strtolower($file);\n\n        if (!isset($dirFiles[$kFile])) {\n            foreach (scandir($real, 2) as $f) {\n                if ('.' !== $f[0]) {\n                    $dirFiles[$f] = $f;\n                    if ($f === $file) {\n                        $kFile = $k = $file;\n                    } elseif ($f !== $k = strtolower($f)) {\n                        $dirFiles[$k] = $f;\n                    }\n                }\n            }\n            self::$darwinCache[$kDir][1] = $dirFiles;\n        }\n\n        return $real.$dirFiles[$kFile];\n    }\n\n    /**\n     * `class_implements` includes interfaces from the parents so we have to manually exclude them.\n     *\n     * @return string[]\n     */\n    private function getOwnInterfaces(string $class, ?string $parent): array\n    {\n        $ownInterfaces = class_implements($class, false);\n\n        if ($parent) {\n            foreach (class_implements($parent, false) as $interface) {\n                unset($ownInterfaces[$interface]);\n            }\n        }\n\n        foreach ($ownInterfaces as $interface) {\n            foreach (class_implements($interface) as $interface) {\n                unset($ownInterfaces[$interface]);\n            }\n        }\n\n        return $ownInterfaces;\n    }\n}\n"
  },
  {
    "path": "ErrorHandler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug;\n\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\LogLevel;\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\nuse Symfony\\Component\\Debug\\Exception\\FatalThrowableError;\nuse Symfony\\Component\\Debug\\Exception\\FlattenException;\nuse Symfony\\Component\\Debug\\Exception\\OutOfMemoryException;\nuse Symfony\\Component\\Debug\\Exception\\SilencedErrorContext;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\FatalErrorHandlerInterface;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', ErrorHandler::class, \\Symfony\\Component\\ErrorHandler\\ErrorHandler::class), \\E_USER_DEPRECATED);\n\n/**\n * A generic ErrorHandler for the PHP engine.\n *\n * Provides five bit fields that control how errors are handled:\n * - thrownErrors: errors thrown as \\ErrorException\n * - loggedErrors: logged errors, when not @-silenced\n * - scopedErrors: errors thrown or logged with their local context\n * - tracedErrors: errors logged with their stack trace\n * - screamedErrors: never @-silenced errors\n *\n * Each error level can be logged by a dedicated PSR-3 logger object.\n * Screaming only applies to logging.\n * Throwing takes precedence over logging.\n * Uncaught exceptions are logged as E_ERROR.\n * E_DEPRECATED and E_USER_DEPRECATED levels never throw.\n * E_RECOVERABLE_ERROR and E_USER_ERROR levels always throw.\n * Non catchable errors that can be detected at shutdown time are logged when the scream bit field allows so.\n * As errors have a performance cost, repeated errors are all logged, so that the developer\n * can see them and weight them as more important to fix than others of the same level.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n * @author Grégoire Pineau <lyrixx@lyrixx.info>\n *\n * @final since Symfony 4.3\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\ErrorHandler instead.\n */\nclass ErrorHandler\n{\n    private $levels = [\n        \\E_DEPRECATED => 'Deprecated',\n        \\E_USER_DEPRECATED => 'User Deprecated',\n        \\E_NOTICE => 'Notice',\n        \\E_USER_NOTICE => 'User Notice',\n        \\E_STRICT => 'Runtime Notice',\n        \\E_WARNING => 'Warning',\n        \\E_USER_WARNING => 'User Warning',\n        \\E_COMPILE_WARNING => 'Compile Warning',\n        \\E_CORE_WARNING => 'Core Warning',\n        \\E_USER_ERROR => 'User Error',\n        \\E_RECOVERABLE_ERROR => 'Catchable Fatal Error',\n        \\E_COMPILE_ERROR => 'Compile Error',\n        \\E_PARSE => 'Parse Error',\n        \\E_ERROR => 'Error',\n        \\E_CORE_ERROR => 'Core Error',\n    ];\n\n    private $loggers = [\n        \\E_DEPRECATED => [null, LogLevel::INFO],\n        \\E_USER_DEPRECATED => [null, LogLevel::INFO],\n        \\E_NOTICE => [null, LogLevel::WARNING],\n        \\E_USER_NOTICE => [null, LogLevel::WARNING],\n        \\E_STRICT => [null, LogLevel::WARNING],\n        \\E_WARNING => [null, LogLevel::WARNING],\n        \\E_USER_WARNING => [null, LogLevel::WARNING],\n        \\E_COMPILE_WARNING => [null, LogLevel::WARNING],\n        \\E_CORE_WARNING => [null, LogLevel::WARNING],\n        \\E_USER_ERROR => [null, LogLevel::CRITICAL],\n        \\E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],\n        \\E_COMPILE_ERROR => [null, LogLevel::CRITICAL],\n        \\E_PARSE => [null, LogLevel::CRITICAL],\n        \\E_ERROR => [null, LogLevel::CRITICAL],\n        \\E_CORE_ERROR => [null, LogLevel::CRITICAL],\n    ];\n\n    private $thrownErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED\n    private $scopedErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED\n    private $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE\n    private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE\n    private $loggedErrors = 0;\n    private $traceReflector;\n\n    private $isRecursive = 0;\n    private $isRoot = false;\n    private $exceptionHandler;\n    private $bootstrappingLogger;\n\n    private static $reservedMemory;\n    private static $toStringException = null;\n    private static $silencedErrorCache = [];\n    private static $silencedErrorCount = 0;\n    private static $exitCode = 0;\n\n    /**\n     * Registers the error handler.\n     *\n     * @param self|null $handler The handler to register\n     * @param bool      $replace Whether to replace or not any existing handler\n     *\n     * @return self The registered error handler\n     */\n    public static function register(self $handler = null, $replace = true)\n    {\n        if (null === self::$reservedMemory) {\n            self::$reservedMemory = str_repeat('x', 32768);\n            register_shutdown_function(__CLASS__.'::handleFatalError');\n        }\n\n        if ($handlerIsNew = null === $handler) {\n            $handler = new static();\n        }\n\n        if (null === $prev = set_error_handler([$handler, 'handleError'])) {\n            restore_error_handler();\n            // Specifying the error types earlier would expose us to https://bugs.php.net/63206\n            set_error_handler([$handler, 'handleError'], $handler->thrownErrors | $handler->loggedErrors);\n            $handler->isRoot = true;\n        }\n\n        if ($handlerIsNew && \\is_array($prev) && $prev[0] instanceof self) {\n            $handler = $prev[0];\n            $replace = false;\n        }\n        if (!$replace && $prev) {\n            restore_error_handler();\n            $handlerIsRegistered = \\is_array($prev) && $handler === $prev[0];\n        } else {\n            $handlerIsRegistered = true;\n        }\n        if (\\is_array($prev = set_exception_handler([$handler, 'handleException'])) && $prev[0] instanceof self) {\n            restore_exception_handler();\n            if (!$handlerIsRegistered) {\n                $handler = $prev[0];\n            } elseif ($handler !== $prev[0] && $replace) {\n                set_exception_handler([$handler, 'handleException']);\n                $p = $prev[0]->setExceptionHandler(null);\n                $handler->setExceptionHandler($p);\n                $prev[0]->setExceptionHandler($p);\n            }\n        } else {\n            $handler->setExceptionHandler($prev);\n        }\n\n        $handler->throwAt(\\E_ALL & $handler->thrownErrors, true);\n\n        return $handler;\n    }\n\n    public function __construct(BufferingLogger $bootstrappingLogger = null)\n    {\n        if ($bootstrappingLogger) {\n            $this->bootstrappingLogger = $bootstrappingLogger;\n            $this->setDefaultLogger($bootstrappingLogger);\n        }\n        $this->traceReflector = new \\ReflectionProperty(\\Exception::class, 'trace');\n        $this->traceReflector->setAccessible(true);\n    }\n\n    /**\n     * Sets a logger to non assigned errors levels.\n     *\n     * @param array|int $levels  An array map of E_* to LogLevel::* or an integer bit field of E_* constants\n     * @param bool      $replace Whether to replace or not any existing logger\n     */\n    public function setDefaultLogger(LoggerInterface $logger, $levels = \\E_ALL, $replace = false)\n    {\n        $loggers = [];\n\n        if (\\is_array($levels)) {\n            foreach ($levels as $type => $logLevel) {\n                if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {\n                    $loggers[$type] = [$logger, $logLevel];\n                }\n            }\n        } else {\n            if (null === $levels) {\n                $levels = \\E_ALL;\n            }\n            foreach ($this->loggers as $type => $log) {\n                if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) {\n                    $log[0] = $logger;\n                    $loggers[$type] = $log;\n                }\n            }\n        }\n\n        $this->setLoggers($loggers);\n    }\n\n    /**\n     * Sets a logger for each error level.\n     *\n     * @param array $loggers Error levels to [LoggerInterface|null, LogLevel::*] map\n     *\n     * @return array The previous map\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function setLoggers(array $loggers)\n    {\n        $prevLogged = $this->loggedErrors;\n        $prev = $this->loggers;\n        $flush = [];\n\n        foreach ($loggers as $type => $log) {\n            if (!isset($prev[$type])) {\n                throw new \\InvalidArgumentException('Unknown error type: '.$type);\n            }\n            if (!\\is_array($log)) {\n                $log = [$log];\n            } elseif (!\\array_key_exists(0, $log)) {\n                throw new \\InvalidArgumentException('No logger provided.');\n            }\n            if (null === $log[0]) {\n                $this->loggedErrors &= ~$type;\n            } elseif ($log[0] instanceof LoggerInterface) {\n                $this->loggedErrors |= $type;\n            } else {\n                throw new \\InvalidArgumentException('Invalid logger provided.');\n            }\n            $this->loggers[$type] = $log + $prev[$type];\n\n            if ($this->bootstrappingLogger && $prev[$type][0] === $this->bootstrappingLogger) {\n                $flush[$type] = $type;\n            }\n        }\n        $this->reRegister($prevLogged | $this->thrownErrors);\n\n        if ($flush) {\n            foreach ($this->bootstrappingLogger->cleanLogs() as $log) {\n                $type = $log[2]['exception'] instanceof \\ErrorException ? $log[2]['exception']->getSeverity() : \\E_ERROR;\n                if (!isset($flush[$type])) {\n                    $this->bootstrappingLogger->log($log[0], $log[1], $log[2]);\n                } elseif ($this->loggers[$type][0]) {\n                    $this->loggers[$type][0]->log($this->loggers[$type][1], $log[1], $log[2]);\n                }\n            }\n        }\n\n        return $prev;\n    }\n\n    /**\n     * Sets a user exception handler.\n     *\n     * @param callable $handler A handler that will be called on Exception\n     *\n     * @return callable|null The previous exception handler\n     */\n    public function setExceptionHandler(callable $handler = null)\n    {\n        $prev = $this->exceptionHandler;\n        $this->exceptionHandler = $handler;\n\n        return $prev;\n    }\n\n    /**\n     * Sets the PHP error levels that throw an exception when a PHP error occurs.\n     *\n     * @param int  $levels  A bit field of E_* constants for thrown errors\n     * @param bool $replace Replace or amend the previous value\n     *\n     * @return int The previous value\n     */\n    public function throwAt($levels, $replace = false)\n    {\n        $prev = $this->thrownErrors;\n        $this->thrownErrors = ($levels | \\E_RECOVERABLE_ERROR | \\E_USER_ERROR) & ~\\E_USER_DEPRECATED & ~\\E_DEPRECATED;\n        if (!$replace) {\n            $this->thrownErrors |= $prev;\n        }\n        $this->reRegister($prev | $this->loggedErrors);\n\n        return $prev;\n    }\n\n    /**\n     * Sets the PHP error levels for which local variables are preserved.\n     *\n     * @param int  $levels  A bit field of E_* constants for scoped errors\n     * @param bool $replace Replace or amend the previous value\n     *\n     * @return int The previous value\n     */\n    public function scopeAt($levels, $replace = false)\n    {\n        $prev = $this->scopedErrors;\n        $this->scopedErrors = (int) $levels;\n        if (!$replace) {\n            $this->scopedErrors |= $prev;\n        }\n\n        return $prev;\n    }\n\n    /**\n     * Sets the PHP error levels for which the stack trace is preserved.\n     *\n     * @param int  $levels  A bit field of E_* constants for traced errors\n     * @param bool $replace Replace or amend the previous value\n     *\n     * @return int The previous value\n     */\n    public function traceAt($levels, $replace = false)\n    {\n        $prev = $this->tracedErrors;\n        $this->tracedErrors = (int) $levels;\n        if (!$replace) {\n            $this->tracedErrors |= $prev;\n        }\n\n        return $prev;\n    }\n\n    /**\n     * Sets the error levels where the @-operator is ignored.\n     *\n     * @param int  $levels  A bit field of E_* constants for screamed errors\n     * @param bool $replace Replace or amend the previous value\n     *\n     * @return int The previous value\n     */\n    public function screamAt($levels, $replace = false)\n    {\n        $prev = $this->screamedErrors;\n        $this->screamedErrors = (int) $levels;\n        if (!$replace) {\n            $this->screamedErrors |= $prev;\n        }\n\n        return $prev;\n    }\n\n    /**\n     * Re-registers as a PHP error handler if levels changed.\n     */\n    private function reRegister(int $prev)\n    {\n        if ($prev !== ($this->thrownErrors | $this->loggedErrors)) {\n            $handler = set_error_handler('is_int');\n            $handler = \\is_array($handler) ? $handler[0] : null;\n            restore_error_handler();\n            if ($handler === $this) {\n                restore_error_handler();\n                if ($this->isRoot) {\n                    set_error_handler([$this, 'handleError'], $this->thrownErrors | $this->loggedErrors);\n                } else {\n                    set_error_handler([$this, 'handleError']);\n                }\n            }\n        }\n    }\n\n    /**\n     * Handles errors by filtering then logging them according to the configured bit fields.\n     *\n     * @param int    $type    One of the E_* constants\n     * @param string $message\n     * @param string $file\n     * @param int    $line\n     *\n     * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself\n     *\n     * @throws \\ErrorException When $this->thrownErrors requests so\n     *\n     * @internal\n     */\n    public function handleError($type, $message, $file, $line)\n    {\n        if (\\PHP_VERSION_ID >= 70300 && \\E_WARNING === $type && '\"' === $message[0] && false !== strpos($message, '\" targeting switch is equivalent to \"break')) {\n            $type = \\E_DEPRECATED;\n        }\n\n        // Level is the current error reporting level to manage silent error.\n        $level = error_reporting();\n        $silenced = 0 === ($level & $type);\n        // Strong errors are not authorized to be silenced.\n        $level |= \\E_RECOVERABLE_ERROR | \\E_USER_ERROR | \\E_DEPRECATED | \\E_USER_DEPRECATED;\n        $log = $this->loggedErrors & $type;\n        $throw = $this->thrownErrors & $type & $level;\n        $type &= $level | $this->screamedErrors;\n\n        if (!$type || (!$log && !$throw)) {\n            return !$silenced && $type && $log;\n        }\n        $scope = $this->scopedErrors & $type;\n\n        if (false !== strpos($message, \"@anonymous\\0\")) {\n            $logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage();\n        } else {\n            $logMessage = $this->levels[$type].': '.$message;\n        }\n\n        if (null !== self::$toStringException) {\n            $errorAsException = self::$toStringException;\n            self::$toStringException = null;\n        } elseif (!$throw && !($type & $level)) {\n            if (!isset(self::$silencedErrorCache[$id = $file.':'.$line])) {\n                $lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(\\DEBUG_BACKTRACE_IGNORE_ARGS, 5), $type, $file, $line, false) : [];\n                $errorAsException = new SilencedErrorContext($type, $file, $line, isset($lightTrace[1]) ? [$lightTrace[0]] : $lightTrace);\n            } elseif (isset(self::$silencedErrorCache[$id][$message])) {\n                $lightTrace = null;\n                $errorAsException = self::$silencedErrorCache[$id][$message];\n                ++$errorAsException->count;\n            } else {\n                $lightTrace = [];\n                $errorAsException = null;\n            }\n\n            if (100 < ++self::$silencedErrorCount) {\n                self::$silencedErrorCache = $lightTrace = [];\n                self::$silencedErrorCount = 1;\n            }\n            if ($errorAsException) {\n                self::$silencedErrorCache[$id][$message] = $errorAsException;\n            }\n            if (null === $lightTrace) {\n                return true;\n            }\n        } else {\n            $errorAsException = new \\ErrorException($logMessage, 0, $type, $file, $line);\n\n            if ($throw || $this->tracedErrors & $type) {\n                $backtrace = $errorAsException->getTrace();\n                $lightTrace = $this->cleanTrace($backtrace, $type, $file, $line, $throw);\n                $this->traceReflector->setValue($errorAsException, $lightTrace);\n            } else {\n                $this->traceReflector->setValue($errorAsException, []);\n                $backtrace = [];\n            }\n        }\n\n        if ($throw) {\n            if (\\PHP_VERSION_ID < 70400 && \\E_USER_ERROR & $type) {\n                for ($i = 1; isset($backtrace[$i]); ++$i) {\n                    if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])\n                        && '__toString' === $backtrace[$i]['function']\n                        && '->' === $backtrace[$i]['type']\n                        && !isset($backtrace[$i - 1]['class'])\n                        && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])\n                    ) {\n                        // Here, we know trigger_error() has been called from __toString().\n                        // PHP triggers a fatal error when throwing from __toString().\n                        // A small convention allows working around the limitation:\n                        // given a caught $e exception in __toString(), quitting the method with\n                        // `return trigger_error($e, E_USER_ERROR);` allows this error handler\n                        // to make $e get through the __toString() barrier.\n\n                        $context = 4 < \\func_num_args() ? (func_get_arg(4) ?: []) : [];\n\n                        foreach ($context as $e) {\n                            if ($e instanceof \\Throwable && $e->__toString() === $message) {\n                                self::$toStringException = $e;\n\n                                return true;\n                            }\n                        }\n\n                        // Display the original error message instead of the default one.\n                        $this->handleException($errorAsException);\n\n                        // Stop the process by giving back the error to the native handler.\n                        return false;\n                    }\n                }\n            }\n\n            throw $errorAsException;\n        }\n\n        if ($this->isRecursive) {\n            $log = 0;\n        } else {\n            if (\\PHP_VERSION_ID < (\\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {\n                $currentErrorHandler = set_error_handler('is_int');\n                restore_error_handler();\n            }\n\n            try {\n                $this->isRecursive = true;\n                $level = ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG;\n                $this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? ['exception' => $errorAsException] : []);\n            } finally {\n                $this->isRecursive = false;\n\n                if (\\PHP_VERSION_ID < (\\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {\n                    set_error_handler($currentErrorHandler);\n                }\n            }\n        }\n\n        return !$silenced && $type && $log;\n    }\n\n    /**\n     * Handles an exception by logging then forwarding it to another handler.\n     *\n     * @param \\Exception|\\Throwable $exception An exception to handle\n     * @param array                 $error     An array as returned by error_get_last()\n     *\n     * @internal\n     */\n    public function handleException($exception, array $error = null)\n    {\n        if (null === $error) {\n            self::$exitCode = 255;\n        }\n        if (!$exception instanceof \\Exception) {\n            $exception = new FatalThrowableError($exception);\n        }\n        $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : \\E_ERROR;\n        $handlerException = null;\n\n        if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {\n            if (false !== strpos($message = $exception->getMessage(), \"@anonymous\\0\")) {\n                $message = (new FlattenException())->setMessage($message)->getMessage();\n            }\n            if ($exception instanceof FatalErrorException) {\n                if ($exception instanceof FatalThrowableError) {\n                    $error = [\n                        'type' => $type,\n                        'message' => $message,\n                        'file' => $exception->getFile(),\n                        'line' => $exception->getLine(),\n                    ];\n                } else {\n                    $message = 'Fatal '.$message;\n                }\n            } elseif ($exception instanceof \\ErrorException) {\n                $message = 'Uncaught '.$message;\n            } else {\n                $message = 'Uncaught Exception: '.$message;\n            }\n        }\n        if ($this->loggedErrors & $type) {\n            try {\n                $this->loggers[$type][0]->log($this->loggers[$type][1], $message, ['exception' => $exception]);\n            } catch (\\Throwable $handlerException) {\n            }\n        }\n        if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {\n            foreach ($this->getFatalErrorHandlers() as $handler) {\n                if ($e = $handler->handleError($error, $exception)) {\n                    $exception = $e;\n                    break;\n                }\n            }\n        }\n        $exceptionHandler = $this->exceptionHandler;\n        $this->exceptionHandler = null;\n        try {\n            if (null !== $exceptionHandler) {\n                $exceptionHandler($exception);\n\n                return;\n            }\n            $handlerException = $handlerException ?: $exception;\n        } catch (\\Throwable $handlerException) {\n        }\n        if ($exception === $handlerException) {\n            self::$reservedMemory = null; // Disable the fatal error handler\n            throw $exception; // Give back $exception to the native handler\n        }\n        $this->handleException($handlerException);\n    }\n\n    /**\n     * Shutdown registered function for handling PHP fatal errors.\n     *\n     * @param array $error An array as returned by error_get_last()\n     *\n     * @internal\n     */\n    public static function handleFatalError(array $error = null)\n    {\n        if (null === self::$reservedMemory) {\n            return;\n        }\n\n        $handler = self::$reservedMemory = null;\n        $handlers = [];\n        $previousHandler = null;\n        $sameHandlerLimit = 10;\n\n        while (!\\is_array($handler) || !$handler[0] instanceof self) {\n            $handler = set_exception_handler('is_int');\n            restore_exception_handler();\n\n            if (!$handler) {\n                break;\n            }\n            restore_exception_handler();\n\n            if ($handler !== $previousHandler) {\n                array_unshift($handlers, $handler);\n                $previousHandler = $handler;\n            } elseif (0 === --$sameHandlerLimit) {\n                $handler = null;\n                break;\n            }\n        }\n        foreach ($handlers as $h) {\n            set_exception_handler($h);\n        }\n        if (!$handler) {\n            return;\n        }\n        if ($handler !== $h) {\n            $handler[0]->setExceptionHandler($h);\n        }\n        $handler = $handler[0];\n        $handlers = [];\n\n        if ($exit = null === $error) {\n            $error = error_get_last();\n        }\n\n        if ($error && $error['type'] &= \\E_PARSE | \\E_ERROR | \\E_CORE_ERROR | \\E_COMPILE_ERROR) {\n            // Let's not throw anymore but keep logging\n            $handler->throwAt(0, true);\n            $trace = $error['backtrace'] ?? null;\n\n            if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {\n                $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false, $trace);\n            } else {\n                $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);\n            }\n        } else {\n            $exception = null;\n        }\n\n        try {\n            if (null !== $exception) {\n                self::$exitCode = 255;\n                $handler->handleException($exception, $error);\n            }\n        } catch (FatalErrorException $e) {\n            // Ignore this re-throw\n        }\n\n        if ($exit && self::$exitCode) {\n            $exitCode = self::$exitCode;\n            register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); });\n        }\n    }\n\n    /**\n     * Gets the fatal error handlers.\n     *\n     * Override this method if you want to define more fatal error handlers.\n     *\n     * @return FatalErrorHandlerInterface[] An array of FatalErrorHandlerInterface\n     */\n    protected function getFatalErrorHandlers()\n    {\n        return [\n            new UndefinedFunctionFatalErrorHandler(),\n            new UndefinedMethodFatalErrorHandler(),\n            new ClassNotFoundFatalErrorHandler(),\n        ];\n    }\n\n    /**\n     * Cleans the trace by removing function arguments and the frames added by the error handler and DebugClassLoader.\n     */\n    private function cleanTrace(array $backtrace, int $type, string $file, int $line, bool $throw): array\n    {\n        $lightTrace = $backtrace;\n\n        for ($i = 0; isset($backtrace[$i]); ++$i) {\n            if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {\n                $lightTrace = \\array_slice($lightTrace, 1 + $i);\n                break;\n            }\n        }\n        if (class_exists(DebugClassLoader::class, false)) {\n            for ($i = \\count($lightTrace) - 2; 0 < $i; --$i) {\n                if (DebugClassLoader::class === ($lightTrace[$i]['class'] ?? null)) {\n                    array_splice($lightTrace, --$i, 2);\n                }\n            }\n        }\n        if (!($throw || $this->scopedErrors & $type)) {\n            for ($i = 0; isset($lightTrace[$i]); ++$i) {\n                unset($lightTrace[$i]['args'], $lightTrace[$i]['object']);\n            }\n        }\n\n        return $lightTrace;\n    }\n}\n"
  },
  {
    "path": "Exception/ClassNotFoundException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', ClassNotFoundException::class, \\Symfony\\Component\\ErrorHandler\\Error\\ClassNotFoundError::class), \\E_USER_DEPRECATED);\n\n/**\n * Class (or Trait or Interface) Not Found Exception.\n *\n * @author Konstanton Myakshin <koc-dp@yandex.ru>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Error\\ClassNotFoundError instead.\n */\nclass ClassNotFoundException extends FatalErrorException\n{\n    public function __construct(string $message, \\ErrorException $previous)\n    {\n        parent::__construct(\n            $message,\n            $previous->getCode(),\n            $previous->getSeverity(),\n            $previous->getFile(),\n            $previous->getLine(),\n            null,\n            true,\n            null,\n            $previous->getPrevious()\n        );\n        $this->setTrace($previous->getTrace());\n    }\n}\n"
  },
  {
    "path": "Exception/FatalErrorException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', FatalErrorException::class, \\Symfony\\Component\\ErrorHandler\\Error\\FatalError::class), \\E_USER_DEPRECATED);\n\n/**\n * Fatal Error Exception.\n *\n * @author Konstanton Myakshin <koc-dp@yandex.ru>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Error\\FatalError instead.\n */\nclass FatalErrorException extends \\ErrorException\n{\n    public function __construct(string $message, int $code, int $severity, string $filename, int $lineno, int $traceOffset = null, bool $traceArgs = true, array $trace = null, \\Throwable $previous = null)\n    {\n        parent::__construct($message, $code, $severity, $filename, $lineno, $previous);\n\n        if (null !== $trace) {\n            if (!$traceArgs) {\n                foreach ($trace as &$frame) {\n                    unset($frame['args'], $frame['this'], $frame);\n                }\n            }\n\n            $this->setTrace($trace);\n        } elseif (null !== $traceOffset) {\n            if (\\function_exists('xdebug_get_function_stack') && $trace = @xdebug_get_function_stack()) {\n                if (0 < $traceOffset) {\n                    array_splice($trace, -$traceOffset);\n                }\n\n                foreach ($trace as &$frame) {\n                    if (!isset($frame['type'])) {\n                        // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695\n                        if (isset($frame['class'])) {\n                            $frame['type'] = '::';\n                        }\n                    } elseif ('dynamic' === $frame['type']) {\n                        $frame['type'] = '->';\n                    } elseif ('static' === $frame['type']) {\n                        $frame['type'] = '::';\n                    }\n\n                    // XDebug also has a different name for the parameters array\n                    if (!$traceArgs) {\n                        unset($frame['params'], $frame['args']);\n                    } elseif (isset($frame['params']) && !isset($frame['args'])) {\n                        $frame['args'] = $frame['params'];\n                        unset($frame['params']);\n                    }\n                }\n\n                unset($frame);\n                $trace = array_reverse($trace);\n            } else {\n                $trace = [];\n            }\n\n            $this->setTrace($trace);\n        }\n    }\n\n    protected function setTrace($trace)\n    {\n        $traceReflector = new \\ReflectionProperty(\\Exception::class, 'trace');\n        $traceReflector->setAccessible(true);\n        $traceReflector->setValue($this, $trace);\n    }\n}\n"
  },
  {
    "path": "Exception/FatalThrowableError.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4.', FatalThrowableError::class), \\E_USER_DEPRECATED);\n\n/**\n * Fatal Throwable Error.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @deprecated since Symfony 4.4\n */\nclass FatalThrowableError extends FatalErrorException\n{\n    private $originalClassName;\n\n    public function __construct(\\Throwable $e)\n    {\n        $this->originalClassName = \\get_class($e);\n\n        if ($e instanceof \\ParseError) {\n            $severity = \\E_PARSE;\n        } elseif ($e instanceof \\TypeError) {\n            $severity = \\E_RECOVERABLE_ERROR;\n        } else {\n            $severity = \\E_ERROR;\n        }\n\n        \\ErrorException::__construct(\n            $e->getMessage(),\n            $e->getCode(),\n            $severity,\n            $e->getFile(),\n            $e->getLine(),\n            $e->getPrevious()\n        );\n\n        $this->setTrace($e->getTrace());\n    }\n\n    public function getOriginalClassName(): string\n    {\n        return $this->originalClassName;\n    }\n}\n"
  },
  {
    "path": "Exception/FlattenException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\nuse Symfony\\Component\\HttpFoundation\\Exception\\RequestExceptionInterface;\nuse Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface;\n\n/**\n * FlattenException wraps a PHP Error or Exception to be able to serialize it.\n *\n * Basically, this class removes all objects from the trace.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Exception\\FlattenException instead.\n */\nclass FlattenException\n{\n    private $message;\n    private $code;\n    private $previous;\n    private $trace;\n    private $traceAsString;\n    private $class;\n    private $statusCode;\n    private $headers;\n    private $file;\n    private $line;\n\n    /**\n     * @return static\n     */\n    public static function create(\\Exception $exception, $statusCode = null, array $headers = [])\n    {\n        return static::createFromThrowable($exception, $statusCode, $headers);\n    }\n\n    /**\n     * @return static\n     */\n    public static function createFromThrowable(\\Throwable $exception, int $statusCode = null, array $headers = [])\n    {\n        $e = new static();\n        $e->setMessage($exception->getMessage());\n        $e->setCode($exception->getCode());\n\n        if ($exception instanceof HttpExceptionInterface) {\n            $statusCode = $exception->getStatusCode();\n            $headers = array_merge($headers, $exception->getHeaders());\n        } elseif ($exception instanceof RequestExceptionInterface) {\n            $statusCode = 400;\n        }\n\n        if (null === $statusCode) {\n            $statusCode = 500;\n        }\n\n        $e->setStatusCode($statusCode);\n        $e->setHeaders($headers);\n        $e->setTraceFromThrowable($exception);\n        $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \\get_class($exception));\n        $e->setFile($exception->getFile());\n        $e->setLine($exception->getLine());\n\n        $previous = $exception->getPrevious();\n\n        if ($previous instanceof \\Throwable) {\n            $e->setPrevious(static::createFromThrowable($previous));\n        }\n\n        return $e;\n    }\n\n    public function toArray()\n    {\n        $exceptions = [];\n        foreach (array_merge([$this], $this->getAllPrevious()) as $exception) {\n            $exceptions[] = [\n                'message' => $exception->getMessage(),\n                'class' => $exception->getClass(),\n                'trace' => $exception->getTrace(),\n            ];\n        }\n\n        return $exceptions;\n    }\n\n    public function getStatusCode()\n    {\n        return $this->statusCode;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setStatusCode($code)\n    {\n        $this->statusCode = $code;\n\n        return $this;\n    }\n\n    public function getHeaders()\n    {\n        return $this->headers;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setHeaders(array $headers)\n    {\n        $this->headers = $headers;\n\n        return $this;\n    }\n\n    public function getClass()\n    {\n        return $this->class;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setClass($class)\n    {\n        $this->class = false !== strpos($class, \"@anonymous\\0\") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class;\n\n        return $this;\n    }\n\n    public function getFile()\n    {\n        return $this->file;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setFile($file)\n    {\n        $this->file = $file;\n\n        return $this;\n    }\n\n    public function getLine()\n    {\n        return $this->line;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setLine($line)\n    {\n        $this->line = $line;\n\n        return $this;\n    }\n\n    public function getMessage()\n    {\n        return $this->message;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setMessage($message)\n    {\n        if (false !== strpos($message, \"@anonymous\\0\")) {\n            $message = preg_replace_callback('/[a-zA-Z_\\x7f-\\xff][\\\\\\\\a-zA-Z0-9_\\x7f-\\xff]*+@anonymous\\x00.*?\\.php(?:0x?|:[0-9]++\\$)[0-9a-fA-F]++/', function ($m) {\n                return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];\n            }, $message);\n        }\n\n        $this->message = $message;\n\n        return $this;\n    }\n\n    public function getCode()\n    {\n        return $this->code;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setCode($code)\n    {\n        $this->code = $code;\n\n        return $this;\n    }\n\n    public function getPrevious()\n    {\n        return $this->previous;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setPrevious(self $previous)\n    {\n        $this->previous = $previous;\n\n        return $this;\n    }\n\n    public function getAllPrevious()\n    {\n        $exceptions = [];\n        $e = $this;\n        while ($e = $e->getPrevious()) {\n            $exceptions[] = $e;\n        }\n\n        return $exceptions;\n    }\n\n    public function getTrace()\n    {\n        return $this->trace;\n    }\n\n    /**\n     * @deprecated since 4.1, use {@see setTraceFromThrowable()} instead.\n     */\n    public function setTraceFromException(\\Exception $exception)\n    {\n        @trigger_error(sprintf('The \"%s()\" method is deprecated since Symfony 4.1, use \"setTraceFromThrowable()\" instead.', __METHOD__), \\E_USER_DEPRECATED);\n\n        $this->setTraceFromThrowable($exception);\n    }\n\n    public function setTraceFromThrowable(\\Throwable $throwable)\n    {\n        $this->traceAsString = $throwable->getTraceAsString();\n\n        return $this->setTrace($throwable->getTrace(), $throwable->getFile(), $throwable->getLine());\n    }\n\n    /**\n     * @return $this\n     */\n    public function setTrace($trace, $file, $line)\n    {\n        $this->trace = [];\n        $this->trace[] = [\n            'namespace' => '',\n            'short_class' => '',\n            'class' => '',\n            'type' => '',\n            'function' => '',\n            'file' => $file,\n            'line' => $line,\n            'args' => [],\n        ];\n        foreach ($trace as $entry) {\n            $class = '';\n            $namespace = '';\n            if (isset($entry['class'])) {\n                $parts = explode('\\\\', $entry['class']);\n                $class = array_pop($parts);\n                $namespace = implode('\\\\', $parts);\n            }\n\n            $this->trace[] = [\n                'namespace' => $namespace,\n                'short_class' => $class,\n                'class' => $entry['class'] ?? '',\n                'type' => $entry['type'] ?? '',\n                'function' => $entry['function'] ?? null,\n                'file' => $entry['file'] ?? null,\n                'line' => $entry['line'] ?? null,\n                'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : [],\n            ];\n        }\n\n        return $this;\n    }\n\n    private function flattenArgs(array $args, int $level = 0, int &$count = 0): array\n    {\n        $result = [];\n        foreach ($args as $key => $value) {\n            if (++$count > 1e4) {\n                return ['array', '*SKIPPED over 10000 entries*'];\n            }\n            if ($value instanceof \\__PHP_Incomplete_Class) {\n                // is_object() returns false on PHP<=7.1\n                $result[$key] = ['incomplete-object', $this->getClassNameFromIncomplete($value)];\n            } elseif (\\is_object($value)) {\n                $result[$key] = ['object', \\get_class($value)];\n            } elseif (\\is_array($value)) {\n                if ($level > 10) {\n                    $result[$key] = ['array', '*DEEP NESTED ARRAY*'];\n                } else {\n                    $result[$key] = ['array', $this->flattenArgs($value, $level + 1, $count)];\n                }\n            } elseif (null === $value) {\n                $result[$key] = ['null', null];\n            } elseif (\\is_bool($value)) {\n                $result[$key] = ['boolean', $value];\n            } elseif (\\is_int($value)) {\n                $result[$key] = ['integer', $value];\n            } elseif (\\is_float($value)) {\n                $result[$key] = ['float', $value];\n            } elseif (\\is_resource($value)) {\n                $result[$key] = ['resource', get_resource_type($value)];\n            } else {\n                $result[$key] = ['string', (string) $value];\n            }\n        }\n\n        return $result;\n    }\n\n    private function getClassNameFromIncomplete(\\__PHP_Incomplete_Class $value): string\n    {\n        $array = new \\ArrayObject($value);\n\n        return $array['__PHP_Incomplete_Class_Name'];\n    }\n\n    public function getTraceAsString()\n    {\n        return $this->traceAsString;\n    }\n\n    public function getAsString()\n    {\n        $message = '';\n        $next = false;\n\n        foreach (array_reverse(array_merge([$this], $this->getAllPrevious())) as $exception) {\n            if ($next) {\n                $message .= 'Next ';\n            } else {\n                $next = true;\n            }\n            $message .= $exception->getClass();\n\n            if ('' != $exception->getMessage()) {\n                $message .= ': '.$exception->getMessage();\n            }\n\n            $message .= ' in '.$exception->getFile().':'.$exception->getLine().\n                \"\\nStack trace:\\n\".$exception->getTraceAsString().\"\\n\\n\";\n        }\n\n        return rtrim($message);\n    }\n}\n"
  },
  {
    "path": "Exception/OutOfMemoryException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', OutOfMemoryException::class, \\Symfony\\Component\\ErrorHandler\\Error\\OutOfMemoryError::class), \\E_USER_DEPRECATED);\n\n/**\n * Out of memory exception.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Error\\OutOfMemoryError instead.\n */\nclass OutOfMemoryException extends FatalErrorException\n{\n}\n"
  },
  {
    "path": "Exception/SilencedErrorContext.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', SilencedErrorContext::class, \\Symfony\\Component\\ErrorHandler\\Exception\\SilencedErrorContext::class), \\E_USER_DEPRECATED);\n\n/**\n * Data Object that represents a Silenced Error.\n *\n * @author Grégoire Pineau <lyrixx@lyrixx.info>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Exception\\SilencedErrorContext instead.\n */\nclass SilencedErrorContext implements \\JsonSerializable\n{\n    public $count = 1;\n\n    private $severity;\n    private $file;\n    private $line;\n    private $trace;\n\n    public function __construct(int $severity, string $file, int $line, array $trace = [], int $count = 1)\n    {\n        $this->severity = $severity;\n        $this->file = $file;\n        $this->line = $line;\n        $this->trace = $trace;\n        $this->count = $count;\n    }\n\n    public function getSeverity()\n    {\n        return $this->severity;\n    }\n\n    public function getFile()\n    {\n        return $this->file;\n    }\n\n    public function getLine()\n    {\n        return $this->line;\n    }\n\n    public function getTrace()\n    {\n        return $this->trace;\n    }\n\n    public function jsonSerialize()\n    {\n        return [\n            'severity' => $this->severity,\n            'file' => $this->file,\n            'line' => $this->line,\n            'trace' => $this->trace,\n            'count' => $this->count,\n        ];\n    }\n}\n"
  },
  {
    "path": "Exception/UndefinedFunctionException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', UndefinedFunctionException::class, \\Symfony\\Component\\ErrorHandler\\Error\\UndefinedFunctionError::class), \\E_USER_DEPRECATED);\n\n/**\n * Undefined Function Exception.\n *\n * @author Konstanton Myakshin <koc-dp@yandex.ru>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Error\\UndefinedFunctionError instead.\n */\nclass UndefinedFunctionException extends FatalErrorException\n{\n    public function __construct(string $message, \\ErrorException $previous)\n    {\n        parent::__construct(\n            $message,\n            $previous->getCode(),\n            $previous->getSeverity(),\n            $previous->getFile(),\n            $previous->getLine(),\n            null,\n            true,\n            null,\n            $previous->getPrevious()\n        );\n        $this->setTrace($previous->getTrace());\n    }\n}\n"
  },
  {
    "path": "Exception/UndefinedMethodException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Exception;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', UndefinedMethodException::class, \\Symfony\\Component\\ErrorHandler\\Error\\UndefinedMethodError::class), \\E_USER_DEPRECATED);\n\n/**\n * Undefined Method Exception.\n *\n * @author Grégoire Pineau <lyrixx@lyrixx.info>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\Error\\UndefinedMethodError instead.\n */\nclass UndefinedMethodException extends FatalErrorException\n{\n    public function __construct(string $message, \\ErrorException $previous)\n    {\n        parent::__construct(\n            $message,\n            $previous->getCode(),\n            $previous->getSeverity(),\n            $previous->getFile(),\n            $previous->getLine(),\n            null,\n            true,\n            null,\n            $previous->getPrevious()\n        );\n        $this->setTrace($previous->getTrace());\n    }\n}\n"
  },
  {
    "path": "ExceptionHandler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug;\n\nuse Symfony\\Component\\Debug\\Exception\\FlattenException;\nuse Symfony\\Component\\Debug\\Exception\\OutOfMemoryException;\nuse Symfony\\Component\\HttpKernel\\Debug\\FileLinkFormatter;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', ExceptionHandler::class, \\Symfony\\Component\\ErrorHandler\\ErrorHandler::class), \\E_USER_DEPRECATED);\n\n/**\n * ExceptionHandler converts an exception to a Response object.\n *\n * It is mostly useful in debug mode to replace the default PHP/XDebug\n * output with something prettier and more useful.\n *\n * As this class is mainly used during Kernel boot, where nothing is yet\n * available, the Response content is always HTML.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @final since Symfony 4.3\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\ErrorHandler instead.\n */\nclass ExceptionHandler\n{\n    private const GHOST_ADDONS = [\n        '02-14' => self::GHOST_HEART,\n        '02-29' => self::GHOST_PLUS,\n        '10-18' => self::GHOST_GIFT,\n    ];\n\n    private const GHOST_GIFT = 'M124.005 5.36c.396-.715 1.119-1.648-.124-1.873-.346-.177-.692-.492-1.038-.141-.769.303-1.435.728-.627 1.523.36.514.685 1.634 1.092 1.758.242-.417.47-.842.697-1.266zm-1.699 1.977c-.706-1.26-1.274-2.612-2.138-3.774-1.051-1.123-3.122-.622-3.593.825-.625 1.431.724 3.14 2.251 2.96 1.159.02 2.324.072 3.48-.011zm5.867.043c1.502-.202 2.365-2.092 1.51-3.347-.757-1.34-2.937-1.387-3.698-.025-.659 1.1-1.23 2.25-1.835 3.38 1.336.077 2.686.06 4.023-.008zm2.487 1.611c.512-.45 2.494-.981.993-1.409-.372-.105-.805-.59-1.14-.457-.726.902-1.842 1.432-3.007 1.376-.228.075-1.391-.114-1.077.1.822.47 1.623.979 2.474 1.395.595-.317 1.173-.667 1.757-1.005zm-11.696.255l1.314-.765c-1.338-.066-2.87.127-3.881-.95-.285-.319-.559-.684-.954-.282-.473.326-1.929.66-.808 1.058.976.576 1.945 1.167 2.946 1.701.476-.223.926-.503 1.383-.762zm6.416 2.846c.567-.456 1.942-.89 1.987-1.38-1.282-.737-2.527-1.56-3.87-2.183-.461-.175-.835.094-1.207.328-1.1.654-2.225 1.267-3.288 1.978 1.39.86 2.798 1.695 4.219 2.504.725-.407 1.44-.83 2.16-1.247zm5.692 1.423l1.765-1.114c-.005-1.244.015-2.488-.019-3.732a77.306 77.306 0 0 0-3.51 2.084c-.126 1.282-.062 2.586-.034 3.876.607-.358 1.2-.741 1.798-1.114zm-13.804-.784c.06-1.06.19-2.269-1.09-2.583-.807-.376-1.926-1.341-2.548-1.332-.02 1.195-.01 2.39-.011 3.585 1.192.744 2.364 1.524 3.582 2.226.119-.616.041-1.269.067-1.896zm8.541 4.105l2.117-1.336c-.003-1.284.05-2.57-.008-3.853-.776.223-1.662.91-2.48 1.337l-1.834 1.075c.012 1.37-.033 2.744.044 4.113.732-.427 1.443-.887 2.161-1.336zm-2.957-.72v-2.057c-1.416-.828-2.828-1.664-4.25-2.482-.078 1.311-.033 2.627-.045 3.94 1.416.887 2.817 1.798 4.25 2.655.057-.683.036-1.372.045-2.057zm8.255 2.755l1.731-1.153c-.024-1.218.06-2.453-.062-3.658-1.2.685-2.358 1.464-3.537 2.195.028 1.261-.058 2.536.072 3.786.609-.373 1.2-.777 1.796-1.17zm-13.851-.683l-.014-1.916c-1.193-.746-2.37-1.517-3.58-2.234-.076 1.224-.033 2.453-.044 3.679 1.203.796 2.392 1.614 3.61 2.385.048-.636.024-1.276.028-1.914zm8.584 4.199l2.102-1.396c-.002-1.298.024-2.596-.01-3.893-1.427.88-2.843 1.775-4.25 2.686-.158 1.253-.055 2.545-.056 3.811.437.266 1.553-.912 2.214-1.208zm-2.988-.556c-.085-.894.365-2.154-.773-2.5-1.146-.727-2.288-1.46-3.45-2.163-.17 1.228.008 2.508-.122 3.751a79.399 79.399 0 0 0 4.278 2.885c.117-.641.044-1.32.067-1.973zm-4.872-.236l-5.087-3.396c.002-3.493-.047-6.988.015-10.48.85-.524 1.753-.954 2.627-1.434-.564-1.616.25-3.58 1.887-4.184 1.372-.563 3.025-.055 3.9 1.13l1.906-.978 1.916.987c.915-1.086 2.483-1.706 3.842-1.097 1.631.573 2.52 2.532 1.936 4.145.88.497 1.837.886 2.644 1.492.036 3.473 0 6.946-.003 10.419-3.374 2.233-6.693 4.55-10.122 6.699-.997 0-1.858-1.083-2.783-1.522a735.316 735.316 0 0 1-2.678-1.781z';\n    private const GHOST_HEART = 'M125.914 8.305c3.036-8.71 14.933 0 0 11.2-14.932-11.2-3.036-19.91 0-11.2z';\n    private const GHOST_PLUS = 'M111.368 8.97h7.324V1.645h7.512v7.323h7.324v7.513h-7.324v7.323h-7.512v-7.323h-7.324z';\n\n    private $debug;\n    private $charset;\n    private $handler;\n    private $caughtBuffer;\n    private $caughtLength;\n    private $fileLinkFormat;\n\n    public function __construct(bool $debug = true, string $charset = null, $fileLinkFormat = null)\n    {\n        $this->debug = $debug;\n        $this->charset = $charset ?: \\ini_get('default_charset') ?: 'UTF-8';\n        $this->fileLinkFormat = $fileLinkFormat;\n    }\n\n    /**\n     * Registers the exception handler.\n     *\n     * @param bool        $debug          Enable/disable debug mode, where the stack trace is displayed\n     * @param string|null $charset        The charset used by exception messages\n     * @param string|null $fileLinkFormat The IDE link template\n     *\n     * @return static\n     */\n    public static function register($debug = true, $charset = null, $fileLinkFormat = null)\n    {\n        $handler = new static($debug, $charset, $fileLinkFormat);\n\n        $prev = set_exception_handler([$handler, 'handle']);\n        if (\\is_array($prev) && $prev[0] instanceof ErrorHandler) {\n            restore_exception_handler();\n            $prev[0]->setExceptionHandler([$handler, 'handle']);\n        }\n\n        return $handler;\n    }\n\n    /**\n     * Sets a user exception handler.\n     *\n     * @param callable $handler An handler that will be called on Exception\n     *\n     * @return callable|null The previous exception handler if any\n     */\n    public function setHandler(callable $handler = null)\n    {\n        $old = $this->handler;\n        $this->handler = $handler;\n\n        return $old;\n    }\n\n    /**\n     * Sets the format for links to source files.\n     *\n     * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files\n     *\n     * @return string The previous file link format\n     */\n    public function setFileLinkFormat($fileLinkFormat)\n    {\n        $old = $this->fileLinkFormat;\n        $this->fileLinkFormat = $fileLinkFormat;\n\n        return $old;\n    }\n\n    /**\n     * Sends a response for the given Exception.\n     *\n     * To be as fail-safe as possible, the exception is first handled\n     * by our simple exception handler, then by the user exception handler.\n     * The latter takes precedence and any output from the former is cancelled,\n     * if and only if nothing bad happens in this handling path.\n     */\n    public function handle(\\Exception $exception)\n    {\n        if (null === $this->handler || $exception instanceof OutOfMemoryException) {\n            $this->sendPhpResponse($exception);\n\n            return;\n        }\n\n        $caughtLength = $this->caughtLength = 0;\n\n        ob_start(function ($buffer) {\n            $this->caughtBuffer = $buffer;\n\n            return '';\n        });\n\n        $this->sendPhpResponse($exception);\n        while (null === $this->caughtBuffer && ob_end_flush()) {\n            // Empty loop, everything is in the condition\n        }\n        if (isset($this->caughtBuffer[0])) {\n            ob_start(function ($buffer) {\n                if ($this->caughtLength) {\n                    // use substr_replace() instead of substr() for mbstring overloading resistance\n                    $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);\n                    if (isset($cleanBuffer[0])) {\n                        $buffer = $cleanBuffer;\n                    }\n                }\n\n                return $buffer;\n            });\n\n            echo $this->caughtBuffer;\n            $caughtLength = ob_get_length();\n        }\n        $this->caughtBuffer = null;\n\n        try {\n            ($this->handler)($exception);\n            $this->caughtLength = $caughtLength;\n        } catch (\\Exception $e) {\n            if (!$caughtLength) {\n                // All handlers failed. Let PHP handle that now.\n                throw $exception;\n            }\n        }\n    }\n\n    /**\n     * Sends the error associated with the given Exception as a plain PHP response.\n     *\n     * This method uses plain PHP functions like header() and echo to output\n     * the response.\n     *\n     * @param \\Throwable|FlattenException $exception A \\Throwable or FlattenException instance\n     */\n    public function sendPhpResponse($exception)\n    {\n        if ($exception instanceof \\Throwable) {\n            $exception = FlattenException::createFromThrowable($exception);\n        }\n\n        if (!headers_sent()) {\n            header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));\n            foreach ($exception->getHeaders() as $name => $value) {\n                header($name.': '.$value, false);\n            }\n            header('Content-Type: text/html; charset='.$this->charset);\n        }\n\n        echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));\n    }\n\n    /**\n     * Gets the full HTML content associated with the given exception.\n     *\n     * @param \\Exception|FlattenException $exception An \\Exception or FlattenException instance\n     *\n     * @return string The HTML content as a string\n     */\n    public function getHtml($exception)\n    {\n        if (!$exception instanceof FlattenException) {\n            $exception = FlattenException::create($exception);\n        }\n\n        return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));\n    }\n\n    /**\n     * Gets the HTML content associated with the given exception.\n     *\n     * @return string The content as a string\n     */\n    public function getContent(FlattenException $exception)\n    {\n        switch ($exception->getStatusCode()) {\n            case 404:\n                $title = 'Sorry, the page you are looking for could not be found.';\n                break;\n            default:\n                $title = $this->debug ? $this->escapeHtml($exception->getMessage()) : 'Whoops, looks like something went wrong.';\n        }\n\n        if (!$this->debug) {\n            return <<<EOF\n                <div class=\"container\">\n                    <h1>$title</h1>\n                </div>\nEOF;\n        }\n\n        $content = '';\n        try {\n            $count = \\count($exception->getAllPrevious());\n            $total = $count + 1;\n            foreach ($exception->toArray() as $position => $e) {\n                $ind = $count - $position + 1;\n                $class = $this->formatClass($e['class']);\n                $message = nl2br($this->escapeHtml($e['message']));\n                $content .= sprintf(<<<'EOF'\n                    <div class=\"trace trace-as-html\">\n                        <table class=\"trace-details\">\n                            <thead class=\"trace-head\"><tr><th>\n                                <h3 class=\"trace-class\">\n                                    <span class=\"text-muted\">(%d/%d)</span>\n                                    <span class=\"exception_title\">%s</span>\n                                </h3>\n                                <p class=\"break-long-words trace-message\">%s</p>\n                            </th></tr></thead>\n                            <tbody>\nEOF\n                    , $ind, $total, $class, $message);\n                foreach ($e['trace'] as $trace) {\n                    $content .= '<tr><td>';\n                    if ($trace['function']) {\n                        $content .= sprintf('at <span class=\"trace-class\">%s</span><span class=\"trace-type\">%s</span><span class=\"trace-method\">%s</span>', $this->formatClass($trace['class']), $trace['type'], $trace['function']);\n\n                        if (isset($trace['args'])) {\n                            $content .= sprintf('(<span class=\"trace-arguments\">%s</span>)', $this->formatArgs($trace['args']));\n                        }\n                    }\n                    if (isset($trace['file']) && isset($trace['line'])) {\n                        $content .= $this->formatPath($trace['file'], $trace['line']);\n                    }\n                    $content .= \"</td></tr>\\n\";\n                }\n\n                $content .= \"</tbody>\\n</table>\\n</div>\\n\";\n            }\n        } catch (\\Exception $e) {\n            // something nasty happened and we cannot throw an exception anymore\n            if ($this->debug) {\n                $e = FlattenException::create($e);\n                $title = sprintf('Exception thrown when handling an exception (%s: %s)', $e->getClass(), $this->escapeHtml($e->getMessage()));\n            } else {\n                $title = 'Whoops, looks like something went wrong.';\n            }\n        }\n\n        $symfonyGhostImageContents = $this->getSymfonyGhostAsSvg();\n\n        return <<<EOF\n            <div class=\"exception-summary\">\n                <div class=\"container\">\n                    <div class=\"exception-message-wrapper\">\n                        <h1 class=\"break-long-words exception-message\">$title</h1>\n                        <div class=\"exception-illustration hidden-xs-down\">$symfonyGhostImageContents</div>\n                    </div>\n                </div>\n            </div>\n\n            <div class=\"container\">\n                $content\n            </div>\nEOF;\n    }\n\n    /**\n     * Gets the stylesheet associated with the given exception.\n     *\n     * @return string The stylesheet as a string\n     */\n    public function getStylesheet(FlattenException $exception)\n    {\n        if (!$this->debug) {\n            return <<<'EOF'\n                body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif; margin: 0; }\n                .container { margin: 30px; max-width: 600px; }\n                h1 { color: #dc3545; font-size: 24px; }\nEOF;\n        }\n\n        return <<<'EOF'\n            body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; }\n\n            a { cursor: pointer; text-decoration: none; }\n            a:hover { text-decoration: underline; }\n            abbr[title] { border-bottom: none; cursor: help; text-decoration: none; }\n\n            code, pre { font: 13px/1.5 Consolas, Monaco, Menlo, \"Ubuntu Mono\", \"Liberation Mono\", monospace; }\n\n            table, tr, th, td { background: #FFF; border-collapse: collapse; vertical-align: top; }\n            table { background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2); margin: 1em 0; width: 100%; }\n            table th, table td { border: solid #E0E0E0; border-width: 1px 0; padding: 8px 10px; }\n            table th { background-color: #E0E0E0; font-weight: bold; text-align: left; }\n\n            .hidden-xs-down { display: none; }\n            .block { display: block; }\n            .break-long-words { -ms-word-break: break-all; word-break: break-all; word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; }\n            .text-muted { color: #999; }\n\n            .container { max-width: 1024px; margin: 0 auto; padding: 0 15px; }\n            .container::after { content: \"\"; display: table; clear: both; }\n\n            .exception-summary { background: #B0413E; border-bottom: 2px solid rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(0, 0, 0, .3); flex: 0 0 auto; margin-bottom: 30px; }\n\n            .exception-message-wrapper { display: flex; align-items: center; min-height: 70px; }\n            .exception-message { flex-grow: 1; padding: 30px 0; }\n            .exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; }\n            .exception-message.long { font-size: 18px; }\n            .exception-message a { border-bottom: 1px solid rgba(255, 255, 255, 0.5); font-size: inherit; text-decoration: none; }\n            .exception-message a:hover { border-bottom-color: #ffffff; }\n\n            .exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }\n\n            .trace + .trace { margin-top: 30px; }\n            .trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; }\n\n            .trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; }\n\n            .trace-file-path, .trace-file-path a { color: #222; margin-top: 3px; font-size: 13px; }\n            .trace-class { color: #B0413E; }\n            .trace-type { padding: 0 2px; }\n            .trace-method { color: #B0413E; font-weight: bold; }\n            .trace-arguments { color: #777; font-weight: normal; padding-left: 2px; }\n\n            @media (min-width: 575px) {\n                .hidden-xs-down { display: initial; }\n            }\nEOF;\n    }\n\n    private function decorate(string $content, string $css): string\n    {\n        return <<<EOF\n<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"{$this->charset}\" />\n        <meta name=\"robots\" content=\"noindex,nofollow\" />\n        <style>$css</style>\n    </head>\n    <body>\n        $content\n    </body>\n</html>\nEOF;\n    }\n\n    private function formatClass(string $class): string\n    {\n        $parts = explode('\\\\', $class);\n\n        return sprintf('<abbr title=\"%s\">%s</abbr>', $class, array_pop($parts));\n    }\n\n    private function formatPath(string $path, int $line): string\n    {\n        $file = $this->escapeHtml(preg_match('#[^/\\\\\\\\]*+$#', $path, $file) ? $file[0] : $path);\n        $fmt = $this->fileLinkFormat ?: \\ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');\n\n        if (!$fmt) {\n            return sprintf('<span class=\"block trace-file-path\">in <span title=\"%s%3$s\"><strong>%s</strong>%s</span></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');\n        }\n\n        if (\\is_string($fmt)) {\n            $i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \\strlen($f);\n            $fmt = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, \\PREG_SPLIT_DELIM_CAPTURE);\n\n            for ($i = 1; isset($fmt[$i]); ++$i) {\n                if (0 === strpos($path, $k = $fmt[$i++])) {\n                    $path = substr_replace($path, $fmt[$i], 0, \\strlen($k));\n                    break;\n                }\n            }\n\n            $link = strtr($fmt[0], ['%f' => $path, '%l' => $line]);\n        } else {\n            try {\n                $link = $fmt->format($path, $line);\n            } catch (\\Exception $e) {\n                return sprintf('<span class=\"block trace-file-path\">in <span title=\"%s%3$s\"><strong>%s</strong>%s</span></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');\n            }\n        }\n\n        return sprintf('<span class=\"block trace-file-path\">in <a href=\"%s\" title=\"Go to source\"><strong>%s</string>%s</a></span>', $this->escapeHtml($link), $file, 0 < $line ? ' line '.$line : '');\n    }\n\n    /**\n     * Formats an array as a string.\n     */\n    private function formatArgs(array $args): string\n    {\n        $result = [];\n        foreach ($args as $key => $item) {\n            if ('object' === $item[0]) {\n                $formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));\n            } elseif ('array' === $item[0]) {\n                $formattedValue = sprintf('<em>array</em>(%s)', \\is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);\n            } elseif ('null' === $item[0]) {\n                $formattedValue = '<em>null</em>';\n            } elseif ('boolean' === $item[0]) {\n                $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';\n            } elseif ('resource' === $item[0]) {\n                $formattedValue = '<em>resource</em>';\n            } else {\n                $formattedValue = str_replace(\"\\n\", '', $this->escapeHtml(var_export($item[1], true)));\n            }\n\n            $result[] = \\is_int($key) ? $formattedValue : sprintf(\"'%s' => %s\", $this->escapeHtml($key), $formattedValue);\n        }\n\n        return implode(', ', $result);\n    }\n\n    /**\n     * HTML-encodes a string.\n     */\n    private function escapeHtml(string $str): string\n    {\n        return htmlspecialchars($str, \\ENT_COMPAT | \\ENT_SUBSTITUTE, $this->charset);\n    }\n\n    private function getSymfonyGhostAsSvg(): string\n    {\n        return '<svg viewBox=\"0 0 136 81\" xmlns=\"http://www.w3.org/2000/svg\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" stroke-linejoin=\"round\" stroke-miterlimit=\"1.4\"><path d=\"M92.4 20.4a23.2 23.2 0 0 1 9 1.9 23.7 23.7 0 0 1 5.2 3 24.3 24.3 0 0 1 3.4 3.4 24.8 24.8 0 0 1 5 9.4c.5 1.7.8 3.4 1 5.2v14.5h.4l.5.2a7.4 7.4 0 0 0 2.5.2l.2-.2.6-.8.8-1.3-.2-.1a5.5 5.5 0 0 1-.8-.3 5.6 5.6 0 0 1-2.3-1.8 5.7 5.7 0 0 1-.9-1.6 6.5 6.5 0 0 1-.2-2.8 7.3 7.3 0 0 1 .5-2l.3-.3.8-.9.3-.3c.2-.2.5-.3.8-.3H120.7c.2 0 .3-.1.4 0h.4l.2.1.3.2.2-.4.3-.4.1-.1 1.2-1 .3-.2.4-.1.4-.1h.3l1.5.1.4.1.8.5.1.2 1 1.1v.2H129.4l.4-.2 1.4-.5h1.1c.3 0 .7.2 1 .4.2 0 .3.2.5.3l.2.2.5.3.4.6.1.3.4 1.4.1.4v.6a7.8 7.8 0 0 1-.1.6 9.9 9.9 0 0 1-.8 2.4 7.8 7.8 0 0 1-3 3.3 6.4 6.4 0 0 1-1 .5 6.1 6.1 0 0 1-.6.2l-.7.1h-.1a23.4 23.4 0 0 1-.2 1.7 14.3 14.3 0 0 1-.6 2.1l-.8 2a9.2 9.2 0 0 1-.4.6l-.7 1a9.1 9.1 0 0 1-2.3 2.2c-.9.5-2 .6-3 .7l-1.4.1h-.5l-.4.1a15.8 15.8 0 0 1-2.8-.1v4.2a9.7 9.7 0 0 1-.7 3.5 9.6 9.6 0 0 1-1.7 2.8 9.3 9.3 0 0 1-3 2.3 9 9 0 0 1-5.4.7 9 9 0 0 1-3-1 9.4 9.4 0 0 1-2.7-2.5 10 10 0 0 1-1 1.2 9.3 9.3 0 0 1-2 1.3 9 9 0 0 1-2.4 1 9 9 0 0 1-6.5-1.1A9.4 9.4 0 0 1 85 77V77a10.9 10.9 0 0 1-.6.6 9.3 9.3 0 0 1-2.7 2 9 9 0 0 1-6 .8 9 9 0 0 1-2.4-1 9.3 9.3 0 0 1-2.3-1.7 9.6 9.6 0 0 1-1.8-2.8 9.7 9.7 0 0 1-.8-3.7v-4a18.5 18.5 0 0 1-2.9.2l-1.2-.1c-1.9-.3-3.7-1-5.1-2.1A8.2 8.2 0 0 1 58 64a10.2 10.2 0 0 1-.9-1.2 15.3 15.3 0 0 1-.7-1.3 20.8 20.8 0 0 1-1.9-6.2v-.2a6.5 6.5 0 0 1-1-.3 6.1 6.1 0 0 1-.6-.3 6.6 6.6 0 0 1-.9-.5 8.2 8.2 0 0 1-2.7-3.8 10 10 0 0 1-.3-1 10.3 10.3 0 0 1-.3-1.9V47v-.4l.1-.4.6-1.4.1-.2a2 2 0 0 1 .8-.8l.3-.2.3-.2a3.2 3.2 0 0 1 1.8-.5h.4l.3.2 1.4.6.2.2.4.3.3.4.7-.7.2-.2.4-.2.6-.2h2.1l.4.2.4.2.3.2.8 1 .2-.1h.1v-.1H63l1.1.1h.3l.8.5.3.4.7 1 .2.3.1.5a11 11 0 0 1 .2 1.5c0 .8 0 1.6-.3 2.3a6 6 0 0 1-.5 1.2 5.5 5.5 0 0 1-3.3 2.5 12.3 12.3 0 0 0 1.4 3h.1l.2.1 1 .2h1.5l.5-.2H67.8l.5-.2h.1V44v-.4a26.7 26.7 0 0 1 .3-2.3 24.7 24.7 0 0 1 5.7-12.5 24.2 24.2 0 0 1 3.5-3.3 23.7 23.7 0 0 1 4.9-3 23.2 23.2 0 0 1 5.6-1.7 23.7 23.7 0 0 1 4-.3zm-.3 2a21.2 21.2 0 0 0-8 1.7 21.6 21.6 0 0 0-4.8 2.7 22.2 22.2 0 0 0-3.2 3 22.7 22.7 0 0 0-5 9.2 23.4 23.4 0 0 0-.7 4.9v15.7l-.5.1a34.3 34.3 0 0 1-1.5.3h-.2l-.4.1h-.4l-.9.2a10 10 0 0 1-1.9 0c-.5 0-1-.2-1.5-.4a1.8 1.8 0 0 1-.3-.2 2 2 0 0 1-.3-.3 5.2 5.2 0 0 1-.1-.2 9 9 0 0 1-.6-.9 13.8 13.8 0 0 1-1-2 14.3 14.3 0 0 1-.6-2 14 14 0 0 1-.1-.8v-.2h.3a12.8 12.8 0 0 0 1.4-.2 4.4 4.4 0 0 0 .3 0 3.6 3.6 0 0 0 1.1-.7 3.4 3.4 0 0 0 1.2-1.7l.2-1.2a5.1 5.1 0 0 0 0-.8 7.2 7.2 0 0 0-.1-.8l-.7-1-1.2-.2-1 .7-.1 1.3a5 5 0 0 1 .1.4v.6a1 1 0 0 1 0 .3c-.1.3-.4.4-.7.5l-1.2.4v-.7A9.9 9.9 0 0 1 60 49l.3-.6v-.2l.1-.1v-1.6l-1-1.2h-1.5l-1 1.1v.4a5.3 5.3 0 0 0-.2.6 5.5 5.5 0 0 0 0 .5c0 .7 0 1.4.3 2 0 .4.2.8.4 1.2L57 51a9.5 9.5 0 0 1-1.1-.5h-.2a2 2 0 0 1-.4-.3c-.4-.4-.5-1-.6-1.6a5.6 5.6 0 0 1 0-.5v-.5-.5l-.6-1.5-1.4-.6-.9.3s-.2 0-.3.2a2 2 0 0 1-.1 0l-.6 1.4v.7a8.5 8.5 0 0 0 .5 2c.4 1.1 1 2.1 2 2.8a4.7 4.7 0 0 0 2.1.9h1a22.8 22.8 0 0 0 .1 1 18.1 18.1 0 0 0 .8 3.8 18.2 18.2 0 0 0 1.6 3.7l1 1.3c1 1 2.3 1.6 3.7 2a11.7 11.7 0 0 0 4.8 0h.4l.5-.2.5-.1.6-.2v6.6a8 8 0 0 0 .1 1.3 7.5 7.5 0 0 0 2.4 4.3 7.2 7.2 0 0 0 2.3 1.3 7 7 0 0 0 7-1.1 7.5 7.5 0 0 0 2-2.6A7.7 7.7 0 0 0 85 72V71a8.2 8.2 0 0 0 .2 1.3c0 .7.3 1.4.6 2a7.5 7.5 0 0 0 1.7 2.3 7.3 7.3 0 0 0 2.2 1.4 7.1 7.1 0 0 0 4.6.2 7.2 7.2 0 0 0 2.4-1.2 7.5 7.5 0 0 0 2.1-2.7 7.8 7.8 0 0 0 .7-2.4V71a9.3 9.3 0 0 0 .1.6 7.6 7.6 0 0 0 .6 2.5 7.5 7.5 0 0 0 2.4 3 7.1 7.1 0 0 0 7 .8 7.3 7.3 0 0 0 2.3-1.5 7.5 7.5 0 0 0 1.6-2.3 7.6 7.6 0 0 0 .5-2l.1-1.1v-6.7l.4.1a12.2 12.2 0 0 0 2 .5 11.1 11.1 0 0 0 2.5 0h.8l1.2-.1a9.5 9.5 0 0 0 1.4-.2l.9-.3a3.5 3.5 0 0 0 .6-.4l1.2-1.4a12.2 12.2 0 0 0 .8-1.2c0-.3.2-.5.3-.7a15.9 15.9 0 0 0 .7-2l.3-1.6v-1.3l.2-.9V54.6a15.5 15.5 0 0 0 1.8 0 4.5 4.5 0 0 0 1.4-.5 5.7 5.7 0 0 0 2.5-3.2 7.6 7.6 0 0 0 .4-1.5v-.3l-.4-1.4a5.2 5.2 0 0 1-.2-.1l-.4-.4a3.8 3.8 0 0 0-.2 0 1.4 1.4 0 0 0-.5-.2l-1.4.4-.7 1.3v.7a5.7 5.7 0 0 1-.1.8l-.7 1.4a1.9 1.9 0 0 1-.5.3h-.3a9.6 9.6 0 0 1-.8.3 8.8 8.8 0 0 1-.6 0l.2-.4.2-.5.2-.3v-.4l.1-.2V50l.1-1 .1-.6v-.6a4.8 4.8 0 0 0 0-.8v-.2l-1-1.1-1.5-.2-1.1 1-.2 1.4v.1l.2.4.2.3v.4l.1 1.1v.3l.1.5v.8a9.6 9.6 0 0 1-.8-.3l-.2-.1h-.3l-.8-.1h-.2a1.6 1.6 0 0 1-.2-.2.9.9 0 0 1-.2-.2 1 1 0 0 1-.1-.5l.2-.9v-1.2l-.9-.8h-1.2l-.8.9v.3a4.8 4.8 0 0 0-.3 2l.3.9a3.5 3.5 0 0 0 1.2 1.6l1 .5.8.2 1.4.1h.4l.2.1a12.1 12.1 0 0 1-1 2.6 13.2 13.2 0 0 1-.8 1.5 9.5 9.5 0 0 1-1 1.2l-.2.3a1.7 1.7 0 0 1-.4.3 2.4 2.4 0 0 1-.7.2h-2.5a7.8 7.8 0 0 1-.6-.2l-.7-.2h-.2a14.8 14.8 0 0 1-.6-.2 23.4 23.4 0 0 1-.4-.1l-.4-.1-.3-.1V43.9a34.6 34.6 0 0 0 0-.6 23.6 23.6 0 0 0-.4-3 22.7 22.7 0 0 0-1.5-4.7 22.6 22.6 0 0 0-4.6-6.7 21.9 21.9 0 0 0-6.9-4.7 21.2 21.2 0 0 0-8.1-1.8H92zm9.1 33.7l.3.1a1 1 0 0 1 .6.8v.4a8.4 8.4 0 0 1 0 .5 8.8 8.8 0 0 1-1.6 4.2l-1 1.3A10 10 0 0 1 95 66c-1.3.3-2.7.4-4 .3a10.4 10.4 0 0 1-2.7-.8 10 10 0 0 1-3.6-2.5 9.3 9.3 0 0 1-.8-1 9 9 0 0 1-.7-1.2 8.6 8.6 0 0 1-.8-3.4V57a1 1 0 0 1 .3-.6 1 1 0 0 1 1.3-.2 1 1 0 0 1 .4.8v.4a6.5 6.5 0 0 0 .5 2.2 7 7 0 0 0 2.1 2.8l1 .6c2.6 1.6 6 1.6 8.5 0a8 8 0 0 0 1.1-.6 7.6 7.6 0 0 0 1.2-1.2 7 7 0 0 0 1-1.7 6.5 6.5 0 0 0 .4-2.5 1 1 0 0 1 .7-1h.4zM30.7 43.7c-15.5 1-28.5-6-30.1-16.4C-1.2 15.7 11.6 4 29 1.3 46.6-1.7 62.3 5.5 64 17.1c1.6 10.4-8.7 21-23.7 25a31.2 31.2 0 0 0 0 .9v.3a19 19 0 0 0 .1 1l.1.4.1.9a4.7 4.7 0 0 0 .5 1l.7 1a9.2 9.2 0 0 0 1.2 1l1.5.8.6.8-.7.6-1.1.3a11.2 11.2 0 0 1-2.6.4 8.6 8.6 0 0 1-3-.5 8.5 8.5 0 0 1-1-.4 11.2 11.2 0 0 1-1.8-1.2 13.3 13.3 0 0 1-1-1 18 18 0 0 1-.7-.6l-.4-.4a23.4 23.4 0 0 1-1.3-1.8l-.1-.1-.3-.5V45l-.3-.6v-.7zM83.1 36c3.6 0 6.5 3.2 6.5 7.1 0 4-3 7.2-6.5 7.2S76.7 47 76.7 43 79.6 36 83 36zm18 0c3.6 0 6.5 3.2 6.5 7.1 0 4-2.9 7.2-6.4 7.2S94.7 47 94.7 43s3-7.1 6.5-7.1zm-18 6.1c2 0 3.5 1.6 3.5 3.6S85 49.2 83 49.2s-3.4-1.6-3.4-3.6S81.2 42 83 42zm17.9 0c1.9 0 3.4 1.6 3.4 3.6s-1.5 3.6-3.4 3.6c-2 0-3.5-1.6-3.5-3.6S99.1 42 101 42zM17 28c-.3 1.6-1.8 5-5.2 5.8-2.5.6-4.1-.8-4.5-2.6-.4-1.9.7-3.5 2.1-4.5A3.5 3.5 0 0 1 8 24.6c-.4-2 .8-3.7 3.2-4.2 1.9-.5 3.1.2 3.4 1.5.3 1.1-.5 2.2-1.8 2.5-.9.3-1.6 0-1.7-.6a1.4 1.4 0 0 1 0-.7s.3.2 1 0c.7-.1 1-.7.9-1.2-.2-.6-1-.8-1.8-.6-1 .2-2 1-1.7 2.6.3 1 .9 1.6 1.5 1.8l.7-.2c1-.2 1.5 0 1.6.5 0 .4-.2 1-1.2 1.2a3.3 3.3 0 0 1-1.5 0c-.9.7-1.6 1.9-1.3 3.2.3 1.3 1.3 2.2 3 1.8 2.5-.7 3.8-3.7 4.2-5-.3-.5-.6-1-.7-1.6-.1-.5.1-1 .9-1.2.4 0 .7.2.8.8a2.8 2.8 0 0 1 0 1l.7 1c.6-2 1.4-4 1.7-4 .6-.2 1.5.6 1.5.6-.8.7-1.7 2.4-2.3 4.2.8.6 1.6 1 2.1 1 .5-.1.8-.6 1-1.2-.3-2.2 1-4.3 2.3-4.6.7-.2 1.3.2 1.4.8.1.5 0 1.3-.9 1.7-.2-1-.6-1.3-1-1.3-.4.1-.7 1.4-.4 2.8.2 1 .7 1.5 1.3 1.4.8-.2 1.3-1.2 1.7-2.1-.3-2.1.9-4.2 2.2-4.5.7-.2 1.2.1 1.4 1 .4 1.4-1 2.8-2.2 3.4.3.7.7 1 1.3.9 1-.3 1.6-1.5 2-2.5l-.5-3v-.3s1.6-.3 1.8.6v.1c.2-.6.7-1.2 1.3-1.4.8-.1 1.5.6 1.7 1.6.5 2.2-.5 4.4-1.8 4.7H33a31.9 31.9 0 0 0 1 5.2c-.4.1-1.8.4-2-.4l-.5-5.6c-.5 1-1.3 2.2-2.5 2.4-1 .3-1.6-.3-2-1.1-.5 1-1.3 2.1-2.4 2.4-.8.2-1.5-.1-2-1-.3.8-.9 1.5-1.5 1.7-.7.1-1.5-.3-2.4-1-.3.8-.4 1.6-.4 2.2 0 0-.7 0-.8-.4-.1-.5 0-1.5.3-2.7a10.3 10.3 0 0 1-.7-.8zm38.2-17.8l.2.9c.5 1.9.4 4.4.8 6.4 0 .6-.4 3-1.4 3.3-.2 0-.3 0-.4-.4-.1-.7 0-1.6-.3-2.6-.2-1.1-.8-1.6-1.5-1.5-.8.2-1.3 1-1.6 2l-.1-.5c-.2-1-1.8-.6-1.8-.6a6.2 6.2 0 0 1 .4 1.3l.2 1c-.2.5-.6 1-1.2 1l-.2.1a7 7 0 0 0-.1-.8c-.3-1.1-1-2-1.6-1.8a.7.7 0 0 0-.4.3c-1.3.3-2.4 2-2.1 3.9-.2.9-.6 1.7-1 1.9-.5 0-.8-.5-1.1-1.8l-.1-1.2a4 4 0 0 0 0-1.7c0-.4-.4-.7-.8-.6-.7.2-.9 1.7-.5 3.8-.2 1-.6 2-1.3 2-.4.2-.8-.2-1-1l-.2-3c1.2-.5 2-1 1.8-1.7-.1-.5-.8-.7-.8-.7s0 .7-1 1.2l-.2-1.4c-.1-.6-.4-1-1.7-.6l.4 1 .2 1.5h-1v.8c0 .3.4.3 1 .2 0 1.3 0 2.7.2 3.6.3 1.4 1.2 2 2 1.7 1-.2 1.6-1.3 2-2.3.3 1.2 1 2 1.9 1.7.7-.2 1.2-1.1 1.6-2.2.4.8 1.1 1.1 2 1 1.2-.4 1.7-1.6 1.8-2.8h.2c.6-.2 1-.6 1.3-1 0 .8 0 1.5.2 2.1.1.5.3.7.6.6.5-.1 1-.9 1-.9a4 4 0 0 1-.3-1c-.3-1.3.3-3.6 1-3.7.2 0 .3.2.5.7v.8l.2 1.5v.7c.2.7.7 1.3 1.5 1 1.3-.2 2-2.6 2.1-3.9.3.2.6.2 1 .1-.6-2.2 0-6.1-.3-7.9-.1-.4-1-.5-1.7-.5h-.4zm-21.5 12c.4 0 .7.3 1 1.1.2 1.3-.3 2.6-.9 2.8-.2 0-.7 0-1-1.2v-.4c0-1.3.4-2 1-2.2zm-5.2 1c.3 0 .6.2.6.5.2.6-.3 1.3-1.2 2-.3-1.4.1-2.3.6-2.5zm18-.4c-.5.2-1-.4-1.2-1.2-.2-1 0-2.1.7-2.5v.5c.2.7.6 1.5 1.3 1.9 0 .7-.2 1.2-.7 1.3zm10-1.6c0 .5.4.7 1 .6.8-.2 1-1 .8-1.6 0-.5-.4-1-1-.8-.5.1-1 .9-.8 1.8zm-14.3-5.5c0-.4-.5-.7-1-.5-.8.2-1 1-.9 1.5.2.6.5 1 1 .8.5 0 1.1-1 1-1.8z\" fill=\"#fff\" fill-opacity=\".6\"/>'.$this->addElementToGhost().'</svg>';\n    }\n\n    private function addElementToGhost(): string\n    {\n        if (!isset(self::GHOST_ADDONS[date('m-d')])) {\n            return '';\n        }\n\n        return '<path d=\"'.self::GHOST_ADDONS[date('m-d')].'\" fill=\"#fff\" fill-opacity=\"0.6\"></path>';\n    }\n}\n"
  },
  {
    "path": "FatalErrorHandler/ClassNotFoundFatalErrorHandler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\FatalErrorHandler;\n\nuse Composer\\Autoload\\ClassLoader as ComposerClassLoader;\nuse Symfony\\Component\\ClassLoader\\ClassLoader as SymfonyClassLoader;\nuse Symfony\\Component\\Debug\\DebugClassLoader;\nuse Symfony\\Component\\Debug\\Exception\\ClassNotFoundException;\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', ClassNotFoundFatalErrorHandler::class, \\Symfony\\Component\\ErrorHandler\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler::class), \\E_USER_DEPRECATED);\n\n/**\n * ErrorHandler for classes that do not exist.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler instead.\n */\nclass ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function handleError(array $error, FatalErrorException $exception)\n    {\n        if (!preg_match('/^(Class|Interface|Trait) [\\'\"]([^\\'\"]+)[\\'\"] not found$/', $error['message'], $matches)) {\n            return null;\n        }\n        $typeName = strtolower($matches[1]);\n        $fullyQualifiedClassName = $matches[2];\n\n        if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\\\')) {\n            $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);\n            $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);\n            $message = sprintf('Attempted to load %s \"%s\" from namespace \"%s\".', $typeName, $className, $namespacePrefix);\n            $tail = ' for another namespace?';\n        } else {\n            $className = $fullyQualifiedClassName;\n            $message = sprintf('Attempted to load %s \"%s\" from the global namespace.', $typeName, $className);\n            $tail = '?';\n        }\n\n        if ($candidates = $this->getClassCandidates($className)) {\n            $tail = array_pop($candidates).'\"?';\n            if ($candidates) {\n                $tail = ' for e.g. \"'.implode('\", \"', $candidates).'\" or \"'.$tail;\n            } else {\n                $tail = ' for \"'.$tail;\n            }\n        }\n        $message .= \"\\nDid you forget a \\\"use\\\" statement\".$tail;\n\n        return new ClassNotFoundException($message, $exception);\n    }\n\n    /**\n     * Tries to guess the full namespace for a given class name.\n     *\n     * By default, it looks for PSR-0 and PSR-4 classes registered via a Symfony or a Composer\n     * autoloader (that should cover all common cases).\n     *\n     * @param string $class A class name (without its namespace)\n     *\n     * @return array An array of possible fully qualified class names\n     */\n    private function getClassCandidates(string $class): array\n    {\n        if (!\\is_array($functions = spl_autoload_functions())) {\n            return [];\n        }\n\n        // find Symfony and Composer autoloaders\n        $classes = [];\n\n        foreach ($functions as $function) {\n            if (!\\is_array($function)) {\n                continue;\n            }\n            // get class loaders wrapped by DebugClassLoader\n            if ($function[0] instanceof DebugClassLoader) {\n                $function = $function[0]->getClassLoader();\n\n                if (!\\is_array($function)) {\n                    continue;\n                }\n            }\n\n            if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader) {\n                foreach ($function[0]->getPrefixes() as $prefix => $paths) {\n                    foreach ($paths as $path) {\n                        $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));\n                    }\n                }\n            }\n            if ($function[0] instanceof ComposerClassLoader) {\n                foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {\n                    foreach ($paths as $path) {\n                        $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));\n                    }\n                }\n            }\n        }\n\n        return array_unique($classes);\n    }\n\n    private function findClassInPath(string $path, string $class, string $prefix): array\n    {\n        if (!$path = realpath($path.'/'.strtr($prefix, '\\\\_', '//')) ?: realpath($path.'/'.\\dirname(strtr($prefix, '\\\\_', '//'))) ?: realpath($path)) {\n            return [];\n        }\n\n        $classes = [];\n        $filename = $class.'.php';\n        foreach (new \\RecursiveIteratorIterator(new \\RecursiveDirectoryIterator($path, \\RecursiveDirectoryIterator::SKIP_DOTS), \\RecursiveIteratorIterator::LEAVES_ONLY) as $file) {\n            if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {\n                $classes[] = $class;\n            }\n        }\n\n        return $classes;\n    }\n\n    private function convertFileToClass(string $path, string $file, string $prefix): ?string\n    {\n        $candidates = [\n            // namespaced class\n            $namespacedClass = str_replace([$path.\\DIRECTORY_SEPARATOR, '.php', '/'], ['', '', '\\\\'], $file),\n            // namespaced class (with target dir)\n            $prefix.$namespacedClass,\n            // namespaced class (with target dir and separator)\n            $prefix.'\\\\'.$namespacedClass,\n            // PEAR class\n            str_replace('\\\\', '_', $namespacedClass),\n            // PEAR class (with target dir)\n            str_replace('\\\\', '_', $prefix.$namespacedClass),\n            // PEAR class (with target dir and separator)\n            str_replace('\\\\', '_', $prefix.'\\\\'.$namespacedClass),\n        ];\n\n        if ($prefix) {\n            $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });\n        }\n\n        // We cannot use the autoloader here as most of them use require; but if the class\n        // is not found, the new autoloader call will require the file again leading to a\n        // \"cannot redeclare class\" error.\n        foreach ($candidates as $candidate) {\n            if ($this->classExists($candidate)) {\n                return $candidate;\n            }\n        }\n\n        try {\n            require_once $file;\n        } catch (\\Throwable $e) {\n            return null;\n        }\n\n        foreach ($candidates as $candidate) {\n            if ($this->classExists($candidate)) {\n                return $candidate;\n            }\n        }\n\n        return null;\n    }\n\n    private function classExists(string $class): bool\n    {\n        return class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);\n    }\n}\n"
  },
  {
    "path": "FatalErrorHandler/FatalErrorHandlerInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\FatalErrorHandler;\n\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', FatalErrorHandlerInterface::class, \\Symfony\\Component\\ErrorHandler\\FatalErrorHandler\\FatalErrorHandlerInterface::class), \\E_USER_DEPRECATED);\n\n/**\n * Attempts to convert fatal errors to exceptions.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\FatalErrorHandler\\FatalErrorHandlerInterface instead.\n */\ninterface FatalErrorHandlerInterface\n{\n    /**\n     * Attempts to convert an error into an exception.\n     *\n     * @param array $error An array as returned by error_get_last()\n     *\n     * @return FatalErrorException|null A FatalErrorException instance if the class is able to convert the error, null otherwise\n     */\n    public function handleError(array $error, FatalErrorException $exception);\n}\n"
  },
  {
    "path": "FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\FatalErrorHandler;\n\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\nuse Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', UndefinedFunctionFatalErrorHandler::class, \\Symfony\\Component\\ErrorHandler\\ErrorEnhancer\\UndefinedFunctionErrorEnhancer::class), \\E_USER_DEPRECATED);\n\n/**\n * ErrorHandler for undefined functions.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\ErrorEnhancer\\UndefinedFunctionErrorEnhancer instead.\n */\nclass UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function handleError(array $error, FatalErrorException $exception)\n    {\n        $messageLen = \\strlen($error['message']);\n        $notFoundSuffix = '()';\n        $notFoundSuffixLen = \\strlen($notFoundSuffix);\n        if ($notFoundSuffixLen > $messageLen) {\n            return null;\n        }\n\n        if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {\n            return null;\n        }\n\n        $prefix = 'Call to undefined function ';\n        $prefixLen = \\strlen($prefix);\n        if (0 !== strpos($error['message'], $prefix)) {\n            return null;\n        }\n\n        $fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);\n        if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\\\')) {\n            $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1);\n            $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex);\n            $message = sprintf('Attempted to call function \"%s\" from namespace \"%s\".', $functionName, $namespacePrefix);\n        } else {\n            $functionName = $fullyQualifiedFunctionName;\n            $message = sprintf('Attempted to call function \"%s\" from the global namespace.', $functionName);\n        }\n\n        $candidates = [];\n        foreach (get_defined_functions() as $type => $definedFunctionNames) {\n            foreach ($definedFunctionNames as $definedFunctionName) {\n                if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\\\')) {\n                    $definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1);\n                } else {\n                    $definedFunctionNameBasename = $definedFunctionName;\n                }\n\n                if ($definedFunctionNameBasename === $functionName) {\n                    $candidates[] = '\\\\'.$definedFunctionName;\n                }\n            }\n        }\n\n        if ($candidates) {\n            sort($candidates);\n            $last = array_pop($candidates).'\"?';\n            if ($candidates) {\n                $candidates = 'e.g. \"'.implode('\", \"', $candidates).'\" or \"'.$last;\n            } else {\n                $candidates = '\"'.$last;\n            }\n            $message .= \"\\nDid you mean to call \".$candidates;\n        }\n\n        return new UndefinedFunctionException($message, $exception);\n    }\n}\n"
  },
  {
    "path": "FatalErrorHandler/UndefinedMethodFatalErrorHandler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\FatalErrorHandler;\n\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\nuse Symfony\\Component\\Debug\\Exception\\UndefinedMethodException;\n\n@trigger_error(sprintf('The \"%s\" class is deprecated since Symfony 4.4, use \"%s\" instead.', UndefinedMethodFatalErrorHandler::class, \\Symfony\\Component\\ErrorHandler\\ErrorEnhancer\\UndefinedMethodErrorEnhancer::class), \\E_USER_DEPRECATED);\n\n/**\n * ErrorHandler for undefined methods.\n *\n * @author Grégoire Pineau <lyrixx@lyrixx.info>\n *\n * @deprecated since Symfony 4.4, use Symfony\\Component\\ErrorHandler\\ErrorEnhancer\\UndefinedMethodErrorEnhancer instead.\n */\nclass UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function handleError(array $error, FatalErrorException $exception)\n    {\n        preg_match('/^Call to undefined method (.*)::(.*)\\(\\)$/', $error['message'], $matches);\n        if (!$matches) {\n            return null;\n        }\n\n        $className = $matches[1];\n        $methodName = $matches[2];\n\n        $message = sprintf('Attempted to call an undefined method named \"%s\" of class \"%s\".', $methodName, $className);\n\n        if ('' === $methodName || !class_exists($className) || null === $methods = get_class_methods($className)) {\n            // failed to get the class or its methods on which an unknown method was called (for example on an anonymous class)\n            return new UndefinedMethodException($message, $exception);\n        }\n\n        $candidates = [];\n        foreach ($methods as $definedMethodName) {\n            $lev = levenshtein($methodName, $definedMethodName);\n            if ($lev <= \\strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {\n                $candidates[] = $definedMethodName;\n            }\n        }\n\n        if ($candidates) {\n            sort($candidates);\n            $last = array_pop($candidates).'\"?';\n            if ($candidates) {\n                $candidates = 'e.g. \"'.implode('\", \"', $candidates).'\" or \"'.$last;\n            } else {\n                $candidates = '\"'.$last;\n            }\n\n            $message .= \"\\nDid you mean to call \".$candidates;\n        }\n\n        return new UndefinedMethodException($message, $exception);\n    }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2004-2022 Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "Debug Component\n===============\n\n**CAUTION**: this component is deprecated since Symfony 4.4. Instead, use the\n[ErrorHandler component](https://github.com/symfony/symfony/tree/master/src/Symfony/Component/ErrorHandler).\n\n-----\n\nThe Debug component provides tools to ease debugging PHP code.\n\nGetting Started\n---------------\n\n```\n$ composer require symfony/debug\n```\n\n```php\nuse Symfony\\Component\\Debug\\Debug;\n\nDebug::enable();\n```\n\nResources\n---------\n\n * [Contributing](https://symfony.com/doc/current/contributing/index.html)\n * [Report issues](https://github.com/symfony/symfony/issues) and\n   [send Pull Requests](https://github.com/symfony/symfony/pulls)\n   in the [main Symfony repository](https://github.com/symfony/symfony)\n"
  },
  {
    "path": "Tests/DebugClassLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Bridge\\Debug\\Tests\\Fixtures\\ExtendsDeprecatedParent;\nuse Symfony\\Component\\Debug\\DebugClassLoader;\n\n/**\n * @group legacy\n */\nclass DebugClassLoaderTest extends TestCase\n{\n    /**\n     * @var int Error reporting level before running tests\n     */\n    private $errorReporting;\n\n    private $loader;\n\n    protected function setUp(): void\n    {\n        $this->errorReporting = error_reporting(E_ALL);\n        $this->loader = [new DebugClassLoader([new ClassLoader(), 'loadClass']), 'loadClass'];\n        spl_autoload_register($this->loader, true, true);\n    }\n\n    protected function tearDown(): void\n    {\n        spl_autoload_unregister($this->loader);\n        error_reporting($this->errorReporting);\n    }\n\n    /**\n     * @runInSeparateProcess\n     */\n    public function testIdempotence()\n    {\n        DebugClassLoader::enable();\n        DebugClassLoader::enable();\n\n        $functions = spl_autoload_functions();\n        foreach ($functions as $function) {\n            if (\\is_array($function) && $function[0] instanceof DebugClassLoader) {\n                $reflClass = new \\ReflectionClass($function[0]);\n                $reflProp = $reflClass->getProperty('classLoader');\n                $reflProp->setAccessible(true);\n\n                $this->assertNotInstanceOf(DebugClassLoader::class, $reflProp->getValue($function[0]));\n\n                return;\n            }\n        }\n\n        $this->fail('DebugClassLoader did not register');\n    }\n\n    public function testThrowingClass()\n    {\n        $this->expectException(\\Exception::class);\n        $this->expectExceptionMessage('boo');\n        try {\n            class_exists(Fixtures\\Throwing::class);\n            $this->fail('Exception expected');\n        } catch (\\Exception $e) {\n            $this->assertSame('boo', $e->getMessage());\n        }\n\n        // the second call also should throw\n        class_exists(Fixtures\\Throwing::class);\n    }\n\n    public function testNameCaseMismatch()\n    {\n        $this->expectException(\\RuntimeException::class);\n        $this->expectExceptionMessage('Case mismatch between loaded and declared class names');\n        class_exists(TestingCaseMismatch::class, true);\n    }\n\n    public function testFileCaseMismatch()\n    {\n        $this->expectException(\\RuntimeException::class);\n        $this->expectExceptionMessage('Case mismatch between class and real file names');\n        if (!file_exists(__DIR__.'/Fixtures/CaseMismatch.php')) {\n            $this->markTestSkipped('Can only be run on case insensitive filesystems');\n        }\n\n        class_exists(Fixtures\\CaseMismatch::class, true);\n    }\n\n    public function testPsr4CaseMismatch()\n    {\n        $this->expectException(\\RuntimeException::class);\n        $this->expectExceptionMessage('Case mismatch between loaded and declared class names');\n        class_exists(__NAMESPACE__.'\\Fixtures\\Psr4CaseMismatch', true);\n    }\n\n    public function testNotPsr0()\n    {\n        $this->assertTrue(class_exists(__NAMESPACE__.'\\Fixtures\\NotPSR0', true));\n    }\n\n    public function testNotPsr0Bis()\n    {\n        $this->assertTrue(class_exists(__NAMESPACE__.'\\Fixtures\\NotPSR0bis', true));\n    }\n\n    public function testClassAlias()\n    {\n        $this->assertTrue(class_exists(Fixtures\\ClassAlias::class, true));\n    }\n\n    /**\n     * @dataProvider provideDeprecatedSuper\n     */\n    public function testDeprecatedSuper($class, $super, $type)\n    {\n        set_error_handler(function () { return false; });\n        $e = error_reporting(0);\n        trigger_error('', E_USER_DEPRECATED);\n\n        class_exists('Test\\\\'.__NAMESPACE__.'\\\\'.$class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $lastError = error_get_last();\n        unset($lastError['file'], $lastError['line']);\n\n        $xError = [\n            'type' => E_USER_DEPRECATED,\n            'message' => 'The \"Test\\Symfony\\Component\\Debug\\Tests\\\\'.$class.'\" class '.$type.' \"Symfony\\Component\\Debug\\Tests\\Fixtures\\\\'.$super.'\" that is deprecated but this is a test deprecation notice.',\n        ];\n\n        $this->assertSame($xError, $lastError);\n    }\n\n    public function provideDeprecatedSuper()\n    {\n        return [\n            ['DeprecatedInterfaceClass', 'DeprecatedInterface', 'implements'],\n            ['DeprecatedParentClass', 'DeprecatedClass', 'extends'],\n        ];\n    }\n\n    public function testInterfaceExtendsDeprecatedInterface()\n    {\n        set_error_handler(function () { return false; });\n        $e = error_reporting(0);\n        trigger_error('', E_USER_NOTICE);\n\n        class_exists('Test\\\\'.NonDeprecatedInterfaceClass::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $lastError = error_get_last();\n        unset($lastError['file'], $lastError['line']);\n\n        $xError = [\n            'type' => E_USER_NOTICE,\n            'message' => '',\n        ];\n\n        $this->assertSame($xError, $lastError);\n    }\n\n    public function testDeprecatedSuperInSameNamespace()\n    {\n        set_error_handler(function () { return false; });\n        $e = error_reporting(0);\n        trigger_error('', E_USER_NOTICE);\n\n        class_exists(ExtendsDeprecatedParent::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $lastError = error_get_last();\n        unset($lastError['file'], $lastError['line']);\n\n        $xError = [\n            'type' => E_USER_NOTICE,\n            'message' => '',\n        ];\n\n        $this->assertSame($xError, $lastError);\n    }\n\n    public function testExtendedFinalClass()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        require __DIR__.'/Fixtures/FinalClasses.php';\n\n        $i = 1;\n        while (class_exists($finalClass = Fixtures\\FinalClass::class.$i++, false)) {\n            spl_autoload_call($finalClass);\n            class_exists('Test\\\\'.__NAMESPACE__.'\\\\Extends'.substr($finalClass, strrpos($finalClass, '\\\\') + 1), true);\n        }\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $this->assertSame([\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass1\" class is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass1\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass2\" class is considered final. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass2\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass3\" class is considered final comment with @@@ and ***. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass3\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass4\" class is considered final. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass4\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass5\" class is considered final multiline comment. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass5\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass6\" class is considered final. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass6\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass7\" class is considered final another multiline comment... It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass7\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalClass8\" class is considered final. It may change without further notice as of its next major version. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsFinalClass8\".',\n        ], $deprecations);\n    }\n\n    public function testExtendedFinalMethod()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        class_exists(Fixtures\\ExtendedFinalMethod::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $xError = [\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalMethod::finalMethod()\" method is considered final. It may change without further notice as of its next major version. You should not extend it from \"Symfony\\Component\\Debug\\Tests\\Fixtures\\ExtendedFinalMethod\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalMethod::finalMethod2()\" method is considered final. It may change without further notice as of its next major version. You should not extend it from \"Symfony\\Component\\Debug\\Tests\\Fixtures\\ExtendedFinalMethod\".',\n        ];\n\n        $this->assertSame($xError, $deprecations);\n    }\n\n    public function testExtendedDeprecatedMethodDoesntTriggerAnyNotice()\n    {\n        set_error_handler(function () { return false; });\n        $e = error_reporting(0);\n        trigger_error('', E_USER_NOTICE);\n\n        class_exists('Test\\\\'.ExtendsAnnotatedClass::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $lastError = error_get_last();\n        unset($lastError['file'], $lastError['line']);\n\n        $this->assertSame(['type' => E_USER_NOTICE, 'message' => ''], $lastError);\n    }\n\n    public function testInternalsUse()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        class_exists('Test\\\\'.ExtendsInternals::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $this->assertSame($deprecations, [\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InternalInterface\" interface is considered internal. It may change without further notice. You should not use it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsInternalsParent\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InternalClass\" class is considered internal. It may change without further notice. You should not use it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsInternalsParent\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InternalTrait\" trait is considered internal. It may change without further notice. You should not use it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsInternals\".',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InternalClass::internalMethod()\" method is considered internal. It may change without further notice. You should not extend it from \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsInternals\".',\n        ]);\n    }\n\n    public function testExtendedMethodDefinesNewParameters()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        class_exists(Fixtures\\SubClassWithAnnotatedParameters::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $this->assertSame([\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::quzMethod()\" method will require a new \"Quz $quz\" argument in the next major version of its parent class \"Symfony\\Component\\Debug\\Tests\\Fixtures\\ClassWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::whereAmI()\" method will require a new \"bool $matrix\" argument in the next major version of its interface \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InterfaceWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::iAmHere()\" method will require a new \"$noType\" argument in the next major version of its interface \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InterfaceWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::iAmHere()\" method will require a new \"callable(\\Throwable|null $reason, mixed $value) $callback\" argument in the next major version of its interface \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InterfaceWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::iAmHere()\" method will require a new \"string $param\" argument in the next major version of its interface \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InterfaceWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::iAmHere()\" method will require a new \"callable  ($a,  $b) $anotherOne\" argument in the next major version of its interface \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InterfaceWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::iAmHere()\" method will require a new \"Type$WithDollarIsStillAType $ccc\" argument in the next major version of its interface \"Symfony\\Component\\Debug\\Tests\\Fixtures\\InterfaceWithAnnotatedParameters\", not defining it is deprecated.',\n            'The \"Symfony\\Component\\Debug\\Tests\\Fixtures\\SubClassWithAnnotatedParameters::isSymfony()\" method will require a new \"true $yes\" argument in the next major version of its parent class \"Symfony\\Component\\Debug\\Tests\\Fixtures\\ClassWithAnnotatedParameters\", not defining it is deprecated.',\n        ], $deprecations);\n    }\n\n    public function testUseTraitWithInternalMethod()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        class_exists('Test\\\\'.UseTraitWithInternalMethod::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $this->assertSame([], $deprecations);\n    }\n\n    public function testVirtualUse()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        class_exists('Test\\\\'.ExtendsVirtual::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $this->assertSame([\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::sameLineInterfaceMethodNoBraces()\".',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::newLineInterfaceMethod()\": Some description!',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::newLineInterfaceMethodNoBraces()\": Description.',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::invalidInterfaceMethod()\".',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::invalidInterfaceMethodNoBraces()\".',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::complexInterfaceMethod($arg, ...$args)\".',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::complexInterfaceMethodTyped($arg, int ...$args)\": Description ...',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"static Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::staticMethodNoBraces()\".',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"static Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::staticMethodTyped(int $arg)\": Description.',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtualParent\" should implement method \"static Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualInterface::staticMethodTypedNoBraces()\".',\n            'Class \"Test\\Symfony\\Component\\Debug\\Tests\\ExtendsVirtual\" should implement method \"Symfony\\Component\\Debug\\Tests\\Fixtures\\VirtualSubInterface::subInterfaceMethod()\".',\n        ], $deprecations);\n    }\n\n    public function testVirtualUseWithMagicCall()\n    {\n        $deprecations = [];\n        set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });\n        $e = error_reporting(E_USER_DEPRECATED);\n\n        class_exists('Test\\\\'.ExtendsVirtualMagicCall::class, true);\n\n        error_reporting($e);\n        restore_error_handler();\n\n        $this->assertSame([], $deprecations);\n    }\n\n    public function testEvaluatedCode()\n    {\n        $this->assertTrue(class_exists(Fixtures\\DefinitionInEvaluatedCode::class, true));\n    }\n}\n\nclass ClassLoader\n{\n    public function loadClass($class)\n    {\n    }\n\n    public function getClassMap()\n    {\n        return [__NAMESPACE__.'\\Fixtures\\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php'];\n    }\n\n    public function findFile($class)\n    {\n        $fixtureDir = __DIR__.\\DIRECTORY_SEPARATOR.'Fixtures'.\\DIRECTORY_SEPARATOR;\n\n        if (TestingUnsilencing::class === $class) {\n            eval('-- parse error --');\n        } elseif (TestingStacking::class === $class) {\n            eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }');\n        } elseif (TestingCaseMismatch::class === $class) {\n            eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');\n        } elseif (__NAMESPACE__.'\\Fixtures\\Psr4CaseMismatch' === $class) {\n            return $fixtureDir.'psr4'.\\DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';\n        } elseif (__NAMESPACE__.'\\Fixtures\\NotPSR0' === $class) {\n            return $fixtureDir.'reallyNotPsr0.php';\n        } elseif (__NAMESPACE__.'\\Fixtures\\NotPSR0bis' === $class) {\n            return $fixtureDir.'notPsr0Bis.php';\n        } elseif ('Symfony\\Bridge\\Debug\\Tests\\Fixtures\\ExtendsDeprecatedParent' === $class) {\n            eval('namespace Symfony\\Bridge\\Debug\\Tests\\Fixtures; class ExtendsDeprecatedParent extends \\\\'.__NAMESPACE__.'\\Fixtures\\DeprecatedClass {}');\n        } elseif ('Test\\\\'.DeprecatedParentClass::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\\\'.__NAMESPACE__.'\\Fixtures\\DeprecatedClass {}');\n        } elseif ('Test\\\\'.DeprecatedInterfaceClass::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class DeprecatedInterfaceClass implements \\\\'.__NAMESPACE__.'\\Fixtures\\DeprecatedInterface {}');\n        } elseif ('Test\\\\'.NonDeprecatedInterfaceClass::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\\\'.__NAMESPACE__.'\\Fixtures\\NonDeprecatedInterface {}');\n        } elseif ('Test\\\\'.Float::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class Float {}');\n        } elseif (0 === strpos($class, 'Test\\\\'.ExtendsFinalClass::class)) {\n            $classShortName = substr($class, strrpos($class, '\\\\') + 1);\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class '.$classShortName.' extends \\\\'.__NAMESPACE__.'\\Fixtures\\\\'.substr($classShortName, 7).' {}');\n        } elseif ('Test\\\\'.ExtendsAnnotatedClass::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class ExtendsAnnotatedClass extends \\\\'.__NAMESPACE__.'\\Fixtures\\AnnotatedClass {\n                public function deprecatedMethod() { }\n            }');\n        } elseif ('Test\\\\'.ExtendsInternals::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class ExtendsInternals extends ExtendsInternalsParent {\n                use \\\\'.__NAMESPACE__.'\\Fixtures\\InternalTrait;\n\n                public function internalMethod() { }\n            }');\n        } elseif ('Test\\\\'.ExtendsInternalsParent::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class ExtendsInternalsParent extends \\\\'.__NAMESPACE__.'\\Fixtures\\InternalClass implements \\\\'.__NAMESPACE__.'\\Fixtures\\InternalInterface { }');\n        } elseif ('Test\\\\'.UseTraitWithInternalMethod::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class UseTraitWithInternalMethod { use \\\\'.__NAMESPACE__.'\\Fixtures\\TraitWithInternalMethod; }');\n        } elseif ('Test\\\\'.ExtendsVirtual::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class ExtendsVirtual extends ExtendsVirtualParent implements \\\\'.__NAMESPACE__.'\\Fixtures\\VirtualSubInterface {\n                public function ownClassMethod() { }\n                public function classMethod() { }\n                public function sameLineInterfaceMethodNoBraces() { }\n            }');\n        } elseif ('Test\\\\'.ExtendsVirtualParent::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class ExtendsVirtualParent extends ExtendsVirtualAbstract {\n                public function ownParentMethod() { }\n                public function traitMethod() { }\n                public function sameLineInterfaceMethod() { }\n                public function staticMethodNoBraces() { } // should be static\n            }');\n        } elseif ('Test\\\\'.ExtendsVirtualAbstract::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; abstract class ExtendsVirtualAbstract extends ExtendsVirtualAbstractBase {\n                public static function staticMethod() { }\n                public function ownAbstractMethod() { }\n                public function interfaceMethod() { }\n            }');\n        } elseif ('Test\\\\'.ExtendsVirtualAbstractBase::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; abstract class ExtendsVirtualAbstractBase extends \\\\'.__NAMESPACE__.'\\Fixtures\\VirtualClass implements \\\\'.__NAMESPACE__.'\\Fixtures\\VirtualInterface {\n                public function ownAbstractBaseMethod() { }\n            }');\n        } elseif ('Test\\\\'.ExtendsVirtualMagicCall::class === $class) {\n            eval('namespace Test\\\\'.__NAMESPACE__.'; class ExtendsVirtualMagicCall extends \\\\'.__NAMESPACE__.'\\Fixtures\\VirtualClassMagicCall implements \\\\'.__NAMESPACE__.'\\Fixtures\\VirtualInterface {\n            }');\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/ErrorHandlerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\nuse Psr\\Log\\LogLevel;\nuse Psr\\Log\\NullLogger;\nuse Symfony\\Component\\Debug\\BufferingLogger;\nuse Symfony\\Component\\Debug\\ErrorHandler;\nuse Symfony\\Component\\Debug\\Exception\\ClassNotFoundException;\nuse Symfony\\Component\\Debug\\Exception\\SilencedErrorContext;\nuse Symfony\\Component\\Debug\\Tests\\Fixtures\\ErrorHandlerThatUsesThePreviousOne;\nuse Symfony\\Component\\Debug\\Tests\\Fixtures\\LoggerThatSetAnErrorHandler;\n\n/**\n * ErrorHandlerTest.\n *\n * @author Robert Schönthal <seroscho@googlemail.com>\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @group legacy\n */\nclass ErrorHandlerTest extends TestCase\n{\n    public function testRegister()\n    {\n        $handler = ErrorHandler::register();\n\n        try {\n            $this->assertInstanceOf(ErrorHandler::class, $handler);\n            $this->assertSame($handler, ErrorHandler::register());\n\n            $newHandler = new ErrorHandler();\n\n            $this->assertSame($handler, ErrorHandler::register($newHandler, false));\n            $h = set_error_handler('var_dump');\n            restore_error_handler();\n            $this->assertSame([$handler, 'handleError'], $h);\n\n            try {\n                $this->assertSame($newHandler, ErrorHandler::register($newHandler, true));\n                $h = set_error_handler('var_dump');\n                restore_error_handler();\n                $this->assertSame([$newHandler, 'handleError'], $h);\n            } catch (\\Exception $e) {\n            }\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            if (isset($e)) {\n                throw $e;\n            }\n        } catch (\\Exception $e) {\n        }\n\n        restore_error_handler();\n        restore_exception_handler();\n\n        if (isset($e)) {\n            throw $e;\n        }\n    }\n\n    public function testErrorGetLast()\n    {\n        $logger = $this->createMock(LoggerInterface::class);\n        $handler = ErrorHandler::register();\n        $handler->setDefaultLogger($logger);\n        $handler->screamAt(\\E_ALL);\n\n        try {\n            @trigger_error('Hello', \\E_USER_WARNING);\n            $expected = [\n                'type' => \\E_USER_WARNING,\n                'message' => 'Hello',\n                'file' => __FILE__,\n                'line' => __LINE__ - 5,\n            ];\n            $this->assertSame($expected, error_get_last());\n        } catch (\\Exception $e) {\n            restore_error_handler();\n            restore_exception_handler();\n\n            throw $e;\n        }\n    }\n\n    public function testNotice()\n    {\n        ErrorHandler::register();\n\n        try {\n            self::triggerNotice($this);\n            $this->fail('ErrorException expected');\n        } catch (\\ErrorException $exception) {\n            // if an exception is thrown, the test passed\n            if (\\PHP_VERSION_ID < 80000) {\n                $this->assertEquals(\\E_NOTICE, $exception->getSeverity());\n                $this->assertMatchesRegularExpression('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());\n            } else {\n                $this->assertEquals(\\E_WARNING, $exception->getSeverity());\n                $this->assertMatchesRegularExpression('/^Warning: Undefined variable \\$(foo|bar)/', $exception->getMessage());\n            }\n            $this->assertEquals(__FILE__, $exception->getFile());\n\n            $trace = $exception->getTrace();\n\n            $this->assertEquals(__FILE__, $trace[0]['file']);\n            $this->assertEquals(__CLASS__, $trace[0]['class']);\n            $this->assertEquals('triggerNotice', $trace[0]['function']);\n            $this->assertEquals('::', $trace[0]['type']);\n\n            $this->assertEquals(__FILE__, $trace[0]['file']);\n            $this->assertEquals(__CLASS__, $trace[1]['class']);\n            $this->assertEquals(__FUNCTION__, $trace[1]['function']);\n            $this->assertEquals('->', $trace[1]['type']);\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n    }\n\n    // dummy function to test trace in error handler.\n    private static function triggerNotice($that)\n    {\n        $that->assertSame('', $foo.$foo.$bar);\n    }\n\n    public function testConstruct()\n    {\n        try {\n            $handler = ErrorHandler::register();\n            $handler->throwAt(3, true);\n            $this->assertEquals(3 | \\E_RECOVERABLE_ERROR | \\E_USER_ERROR, $handler->throwAt(0));\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n    }\n\n    public function testDefaultLogger()\n    {\n        try {\n            $logger = $this->createMock(LoggerInterface::class);\n            $handler = ErrorHandler::register();\n\n            $handler->setDefaultLogger($logger, \\E_NOTICE);\n            $handler->setDefaultLogger($logger, [\\E_USER_NOTICE => LogLevel::CRITICAL]);\n\n            $loggers = [\n                \\E_DEPRECATED => [null, LogLevel::INFO],\n                \\E_USER_DEPRECATED => [null, LogLevel::INFO],\n                \\E_NOTICE => [$logger, LogLevel::WARNING],\n                \\E_USER_NOTICE => [$logger, LogLevel::CRITICAL],\n                \\E_STRICT => [null, LogLevel::WARNING],\n                \\E_WARNING => [null, LogLevel::WARNING],\n                \\E_USER_WARNING => [null, LogLevel::WARNING],\n                \\E_COMPILE_WARNING => [null, LogLevel::WARNING],\n                \\E_CORE_WARNING => [null, LogLevel::WARNING],\n                \\E_USER_ERROR => [null, LogLevel::CRITICAL],\n                \\E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],\n                \\E_COMPILE_ERROR => [null, LogLevel::CRITICAL],\n                \\E_PARSE => [null, LogLevel::CRITICAL],\n                \\E_ERROR => [null, LogLevel::CRITICAL],\n                \\E_CORE_ERROR => [null, LogLevel::CRITICAL],\n            ];\n            $this->assertSame($loggers, $handler->setLoggers([]));\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n    }\n\n    public function testHandleError()\n    {\n        try {\n            $handler = ErrorHandler::register();\n            $handler->throwAt(0, true);\n            $this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, []));\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            $handler = ErrorHandler::register();\n            $handler->throwAt(3, true);\n            $this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, []));\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            $handler = ErrorHandler::register();\n            $handler->throwAt(3, true);\n            try {\n                $handler->handleError(4, 'foo', 'foo.php', 12, []);\n            } catch (\\ErrorException $e) {\n                $this->assertSame('Parse Error: foo', $e->getMessage());\n                $this->assertSame(4, $e->getSeverity());\n                $this->assertSame('foo.php', $e->getFile());\n                $this->assertSame(12, $e->getLine());\n            }\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            $handler = ErrorHandler::register();\n            $handler->throwAt(\\E_USER_DEPRECATED, true);\n            $this->assertFalse($handler->handleError(\\E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            $handler = ErrorHandler::register();\n            $handler->throwAt(\\E_DEPRECATED, true);\n            $this->assertFalse($handler->handleError(\\E_DEPRECATED, 'foo', 'foo.php', 12, []));\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            $logger = $this->createMock(LoggerInterface::class);\n\n            $warnArgCheck = function ($logLevel, $message, $context) {\n                $this->assertEquals('info', $logLevel);\n                $this->assertEquals('User Deprecated: foo', $message);\n                $this->assertArrayHasKey('exception', $context);\n                $exception = $context['exception'];\n                $this->assertInstanceOf(\\ErrorException::class, $exception);\n                $this->assertSame('User Deprecated: foo', $exception->getMessage());\n                $this->assertSame(\\E_USER_DEPRECATED, $exception->getSeverity());\n            };\n\n            $logger\n                ->expects($this->once())\n                ->method('log')\n                ->willReturnCallback($warnArgCheck)\n            ;\n\n            $handler = ErrorHandler::register();\n            $handler->setDefaultLogger($logger, \\E_USER_DEPRECATED);\n            $this->assertTrue($handler->handleError(\\E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));\n\n            restore_error_handler();\n            restore_exception_handler();\n\n            $logger = $this->createMock(LoggerInterface::class);\n\n            $line = null;\n            $logArgCheck = function ($level, $message, $context) use (&$line) {\n                $this->assertArrayHasKey('exception', $context);\n                $exception = $context['exception'];\n\n                if (\\PHP_VERSION_ID < 80000) {\n                    $this->assertEquals('Notice: Undefined variable: undefVar', $message);\n                    $this->assertSame(\\E_NOTICE, $exception->getSeverity());\n                } else {\n                    $this->assertEquals('Warning: Undefined variable $undefVar', $message);\n                    $this->assertSame(\\E_WARNING, $exception->getSeverity());\n                }\n                $this->assertInstanceOf(SilencedErrorContext::class, $exception);\n                $this->assertSame(__FILE__, $exception->getFile());\n                $this->assertSame($line, $exception->getLine());\n                $this->assertNotEmpty($exception->getTrace());\n                $this->assertSame(1, $exception->count);\n            };\n\n            $logger\n                ->expects($this->once())\n                ->method('log')\n                ->willReturnCallback($logArgCheck)\n            ;\n\n            $handler = ErrorHandler::register();\n            if (\\PHP_VERSION_ID < 80000) {\n                $handler->setDefaultLogger($logger, \\E_NOTICE);\n                $handler->screamAt(\\E_NOTICE);\n            } else {\n                $handler->setDefaultLogger($logger, \\E_WARNING);\n                $handler->screamAt(\\E_WARNING);\n            }\n            unset($undefVar);\n            $line = __LINE__ + 1;\n            @$undefVar++;\n\n            restore_error_handler();\n            restore_exception_handler();\n        } catch (\\Exception $e) {\n            restore_error_handler();\n            restore_exception_handler();\n\n            throw $e;\n        }\n    }\n\n    public function testHandleUserError()\n    {\n        if (\\PHP_VERSION_ID >= 70400) {\n            $this->markTestSkipped('PHP 7.4 allows __toString to throw exceptions');\n        }\n\n        try {\n            $handler = ErrorHandler::register();\n            $handler->throwAt(0, true);\n\n            $e = null;\n            $x = new \\Exception('Foo');\n\n            try {\n                $f = new Fixtures\\ToStringThrower($x);\n                $f .= ''; // Trigger $f->__toString()\n            } catch (\\Exception $e) {\n            }\n\n            $this->assertSame($x, $e);\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n    }\n\n    public function testHandleErrorWithAnonymousClass()\n    {\n        $handler = ErrorHandler::register();\n        $handler->throwAt(\\E_USER_WARNING, true);\n        try {\n            $handler->handleError(\\E_USER_WARNING, 'foo '.\\get_class(new class() extends \\stdClass {\n            }).' bar', 'foo.php', 12);\n            $this->fail('Exception expected.');\n        } catch (\\ErrorException $e) {\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n\n        $this->assertSame('User Warning: foo stdClass@anonymous bar', $e->getMessage());\n        $this->assertSame(\\E_USER_WARNING, $e->getSeverity());\n        $this->assertSame('foo.php', $e->getFile());\n        $this->assertSame(12, $e->getLine());\n    }\n\n    public function testHandleDeprecation()\n    {\n        $logArgCheck = function ($level, $message, $context) {\n            $this->assertEquals(LogLevel::INFO, $level);\n            $this->assertArrayHasKey('exception', $context);\n            $exception = $context['exception'];\n            $this->assertInstanceOf(\\ErrorException::class, $exception);\n            $this->assertSame('User Deprecated: Foo deprecation', $exception->getMessage());\n        };\n\n        $logger = $this->createMock(LoggerInterface::class);\n        $logger\n            ->expects($this->once())\n            ->method('log')\n            ->willReturnCallback($logArgCheck)\n        ;\n\n        $handler = new ErrorHandler();\n        $handler->setDefaultLogger($logger);\n        @$handler->handleError(\\E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);\n    }\n\n    public function testHandleException()\n    {\n        try {\n            $logger = $this->createMock(LoggerInterface::class);\n            $handler = ErrorHandler::register();\n\n            $exception = new \\Exception('foo');\n\n            $logArgCheck = function ($level, $message, $context) {\n                $this->assertSame('Uncaught Exception: foo', $message);\n                $this->assertArrayHasKey('exception', $context);\n                $this->assertInstanceOf(\\Exception::class, $context['exception']);\n            };\n\n            $logger\n                ->expects($this->exactly(2))\n                ->method('log')\n                ->willReturnCallback($logArgCheck)\n            ;\n\n            $handler->setDefaultLogger($logger, \\E_ERROR);\n\n            try {\n                $handler->handleException($exception);\n                $this->fail('Exception expected');\n            } catch (\\Exception $e) {\n                $this->assertSame($exception, $e);\n            }\n\n            $handler->setExceptionHandler(function ($e) use ($exception) {\n                $this->assertSame($exception, $e);\n            });\n\n            $handler->handleException($exception);\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n    }\n\n    public function testBootstrappingLogger()\n    {\n        $bootLogger = new BufferingLogger();\n        $handler = new ErrorHandler($bootLogger);\n\n        $loggers = [\n            \\E_DEPRECATED => [$bootLogger, LogLevel::INFO],\n            \\E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO],\n            \\E_NOTICE => [$bootLogger, LogLevel::WARNING],\n            \\E_USER_NOTICE => [$bootLogger, LogLevel::WARNING],\n            \\E_STRICT => [$bootLogger, LogLevel::WARNING],\n            \\E_WARNING => [$bootLogger, LogLevel::WARNING],\n            \\E_USER_WARNING => [$bootLogger, LogLevel::WARNING],\n            \\E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING],\n            \\E_CORE_WARNING => [$bootLogger, LogLevel::WARNING],\n            \\E_USER_ERROR => [$bootLogger, LogLevel::CRITICAL],\n            \\E_RECOVERABLE_ERROR => [$bootLogger, LogLevel::CRITICAL],\n            \\E_COMPILE_ERROR => [$bootLogger, LogLevel::CRITICAL],\n            \\E_PARSE => [$bootLogger, LogLevel::CRITICAL],\n            \\E_ERROR => [$bootLogger, LogLevel::CRITICAL],\n            \\E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL],\n        ];\n\n        $this->assertSame($loggers, $handler->setLoggers([]));\n\n        $handler->handleError(\\E_DEPRECATED, 'Foo message', __FILE__, 123, []);\n\n        $logs = $bootLogger->cleanLogs();\n\n        $this->assertCount(1, $logs);\n        $log = $logs[0];\n        $this->assertSame('info', $log[0]);\n        $this->assertSame('Deprecated: Foo message', $log[1]);\n        $this->assertArrayHasKey('exception', $log[2]);\n        $exception = $log[2]['exception'];\n        $this->assertInstanceOf(\\ErrorException::class, $exception);\n        $this->assertSame('Deprecated: Foo message', $exception->getMessage());\n        $this->assertSame(__FILE__, $exception->getFile());\n        $this->assertSame(123, $exception->getLine());\n        $this->assertSame(\\E_DEPRECATED, $exception->getSeverity());\n\n        $bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);\n\n        $mockLogger = $this->createMock(LoggerInterface::class);\n        $mockLogger->expects($this->once())\n            ->method('log')\n            ->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);\n\n        $handler->setLoggers([\\E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);\n    }\n\n    public function testSettingLoggerWhenExceptionIsBuffered()\n    {\n        $bootLogger = new BufferingLogger();\n        $handler = new ErrorHandler($bootLogger);\n\n        $exception = new \\Exception('Foo message');\n\n        $mockLogger = $this->createMock(LoggerInterface::class);\n        $mockLogger->expects($this->once())\n            ->method('log')\n            ->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]);\n\n        $handler->setExceptionHandler(function () use ($handler, $mockLogger) {\n            $handler->setDefaultLogger($mockLogger);\n        });\n\n        $handler->handleException($exception);\n    }\n\n    public function testHandleFatalError()\n    {\n        try {\n            $logger = $this->createMock(LoggerInterface::class);\n            $handler = ErrorHandler::register();\n\n            $error = [\n                'type' => \\E_PARSE,\n                'message' => 'foo',\n                'file' => 'bar',\n                'line' => 123,\n            ];\n\n            $logArgCheck = function ($level, $message, $context) {\n                $this->assertEquals('Fatal Parse Error: foo', $message);\n                $this->assertArrayHasKey('exception', $context);\n                $this->assertInstanceOf(\\Exception::class, $context['exception']);\n            };\n\n            $logger\n                ->expects($this->once())\n                ->method('log')\n                ->willReturnCallback($logArgCheck)\n            ;\n\n            $handler->setDefaultLogger($logger, \\E_PARSE);\n\n            $handler->handleFatalError($error);\n\n            restore_error_handler();\n            restore_exception_handler();\n        } catch (\\Exception $e) {\n            restore_error_handler();\n            restore_exception_handler();\n\n            throw $e;\n        }\n    }\n\n    public function testHandleErrorException()\n    {\n        $exception = new \\Error(\"Class 'IReallyReallyDoNotExistAnywhereInTheRepositoryISwear' not found\");\n\n        $handler = new ErrorHandler();\n        $handler->setExceptionHandler(function () use (&$args) {\n            $args = \\func_get_args();\n        });\n\n        $handler->handleException($exception);\n\n        $this->assertInstanceOf(ClassNotFoundException::class, $args[0]);\n        $this->assertStringStartsWith(\"Attempted to load class \\\"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\\\" from the global namespace.\\nDid you forget a \\\"use\\\" statement\", $args[0]->getMessage());\n    }\n\n    public function testCustomExceptionHandler()\n    {\n        $this->expectException(\\Exception::class);\n        $handler = new ErrorHandler();\n        $handler->setExceptionHandler(function ($e) use ($handler) {\n            $handler->handleException($e);\n        });\n\n        $handler->handleException(new \\Exception());\n    }\n\n    /**\n     * @dataProvider errorHandlerWhenLoggingProvider\n     */\n    public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined)\n    {\n        try {\n            if ($previousHandlerWasDefined) {\n                set_error_handler('count');\n            }\n\n            $logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger();\n\n            $handler = ErrorHandler::register();\n            $handler->setDefaultLogger($logger);\n\n            if ($nextHandlerIsDefined) {\n                $handler = ErrorHandlerThatUsesThePreviousOne::register();\n            }\n\n            @trigger_error('foo', \\E_USER_DEPRECATED);\n            @trigger_error('bar', \\E_USER_DEPRECATED);\n\n            $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));\n\n            if ($logger instanceof LoggerThatSetAnErrorHandler) {\n                $this->assertCount(2, $logger->cleanLogs());\n            }\n\n            restore_error_handler();\n\n            if ($previousHandlerWasDefined) {\n                restore_error_handler();\n            }\n\n            if ($nextHandlerIsDefined) {\n                restore_error_handler();\n            }\n        } finally {\n            restore_error_handler();\n            restore_exception_handler();\n        }\n    }\n\n    public function errorHandlerWhenLoggingProvider()\n    {\n        foreach ([false, true] as $previousHandlerWasDefined) {\n            foreach ([false, true] as $loggerSetsAnotherHandler) {\n                foreach ([false, true] as $nextHandlerIsDefined) {\n                    yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined];\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/Exception/FlattenExceptionTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests\\Exception;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Debug\\Exception\\FatalThrowableError;\nuse Symfony\\Component\\Debug\\Exception\\FlattenException;\nuse Symfony\\Component\\HttpFoundation\\Exception\\SuspiciousOperationException;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\ConflictHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\GoneHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\LengthRequiredHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotAcceptableHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\PreconditionFailedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\PreconditionRequiredHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\ServiceUnavailableHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\TooManyRequestsHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\UnsupportedMediaTypeHttpException;\n\n/**\n * @group legacy\n */\nclass FlattenExceptionTest extends TestCase\n{\n    public function testStatusCode()\n    {\n        $flattened = FlattenException::create(new \\RuntimeException(), 403);\n        $this->assertEquals('403', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new \\RuntimeException());\n        $this->assertEquals('500', $flattened->getStatusCode());\n\n        $flattened = FlattenException::createFromThrowable(new \\DivisionByZeroError(), 403);\n        $this->assertEquals('403', $flattened->getStatusCode());\n\n        $flattened = FlattenException::createFromThrowable(new \\DivisionByZeroError());\n        $this->assertEquals('500', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new NotFoundHttpException());\n        $this->assertEquals('404', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm=\"My Realm\"'));\n        $this->assertEquals('401', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new BadRequestHttpException());\n        $this->assertEquals('400', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new NotAcceptableHttpException());\n        $this->assertEquals('406', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new ConflictHttpException());\n        $this->assertEquals('409', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));\n        $this->assertEquals('405', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new AccessDeniedHttpException());\n        $this->assertEquals('403', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new GoneHttpException());\n        $this->assertEquals('410', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new LengthRequiredHttpException());\n        $this->assertEquals('411', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new PreconditionFailedHttpException());\n        $this->assertEquals('412', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new PreconditionRequiredHttpException());\n        $this->assertEquals('428', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new ServiceUnavailableHttpException());\n        $this->assertEquals('503', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new TooManyRequestsHttpException());\n        $this->assertEquals('429', $flattened->getStatusCode());\n\n        $flattened = FlattenException::create(new UnsupportedMediaTypeHttpException());\n        $this->assertEquals('415', $flattened->getStatusCode());\n\n        if (class_exists(SuspiciousOperationException::class)) {\n            $flattened = FlattenException::create(new SuspiciousOperationException());\n            $this->assertEquals('400', $flattened->getStatusCode());\n        }\n    }\n\n    public function testHeadersForHttpException()\n    {\n        $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));\n        $this->assertEquals(['Allow' => 'POST'], $flattened->getHeaders());\n\n        $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm=\"My Realm\"'));\n        $this->assertEquals(['WWW-Authenticate' => 'Basic realm=\"My Realm\"'], $flattened->getHeaders());\n\n        $flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));\n        $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());\n\n        $flattened = FlattenException::create(new ServiceUnavailableHttpException(120));\n        $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());\n\n        $flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));\n        $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());\n\n        $flattened = FlattenException::create(new TooManyRequestsHttpException(120));\n        $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());\n    }\n\n    /**\n     * @dataProvider flattenDataProvider\n     */\n    public function testFlattenHttpException(\\Throwable $exception)\n    {\n        $flattened = FlattenException::createFromThrowable($exception);\n        $flattened2 = FlattenException::createFromThrowable($exception);\n\n        $flattened->setPrevious($flattened2);\n\n        $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.');\n        $this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.');\n        $this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');\n    }\n\n    public function testWrappedThrowable()\n    {\n        $exception = new FatalThrowableError(new \\DivisionByZeroError('Ouch', 42));\n        $flattened = FlattenException::create($exception);\n\n        $this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');\n        $this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');\n        $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');\n    }\n\n    public function testThrowable()\n    {\n        $error = new \\DivisionByZeroError('Ouch', 42);\n        $flattened = FlattenException::createFromThrowable($error);\n\n        $this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');\n        $this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');\n        $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');\n    }\n\n    /**\n     * @dataProvider flattenDataProvider\n     */\n    public function testPrevious(\\Throwable $exception)\n    {\n        $flattened = FlattenException::createFromThrowable($exception);\n        $flattened2 = FlattenException::createFromThrowable($exception);\n\n        $flattened->setPrevious($flattened2);\n\n        $this->assertSame($flattened2, $flattened->getPrevious());\n\n        $this->assertSame([$flattened2], $flattened->getAllPrevious());\n    }\n\n    public function testPreviousError()\n    {\n        $exception = new \\Exception('test', 123, new \\ParseError('Oh noes!', 42));\n\n        $flattened = FlattenException::create($exception)->getPrevious();\n\n        $this->assertEquals('Oh noes!', $flattened->getMessage(), 'The message is copied from the original exception.');\n        $this->assertEquals(42, $flattened->getCode(), 'The code is copied from the original exception.');\n        $this->assertEquals('ParseError', $flattened->getClass(), 'The class is set to the class of the original exception');\n    }\n\n    /**\n     * @dataProvider flattenDataProvider\n     */\n    public function testLine(\\Throwable $exception)\n    {\n        $flattened = FlattenException::createFromThrowable($exception);\n        $this->assertSame($exception->getLine(), $flattened->getLine());\n    }\n\n    /**\n     * @dataProvider flattenDataProvider\n     */\n    public function testFile(\\Throwable $exception)\n    {\n        $flattened = FlattenException::createFromThrowable($exception);\n        $this->assertSame($exception->getFile(), $flattened->getFile());\n    }\n\n    /**\n     * @dataProvider flattenDataProvider\n     */\n    public function testToArray(\\Throwable $exception, string $expectedClass)\n    {\n        $flattened = FlattenException::createFromThrowable($exception);\n        $flattened->setTrace([], 'foo.php', 123);\n\n        $this->assertEquals([\n            [\n                'message' => 'test',\n                'class' => $expectedClass,\n                'trace' => [[\n                    'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123,\n                    'args' => [],\n                ]],\n            ],\n        ], $flattened->toArray());\n    }\n\n    public function testCreate()\n    {\n        $exception = new NotFoundHttpException(\n            'test',\n            new \\RuntimeException('previous', 123)\n        );\n\n        $this->assertSame(\n            FlattenException::createFromThrowable($exception)->toArray(),\n            FlattenException::create($exception)->toArray()\n        );\n    }\n\n    public function flattenDataProvider()\n    {\n        return [\n            [new \\Exception('test', 123), 'Exception'],\n            [new \\Error('test', 123), 'Error'],\n        ];\n    }\n\n    public function testArguments()\n    {\n        if (\\PHP_VERSION_ID >= 70400) {\n            $this->markTestSkipped('PHP 7.4 removes arguments from exception traces.');\n        }\n\n        $dh = opendir(__DIR__);\n        $fh = tmpfile();\n\n        $incomplete = unserialize('O:14:\"BogusTestClass\":0:{}');\n\n        $exception = $this->createException([\n            (object) ['foo' => 1],\n            new NotFoundHttpException(),\n            $incomplete,\n            $dh,\n            $fh,\n            function () {},\n            [1, 2],\n            ['foo' => 123],\n            null,\n            true,\n            false,\n            0,\n            0.0,\n            '0',\n            '',\n            \\INF,\n            \\NAN,\n        ]);\n\n        $flattened = FlattenException::create($exception);\n        $trace = $flattened->getTrace();\n        $args = $trace[1]['args'];\n        $array = $args[0][1];\n\n        closedir($dh);\n        fclose($fh);\n\n        $i = 0;\n        $this->assertSame(['object', 'stdClass'], $array[$i++]);\n        $this->assertSame(['object', 'Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException'], $array[$i++]);\n        $this->assertSame(['incomplete-object', 'BogusTestClass'], $array[$i++]);\n        $this->assertSame(['resource', 'stream'], $array[$i++]);\n        $this->assertSame(['resource', 'stream'], $array[$i++]);\n\n        $args = $array[$i++];\n        $this->assertSame($args[0], 'object');\n        $this->assertTrue('Closure' === $args[1] || is_subclass_of($args[1], \\Closure::class), 'Expect object class name to be Closure or a subclass of Closure.');\n\n        $this->assertSame(['array', [['integer', 1], ['integer', 2]]], $array[$i++]);\n        $this->assertSame(['array', ['foo' => ['integer', 123]]], $array[$i++]);\n        $this->assertSame(['null', null], $array[$i++]);\n        $this->assertSame(['boolean', true], $array[$i++]);\n        $this->assertSame(['boolean', false], $array[$i++]);\n        $this->assertSame(['integer', 0], $array[$i++]);\n        $this->assertSame(['float', 0.0], $array[$i++]);\n        $this->assertSame(['string', '0'], $array[$i++]);\n        $this->assertSame(['string', ''], $array[$i++]);\n        $this->assertSame(['float', \\INF], $array[$i++]);\n\n        // assertEquals() does not like NAN values.\n        $this->assertEquals('float', $array[$i][0]);\n        $this->assertNan($array[$i][1]);\n    }\n\n    public function testRecursionInArguments()\n    {\n        if (\\PHP_VERSION_ID >= 70400) {\n            $this->markTestSkipped('PHP 7.4 removes arguments from exception traces.');\n        }\n\n        $a = null;\n        $a = ['foo', [2, &$a]];\n        $exception = $this->createException($a);\n\n        $flattened = FlattenException::create($exception);\n        $trace = $flattened->getTrace();\n        $this->assertStringContainsString('*DEEP NESTED ARRAY*', serialize($trace));\n    }\n\n    public function testTooBigArray()\n    {\n        if (\\PHP_VERSION_ID >= 70400) {\n            $this->markTestSkipped('PHP 7.4 removes arguments from exception traces.');\n        }\n\n        $a = [];\n        for ($i = 0; $i < 20; ++$i) {\n            for ($j = 0; $j < 50; ++$j) {\n                for ($k = 0; $k < 10; ++$k) {\n                    $a[$i][$j][$k] = 'value';\n                }\n            }\n        }\n        $a[20] = 'value';\n        $a[21] = 'value1';\n        $exception = $this->createException($a);\n\n        $flattened = FlattenException::create($exception);\n        $trace = $flattened->getTrace();\n\n        $this->assertSame($trace[1]['args'][0], ['array', ['array', '*SKIPPED over 10000 entries*']]);\n\n        $serializeTrace = serialize($trace);\n\n        $this->assertStringContainsString('*SKIPPED over 10000 entries*', $serializeTrace);\n        $this->assertStringNotContainsString('*value1*', $serializeTrace);\n    }\n\n    public function testAnonymousClass()\n    {\n        $flattened = FlattenException::create(new class() extends \\RuntimeException {\n        });\n\n        $this->assertSame('RuntimeException@anonymous', $flattened->getClass());\n\n        $flattened->setClass(\\get_class(new class('Oops') extends NotFoundHttpException {\n        }));\n\n        $this->assertSame('Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException@anonymous', $flattened->getClass());\n\n        $flattened = FlattenException::create(new \\Exception(sprintf('Class \"%s\" blah.', \\get_class(new class() extends \\RuntimeException {\n        }))));\n\n        $this->assertSame('Class \"RuntimeException@anonymous\" blah.', $flattened->getMessage());\n    }\n\n    public function testToStringEmptyMessage()\n    {\n        $exception = new \\RuntimeException();\n\n        $flattened = FlattenException::create($exception);\n\n        $this->assertSame($exception->getTraceAsString(), $flattened->getTraceAsString());\n        $this->assertSame($exception->__toString(), $flattened->getAsString());\n    }\n\n    public function testToString()\n    {\n        $test = function ($a, $b, $c, $d) {\n            return new \\RuntimeException('This is a test message');\n        };\n\n        $exception = $test('foo123', 1, null, 1.5);\n\n        $flattened = FlattenException::create($exception);\n\n        $this->assertSame($exception->getTraceAsString(), $flattened->getTraceAsString());\n        $this->assertSame($exception->__toString(), $flattened->getAsString());\n    }\n\n    public function testToStringParent()\n    {\n        $exception = new \\LogicException('This is message 1');\n        $exception = new \\RuntimeException('This is messsage 2', 500, $exception);\n\n        $flattened = FlattenException::create($exception);\n\n        $this->assertSame($exception->getTraceAsString(), $flattened->getTraceAsString());\n        $this->assertSame($exception->__toString(), $flattened->getAsString());\n    }\n\n    private function createException($foo)\n    {\n        return new \\Exception();\n    }\n}\n"
  },
  {
    "path": "Tests/ExceptionHandlerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Debug\\Exception\\OutOfMemoryException;\nuse Symfony\\Component\\Debug\\ExceptionHandler;\nuse Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException;\nuse Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n\nrequire_once __DIR__.'/HeaderMock.php';\n\n/**\n * @group legacy\n */\nclass ExceptionHandlerTest extends TestCase\n{\n    protected function setUp(): void\n    {\n        testHeader();\n    }\n\n    protected function tearDown(): void\n    {\n        testHeader();\n    }\n\n    /**\n     * @group legacy\n     */\n    public function testDebug()\n    {\n        $handler = new ExceptionHandler(false);\n\n        ob_start();\n        $handler->sendPhpResponse(new \\RuntimeException('Foo'));\n        $response = ob_get_clean();\n\n        $this->assertStringContainsString('Whoops, looks like something went wrong.', $response);\n        $this->assertStringNotContainsString('<div class=\"trace trace-as-html\">', $response);\n\n        $handler = new ExceptionHandler(true);\n\n        ob_start();\n        $handler->sendPhpResponse(new \\RuntimeException('Foo'));\n        $response = ob_get_clean();\n\n        $this->assertStringContainsString('<h1 class=\"break-long-words exception-message\">Foo</h1>', $response);\n        $this->assertStringContainsString('<div class=\"trace trace-as-html\">', $response);\n\n        // taken from https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)\n        $htmlWithXss = '<body onload=alert(\\'test1\\')> <b onmouseover=alert(\\'Wufff!\\')>click me!</b> <img src=\"j&#X41vascript:alert(\\'test2\\')\"> <meta http-equiv=\"refresh\"\ncontent=\"0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg\">';\n        ob_start();\n        $handler->sendPhpResponse(new \\RuntimeException($htmlWithXss));\n        $response = ob_get_clean();\n\n        $this->assertStringContainsString(sprintf('<h1 class=\"break-long-words exception-message\">%s</h1>', htmlspecialchars($htmlWithXss, \\ENT_COMPAT | \\ENT_SUBSTITUTE, 'UTF-8')), $response);\n    }\n\n    public function testStatusCode()\n    {\n        $handler = new ExceptionHandler(false, 'iso8859-1');\n\n        ob_start();\n        $handler->sendPhpResponse(new NotFoundHttpException('Foo'));\n        $response = ob_get_clean();\n\n        $this->assertStringContainsString('Sorry, the page you are looking for could not be found.', $response);\n\n        $expectedHeaders = [\n            ['HTTP/1.0 404', true, null],\n            ['Content-Type: text/html; charset=iso8859-1', true, null],\n        ];\n\n        $this->assertSame($expectedHeaders, testHeader());\n    }\n\n    public function testHeaders()\n    {\n        $handler = new ExceptionHandler(false, 'iso8859-1');\n\n        ob_start();\n        $handler->sendPhpResponse(new MethodNotAllowedHttpException(['POST']));\n        ob_get_clean();\n\n        $expectedHeaders = [\n            ['HTTP/1.0 405', true, null],\n            ['Allow: POST', false, null],\n            ['Content-Type: text/html; charset=iso8859-1', true, null],\n        ];\n\n        $this->assertSame($expectedHeaders, testHeader());\n    }\n\n    public function testNestedExceptions()\n    {\n        $handler = new ExceptionHandler(true);\n        ob_start();\n        $handler->sendPhpResponse(new \\RuntimeException('Foo', 0, new \\RuntimeException('Bar')));\n        $response = ob_get_clean();\n\n        $this->assertStringMatchesFormat('%A<p class=\"break-long-words trace-message\">Foo</p>%A<p class=\"break-long-words trace-message\">Bar</p>%A', $response);\n    }\n\n    public function testHandle()\n    {\n        $handler = new ExceptionHandler(true);\n        ob_start();\n\n        $handler->handle(new \\Exception('foo'));\n\n        $this->assertThatTheExceptionWasOutput(ob_get_clean(), \\Exception::class, 'Exception', 'foo');\n    }\n\n    public function testHandleWithACustomHandlerThatOutputsSomething()\n    {\n        $handler = new ExceptionHandler(true);\n        ob_start();\n        $handler->setHandler(function () {\n            echo 'ccc';\n        });\n\n        $handler->handle(new \\Exception());\n        ob_end_flush(); // Necessary because of this PHP bug : https://bugs.php.net/76563\n        $this->assertSame('ccc', ob_get_clean());\n    }\n\n    public function testHandleWithACustomHandlerThatOutputsNothing()\n    {\n        $handler = new ExceptionHandler(true);\n        $handler->setHandler(function () {});\n\n        $handler->handle(new \\Exception('ccc'));\n\n        $this->assertThatTheExceptionWasOutput(ob_get_clean(), \\Exception::class, 'Exception', 'ccc');\n    }\n\n    public function testHandleWithACustomHandlerThatFails()\n    {\n        $handler = new ExceptionHandler(true);\n        $handler->setHandler(function () {\n            throw new \\RuntimeException();\n        });\n\n        $handler->handle(new \\Exception('ccc'));\n\n        $this->assertThatTheExceptionWasOutput(ob_get_clean(), \\Exception::class, 'Exception', 'ccc');\n    }\n\n    public function testHandleOutOfMemoryException()\n    {\n        $handler = new ExceptionHandler(true);\n        ob_start();\n        $handler->setHandler(function () {\n            $this->fail('OutOfMemoryException should bypass the handler');\n        });\n\n        $handler->handle(new OutOfMemoryException('foo', 0, \\E_ERROR, __FILE__, __LINE__));\n\n        $this->assertThatTheExceptionWasOutput(ob_get_clean(), OutOfMemoryException::class, 'OutOfMemoryException', 'foo');\n    }\n\n    private function assertThatTheExceptionWasOutput($content, $expectedClass, $expectedTitle, $expectedMessage)\n    {\n        $this->assertStringContainsString(sprintf('<span class=\"exception_title\"><abbr title=\"%s\">%s</abbr></span>', $expectedClass, $expectedTitle), $content);\n        $this->assertStringContainsString(sprintf('<p class=\"break-long-words trace-message\">%s</p>', $expectedMessage), $content);\n    }\n}\n"
  },
  {
    "path": "Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests\\FatalErrorHandler;\n\nuse Composer\\Autoload\\ClassLoader as ComposerClassLoader;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Debug\\DebugClassLoader;\nuse Symfony\\Component\\Debug\\Exception\\ClassNotFoundException;\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler;\n\n/**\n * @group legacy\n */\nclass ClassNotFoundFatalErrorHandlerTest extends TestCase\n{\n    public static function setUpBeforeClass(): void\n    {\n        foreach (spl_autoload_functions() as $function) {\n            if (!\\is_array($function)) {\n                continue;\n            }\n\n            // get class loaders wrapped by DebugClassLoader\n            if ($function[0] instanceof DebugClassLoader) {\n                $function = $function[0]->getClassLoader();\n\n                if (!\\is_array($function)) {\n                    continue;\n                }\n            }\n\n            if ($function[0] instanceof ComposerClassLoader) {\n                $function[0]->add('Symfony_Component_Debug_Tests_Fixtures', \\dirname(__DIR__, 5));\n                break;\n            }\n        }\n    }\n\n    /**\n     * @dataProvider provideClassNotFoundData\n     */\n    public function testHandleClassNotFound($error, $translatedMessage, $autoloader = null)\n    {\n        if ($autoloader) {\n            // Unregister all autoloaders to ensure the custom provided\n            // autoloader is the only one to be used during the test run.\n            $autoloaders = spl_autoload_functions();\n            array_map('spl_autoload_unregister', $autoloaders);\n            spl_autoload_register($autoloader);\n        }\n\n        $handler = new ClassNotFoundFatalErrorHandler();\n\n        $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));\n\n        if ($autoloader) {\n            spl_autoload_unregister($autoloader);\n            array_map('spl_autoload_register', $autoloaders);\n        }\n\n        $this->assertInstanceOf(ClassNotFoundException::class, $exception);\n        $this->assertMatchesRegularExpression($translatedMessage, $exception->getMessage());\n        $this->assertSame($error['type'], $exception->getSeverity());\n        $this->assertSame($error['file'], $exception->getFile());\n        $this->assertSame($error['line'], $exception->getLine());\n    }\n\n    public function provideClassNotFoundData()\n    {\n        $autoloader = new ComposerClassLoader();\n        $autoloader->add('Symfony\\Component\\Debug\\Exception\\\\', realpath(__DIR__.'/../../Exception'));\n        $autoloader->add('Symfony_Component_Debug_Tests_Fixtures', realpath(__DIR__.'/../../Tests/Fixtures'));\n\n        $debugClassLoader = new DebugClassLoader([$autoloader, 'loadClass']);\n\n        return [\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \"WhizBangFactory\" not found',\n                ],\n                \"/^Attempted to load class \\\"WhizBangFactory\\\" from the global namespace.\\nDid you forget a \\\"use\\\" statement\\?$/\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'WhizBangFactory\\' not found',\n                ],\n                \"/^Attempted to load class \\\"WhizBangFactory\\\" from the global namespace.\\nDid you forget a \\\"use\\\" statement\\?$/\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'Foo\\\\Bar\\\\WhizBangFactory\\' not found',\n                ],\n                \"/^Attempted to load class \\\"WhizBangFactory\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for another namespace\\?$/\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \"Foo\\\\Bar\\\\WhizBangFactory\" not found',\n                ],\n                \"/^Attempted to load class \\\"WhizBangFactory\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for another namespace\\?$/\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Interface \"Foo\\\\Bar\\\\WhizBangInterface\" not found',\n                ],\n                \"/^Attempted to load interface \\\"WhizBangInterface\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for another namespace\\?$/\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Trait \"Foo\\\\Bar\\\\WhizBangTrait\" not found',\n                ],\n                \"/^Attempted to load trait \\\"WhizBangTrait\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for another namespace\\?$/\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'UndefinedFunctionException\\' not found',\n                ],\n                \"/^Attempted to load class \\\"UndefinedFunctionException\\\" from the global namespace.\\nDid you forget a \\\"use\\\" statement for .*\\\"Symfony\\\\\\\\Component\\\\\\\\Debug\\\\\\\\Exception\\\\\\\\UndefinedFunctionException\\\"\\?$/\",\n                [$debugClassLoader, 'loadClass'],\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'PEARClass\\' not found',\n                ],\n                \"/^Attempted to load class \\\"PEARClass\\\" from the global namespace.\\nDid you forget a \\\"use\\\" statement for \\\"Symfony_Component_Debug_Tests_Fixtures_PEARClass\\\"\\?$/\",\n                [$debugClassLoader, 'loadClass'],\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'Foo\\\\Bar\\\\UndefinedFunctionException\\' not found',\n                ],\n                \"/^Attempted to load class \\\"UndefinedFunctionException\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for .*\\\"Symfony\\\\\\\\Component\\\\\\\\Debug\\\\\\\\Exception\\\\\\\\UndefinedFunctionException\\\"\\?$/\",\n                [$debugClassLoader, 'loadClass'],\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'Foo\\\\Bar\\\\UndefinedFunctionException\\' not found',\n                ],\n                \"/^Attempted to load class \\\"UndefinedFunctionException\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for \\\"Symfony\\\\\\\\Component\\\\\\\\Debug\\\\\\\\Exception\\\\\\\\UndefinedFunctionException\\\"\\?$/\",\n                [$autoloader, 'loadClass'],\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'Foo\\\\Bar\\\\UndefinedFunctionException\\' not found',\n                ],\n                \"/^Attempted to load class \\\"UndefinedFunctionException\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for \\\"Symfony\\\\\\\\Component\\\\\\\\Debug\\\\\\\\Exception\\\\\\\\UndefinedFunctionException\\\"\\?/\",\n                [$debugClassLoader, 'loadClass'],\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Class \\'Foo\\\\Bar\\\\UndefinedFunctionException\\' not found',\n                ],\n                \"/^Attempted to load class \\\"UndefinedFunctionException\\\" from namespace \\\"Foo\\\\\\\\Bar\\\".\\nDid you forget a \\\"use\\\" statement for another namespace\\?$/\",\n                function ($className) { /* do nothing here */ },\n            ],\n        ];\n    }\n\n    public function testCannotRedeclareClass()\n    {\n        if (!file_exists(__DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP')) {\n            $this->markTestSkipped('Can only be run on case insensitive filesystems');\n        }\n\n        require_once __DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP';\n\n        $error = [\n            'type' => 1,\n            'line' => 12,\n            'file' => 'foo.php',\n            'message' => 'Class \\'Foo\\\\Bar\\\\RequiredTwice\\' not found',\n        ];\n\n        $handler = new ClassNotFoundFatalErrorHandler();\n        $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));\n\n        $this->assertInstanceOf(ClassNotFoundException::class, $exception);\n    }\n}\n"
  },
  {
    "path": "Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests\\FatalErrorHandler;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\nuse Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler;\n\n/**\n * @group legacy\n */\nclass UndefinedFunctionFatalErrorHandlerTest extends TestCase\n{\n    /**\n     * @dataProvider provideUndefinedFunctionData\n     */\n    public function testUndefinedFunction($error, $translatedMessage)\n    {\n        $handler = new UndefinedFunctionFatalErrorHandler();\n        $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));\n\n        $this->assertInstanceOf(UndefinedFunctionException::class, $exception);\n        // class names are case insensitive and PHP do not return the same\n        $this->assertSame(strtolower($translatedMessage), strtolower($exception->getMessage()));\n        $this->assertSame($error['type'], $exception->getSeverity());\n        $this->assertSame($error['file'], $exception->getFile());\n        $this->assertSame($error['line'], $exception->getLine());\n    }\n\n    public function provideUndefinedFunctionData()\n    {\n        return [\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined function test_namespaced_function()',\n                ],\n                \"Attempted to call function \\\"test_namespaced_function\\\" from the global namespace.\\nDid you mean to call \\\"\\\\symfony\\\\component\\\\debug\\\\tests\\\\fatalerrorhandler\\\\test_namespaced_function\\\"?\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined function Foo\\\\Bar\\\\Baz\\\\test_namespaced_function()',\n                ],\n                \"Attempted to call function \\\"test_namespaced_function\\\" from namespace \\\"Foo\\\\Bar\\\\Baz\\\".\\nDid you mean to call \\\"\\\\symfony\\\\component\\\\debug\\\\tests\\\\fatalerrorhandler\\\\test_namespaced_function\\\"?\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined function foo()',\n                ],\n                'Attempted to call function \"foo\" from the global namespace.',\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined function Foo\\\\Bar\\\\Baz\\\\foo()',\n                ],\n                'Attempted to call function \"foo\" from namespace \"Foo\\Bar\\Baz\".',\n            ],\n        ];\n    }\n}\n\nfunction test_namespaced_function()\n{\n}\n"
  },
  {
    "path": "Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests\\FatalErrorHandler;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Debug\\Exception\\FatalErrorException;\nuse Symfony\\Component\\Debug\\Exception\\UndefinedMethodException;\nuse Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler;\n\n/**\n * @group legacy\n */\nclass UndefinedMethodFatalErrorHandlerTest extends TestCase\n{\n    /**\n     * @dataProvider provideUndefinedMethodData\n     */\n    public function testUndefinedMethod($error, $translatedMessage)\n    {\n        $handler = new UndefinedMethodFatalErrorHandler();\n        $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));\n\n        $this->assertInstanceOf(UndefinedMethodException::class, $exception);\n        $this->assertSame($translatedMessage, $exception->getMessage());\n        $this->assertSame($error['type'], $exception->getSeverity());\n        $this->assertSame($error['file'], $exception->getFile());\n        $this->assertSame($error['line'], $exception->getLine());\n    }\n\n    public function provideUndefinedMethodData()\n    {\n        return [\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined method SplObjectStorage::what()',\n                ],\n                'Attempted to call an undefined method named \"what\" of class \"SplObjectStorage\".',\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined method SplObjectStorage::()',\n                ],\n                'Attempted to call an undefined method named \"\" of class \"SplObjectStorage\".',\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined method SplObjectStorage::walid()',\n                ],\n                \"Attempted to call an undefined method named \\\"walid\\\" of class \\\"SplObjectStorage\\\".\\nDid you mean to call \\\"valid\\\"?\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'line' => 12,\n                    'file' => 'foo.php',\n                    'message' => 'Call to undefined method SplObjectStorage::offsetFet()',\n                ],\n                \"Attempted to call an undefined method named \\\"offsetFet\\\" of class \\\"SplObjectStorage\\\".\\nDid you mean to call e.g. \\\"offsetGet\\\", \\\"offsetSet\\\" or \\\"offsetUnset\\\"?\",\n            ],\n            [\n                [\n                    'type' => 1,\n                    'message' => 'Call to undefined method class@anonymous::test()',\n                    'file' => '/home/possum/work/symfony/test.php',\n                    'line' => 11,\n                ],\n                'Attempted to call an undefined method named \"test\" of class \"class@anonymous\".',\n            ],\n        ];\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AnnotatedClass.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass AnnotatedClass\n{\n    /**\n     * @deprecated\n     */\n    public function deprecatedMethod()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/ClassAlias.php",
    "content": "<?php\n\nclass_alias('Symfony\\Component\\Debug\\Tests\\Fixtures\\NotPSR0bis', 'Symfony\\Component\\Debug\\Tests\\Fixtures\\ClassAlias');\n"
  },
  {
    "path": "Tests/Fixtures/ClassWithAnnotatedParameters.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass ClassWithAnnotatedParameters\n{\n    /**\n     * @param string $foo this is a foo parameter\n     */\n    public function fooMethod(string $foo)\n    {\n    }\n\n    /**\n     * @param string $bar parameter not implemented yet\n     */\n    public function barMethod(/* string $bar = null */)\n    {\n    }\n\n    /**\n     * @param Quz $quz parameter not implemented yet\n     */\n    public function quzMethod(/* Quz $quz = null */)\n    {\n    }\n\n    /**\n     * @param true $yes\n     */\n    public function isSymfony()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/DefinitionInEvaluatedCode.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\neval('\n    namespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n    class DefinitionInEvaluatedCode\n    {\n    }\n');\n"
  },
  {
    "path": "Tests/Fixtures/DeprecatedClass.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @deprecated but this is a test\n *             deprecation notice\n * @foobar\n */\nclass DeprecatedClass\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/DeprecatedInterface.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @deprecated but this is a test\n *             deprecation notice\n * @foobar\n */\ninterface DeprecatedInterface\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/ErrorHandlerThatUsesThePreviousOne.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass ErrorHandlerThatUsesThePreviousOne\n{\n    private static $previous;\n\n    public static function register()\n    {\n        $handler = new static();\n\n        self::$previous = set_error_handler([$handler, 'handleError']);\n\n        return $handler;\n    }\n\n    public function handleError()\n    {\n        return \\call_user_func_array(self::$previous, \\func_get_args());\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/ExtendedFinalMethod.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass ExtendedFinalMethod extends FinalMethod\n{\n    use FinalMethod2Trait;\n\n    /**\n     * {@inheritdoc}\n     */\n    public function finalMethod()\n    {\n    }\n\n    public function anotherMethod()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/FinalClasses.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @final since version 3.3.\n */\nclass FinalClass1\n{\n    // simple comment\n}\n\n/**\n * @final\n */\nclass FinalClass2\n{\n    // no comment\n}\n\n/**\n * @final comment with @@@ and ***\n *\n * @author John Doe\n */\nclass FinalClass3\n{\n    // with comment and a tag after\n}\n\n/**\n * @final\n *\n * @author John Doe\n */\nclass FinalClass4\n{\n    // without comment and a tag after\n}\n\n/**\n * @author John Doe\n *\n * @final multiline\n * comment\n */\nclass FinalClass5\n{\n    // with comment and a tag before\n}\n\n/**\n * @author John Doe\n *\n * @final\n */\nclass FinalClass6\n{\n    // without comment and a tag before\n}\n\n/**\n * @author John Doe\n *\n * @final another\n *        multiline comment...\n *\n * @return string\n */\nclass FinalClass7\n{\n    // with comment and a tag before and after\n}\n\n/**\n * @author John Doe\n * @final\n *\n * @return string\n */\nclass FinalClass8\n{\n    // without comment and a tag before and after\n}\n"
  },
  {
    "path": "Tests/Fixtures/FinalMethod.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass FinalMethod\n{\n    /**\n     * @final\n     */\n    public function finalMethod()\n    {\n    }\n\n    /**\n     * @final\n     *\n     * @return int\n     */\n    public function finalMethod2()\n    {\n    }\n\n    public function anotherMethod()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/FinalMethod2Trait.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\ntrait FinalMethod2Trait\n{\n    public function finalMethod2()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/InterfaceWithAnnotatedParameters.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * Ensures a deprecation is triggered when a new parameter is not declared in child classes.\n */\ninterface InterfaceWithAnnotatedParameters\n{\n    /**\n     * @param bool $matrix\n     */\n    public function whereAmI();\n\n    /**\n     * @param       $noType\n     * @param callable(\\Throwable|null $reason, mixed $value) $callback and a comment\n     * about this great param\n     * @param string                                          $param (comment with $dollar)\n     * @param $defined\n     * @param  callable  ($a,  $b)  $anotherOne\n     * @param callable (mixed $a, $b) $definedCallable\n     * @param Type$WithDollarIsStillAType $ccc\n     * @param \\JustAType\n     */\n    public function iAmHere();\n}\n"
  },
  {
    "path": "Tests/Fixtures/InternalClass.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @internal\n */\nclass InternalClass\n{\n    use InternalTrait2;\n\n    public function usedInInternalClass()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/InternalInterface.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @internal\n */\ninterface InternalInterface\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/InternalTrait.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @internal\n */\ntrait InternalTrait\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/InternalTrait2.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @internal\n */\ntrait InternalTrait2\n{\n    /**\n     * @internal\n     */\n    public function internalMethod()\n    {\n    }\n\n    /**\n     * @internal but should not trigger a deprecation\n     */\n    public function usedInInternalClass()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/LoggerThatSetAnErrorHandler.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nuse Symfony\\Component\\Debug\\BufferingLogger;\n\nclass LoggerThatSetAnErrorHandler extends BufferingLogger\n{\n    public function log($level, $message, array $context = []): void\n    {\n        set_error_handler('is_string');\n        parent::log($level, $message, $context);\n        restore_error_handler();\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/NonDeprecatedInterface.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\ninterface NonDeprecatedInterface extends DeprecatedInterface\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/PEARClass.php",
    "content": "<?php\n\nclass Symfony_Component_Debug_Tests_Fixtures_PEARClass\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/SubClassWithAnnotatedParameters.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass SubClassWithAnnotatedParameters extends ClassWithAnnotatedParameters implements InterfaceWithAnnotatedParameters\n{\n    use TraitWithAnnotatedParameters;\n\n    public function fooMethod(string $foo)\n    {\n    }\n\n    public function barMethod($bar = null)\n    {\n    }\n\n    public function quzMethod()\n    {\n    }\n\n    public function whereAmI()\n    {\n    }\n\n    /**\n     * @param                      $defined\n     * @param Type\\Does\\Not\\Matter $definedCallable\n     */\n    public function iAmHere()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Throwing.php",
    "content": "<?php\n\nthrow new \\Exception('boo');\n"
  },
  {
    "path": "Tests/Fixtures/ToStringThrower.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass ToStringThrower\n{\n    private $exception;\n\n    public function __construct(\\Exception $e)\n    {\n        $this->exception = $e;\n    }\n\n    public function __toString()\n    {\n        try {\n            throw $this->exception;\n        } catch (\\Exception $e) {\n            // Using user_error() here is on purpose so we do not forget\n            // that this alias also should work alongside with trigger_error().\n            return trigger_error($e, E_USER_ERROR);\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/TraitWithAnnotatedParameters.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\ntrait TraitWithAnnotatedParameters\n{\n    /**\n     * `@param` annotations in traits are not parsed.\n     */\n    public function isSymfony()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/TraitWithInternalMethod.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\ntrait TraitWithInternalMethod\n{\n    /**\n     * @internal\n     */\n    public function foo()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/VirtualClass.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @method string classMethod()\n */\nclass VirtualClass\n{\n    use VirtualTrait;\n}\n"
  },
  {
    "path": "Tests/Fixtures/VirtualClassMagicCall.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @method string magicMethod()\n * @method static string staticMagicMethod()\n */\nclass VirtualClassMagicCall\n{\n    public static function __callStatic($name, $arguments)\n    {\n    }\n\n    public function __call($name, $arguments)\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/VirtualInterface.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @method string interfaceMethod()\n * @method        sameLineInterfaceMethod($arg)\n * @method sameLineInterfaceMethodNoBraces\n *\n * Ignored\n * @method\n * @method\n *\n * Not ignored\n * @method newLineInterfaceMethod() Some description!\n * @method \\stdClass newLineInterfaceMethodNoBraces Description\n *\n * Invalid\n * @method unknownType invalidInterfaceMethod()\n * @method unknownType|string invalidInterfaceMethodNoBraces\n *\n * Complex\n * @method              complexInterfaceMethod($arg, ...$args)\n * @method string[]|int complexInterfaceMethodTyped($arg, int ...$args) Description ...\n *\n * Static\n * @method static Foo&Bar staticMethod()\n * @method static staticMethodNoBraces\n * @method static \\stdClass staticMethodTyped(int $arg) Description\n * @method static \\stdClass[] staticMethodTypedNoBraces\n */\ninterface VirtualInterface\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/VirtualSubInterface.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @method string subInterfaceMethod()\n */\ninterface VirtualSubInterface extends VirtualInterface\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/VirtualTrait.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\n/**\n * @method string traitMethod()\n */\ntrait VirtualTrait\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/casemismatch.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass CaseMismatch\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/notPsr0Bis.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass NotPSR0bis\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/psr4/Psr4CaseMismatch.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass PSR4CaseMismatch\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/reallyNotPsr0.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nclass NotPSR0\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures2/RequiredTwice.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures2;\n\nclass RequiredTwice\n{\n}\n"
  },
  {
    "path": "Tests/HeaderMock.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Debug;\n\nfunction headers_sent()\n{\n    return false;\n}\n\nfunction header($str, $replace = true, $status = null)\n{\n    Tests\\testHeader($str, $replace, $status);\n}\n\nnamespace Symfony\\Component\\Debug\\Tests;\n\nfunction testHeader()\n{\n    static $headers = [];\n\n    if (!$h = \\func_get_args()) {\n        $h = $headers;\n        $headers = [];\n\n        return $h;\n    }\n\n    $headers[] = \\func_get_args();\n}\n"
  },
  {
    "path": "Tests/phpt/debug_class_loader.phpt",
    "content": "--TEST--\nTest DebugClassLoader with previously loaded parents\n--FILE--\n<?php\n\nnamespace Symfony\\Component\\Debug\\Tests\\Fixtures;\n\nuse Symfony\\Component\\Debug\\DebugClassLoader;\n\n$vendor = __DIR__;\nwhile (!file_exists($vendor.'/vendor')) {\n    $vendor = \\dirname($vendor);\n}\nrequire $vendor.'/vendor/autoload.php';\n\nclass_exists(FinalMethod::class);\n\nset_error_handler(function ($type, $msg) { echo $msg, \"\\n\"; });\n\nDebugClassLoader::enable();\n\nclass_exists(ExtendedFinalMethod::class);\n\n?>\n--EXPECTF--\n%A\nThe \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalMethod::finalMethod()\" method is considered final. It may change without further notice as of its next major version. You should not extend it from \"Symfony\\Component\\Debug\\Tests\\Fixtures\\ExtendedFinalMethod\".\nThe \"Symfony\\Component\\Debug\\Tests\\Fixtures\\FinalMethod::finalMethod2()\" method is considered final. It may change without further notice as of its next major version. You should not extend it from \"Symfony\\Component\\Debug\\Tests\\Fixtures\\ExtendedFinalMethod\".\n"
  },
  {
    "path": "Tests/phpt/decorate_exception_hander.phpt",
    "content": "--TEST--\nTest catching fatal errors when handlers are nested\n--INI--\ndisplay_errors=0\n--FILE--\n<?php\n\nnamespace Symfony\\Component\\Debug;\n\n$vendor = __DIR__;\nwhile (!file_exists($vendor.'/vendor')) {\n    $vendor = \\dirname($vendor);\n}\nrequire $vendor.'/vendor/autoload.php';\n\nset_error_handler('var_dump');\nset_exception_handler('var_dump');\n\nErrorHandler::register(null, false);\n\nif (true) {\n    class foo extends missing\n    {\n    }\n}\n\n?>\n--EXPECTF--\n%A\nobject(Symfony\\Component\\Debug\\Exception\\ClassNotFoundException)#%d (8) {\n  [\"message\":protected]=>\n  string(131) \"Attempted to load class \"missing\" from namespace \"Symfony\\Component\\Debug\".\nDid you forget a \"use\" statement for another namespace?\"\n  [\"string\":\"Exception\":private]=>\n  string(0) \"\"\n  [\"code\":protected]=>\n  int(0)\n  [\"file\":protected]=>\n  string(%d) \"%s\"\n  [\"line\":protected]=>\n  int(%d)\n  [\"trace\":\"Exception\":private]=>\n  array(%d) {%A}\n  [\"previous\":\"Exception\":private]=>\n  NULL\n  [\"severity\":protected]=>\n  int(1)\n}\n"
  },
  {
    "path": "Tests/phpt/exception_rethrown.phpt",
    "content": "--TEST--\nTest rethrowing in custom exception handler\n--FILE--\n<?php\n\nnamespace Symfony\\Component\\Debug;\n\n$vendor = __DIR__;\nwhile (!file_exists($vendor.'/vendor')) {\n    $vendor = \\dirname($vendor);\n}\nrequire $vendor.'/vendor/autoload.php';\n\nif (true) {\n    class TestLogger extends \\Psr\\Log\\AbstractLogger\n    {\n        public function log($level, $message, array $context = []): void\n        {\n            echo $message, \"\\n\";\n        }\n    }\n}\n\nset_exception_handler(function ($e) { echo 123; throw $e; });\nErrorHandler::register()->setDefaultLogger(new TestLogger());\nini_set('display_errors', 1);\n\nthrow new \\Exception('foo');\n?>\n--EXPECTF--\nUncaught Exception: foo\n123\nFatal error: Uncaught %s:25\nStack trace:\n%a\n"
  },
  {
    "path": "Tests/phpt/fatal_with_nested_handlers.phpt",
    "content": "--TEST--\nTest catching fatal errors when handlers are nested\n--FILE--\n<?php\n\nnamespace Symfony\\Component\\Debug;\n\n$vendor = __DIR__;\nwhile (!file_exists($vendor.'/vendor')) {\n    $vendor = \\dirname($vendor);\n}\nrequire $vendor.'/vendor/autoload.php';\n\nDebug::enable();\nini_set('display_errors', 0);\n\n$eHandler = set_error_handler('var_dump');\n$xHandler = set_exception_handler('var_dump');\n\nvar_dump([\n    $eHandler[0] === $xHandler[0] ? 'Error and exception handlers do match' : 'Error and exception handlers are different',\n]);\n\n$eHandler[0]->setExceptionHandler('print_r');\n\nif (true) {\n    class Broken implements \\JsonSerializable\n    {\n    }\n}\n\n?>\n--EXPECTF--\narray(1) {\n  [0]=>\n  string(37) \"Error and exception handlers do match\"\n}\n%A\nobject(Symfony\\Component\\Debug\\Exception\\FatalErrorException)#%d (%d) {\n  [\"message\":protected]=>\n  string(179) \"Error: Class Symfony\\Component\\Debug\\Broken contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (JsonSerializable::jsonSerialize)\"\n%a\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"symfony/debug\",\n    \"type\": \"library\",\n    \"description\": \"Provides tools to ease debugging PHP code\",\n    \"keywords\": [],\n    \"homepage\": \"https://symfony.com\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Fabien Potencier\",\n            \"email\": \"fabien@symfony.com\"\n        },\n        {\n            \"name\": \"Symfony Community\",\n            \"homepage\": \"https://symfony.com/contributors\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=7.1.3\",\n        \"psr/log\": \"^1|^2|^3\"\n    },\n    \"conflict\": {\n        \"symfony/http-kernel\": \"<3.4\"\n    },\n    \"require-dev\": {\n        \"symfony/http-kernel\": \"^3.4|^4.0|^5.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": { \"Symfony\\\\Component\\\\Debug\\\\\": \"\" },\n        \"exclude-from-classmap\": [\n            \"/Tests/\"\n        ]\n    },\n    \"minimum-stability\": \"dev\"\n}\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"http://schema.phpunit.de/5.2/phpunit.xsd\"\n         backupGlobals=\"false\"\n         colors=\"true\"\n         bootstrap=\"vendor/autoload.php\"\n         failOnRisky=\"true\"\n         failOnWarning=\"true\"\n>\n    <php>\n        <ini name=\"error_reporting\" value=\"-1\" />\n    </php>\n\n    <testsuites>\n        <testsuite name=\"Symfony Debug Component Test Suite\">\n            <directory suffix=\".phpt\">./Tests/</directory>\n        </testsuite>\n    </testsuites>\n\n    <filter>\n        <whitelist>\n            <directory>./</directory>\n            <exclude>\n                <directory>./Tests</directory>\n                <directory>./vendor</directory>\n            </exclude>\n        </whitelist>\n    </filter>\n</phpunit>\n"
  }
]