From 8495dfb98a31c2ab209591950f40f4c31048b20a Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Nov 2022 21:06:24 +0900 Subject: [PATCH 1/4] chore: update Kint to 5.0 --- composer.json | 2 +- system/ThirdParty/Kint/CallFinder.php | 94 +++++-- system/ThirdParty/Kint/FacadeInterface.php | 49 ++++ system/ThirdParty/Kint/Kint.php | 229 +++++++++--------- .../Parser/{Plugin.php => AbstractPlugin.php} | 28 +-- .../Kint/Parser/ArrayLimitPlugin.php | 14 +- .../Kint/Parser/ArrayObjectPlugin.php | 10 +- .../ThirdParty/Kint/Parser/Base64Plugin.php | 10 +- .../ThirdParty/Kint/Parser/BinaryPlugin.php | 10 +- .../Kint/Parser/BlacklistPlugin.php | 23 +- .../Kint/Parser/ClassMethodsPlugin.php | 20 +- .../Kint/Parser/ClassStaticsPlugin.php | 34 ++- .../ThirdParty/Kint/Parser/ClosurePlugin.php | 10 +- system/ThirdParty/Kint/Parser/ColorPlugin.php | 10 +- .../Parser/ConstructablePluginInterface.php | 33 +++ .../Kint/Parser/DOMDocumentPlugin.php | 45 +++- .../ThirdParty/Kint/Parser/DateTimePlugin.php | 10 +- system/ThirdParty/Kint/Parser/EnumPlugin.php | 10 +- .../ThirdParty/Kint/Parser/FsPathPlugin.php | 10 +- .../ThirdParty/Kint/Parser/IteratorPlugin.php | 10 +- system/ThirdParty/Kint/Parser/JsonPlugin.php | 10 +- .../Kint/Parser/MicrotimePlugin.php | 16 +- .../ThirdParty/Kint/Parser/MysqliPlugin.php | 28 ++- system/ThirdParty/Kint/Parser/Parser.php | 135 ++++++----- .../Kint/Parser/PluginInterface.php | 44 ++++ system/ThirdParty/Kint/Parser/ProxyPlugin.php | 27 ++- .../Kint/Parser/SerializePlugin.php | 33 +-- .../Kint/Parser/SimpleXMLElementPlugin.php | 18 +- .../Kint/Parser/SplFileInfoPlugin.php | 10 +- .../Kint/Parser/SplObjectStoragePlugin.php | 10 +- .../ThirdParty/Kint/Parser/StreamPlugin.php | 10 +- system/ThirdParty/Kint/Parser/TablePlugin.php | 10 +- .../Kint/Parser/ThrowablePlugin.php | 13 +- .../Kint/Parser/TimestampPlugin.php | 10 +- .../ThirdParty/Kint/Parser/ToStringPlugin.php | 10 +- system/ThirdParty/Kint/Parser/TracePlugin.php | 16 +- system/ThirdParty/Kint/Parser/XmlPlugin.php | 38 +-- .../{Renderer.php => AbstractRenderer.php} | 94 ++++--- .../ThirdParty/Kint/Renderer/CliRenderer.php | 29 ++- .../Kint/Renderer/PlainRenderer.php | 58 ++--- .../Kint/Renderer/RendererInterface.php | 57 +++++ .../Rich/{Plugin.php => AbstractPlugin.php} | 31 ++- .../Kint/Renderer/Rich/ArrayLimitPlugin.php | 6 +- .../Kint/Renderer/Rich/BinaryPlugin.php | 14 +- .../Kint/Renderer/Rich/BlacklistPlugin.php | 6 +- .../Kint/Renderer/Rich/CallablePlugin.php | 62 +---- .../Kint/Renderer/Rich/ClosurePlugin.php | 33 +-- .../Kint/Renderer/Rich/ColorPlugin.php | 14 +- .../Kint/Renderer/Rich/DepthLimitPlugin.php | 6 +- ...gPlugin.php => MethodDefinitionPlugin.php} | 54 +++-- .../Kint/Renderer/Rich/MicrotimePlugin.php | 20 +- .../Kint/Renderer/Rich/PluginInterface.php | 2 + .../Kint/Renderer/Rich/RecursionPlugin.php | 6 +- .../Renderer/Rich/SimpleXMLElementPlugin.php | 51 ++-- .../Kint/Renderer/Rich/SourcePlugin.php | 10 +- .../Kint/Renderer/Rich/TabPluginInterface.php | 7 +- .../Kint/Renderer/Rich/TablePlugin.php | 16 +- .../Kint/Renderer/Rich/TimestampPlugin.php | 12 +- .../Kint/Renderer/Rich/TraceFramePlugin.php | 8 +- .../Renderer/Rich/ValuePluginInterface.php | 7 +- .../ThirdParty/Kint/Renderer/RichRenderer.php | 208 +++++++++------- .../Kint/Renderer/Text/AbstractPlugin.php | 63 +++++ .../Kint/Renderer/Text/ArrayLimitPlugin.php | 16 +- .../Kint/Renderer/Text/BlacklistPlugin.php | 16 +- .../Kint/Renderer/Text/DepthLimitPlugin.php | 16 +- .../Kint/Renderer/Text/EnumPlugin.php | 16 +- .../Kint/Renderer/Text/MicrotimePlugin.php | 14 +- .../Text/{Plugin.php => PluginInterface.php} | 16 +- .../Kint/Renderer/Text/RecursionPlugin.php | 16 +- .../Kint/Renderer/Text/TracePlugin.php | 12 +- .../ThirdParty/Kint/Renderer/TextRenderer.php | 107 +++++--- system/ThirdParty/Kint/Utils.php | 51 ++-- system/ThirdParty/Kint/Zval/BlobValue.php | 35 ++- system/ThirdParty/Kint/Zval/ClosureValue.php | 36 +-- system/ThirdParty/Kint/Zval/DateTimeValue.php | 4 +- system/ThirdParty/Kint/Zval/EnumValue.php | 28 ++- system/ThirdParty/Kint/Zval/InstanceValue.php | 30 +-- system/ThirdParty/Kint/Zval/MethodValue.php | 75 ++---- .../Kint/Zval/ParameterHoldingTrait.php | 63 +++++ .../ThirdParty/Kint/Zval/ParameterValue.php | 28 +-- .../Representation/ColorRepresentation.php | 70 +++--- ...php => MethodDefinitionRepresentation.php} | 13 +- .../MicrotimeRepresentation.php | 12 +- .../Zval/Representation/Representation.php | 12 +- .../Representation/SourceRepresentation.php | 8 +- .../SplFileInfoRepresentation.php | 34 ++- system/ThirdParty/Kint/Zval/ResourceValue.php | 6 +- .../Kint/Zval/SimpleXMLElementValue.php | 16 +- system/ThirdParty/Kint/Zval/StreamValue.php | 6 +- .../ThirdParty/Kint/Zval/ThrowableValue.php | 14 +- .../ThirdParty/Kint/Zval/TraceFrameValue.php | 10 +- system/ThirdParty/Kint/Zval/TraceValue.php | 6 +- system/ThirdParty/Kint/Zval/Value.php | 104 ++++---- system/ThirdParty/Kint/init.php | 20 +- system/ThirdParty/Kint/init_helpers.php | 2 + .../Kint/resources/compiled/microtime.js | 2 +- .../Kint/resources/compiled/rich.js | 2 +- .../Kint/resources/compiled/shared.js | 2 +- 98 files changed, 1710 insertions(+), 1181 deletions(-) create mode 100644 system/ThirdParty/Kint/FacadeInterface.php rename system/ThirdParty/Kint/Parser/{Plugin.php => AbstractPlugin.php} (75%) create mode 100644 system/ThirdParty/Kint/Parser/ConstructablePluginInterface.php create mode 100644 system/ThirdParty/Kint/Parser/PluginInterface.php rename system/ThirdParty/Kint/Renderer/{Renderer.php => AbstractRenderer.php} (72%) create mode 100644 system/ThirdParty/Kint/Renderer/RendererInterface.php rename system/ThirdParty/Kint/Renderer/Rich/{Plugin.php => AbstractPlugin.php} (76%) rename system/ThirdParty/Kint/Renderer/Rich/{DocstringPlugin.php => MethodDefinitionPlugin.php} (55%) create mode 100644 system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php rename system/ThirdParty/Kint/Renderer/Text/{Plugin.php => PluginInterface.php} (85%) create mode 100644 system/ThirdParty/Kint/Zval/ParameterHoldingTrait.php rename system/ThirdParty/Kint/Zval/Representation/{DocstringRepresentation.php => MethodDefinitionRepresentation.php} (86%) diff --git a/composer.json b/composer.json index 0afb76af2f8d..1fa6482a0856 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "psr/log": "^1.1" }, "require-dev": { - "kint-php/kint": "^4.2", + "kint-php/kint": "^5.0", "codeigniter/coding-standard": "^1.5", "fakerphp/faker": "^1.9", "friendsofphp/php-cs-fixer": "~3.13.0", diff --git a/system/ThirdParty/Kint/CallFinder.php b/system/ThirdParty/Kint/CallFinder.php index e77a6407f018..e36e91eac0d0 100644 --- a/system/ThirdParty/Kint/CallFinder.php +++ b/system/ThirdParty/Kint/CallFinder.php @@ -1,5 +1,7 @@ true, T_POW => true, T_POW_EQUAL => true, + T_SPACESHIP => true, T_DOUBLE_ARROW => true, '!' => true, '%' => true, @@ -128,7 +135,14 @@ class CallFinder T_STRING => true, ]; - public static function getFunctionCalls($source, $line, $function) + /** + * @psalm-param callable-array|callable-string $function + * + * @param mixed $function + * + * @return array List of matching calls on the relevant line + */ + public static function getFunctionCalls(string $source, int $line, $function): array { static $up = [ '(' => true, @@ -155,11 +169,8 @@ public static function getFunctionCalls($source, $line, $function) T_NS_SEPARATOR => true, ]; - if (KINT_PHP70) { - self::$operator[T_SPACESHIP] = true; - } - if (KINT_PHP74) { + self::$operator[T_FN] = true; self::$operator[T_COALESCE_EQUAL] = true; } @@ -179,7 +190,9 @@ public static function getFunctionCalls($source, $line, $function) $tokens = \token_get_all($source); $cursor = 1; $function_calls = []; + // Performance optimization preventing backwards loops + /** @psalm-var array */ $prev_tokens = [null, null, null]; if (\is_array($function)) { @@ -188,6 +201,9 @@ public static function getFunctionCalls($source, $line, $function) $function = \strtolower($function[1]); } else { $class = null; + /** + * @psalm-suppress RedundantFunctionCallGivenDocblockType + */ $function = \strtolower($function); } @@ -243,8 +259,8 @@ public static function getFunctionCalls($source, $line, $function) continue; } - /** @var array{int, string, int} $prev_tokens[0] */ // All self::$namespace tokens are T_ constants + /** @psalm-var PhpTokenArray $prev_tokens[0] */ $ns = \explode('\\', \strtolower($prev_tokens[0][1])); if (\end($ns) !== $class) { @@ -350,6 +366,7 @@ public static function getFunctionCalls($source, $line, $function) // Format the final output parameters foreach ($params as &$param) { $name = self::tokensFormatted($param['short']); + $expression = false; foreach ($name as $token) { if (self::tokenIsOperator($token)) { @@ -365,6 +382,12 @@ public static function getFunctionCalls($source, $line, $function) ]; } + // Skip first-class callables + /** @psalm-var list $params */ + if (KINT_PHP81 && 1 === \count($params) && '...' === \reset($params)['path']) { + continue; + } + // Get the modifiers --$index; @@ -402,7 +425,10 @@ public static function getFunctionCalls($source, $line, $function) return $function_calls; } - private static function realTokenIndex(array $tokens, $index) + /** + * @psalm-param PhpToken[] $tokens + */ + private static function realTokenIndex(array $tokens, int $index): ?int { ++$index; @@ -422,23 +448,26 @@ private static function realTokenIndex(array $tokens, $index) * occasionally add "..." to short parameter versions. If we simply check * for `$token[0]` then "..." will incorrectly match the "." operator. * - * @param array|string $token The token to check + * @psalm-param PhpToken $token The token to check * - * @return bool + * @param mixed $token */ - private static function tokenIsOperator($token) + private static function tokenIsOperator($token): bool { return '...' !== $token && isset(self::$operator[$token[0]]); } - private static function tokensToString(array $tokens) + /** + * @psalm-param PhpToken[] $tokens + */ + private static function tokensToString(array $tokens): string { $out = ''; foreach ($tokens as $token) { if (\is_string($token)) { $out .= $token; - } elseif (\is_array($token)) { + } else { $out .= $token[1]; } } @@ -446,7 +475,10 @@ private static function tokensToString(array $tokens) return $out; } - private static function tokensTrim(array $tokens) + /** + * @psalm-param PhpToken[] $tokens + */ + private static function tokensTrim(array $tokens): array { foreach ($tokens as $index => $token) { if (isset(self::$ignore[$token[0]])) { @@ -469,32 +501,52 @@ private static function tokensTrim(array $tokens) return \array_reverse($tokens); } - private static function tokensFormatted(array $tokens) + /** + * @psalm-param PhpToken[] $tokens + * + * @psalm-return PhpToken[] + */ + private static function tokensFormatted(array $tokens): array { - $space = false; - $attribute = false; - $tokens = self::tokensTrim($tokens); + $space = false; + $attribute = false; + // Keep space between "strip" symbols for different behavior for matches or closures + // Normally we want to strip spaces between strip tokens: $x{...}[...] + // However with closures and matches we don't: function (...) {...} + $ignorestrip = false; $output = []; $last = null; + if (T_FUNCTION === $tokens[0][0] || + (KINT_PHP74 && T_FN === $tokens[0][0]) || + (KINT_PHP80 && T_MATCH === $tokens[0][0]) + ) { + $ignorestrip = true; + } + foreach ($tokens as $index => $token) { if (isset(self::$ignore[$token[0]])) { if ($space) { continue; } - $next = $tokens[self::realTokenIndex($tokens, $index)]; + $next = self::realTokenIndex($tokens, $index); + if (null === $next) { + // This should be impossible, since we always call tokensTrim first + break; // @codeCoverageIgnore + } + $next = $tokens[$next]; - /** @var array|string $last */ + /** @psalm-var PhpToken $last */ if ($attribute && ']' === $last[0]) { $attribute = false; - } elseif (isset(self::$strip[$last[0]]) && !self::tokenIsOperator($next)) { + } elseif (!$ignorestrip && isset(self::$strip[$last[0]]) && !self::tokenIsOperator($next)) { continue; } - if (isset(self::$strip[$next[0]]) && $last && !self::tokenIsOperator($last)) { + if (!$ignorestrip && isset(self::$strip[$next[0]]) && $last && !self::tokenIsOperator($last)) { continue; } diff --git a/system/ThirdParty/Kint/FacadeInterface.php b/system/ThirdParty/Kint/FacadeInterface.php new file mode 100644 index 000000000000..da4badcd869a --- /dev/null +++ b/system/ThirdParty/Kint/FacadeInterface.php @@ -0,0 +1,49 @@ + Array of modes to renderer class names + * @psalm-var class-string[] Array of modes to renderer class names */ public static $renderers = [ - self::MODE_RICH => 'Kint\\Renderer\\RichRenderer', - self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer', - self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer', - self::MODE_CLI => 'Kint\\Renderer\\CliRenderer', + self::MODE_RICH => \Kint\Renderer\RichRenderer::class, + self::MODE_PLAIN => \Kint\Renderer\PlainRenderer::class, + self::MODE_TEXT => \Kint\Renderer\TextRenderer::class, + self::MODE_CLI => \Kint\Renderer\CliRenderer::class, ]; + /** + * @psalm-var class-string[] + */ public static $plugins = [ - 'Kint\\Parser\\ArrayLimitPlugin', - 'Kint\\Parser\\ArrayObjectPlugin', - 'Kint\\Parser\\Base64Plugin', - 'Kint\\Parser\\BlacklistPlugin', - 'Kint\\Parser\\ClassMethodsPlugin', - 'Kint\\Parser\\ClassStaticsPlugin', - 'Kint\\Parser\\ClosurePlugin', - 'Kint\\Parser\\ColorPlugin', - 'Kint\\Parser\\DateTimePlugin', - 'Kint\\Parser\\EnumPlugin', - 'Kint\\Parser\\FsPathPlugin', - 'Kint\\Parser\\IteratorPlugin', - 'Kint\\Parser\\JsonPlugin', - 'Kint\\Parser\\MicrotimePlugin', - 'Kint\\Parser\\SimpleXMLElementPlugin', - 'Kint\\Parser\\SplFileInfoPlugin', - 'Kint\\Parser\\SplObjectStoragePlugin', - 'Kint\\Parser\\StreamPlugin', - 'Kint\\Parser\\TablePlugin', - 'Kint\\Parser\\ThrowablePlugin', - 'Kint\\Parser\\TimestampPlugin', - 'Kint\\Parser\\TracePlugin', - 'Kint\\Parser\\XmlPlugin', + \Kint\Parser\ArrayLimitPlugin::class, + \Kint\Parser\ArrayObjectPlugin::class, + \Kint\Parser\Base64Plugin::class, + \Kint\Parser\BlacklistPlugin::class, + \Kint\Parser\ClassMethodsPlugin::class, + \Kint\Parser\ClassStaticsPlugin::class, + \Kint\Parser\ClosurePlugin::class, + \Kint\Parser\ColorPlugin::class, + \Kint\Parser\DateTimePlugin::class, + \Kint\Parser\EnumPlugin::class, + \Kint\Parser\FsPathPlugin::class, + \Kint\Parser\IteratorPlugin::class, + \Kint\Parser\JsonPlugin::class, + \Kint\Parser\MicrotimePlugin::class, + \Kint\Parser\SimpleXMLElementPlugin::class, + \Kint\Parser\SplFileInfoPlugin::class, + \Kint\Parser\SplObjectStoragePlugin::class, + \Kint\Parser\StreamPlugin::class, + \Kint\Parser\TablePlugin::class, + \Kint\Parser\ThrowablePlugin::class, + \Kint\Parser\TimestampPlugin::class, + \Kint\Parser\TracePlugin::class, + \Kint\Parser\XmlPlugin::class, ]; protected static $plugin_pool = []; @@ -171,33 +180,33 @@ class Kint protected $parser; protected $renderer; - public function __construct(Parser $p, Renderer $r) + public function __construct(Parser $p, RendererInterface $r) { $this->parser = $p; $this->renderer = $r; } - public function setParser(Parser $p) + public function setParser(Parser $p): void { $this->parser = $p; } - public function getParser() + public function getParser(): Parser { return $this->parser; } - public function setRenderer(Renderer $r) + public function setRenderer(RendererInterface $r): void { $this->renderer = $r; } - public function getRenderer() + public function getRenderer(): RendererInterface { return $this->renderer; } - public function setStatesFromStatics(array $statics) + public function setStatesFromStatics(array $statics): void { $this->renderer->setStatics($statics); @@ -211,11 +220,10 @@ public function setStatesFromStatics(array $statics) $plugins = []; foreach ($statics['plugins'] as $plugin) { - if ($plugin instanceof Plugin) { + if ($plugin instanceof PluginInterface) { $plugins[] = $plugin; - } elseif (\is_string($plugin) && \is_subclass_of($plugin, Plugin::class)) { + } elseif (\is_string($plugin) && \is_subclass_of($plugin, ConstructablePluginInterface::class)) { if (!isset(static::$plugin_pool[$plugin])) { - /** @psalm-suppress UnsafeInstantiation */ $p = new $plugin(); static::$plugin_pool[$plugin] = $p; } @@ -230,7 +238,7 @@ public function setStatesFromStatics(array $statics) } } - public function setStatesFromCallInfo(array $info) + public function setStatesFromCallInfo(array $info): void { $this->renderer->setCallInfo($info); @@ -241,15 +249,7 @@ public function setStatesFromCallInfo(array $info) $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null); } - /** - * Renders a list of vars including the pre and post renders. - * - * @param array $vars Data to dump - * @param array $base Base Zval\Value objects - * - * @return string - */ - public function dumpAll(array $vars, array $base) + public function dumpAll(array $vars, array $base): string { if (\array_keys($vars) !== \array_keys($base)) { throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments'); @@ -276,12 +276,10 @@ public function dumpAll(array $vars, array $base) /** * Dumps and renders a var. * - * @param mixed $var Data to dump + * @param mixed &$var Data to dump * @param Value $base Base object - * - * @return string */ - public function dumpVar(&$var, Value $base) + protected function dumpVar(&$var, Value $base): string { return $this->renderer->render( $this->parser->parse($var, $base) @@ -293,7 +291,7 @@ public function dumpVar(&$var, Value $base) * * @return array Current static settings */ - public static function getStatics() + public static function getStatics(): array { return [ 'aliases' => static::$aliases, @@ -313,15 +311,11 @@ public static function getStatics() } /** - * Creates a Kint instances based on static settings. - * - * Also calls setStatesFromStatics for you + * Creates a Kint instance based on static settings. * * @param array $statics array of statics as returned by getStatics - * - * @return null|\Kint\Kint */ - public static function createFromStatics(array $statics) + public static function createFromStatics(array $statics): ?FacadeInterface { $mode = false; @@ -341,14 +335,13 @@ public static function createFromStatics(array $statics) return null; } - if (!isset($statics['renderers'][$mode])) { - $renderer = new TextRenderer(); - } else { - /** @var Renderer */ + /** @psalm-var class-string[] $statics['renderers'] */ + if (isset($statics['renderers'][$mode]) && \is_subclass_of($statics['renderers'][$mode], RendererInterface::class)) { $renderer = new $statics['renderers'][$mode](); + } else { + $renderer = new TextRenderer(); } - /** @psalm-suppress UnsafeInstantiation */ return new static(new Parser(), $renderer); } @@ -360,7 +353,7 @@ public static function createFromStatics(array $statics) * * @return Value[] Base objects for the arguments */ - public static function getBasesFromParamInfo(array $params, $argc) + public static function getBasesFromParamInfo(array $params, int $argc): array { static $blacklist = [ 'null', @@ -382,11 +375,7 @@ public static function getBasesFromParamInfo(array $params, $argc) $bases = []; for ($i = 0; $i < $argc; ++$i) { - if (isset($params[$i])) { - $param = $params[$i]; - } else { - $param = null; - } + $param = $params[$i] ?? null; if (!isset($param['name']) || \is_numeric($param['name'])) { $name = null; @@ -419,11 +408,11 @@ public static function getBasesFromParamInfo(array $params, $argc) * * @param array $aliases Call aliases as found in Kint::$aliases * @param array[] $trace Backtrace - * @param int $argc Number of arguments + * @param array $args Arguments * - * @return array{params:null|array, modifiers:array, callee:null|array, caller:null|array, trace:array[]} Call info + * @return array Call info */ - public static function getCallInfo(array $aliases, array $trace, $argc) + public static function getCallInfo(array $aliases, array $trace, array $args): array { $found = false; $callee = null; @@ -457,7 +446,7 @@ public static function getCallInfo(array $aliases, array $trace, $argc) $miniTrace = \array_values($miniTrace); - $call = static::getSingleCall($callee ?: [], $argc); + $call = static::getSingleCall($callee ?: [], $args); $ret = [ 'params' => null, @@ -490,7 +479,7 @@ public static function trace() Utils::normalizeAliases(static::$aliases); - $call_info = static::getCallInfo(static::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \func_num_args()); + $call_info = static::getCallInfo(static::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), []); $statics = static::getStatics(); @@ -500,8 +489,7 @@ public static function trace() $kintstance = static::createFromStatics($statics); if (!$kintstance) { - // Should never happen - return 0; // @codeCoverageIgnore + return 0; } if (\in_array('-', $call_info['modifiers'], true)) { @@ -561,7 +549,7 @@ public static function dump(...$args) Utils::normalizeAliases(static::$aliases); - $call_info = static::getCallInfo(static::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); + $call_info = static::getCallInfo(static::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), $args); $statics = static::getStatics(); @@ -571,8 +559,7 @@ public static function dump(...$args) $kintstance = static::createFromStatics($statics); if (!$kintstance) { - // Should never happen - return 0; // @codeCoverageIgnore + return 0; } if (\in_array('-', $call_info['modifiers'], true)) { @@ -584,10 +571,7 @@ public static function dump(...$args) $kintstance->setStatesFromStatics($statics); $kintstance->setStatesFromCallInfo($call_info); - $bases = static::getBasesFromParamInfo( - isset($call_info['params']) ? $call_info['params'] : [], - \count($args) - ); + $bases = static::getBasesFromParamInfo($call_info['params'] ?? [], \count($args)); $output = $kintstance->dumpAll(\array_values($args), $bases); if (static::$return || \in_array('@', $call_info['modifiers'], true)) { @@ -606,12 +590,8 @@ public static function dump(...$args) /** * generic path display callback, can be configured in app_root_dirs; purpose is * to show relevant path info and hide as much of the path as possible. - * - * @param string $file - * - * @return string */ - public static function shortenPath($file) + public static function shortenPath(string $file): string { $file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen')); @@ -649,7 +629,7 @@ public static function shortenPath($file) return '/'.\implode('/', $file); } - public static function getIdeLink($file, $line) + public static function getIdeLink(string $file, int $line): string { return \str_replace(['%f', '%l'], [$file, $line], static::$file_link_format); } @@ -658,13 +638,17 @@ public static function getIdeLink($file, $line) * Returns specific function call info from a stack trace frame, or null if no match could be found. * * @param array $frame The stack trace frame in question - * @param int $argc The amount of arguments received + * @param array $args The arguments * - * @return null|array{parameters:array, modifiers:array} params and modifiers, or null if a specific call could not be determined + * @return ?array params and modifiers, or null if a specific call could not be determined */ - protected static function getSingleCall(array $frame, $argc) + protected static function getSingleCall(array $frame, array $args): ?array { - if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) { + if ( + !isset($frame['file'], $frame['line'], $frame['function']) || + !\is_readable($frame['file']) || + !$source = \file_get_contents($frame['file']) + ) { return null; } @@ -674,11 +658,9 @@ protected static function getSingleCall(array $frame, $argc) $callfunc = [$frame['class'], $frame['function']]; } - $calls = CallFinder::getFunctionCalls( - \file_get_contents($frame['file']), - $frame['line'], - $callfunc - ); + $calls = CallFinder::getFunctionCalls($source, $frame['line'], $callfunc); + + $argc = \count($args); $return = null; @@ -688,23 +670,40 @@ protected static function getSingleCall(array $frame, $argc) // Handle argument unpacking as a last resort foreach ($call['parameters'] as $i => &$param) { if (0 === \strpos($param['name'], '...')) { + $is_unpack = true; + + // If we're on the last param if ($i < $argc && $i === \count($call['parameters']) - 1) { - for ($j = 1; $j + $i < $argc; ++$j) { - $call['parameters'][] = [ - 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']', - 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']', - 'expression' => false, - ]; + unset($call['parameters'][$i]); + + if (Utils::isAssoc($args)) { + // Associated unpacked arrays can be accessed by key + $keys = \array_slice(\array_keys($args), $i); + + foreach ($keys as $key) { + $call['parameters'][] = [ + 'name' => \substr($param['name'], 3).'['.\var_export($key, true).']', + 'path' => \substr($param['path'], 3).'['.\var_export($key, true).']', + 'expression' => false, + ]; + } + } else { + // Numeric unpacked arrays have their order blown away like a pass + // through array_values so we can't access them directly at all + for ($j = 0; $j + $i < $argc; ++$j) { + $call['parameters'][] = [ + 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']', + 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']', + 'expression' => false, + ]; + } } - $param['name'] = 'reset('.\substr($param['name'], 3).')'; - $param['path'] = 'reset('.\substr($param['path'], 3).')'; - $param['expression'] = false; + $call['parameters'] = \array_values($call['parameters']); } else { $call['parameters'] = \array_slice($call['parameters'], 0, $i); } - $is_unpack = true; break; } diff --git a/system/ThirdParty/Kint/Parser/Plugin.php b/system/ThirdParty/Kint/Parser/AbstractPlugin.php similarity index 75% rename from system/ThirdParty/Kint/Parser/Plugin.php rename to system/ThirdParty/Kint/Parser/AbstractPlugin.php index 981d2aa56e1b..a3f896843a3a 100644 --- a/system/ThirdParty/Kint/Parser/Plugin.php +++ b/system/ThirdParty/Kint/Parser/AbstractPlugin.php @@ -1,5 +1,7 @@ parser = $p; } - /** - * An array of types (As returned by gettype) for all data this plugin can operate on. - * - * @return array List of types - */ - public function getTypes() + public function setParser(Parser $p): void { - return []; - } - - public function getTriggers() - { - return Parser::TRIGGER_NONE; + $this->parser = $p; } - - abstract public function parse(&$var, Value &$o, $trigger); } diff --git a/system/ThirdParty/Kint/Parser/ArrayLimitPlugin.php b/system/ThirdParty/Kint/Parser/ArrayLimitPlugin.php index 4fa94c63c3b9..2e7fca93842d 100644 --- a/system/ThirdParty/Kint/Parser/ArrayLimitPlugin.php +++ b/system/ThirdParty/Kint/Parser/ArrayLimitPlugin.php @@ -1,5 +1,7 @@ = self::$trigger) { throw new InvalidArgumentException('ArrayLimitPlugin::$limit can not be lower than ArrayLimitPlugin::$trigger'); @@ -90,7 +92,7 @@ public function parse(&$var, Value &$o, $trigger) $base->depth = $depth - 1; $obj = $this->parser->parse($var, $base); - if (!$obj instanceof Value || 'array' != $obj->type) { + if ('array' != $obj->type) { return; // @codeCoverageIgnore } @@ -115,7 +117,7 @@ public function parse(&$var, Value &$o, $trigger) $this->parser->haltParse(); } - protected function recalcDepthLimit(Value $o) + protected function recalcDepthLimit(Value $o): void { $hintkey = \array_search('depth_limit', $o->hints, true); if (false !== $hintkey) { diff --git a/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php b/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php index f32b4fada23a..82ff7593e3b7 100644 --- a/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php +++ b/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php @@ -1,5 +1,7 @@ encoding, ['ASCII', 'UTF-8'], true)) { $o->value->hints[] = 'binary'; diff --git a/system/ThirdParty/Kint/Parser/BlacklistPlugin.php b/system/ThirdParty/Kint/Parser/BlacklistPlugin.php index 9c472d43e798..90ec3c223327 100644 --- a/system/ThirdParty/Kint/Parser/BlacklistPlugin.php +++ b/system/ThirdParty/Kint/Parser/BlacklistPlugin.php @@ -1,5 +1,7 @@ blacklistValue($var, $o); + $this->blacklistValue($var, $o); + + return; } } @@ -68,12 +72,17 @@ public function parse(&$var, Value &$o, $trigger) foreach (self::$shallow_blacklist as $class) { if ($var instanceof $class) { - return $this->blacklistValue($var, $o); + $this->blacklistValue($var, $o); + + return; } } } - protected function blacklistValue(&$var, Value &$o) + /** + * @param object &$var + */ + protected function blacklistValue(&$var, Value &$o): void { $object = new InstanceValue(); $object->transplant($o); diff --git a/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php b/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php index 152e59d9c762..e71d537aa838 100644 --- a/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php +++ b/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php @@ -1,5 +1,7 @@ setAccessPathFrom($o); } - if ($method->owner_class !== $class && $ds = $method->getRepresentation('docstring')) { - $ds = clone $ds; - $ds->class = $method->owner_class; - $method->replaceRepresentation($ds); + if ($method->owner_class !== $class && $d = $method->getRepresentation('method_definition')) { + $d = clone $d; + $d->inherited = true; + $method->replaceRepresentation($d); } $rep->contents[] = $method; @@ -91,7 +93,7 @@ public function parse(&$var, Value &$o, $trigger) } } - private static function sort(MethodValue $a, MethodValue $b) + private static function sort(MethodValue $a, MethodValue $b): int { $sort = ((int) $a->static) - ((int) $b->static); if ($sort) { diff --git a/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php b/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php index 7d2673f849d2..5435da932bfc 100644 --- a/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php +++ b/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php @@ -1,5 +1,7 @@ const = true; $const->depth = $o->depth + 1; $const->owner_class = $class; $const->operator = Value::OPERATOR_STATIC; + + $creflection = new ReflectionClassConstant($class, $name); + + $const->access = Value::ACCESS_PUBLIC; + if ($creflection->isProtected()) { + $const->access = Value::ACCESS_PROTECTED; + } elseif ($creflection->isPrivate()) { + $const->access = Value::ACCESS_PRIVATE; + } + + if ($this->parser->childHasPath($o, $const)) { + $const->access_path = '\\'.$class.'::'.$name; + } + $const = $this->parser->parse($val, $const); $consts[] = $const; @@ -117,7 +137,7 @@ public function parse(&$var, Value &$o, $trigger) $o->addRepresentation($statics); } - private static function sort(Value $a, Value $b) + private static function sort(Value $a, Value $b): int { $sort = ((int) $a->const) - ((int) $b->const); if ($sort) { diff --git a/system/ThirdParty/Kint/Parser/ClosurePlugin.php b/system/ThirdParty/Kint/Parser/ClosurePlugin.php index f4a68f5db737..8b199781078e 100644 --- a/system/ThirdParty/Kint/Parser/ClosurePlugin.php +++ b/system/ThirdParty/Kint/Parser/ClosurePlugin.php @@ -1,5 +1,7 @@ 32) { return; diff --git a/system/ThirdParty/Kint/Parser/ConstructablePluginInterface.php b/system/ThirdParty/Kint/Parser/ConstructablePluginInterface.php new file mode 100644 index 000000000000..689b24e61668 --- /dev/null +++ b/system/ThirdParty/Kint/Parser/ConstructablePluginInterface.php @@ -0,0 +1,33 @@ +parseList($var, $o, $trigger); + $this->parseList($var, $o, $trigger); + + return; } if ($var instanceof DOMNode) { - return $this->parseNode($var, $o); + $this->parseNode($var, $o); + + return; } } - protected function parseList(&$var, InstanceValue &$o, $trigger) + /** + * @param DOMNamedNodeMap|DOMNodeList &$var + */ + protected function parseList($var, InstanceValue &$o, int $trigger): void { + if (!$var instanceof DOMNamedNodeMap && !$var instanceof DOMNodeList) { + return; + } + // Recursion should never happen, should always be stopped at the parent // DOMNode. Depth limit on the other hand we're going to skip since // that would show an empty iterator and rather useless. Let the depth @@ -160,7 +174,7 @@ protected function parseList(&$var, InstanceValue &$o, $trigger) $base_obj->access_path .= ', '; $base_obj->access_path .= \var_export($item->name, true); $base_obj->access_path .= ')'; - } elseif ($var instanceof DOMNodeList) { + } else { // DOMNodeList $base_obj->access_path = $o->access_path.'->item('.\var_export($key, true).')'; } } @@ -169,7 +183,10 @@ protected function parseList(&$var, InstanceValue &$o, $trigger) } } - protected function parseNode(&$var, InstanceValue &$o) + /** + * @psalm-param-out Value &$o + */ + protected function parseNode(DOMNode $var, InstanceValue &$o): void { // Fill the properties // They can't be enumerated through reflection or casting, @@ -272,7 +289,7 @@ protected function parseNode(&$var, InstanceValue &$o) } } - protected function parseProperty(InstanceValue $o, $prop, &$var) + protected function parseProperty(InstanceValue $o, string $prop, DOMNode &$var): Value { // Duplicating (And slightly optimizing) the Parser::parseObject() code here $base_obj = new Value(); @@ -315,14 +332,14 @@ protected function parseProperty(InstanceValue $o, $prop, &$var) return $base_obj; } - protected static function textualNodeToString(InstanceValue $o) + protected static function textualNodeToString(InstanceValue $o): Value { if (empty($o->value) || empty($o->value->contents) || empty($o->classname)) { - return; + throw new InvalidArgumentException('Invalid DOMNode passed to DOMDocumentPlugin::textualNodeToString'); } if (!\in_array($o->classname, ['DOMText', 'DOMAttr', 'DOMComment'], true)) { - return; + throw new InvalidArgumentException('Invalid DOMNode passed to DOMDocumentPlugin::textualNodeToString'); } foreach ($o->value->contents as $property) { @@ -333,5 +350,7 @@ protected static function textualNodeToString(InstanceValue $o) return $ret; } } + + throw new InvalidArgumentException('Invalid DOMNode passed to DOMDocumentPlugin::textualNodeToString'); } } diff --git a/system/ThirdParty/Kint/Parser/DateTimePlugin.php b/system/ThirdParty/Kint/Parser/DateTimePlugin.php index 1c546fd7d2a1..038acea133ec 100644 --- a/system/ThirdParty/Kint/Parser/DateTimePlugin.php +++ b/system/ThirdParty/Kint/Parser/DateTimePlugin.php @@ -1,5 +1,7 @@ 2048) { return; diff --git a/system/ThirdParty/Kint/Parser/IteratorPlugin.php b/system/ThirdParty/Kint/Parser/IteratorPlugin.php index 8aa1c342f5ce..7ebfe73e5cef 100644 --- a/system/ThirdParty/Kint/Parser/IteratorPlugin.php +++ b/system/ThirdParty/Kint/Parser/IteratorPlugin.php @@ -1,5 +1,7 @@ depth) { return; @@ -63,9 +65,9 @@ public function parse(&$var, Value &$o, $trigger) return; } - $sec = \floor($var); + $sec = (int) \floor($var); $usec = $var - $sec; - $usec = \floor($usec * 1000000); + $usec = (int) \floor($usec * 1000000); } $time = $sec + ($usec / 1000000); @@ -95,7 +97,7 @@ public function parse(&$var, Value &$o, $trigger) $o->hints[] = 'microtime'; } - public static function clean() + public static function clean(): void { self::$last = null; self::$start = null; diff --git a/system/ThirdParty/Kint/Parser/MysqliPlugin.php b/system/ThirdParty/Kint/Parser/MysqliPlugin.php index 4c95d790a772..90a4abd6b511 100644 --- a/system/ThirdParty/Kint/Parser/MysqliPlugin.php +++ b/system/ThirdParty/Kint/Parser/MysqliPlugin.php @@ -1,5 +1,7 @@ true, ]; - public function getTypes() + public function getTypes(): array { return ['object']; } - public function getTriggers() + public function getTriggers(): int { return Parser::TRIGGER_COMPLETE; } - public function parse(&$var, Value &$o, $trigger) + public function parse(&$var, Value &$o, int $trigger): void { - if (!$var instanceof Mysqli) { + if (!$var instanceof mysqli) { return; } + /** @psalm-var ?string $var->sqlstate */ try { $connected = \is_string(@$var->sqlstate); } catch (Throwable $t) { $connected = false; } + /** @psalm-var ?string $var->client_info */ try { $empty = !$connected && \is_string(@$var->client_info); } catch (Throwable $t) { // @codeCoverageIgnore @@ -139,9 +143,9 @@ public function parse(&$var, Value &$o, $trigger) // @codeCoverageIgnoreEnd } - // PHP81 returns an empty array when casting a Mysqli instance + // PHP81 returns an empty array when casting a mysqli instance if (KINT_PHP81) { - $r = new ReflectionClass(Mysqli::class); + $r = new ReflectionClass(mysqli::class); $basepropvalues = []; @@ -163,7 +167,7 @@ public function parse(&$var, Value &$o, $trigger) $child = new Value(); $child->depth = $o->depth + 1; - $child->owner_class = Mysqli::class; + $child->owner_class = mysqli::class; $child->operator = Value::OPERATOR_OBJECT; $child->name = $pname; @@ -175,7 +179,7 @@ public function parse(&$var, Value &$o, $trigger) $child->access = Value::ACCESS_PRIVATE; // @codeCoverageIgnore } - // We only do base Mysqli properties so we don't need to worry about complex names + // We only do base mysqli properties so we don't need to worry about complex names if ($this->parser->childHasPath($o, $child)) { $child->access_path .= $o->access_path.'->'.$child->name; } diff --git a/system/ThirdParty/Kint/Parser/Parser.php b/system/ThirdParty/Kint/Parser/Parser.php index 77e825a9920f..5c7a40a3ac1a 100644 --- a/system/ThirdParty/Kint/Parser/Parser.php +++ b/system/ThirdParty/Kint/Parser/Parser.php @@ -1,5 +1,7 @@ marker = \uniqid("kint\0", true); + $this->marker = "kint\0".\random_bytes(16); $this->depth_limit = $depth_limit; $this->caller_class = $caller; @@ -79,17 +82,15 @@ public function __construct($depth_limit = 0, $caller = null) /** * Set the caller class. - * - * @param null|string $caller Caller class name */ - public function setCallerClass($caller = null) + public function setCallerClass(?string $caller = null): void { $this->noRecurseCall(); $this->caller_class = $caller; } - public function getCallerClass() + public function getCallerClass(): ?string { return $this->caller_class; } @@ -97,16 +98,16 @@ public function getCallerClass() /** * Set the depth limit. * - * @param int $depth_limit Maximum depth to parse data + * @param int $depth_limit Maximum depth to parse data, 0 for none */ - public function setDepthLimit($depth_limit = 0) + public function setDepthLimit(int $depth_limit = 0): void { $this->noRecurseCall(); $this->depth_limit = $depth_limit; } - public function getDepthLimit() + public function getDepthLimit(): int { return $this->depth_limit; } @@ -114,12 +115,10 @@ public function getDepthLimit() /** * Parses a variable into a Kint object structure. * - * @param mixed $var The input variable - * @param Value $o The base object - * - * @return Value + * @param mixed &$var The input variable + * @param Value $o The base object */ - public function parse(&$var, Value $o) + public function parse(&$var, Value $o): Value { $o->type = \strtolower(\gettype($var)); @@ -148,7 +147,7 @@ public function parse(&$var, Value $o) } } - public function addPlugin(Plugin $p) + public function addPlugin(PluginInterface $p): bool { if (!$types = $p->getTypes()) { return false; @@ -180,17 +179,17 @@ public function addPlugin(Plugin $p) return true; } - public function clearPlugins() + public function clearPlugins(): void { $this->plugins = []; } - public function haltParse() + public function haltParse(): void { $this->parse_break = true; } - public function childHasPath(InstanceValue $parent, Value $child) + public function childHasPath(InstanceValue $parent, Value $child): bool { if ('__PHP_Incomplete_Class' === $parent->classname) { return false; @@ -233,14 +232,14 @@ public function childHasPath(InstanceValue $parent, Value $child) * * @return array Array with recursion marker removed */ - public function getCleanArray(array $array) + public function getCleanArray(array $array): array { unset($array[$this->marker]); return $array; } - protected function noRecurseCall() + protected function noRecurseCall(): void { $bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS); @@ -259,7 +258,10 @@ protected function noRecurseCall() } } - private function parseGeneric(&$var, Value $o) + /** + * @param null|bool|float|int &$var + */ + private function parseGeneric(&$var, Value $o): Value { $rep = new Representation('Contents'); $rep->contents = $var; @@ -275,12 +277,10 @@ private function parseGeneric(&$var, Value $o) /** * Parses a string into a Kint BlobValue structure. * - * @param string $var The input variable - * @param Value $o The base object - * - * @return Value + * @param string &$var The input variable + * @param Value $o The base object */ - private function parseString(&$var, Value $o) + private function parseString(string &$var, Value $o): Value { $string = new BlobValue(); $string->transplant($o); @@ -302,12 +302,10 @@ private function parseString(&$var, Value $o) /** * Parses an array into a Kint object structure. * - * @param array $var The input variable - * @param Value $o The base object - * - * @return Value + * @param array &$var The input variable + * @param Value $o The base object */ - private function parseArray(array &$var, Value $o) + private function parseArray(array &$var, Value $o): Value { $array = new Value(); $array->transplant($o); @@ -395,12 +393,10 @@ private function parseArray(array &$var, Value $o) /** * Parses an object into a Kint InstanceValue structure. * - * @param object $var The input variable - * @param Value $o The base object - * - * @return Value + * @param object &$var The input variable + * @param Value $o The base object */ - private function parseObject(&$var, Value $o) + private function parseObject(&$var, Value $o): Value { $hash = \spl_object_hash($var); $values = (array) $var; @@ -411,6 +407,10 @@ private function parseObject(&$var, Value $o) $object->spl_object_hash = $hash; $object->size = \count($values); + if (KINT_PHP72) { + $object->spl_object_id = \spl_object_id($var); + } + if (isset($this->object_hashes[$hash])) { $object->hints[] = 'recursion'; @@ -439,15 +439,34 @@ private function parseObject(&$var, Value $o) $rep = new Representation('Properties'); + $readonly = []; + + // Reflection is both slower and more painful to use than array casting + // We only use it to identify readonly and uninitialized properties if (KINT_PHP74 && '__PHP_Incomplete_Class' != $object->classname) { $rprops = $reflector->getProperties(); + while ($reflector = $reflector->getParentClass()) { + $rprops = \array_merge($rprops, $reflector->getProperties(ReflectionProperty::IS_PRIVATE)); + } + foreach ($rprops as $rprop) { if ($rprop->isStatic()) { continue; } $rprop->setAccessible(true); + + if (KINT_PHP81 && $rprop->isReadOnly()) { + if ($rprop->isPublic()) { + $readonly[$rprop->getName()] = true; + } elseif ($rprop->isProtected()) { + $readonly["\0*\0".$rprop->getName()] = true; + } elseif ($rprop->isPrivate()) { + $readonly["\0".$rprop->getDeclaringClass()->getName()."\0".$rprop->getName()] = true; + } + } + if ($rprop->isInitialized($var)) { continue; } @@ -460,6 +479,7 @@ private function parseObject(&$var, Value $o) $child->owner_class = $rprop->getDeclaringClass()->getName(); $child->operator = Value::OPERATOR_OBJECT; $child->name = $rprop->getName(); + $child->readonly = KINT_PHP81 && $rprop->isReadOnly(); if ($rprop->isPublic()) { $child->access = Value::ACCESS_PUBLIC; @@ -499,8 +519,11 @@ private function parseObject(&$var, Value $o) $child->owner_class = $object->classname; $child->operator = Value::OPERATOR_OBJECT; $child->access = Value::ACCESS_PUBLIC; + if (isset($readonly[$key])) { + $child->readonly = true; + } - $split_key = \explode("\0", $key, 3); + $split_key = \explode("\0", (string) $key, 3); if (3 === \count($split_key) && '' === $split_key[0]) { $child->name = $split_key[2]; @@ -554,12 +577,10 @@ private function parseObject(&$var, Value $o) /** * Parses a resource into a Kint ResourceValue structure. * - * @param resource $var The input variable - * @param Value $o The base object - * - * @return Value + * @param resource &$var The input variable + * @param Value $o The base object */ - private function parseResource(&$var, Value $o) + private function parseResource(&$var, Value $o): Value { $resource = new ResourceValue(); $resource->transplant($o); @@ -573,12 +594,10 @@ private function parseResource(&$var, Value $o) /** * Parses a closed resource into a Kint object structure. * - * @param mixed $var The input variable - * @param Value $o The base object - * - * @return Value + * @param mixed &$var The input variable + * @param Value $o The base object */ - private function parseResourceClosed(&$var, Value $o) + private function parseResourceClosed(&$var, Value $o): Value { $o->type = 'resource (closed)'; $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS); @@ -589,17 +608,17 @@ private function parseResourceClosed(&$var, Value $o) /** * Applies plugins for an object type. * - * @param mixed $var variable + * @param mixed &$var variable * @param Value $o Kint object parsed so far * @param int $trigger The trigger to check for the plugins * * @return bool Continue parsing */ - private function applyPlugins(&$var, Value &$o, $trigger) + private function applyPlugins(&$var, Value &$o, int $trigger): bool { $break_stash = $this->parse_break; - /** @var bool Psalm bug workaround */ + /** @psalm-var bool */ $this->parse_break = false; $plugins = []; diff --git a/system/ThirdParty/Kint/Parser/PluginInterface.php b/system/ThirdParty/Kint/Parser/PluginInterface.php new file mode 100644 index 000000000000..ff169fd17d4d --- /dev/null +++ b/system/ThirdParty/Kint/Parser/PluginInterface.php @@ -0,0 +1,44 @@ +callback = $callback; } - public function getTypes() + public function setParser(Parser $p): void + { + $this->parser = $p; + } + + public function getTypes(): array { return $this->types; } - public function getTriggers() + public function getTriggers(): int { return $this->triggers; } - public function parse(&$var, Value &$o, $trigger) + public function parse(&$var, Value &$o, int $trigger): void { - return \call_user_func_array($this->callback, [&$var, &$o, $trigger, $this->parser]); + \call_user_func_array($this->callback, [&$var, &$o, $trigger, $this->parser]); } } diff --git a/system/ThirdParty/Kint/Parser/SerializePlugin.php b/system/ThirdParty/Kint/Parser/SerializePlugin.php index 5924483fc50e..4991087848e6 100644 --- a/system/ThirdParty/Kint/Parser/SerializePlugin.php +++ b/system/ThirdParty/Kint/Parser/SerializePlugin.php @@ -1,5 +1,7 @@ self::$allowed_classes]; + if (!self::$safe_mode || !\in_array($trimmed[0], ['C', 'O', 'a'], true)) { - // Second parameter only supported on PHP 7 - if (KINT_PHP70) { - // Suppress warnings on unserializeable variable - $data = @\unserialize($trimmed, self::$options); - } else { - $data = @\unserialize($trimmed); - } + // Suppress warnings on unserializeable variable + $data = @\unserialize($trimmed, $options); if (false === $data && 'b:0;' !== \substr($trimmed, 0, 4)) { return; @@ -85,12 +88,10 @@ public function parse(&$var, Value &$o, $trigger) if ($o->access_path) { $base_obj->access_path = 'unserialize('.$o->access_path; - if (!KINT_PHP70 || self::$options === [true]) { + if (true === self::$allowed_classes) { $base_obj->access_path .= ')'; - } elseif (self::$options === [false]) { - $base_obj->access_path .= ', false)'; } else { - $base_obj->access_path .= ', Serialize::$options)'; + $base_obj->access_path .= ', '.\var_export($options, true).')'; } } diff --git a/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php b/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php index 9e44e5388ec8..db6f9b9c1c2b 100644 --- a/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php +++ b/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php @@ -1,5 +1,7 @@ addRepresentation($a, 0); + if ($a->contents) { + $x->addRepresentation($a, 0); + } // Children $c = new Representation('Children'); @@ -193,14 +197,14 @@ public function parse(&$var, Value &$o, $trigger) $s = $this->parser->parse($value, $base_obj); $srep = $s->getRepresentation('contents'); - $svalrep = $s->value && 'contents' == $s->value->getName() ? $s : null; + $svalrep = $s->value && 'contents' == $s->value->getName() ? $s->value : null; if ($srep || $svalrep) { $x->setIsStringValue(true); $x->value = $srep ?: $svalrep; if ($srep) { - $x->replaceRepresentation($x->value, 0); + $x->replaceRepresentation($srep, 0); } } diff --git a/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php b/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php index ada3e1fb8e85..696f36007013 100644 --- a/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php +++ b/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php @@ -1,5 +1,7 @@ getRepresentation('iterator'))) { return; diff --git a/system/ThirdParty/Kint/Parser/StreamPlugin.php b/system/ThirdParty/Kint/Parser/StreamPlugin.php index 76608d94a6a6..748b53c51997 100644 --- a/system/ThirdParty/Kint/Parser/StreamPlugin.php +++ b/system/ThirdParty/Kint/Parser/StreamPlugin.php @@ -1,5 +1,7 @@ resource_type) { return; diff --git a/system/ThirdParty/Kint/Parser/TablePlugin.php b/system/ThirdParty/Kint/Parser/TablePlugin.php index c6ca6e248d68..8d7e155c95cc 100644 --- a/system/ThirdParty/Kint/Parser/TablePlugin.php +++ b/system/ThirdParty/Kint/Parser/TablePlugin.php @@ -1,5 +1,7 @@ value->contents)) { return; diff --git a/system/ThirdParty/Kint/Parser/ThrowablePlugin.php b/system/ThirdParty/Kint/Parser/ThrowablePlugin.php index ea343e96ee78..7fd065f61910 100644 --- a/system/ThirdParty/Kint/Parser/ThrowablePlugin.php +++ b/system/ThirdParty/Kint/Parser/ThrowablePlugin.php @@ -1,5 +1,7 @@ hasMethod('__toString')) { diff --git a/system/ThirdParty/Kint/Parser/TracePlugin.php b/system/ThirdParty/Kint/Parser/TracePlugin.php index ccdcadec59a8..a5f47dcfcdf9 100644 --- a/system/ThirdParty/Kint/Parser/TracePlugin.php +++ b/system/ThirdParty/Kint/Parser/TracePlugin.php @@ -1,5 +1,7 @@ value) { return; } - /** @var array[] $trace Psalm workaround */ $trace = $this->parser->getCleanArray($var); if (\count($trace) !== \count($o->value->contents) || !Utils::isTrace($trace)) { @@ -81,8 +82,7 @@ public function parse(&$var, Value &$o, $trigger) continue; } - if (isset($trace[$index]['file'])) { - $realfile = \realpath($trace[$index]['file']); + if (isset($trace[$index]['file']) && ($realfile = \realpath($trace[$index]['file']))) { foreach ($path_blacklist as $path) { if (0 === \strpos($realfile, $path)) { continue 2; @@ -102,7 +102,7 @@ public function parse(&$var, Value &$o, $trigger) $o = $traceobj; } - protected static function normalizePaths(array $paths) + protected static function normalizePaths(array $paths): array { $normalized = []; diff --git a/system/ThirdParty/Kint/Parser/XmlPlugin.php b/system/ThirdParty/Kint/Parser/XmlPlugin.php index a4fa2b0c21c8..4e5671fb7273 100644 --- a/system/ThirdParty/Kint/Parser/XmlPlugin.php +++ b/system/ThirdParty/Kint/Parser/XmlPlugin.php @@ -1,5 +1,7 @@ depth = $o->depth + 1; @@ -82,22 +84,19 @@ public function parse(&$var, Value &$o, $trigger) $o->addRepresentation($r, 0); } - protected static function xmlToSimpleXML($var, $parent_path) + protected static function xmlToSimpleXML(string $var, ?string $parent_path): ?array { + $errors = \libxml_use_internal_errors(true); try { - $errors = \libxml_use_internal_errors(true); $xml = \simplexml_load_string($var); - \libxml_use_internal_errors($errors); } catch (Exception $e) { - if (isset($errors)) { - \libxml_use_internal_errors($errors); - } - - return; + return null; + } finally { + \libxml_use_internal_errors($errors); } if (false === $xml) { - return; + return null; } if (null === $parent_path) { @@ -121,12 +120,13 @@ protected static function xmlToSimpleXML($var, $parent_path) * * If it errors loading then we wouldn't have gotten this far in the first place. * - * @param string $var The XML string - * @param null|string $parent_path The path to the parent, in this case the XML string + * @psalm-param non-empty-string $var The XML string + * + * @param ?string $parent_path The path to the parent, in this case the XML string * - * @return null|array The root element DOMNode, the access path, and the root element name + * @return ?array The root element DOMNode, the access path, and the root element name */ - protected static function xmlToDOMDocument($var, $parent_path) + protected static function xmlToDOMDocument(string $var, ?string $parent_path): ?array { // There's no way to check validity in DOMDocument without making errors. For shame! if (!self::xmlToSimpleXML($var, $parent_path)) { @@ -150,7 +150,7 @@ protected static function xmlToDOMDocument($var, $parent_path) $access_path = '(function($s){$x = new \\DomDocument(); $x->loadXML($s); return $x;})('.$parent_path.')->'.$access_path; } - $name = isset($xml->nodeName) ? $xml->nodeName : null; + $name = $xml->nodeName ?? null; return [$xml, $access_path, $name]; } diff --git a/system/ThirdParty/Kint/Renderer/Renderer.php b/system/ThirdParty/Kint/Renderer/AbstractRenderer.php similarity index 72% rename from system/ThirdParty/Kint/Renderer/Renderer.php rename to system/ThirdParty/Kint/Renderer/AbstractRenderer.php index 0ed7ce0895b5..adec8f071d97 100644 --- a/system/ThirdParty/Kint/Renderer/Renderer.php +++ b/system/ThirdParty/Kint/Renderer/AbstractRenderer.php @@ -1,5 +1,7 @@ + * + * @psalm-consistent-constructor + */ +abstract class AbstractRenderer implements RendererInterface { - const SORT_NONE = 0; - const SORT_VISIBILITY = 1; - const SORT_FULL = 2; + public const SORT_NONE = 0; + public const SORT_VISIBILITY = 1; + public const SORT_FULL = 2; protected $call_info = []; protected $statics = []; protected $show_trace = true; - abstract public function render(Value $o); - - abstract public function renderNothing(); - - public function setCallInfo(array $info) + public function setCallInfo(array $info): void { - if (!isset($info['params'])) { - $info['params'] = null; - } - if (!isset($info['modifiers']) || !\is_array($info['modifiers'])) { $info['modifiers'] = []; } - if (!isset($info['callee'])) { - $info['callee'] = null; - } - - if (!isset($info['caller'])) { - $info['caller'] = null; - } - if (!isset($info['trace']) || !\is_array($info['trace'])) { $info['trace'] = []; } $this->call_info = [ - 'params' => $info['params'], + 'params' => $info['params'] ?? null, 'modifiers' => $info['modifiers'], - 'callee' => $info['callee'], - 'caller' => $info['caller'], + 'callee' => $info['callee'] ?? null, + 'caller' => $info['caller'] ?? null, 'trace' => $info['trace'], ]; } - public function getCallInfo() + public function getCallInfo(): array { return $this->call_info; } - public function setStatics(array $statics) + public function setStatics(array $statics): void { $this->statics = $statics; $this->setShowTrace(!empty($statics['display_called_from'])); } - public function getStatics() + public function getStatics(): array { return $this->statics; } - public function setShowTrace($show_trace) + public function setShowTrace(bool $show_trace): void { $this->show_trace = $show_trace; } - public function getShowTrace() + public function getShowTrace(): bool { return $this->show_trace; } + public function filterParserPlugins(array $plugins): array + { + return $plugins; + } + + public function preRender(): string + { + return ''; + } + + public function postRender(): string + { + return ''; + } + /** * Returns the first compatible plugin available. * - * @param array $plugins Array of hints to class strings - * @param array $hints Array of object hints + * @psalm-param PluginMap $plugins Array of hints to class strings + * @psalm-param string[] $hints Array of object hints * - * @return array Array of hints to class strings filtered and sorted by object hints + * @psalm-return PluginMap Array of hints to class strings filtered and sorted by object hints */ - public function matchPlugins(array $plugins, array $hints) + public function matchPlugins(array $plugins, array $hints): array { $out = []; @@ -120,22 +126,7 @@ public function matchPlugins(array $plugins, array $hints) return $out; } - public function filterParserPlugins(array $plugins) - { - return $plugins; - } - - public function preRender() - { - return ''; - } - - public function postRender() - { - return ''; - } - - public static function sortPropertiesFull(Value $a, Value $b) + public static function sortPropertiesFull(Value $a, Value $b): int { $sort = Value::sortByAccess($a, $b); if ($sort) { @@ -154,11 +145,10 @@ public static function sortPropertiesFull(Value $a, Value $b) * Sorts an array of Value. * * @param Value[] $contents Object properties to sort - * @param int $sort * * @return Value[] */ - public static function sortProperties(array $contents, $sort) + public static function sortProperties(array $contents, int $sort): array { switch ($sort) { case self::SORT_VISIBILITY: @@ -176,7 +166,7 @@ public static function sortProperties(array $contents, $sort) return \call_user_func_array('array_merge', $containers); case self::SORT_FULL: - \usort($contents, ['Kint\\Renderer\\Renderer', 'sortPropertiesFull']); + \usort($contents, [self::class, 'sortPropertiesFull']); // no break default: return $contents; diff --git a/system/ThirdParty/Kint/Renderer/CliRenderer.php b/system/ThirdParty/Kint/Renderer/CliRenderer.php index ae626167ad36..c2ea103b6644 100644 --- a/system/ThirdParty/Kint/Renderer/CliRenderer.php +++ b/system/ThirdParty/Kint/Renderer/CliRenderer.php @@ -1,5 +1,7 @@ windows_output = true; } else { $stream = self::$windows_stream; @@ -99,9 +100,7 @@ public function __construct() if (!self::$terminal_width) { if (!KINT_WIN && self::$detect_width) { try { - self::$terminal_width = \exec('tput cols'); - } catch (Exception $e) { - self::$terminal_width = self::$default_width; + self::$terminal_width = (int) \exec('tput cols'); } catch (Throwable $t) { self::$terminal_width = self::$default_width; } @@ -117,7 +116,7 @@ public function __construct() $this->header_width = self::$terminal_width; } - public function colorValue($string) + public function colorValue(string $string): string { if (!$this->colors) { return $string; @@ -126,7 +125,7 @@ public function colorValue($string) return "\x1b[32m".\str_replace("\n", "\x1b[0m\n\x1b[32m", $string)."\x1b[0m"; } - public function colorType($string) + public function colorType(string $string): string { if (!$this->colors) { return $string; @@ -135,7 +134,7 @@ public function colorType($string) return "\x1b[35;1m".\str_replace("\n", "\x1b[0m\n\x1b[35;1m", $string)."\x1b[0m"; } - public function colorTitle($string) + public function colorTitle(string $string): string { if (!$this->colors) { return $string; @@ -144,7 +143,7 @@ public function colorTitle($string) return "\x1b[36m".\str_replace("\n", "\x1b[0m\n\x1b[36m", $string)."\x1b[0m"; } - public function renderTitle(Value $o) + public function renderTitle(Value $o): string { if ($this->windows_output) { return $this->utf8ToWindows(parent::renderTitle($o)); @@ -153,12 +152,12 @@ public function renderTitle(Value $o) return parent::renderTitle($o); } - public function preRender() + public function preRender(): string { return PHP_EOL; } - public function postRender() + public function postRender(): string { if ($this->windows_output) { return $this->utf8ToWindows(parent::postRender()); @@ -167,12 +166,12 @@ public function postRender() return parent::postRender(); } - public function escape($string, $encoding = false) + public function escape(string $string, $encoding = false): string { return \str_replace("\x1b", '\\x1b', $string); } - protected function utf8ToWindows($string) + protected function utf8ToWindows(string $string): string { return \str_replace( ['┌', '═', '┐', '│', '└', '─', '┘'], diff --git a/system/ThirdParty/Kint/Renderer/PlainRenderer.php b/system/ThirdParty/Kint/Renderer/PlainRenderer.php index 4b8102a4750f..7210f55f3072 100644 --- a/system/ThirdParty/Kint/Renderer/PlainRenderer.php +++ b/system/ThirdParty/Kint/Renderer/PlainRenderer.php @@ -1,5 +1,7 @@ pre_render = self::$needs_pre_render; - - if (self::$always_pre_render) { - $this->setPreRender(true); - } + $this->setForcePreRender(self::$always_pre_render); } - public function setCallInfo(array $info) + public function setCallInfo(array $info): void { parent::setCallInfo($info); if (\in_array('@', $this->call_info['modifiers'], true)) { - $this->setPreRender(true); + $this->setForcePreRender(true); } } - public function setStatics(array $statics) + public function setStatics(array $statics): void { parent::setStatics($statics); if (!empty($statics['return'])) { - $this->setPreRender(true); + $this->setForcePreRender(true); } } - public function setPreRender($pre_render) + public function setForcePreRender(bool $force_pre_render): void + { + $this->force_pre_render = $force_pre_render; + } + + public function getForcePreRender(): bool { - $this->pre_render = $pre_render; - $this->force_pre_render = true; + return $this->force_pre_render; } - public function getPreRender() + public function shouldPreRender(): bool { - return $this->pre_render; + return $this->getForcePreRender() || self::$needs_pre_render; } - public function colorValue($string) + public function colorValue(string $string): string { return ''.$string.''; } - public function colorType($string) + public function colorType(string $string): string { return ''.$string.''; } - public function colorTitle($string) + public function colorTitle(string $string): string { return ''.$string.''; } - public function renderTitle(Value $o) + public function renderTitle(Value $o): string { if (self::$disable_utf8) { return $this->utf8ToHtmlentity(parent::renderTitle($o)); @@ -127,11 +127,11 @@ public function renderTitle(Value $o) return parent::renderTitle($o); } - public function preRender() + public function preRender(): string { $output = ''; - if ($this->pre_render) { + if ($this->shouldPreRender()) { foreach (self::$pre_render_sources as $type => $values) { $contents = ''; foreach ($values as $v) { @@ -155,7 +155,7 @@ public function preRender() } // Don't pre-render on every dump - if (!$this->force_pre_render) { + if (!$this->getForcePreRender()) { self::$needs_pre_render = false; } } @@ -163,7 +163,7 @@ public function preRender() return $output.'
'; } - public function postRender() + public function postRender(): string { if (self::$disable_utf8) { return $this->utf8ToHtmlentity(parent::postRender()).'
'; @@ -172,7 +172,7 @@ public function postRender() return parent::postRender().''; } - public function ideLink($file, $line) + public function ideLink(string $file, int $line): string { $path = $this->escape(Kint::shortenPath($file)).':'.$line; $ideLink = Kint::getIdeLink($file, $line); @@ -190,7 +190,7 @@ public function ideLink($file, $line) return ''.$path.''; } - public function escape($string, $encoding = false) + public function escape(string $string, $encoding = false): string { if (false === $encoding) { $encoding = BlobValue::detectEncoding($string); @@ -212,7 +212,7 @@ public function escape($string, $encoding = false) return $string; } - protected function utf8ToHtmlentity($string) + protected function utf8ToHtmlentity(string $string): string { return \str_replace( ['┌', '═', '┐', '│', '└', '─', '┘'], @@ -221,12 +221,12 @@ protected function utf8ToHtmlentity($string) ); } - protected static function renderJs() + protected static function renderJs(): string { return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/plain.js'); } - protected static function renderCss() + protected static function renderCss(): string { if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) { return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme); diff --git a/system/ThirdParty/Kint/Renderer/RendererInterface.php b/system/ThirdParty/Kint/Renderer/RendererInterface.php new file mode 100644 index 000000000000..577e9df02074 --- /dev/null +++ b/system/ThirdParty/Kint/Renderer/RendererInterface.php @@ -0,0 +1,57 @@ +'; @@ -65,17 +69,28 @@ public function renderLockedHeader(Value $o, $content) } if (null !== ($s = $o->getType())) { - $s = $this->renderer->escape($s); + if (RichRenderer::$escape_types) { + $s = $this->renderer->escape($s); + } if ($o->reference) { $s = '&'.$s; } - $header .= ''.$s.' '; + $header .= ''.$s.''; + + if ($o instanceof InstanceValue && isset($o->spl_object_id)) { + $header .= '#'.((int) $o->spl_object_id); + } + + $header .= ' '; } if (null !== ($s = $o->getSize())) { - $header .= '('.$this->renderer->escape($s).') '; + if (RichRenderer::$escape_types) { + $s = $this->renderer->escape($s); + } + $header .= '('.$s.') '; } $header .= $content; diff --git a/system/ThirdParty/Kint/Renderer/Rich/ArrayLimitPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/ArrayLimitPlugin.php index e6ebe569b85e..15220e5d9bda 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/ArrayLimitPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/ArrayLimitPlugin.php @@ -1,5 +1,7 @@ '.$this->renderLockedHeader($o, 'Array Limit').''; } diff --git a/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php index b12690a49969..4cbce1ae2b97 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php @@ -1,5 +1,7 @@ contents)) { + return null; + } + $out = '
';
 
-        /** @var string[] Psalm bug workaround */
         $lines = \str_split($r->contents, self::$line_length);
 
         foreach ($lines as $index => $line) {
             $out .= \sprintf('%08X', $index * self::$line_length).":\t";
 
-            /** @var string[] Psalm bug workaround */
             $chunks = \str_split(\str_pad(\bin2hex($line), 2 * self::$line_length, ' '), self::$chunk_length);
 
             $out .= \implode(' ', $chunks);
diff --git a/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php
index ed7f4ec96495..78064a7a01bc 100644
--- a/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php
+++ b/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php
@@ -1,5 +1,7 @@
 '.$this->renderLockedHeader($o, 'Blacklisted').'';
     }
diff --git a/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php b/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php
index b28b56a07ad1..744380524080 100644
--- a/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php
+++ b/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php
@@ -1,5 +1,7 @@
 renderMethod($o);
         }
 
         if ($o instanceof ClosureValue) {
-            return $this->renderClosure($o);
-        }
-
-        return $this->renderCallable($o);
-    }
-
-    protected function renderClosure(ClosureValue $o)
-    {
-        $children = $this->renderer->renderChildren($o);
-
-        $header = '';
-
-        if (null !== ($s = $o->getModifiers())) {
-            $header .= ''.$s.' ';
-        }
-
-        if (null !== ($s = $o->getName())) {
-            $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')';
-        }
-
-        if (null !== ($s = $o->getValueShort())) {
-            if (RichRenderer::$strlen_max) {
-                $s = Utils::truncateString($s, RichRenderer::$strlen_max);
-            }
-            $header .= ' '.$this->renderer->escape($s);
-        }
-
-        return '
'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'
'; - } - - protected function renderCallable(Value $o) - { - $children = $this->renderer->renderChildren($o); - - $header = ''; - - if (null !== ($s = $o->getModifiers())) { - $header .= ''.$s.' '; - } - - if (null !== ($s = $o->getName())) { - $header .= ''.$this->renderer->escape($s).''; - } - - if (null !== ($s = $o->getValueShort())) { - if (RichRenderer::$strlen_max) { - $s = Utils::truncateString($s, RichRenderer::$strlen_max); - } - $header .= ' '.$this->renderer->escape($s); + return parent::renderValue($o); } - return '
'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'
'; + return null; } - protected function renderMethod(MethodValue $o) + protected function renderMethod(MethodValue $o): string { if (!empty(self::$method_cache[$o->owner_class][$o->name])) { $children = self::$method_cache[$o->owner_class][$o->name]['children']; diff --git a/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php b/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php index 44813e3ef89f..a2b5a7e06e9f 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php @@ -1,5 +1,7 @@ renderer->renderChildren($o); - if (!($o instanceof ClosureValue)) { - $header = $this->renderer->renderHeader($o); - } else { - $header = ''; + $header = ''; - if (null !== ($s = $o->getModifiers())) { - $header .= ''.$s.' '; - } + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } - if (null !== ($s = $o->getName())) { - $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).') '; - } + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).') '; + } - $header .= 'Closure '; - $header .= $this->renderer->escape(Kint::shortenPath($o->filename)).':'.(int) $o->startline; + $header .= 'Closure'; + if (isset($o->spl_object_id)) { + $header .= '#'.((int) $o->spl_object_id); } + $header .= ' '.$this->renderer->escape(Kint::shortenPath($o->filename)).':'.(int) $o->startline; $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); diff --git a/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php index ebd02cb59e24..f1de5fe3670b 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php @@ -1,5 +1,7 @@ getRepresentation('color'); if (!$r instanceof ColorRepresentation) { - return; + return null; } $children = $this->renderer->renderChildren($o); @@ -51,10 +53,10 @@ public function renderValue(Value $o) return '
'.$header.$children.'
'; } - public function renderTab(Representation $r) + public function renderTab(Representation $r): ?string { if (!$r instanceof ColorRepresentation) { - return; + return null; } $out = ''; @@ -92,7 +94,7 @@ public function renderTab(Representation $r) } if (!\strlen($out)) { - return; + return null; } return '
'.$out.'
'; diff --git a/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php index 69808c7c3e1d..3b73b6be5df7 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php @@ -1,5 +1,7 @@ '.$this->renderLockedHeader($o, 'Depth Limit').''; } diff --git a/system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/MethodDefinitionPlugin.php similarity index 55% rename from system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php rename to system/ThirdParty/Kint/Renderer/Rich/MethodDefinitionPlugin.php index cb53a74fb182..f5ed37b624b5 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/MethodDefinitionPlugin.php @@ -1,5 +1,7 @@ contents) as $line) { - $docstring[] = \trim($line); + if (!$r instanceof MethodDefinitionRepresentation) { + return null; } - $docstring = \implode("\n", $docstring); + if (isset($r->contents)) { + $docstring = []; + foreach (\explode("\n", $r->contents) as $line) { + $docstring[] = \trim($line); + } - $location = []; + $docstring = $this->renderer->escape(\implode("\n", $docstring)); + } - if ($r->class) { - $location[] = 'Inherited from '.$this->renderer->escape($r->class); + $addendum = []; + if (isset($r->class) && $r->inherited) { + $addendum[] = 'Inherited from '.$this->renderer->escape($r->class); } - if ($r->file && $r->line) { - $location[] = 'Defined in '.$this->renderer->escape(Kint::shortenPath($r->file)).':'.((int) $r->line); + + if (isset($r->file, $r->line)) { + $addendum[] = 'Defined in '.$this->renderer->escape(Kint::shortenPath($r->file)).':'.((int) $r->line); } - $location = \implode("\n", $location); + if ($addendum) { + $addendum = ''.\implode("\n", $addendum).''; - if ($location) { - if (\strlen($docstring)) { - $docstring .= "\n\n"; + if (isset($docstring)) { + $docstring .= "\n\n".$addendum; + } else { + $docstring = $addendum; } + } - $location = ''.$location.''; - } elseif (0 === \strlen($docstring)) { - return ''; + if (!isset($docstring)) { + return null; } - return '
'.$this->renderer->escape($docstring).$location.'
'; + return '
'.$docstring.'
'; } } diff --git a/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php b/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php index 3d06b529252b..086e81447b12 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php @@ -1,5 +1,7 @@ getDateTime())) { + return null; } - $out = $r->getDateTime()->format('Y-m-d H:i:s.u'); + $out = $dt->format('Y-m-d H:i:s.u'); if (null !== $r->lap) { $out .= '
SINCE LAST CALL: '.\round($r->lap, 4).'s.'; } @@ -61,8 +63,12 @@ public function renderTab(Representation $r) return '
'.$out.'
'; } - public static function renderJs() + public static function renderJs(): string { - return \file_get_contents(KINT_DIR.'/resources/compiled/microtime.js'); + if (\is_string($out = \file_get_contents(KINT_DIR.'/resources/compiled/microtime.js'))) { + return $out; + } + + return ''; } } diff --git a/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php b/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php index 79828e7d5e26..bbdb8ac5a979 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php +++ b/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php @@ -1,5 +1,7 @@ '.$this->renderLockedHeader($o, 'Recursion').''; } diff --git a/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php index 718cd67aace3..87d9870790f2 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php @@ -1,5 +1,7 @@ renderer->renderChildren($o); - - $header = ''; - - if (null !== ($s = $o->getModifiers())) { - $header .= ''.$s.' '; + if (!($o instanceof SimpleXMLElementValue)) { + return null; } - if (null !== ($s = $o->getName())) { - $header .= ''.$this->renderer->escape($s).' '; - - if ($s = $o->getOperator()) { - $header .= $this->renderer->escape($s, 'ASCII').' '; - } + if (!$o->isStringValue() || !empty($o->getRepresentation('attributes')->contents)) { + return null; } - if (null !== ($s = $o->getType())) { - $s = $this->renderer->escape($s); - - if ($o->reference) { - $s = '&'.$s; - } - - $header .= ''.$this->renderer->escape($s).' '; - } - - if (null !== ($s = $o->getSize())) { - $header .= '('.$this->renderer->escape($s).') '; - } - - if (null !== ($s = $o->getValueShort())) { - if (RichRenderer::$strlen_max) { - $s = Utils::truncateString($s, RichRenderer::$strlen_max); - } - $header .= $this->renderer->escape($s); - } + $b = new BlobValue(); + $b->transplant($o); + $b->type = 'string'; + $children = $this->renderer->renderChildren($b); + $header = $this->renderer->renderHeader($o); $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); return '
'.$header.$children.'
'; diff --git a/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php b/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php index 4be024b627b2..a02f7ec1ef0e 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php @@ -1,5 +1,7 @@ source)) { - return; + return null; } $source = $r->source; @@ -75,5 +77,7 @@ public function renderTab(Representation $r) return '
'.$output.'
'; } + + return null; } } diff --git a/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php b/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php index 779e13acd3a9..fb310af5c696 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php +++ b/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php @@ -1,5 +1,7 @@ '; $firstrow = \reset($r->contents); foreach ($firstrow->value->contents as $field) { - $out .= ''; + $out .= ''; } $out .= ''; foreach ($r->contents as $row) { $out .= ''; foreach ($row->value->contents as $field) { diff --git a/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php b/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php index f0c58e67a3cc..43abfb60ea98 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php @@ -1,5 +1,7 @@ contents); - - if ($dt) { + if ($dt = DateTime::createFromFormat('U', (string) $r->contents)) { return '
'.$dt->setTimeZone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s T').'
'; } + + return null; } } diff --git a/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php b/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php index ea7048bcdd09..147e2e31620f 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php +++ b/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php @@ -1,5 +1,7 @@ trace['file']) && !empty($o->trace['line'])) { diff --git a/system/ThirdParty/Kint/Renderer/Rich/ValuePluginInterface.php b/system/ThirdParty/Kint/Renderer/Rich/ValuePluginInterface.php index 8f750eda6bad..112a7f7d03cf 100644 --- a/system/ThirdParty/Kint/Renderer/Rich/ValuePluginInterface.php +++ b/system/ThirdParty/Kint/Renderer/Rich/ValuePluginInterface.php @@ -1,5 +1,7 @@ 'Kint\\Renderer\\Rich\\ArrayLimitPlugin', - 'blacklist' => 'Kint\\Renderer\\Rich\\BlacklistPlugin', - 'callable' => 'Kint\\Renderer\\Rich\\CallablePlugin', - 'closure' => 'Kint\\Renderer\\Rich\\ClosurePlugin', - 'color' => 'Kint\\Renderer\\Rich\\ColorPlugin', - 'depth_limit' => 'Kint\\Renderer\\Rich\\DepthLimitPlugin', - 'recursion' => 'Kint\\Renderer\\Rich\\RecursionPlugin', - 'simplexml_element' => 'Kint\\Renderer\\Rich\\SimpleXMLElementPlugin', - 'trace_frame' => 'Kint\\Renderer\\Rich\\TraceFramePlugin', + 'array_limit' => Rich\ArrayLimitPlugin::class, + 'blacklist' => Rich\BlacklistPlugin::class, + 'callable' => Rich\CallablePlugin::class, + 'color' => Rich\ColorPlugin::class, + 'depth_limit' => Rich\DepthLimitPlugin::class, + 'recursion' => Rich\RecursionPlugin::class, + 'simplexml_element' => Rich\SimpleXMLElementPlugin::class, + 'trace_frame' => Rich\TraceFramePlugin::class, ]; /** - * RichRenderer tab plugins should implement Kint\Renderer\Rich\TabPluginInterface. + * RichRenderer tab plugins should implement TabPluginInterface. + * + * @psalm-var PluginMap */ public static $tab_plugins = [ - 'binary' => 'Kint\\Renderer\\Rich\\BinaryPlugin', - 'color' => 'Kint\\Renderer\\Rich\\ColorPlugin', - 'docstring' => 'Kint\\Renderer\\Rich\\DocstringPlugin', - 'microtime' => 'Kint\\Renderer\\Rich\\MicrotimePlugin', - 'source' => 'Kint\\Renderer\\Rich\\SourcePlugin', - 'table' => 'Kint\\Renderer\\Rich\\TablePlugin', - 'timestamp' => 'Kint\\Renderer\\Rich\\TimestampPlugin', + 'binary' => Rich\BinaryPlugin::class, + 'color' => Rich\ColorPlugin::class, + 'method_definition' => Rich\MethodDefinitionPlugin::class, + 'microtime' => Rich\MicrotimePlugin::class, + 'source' => Rich\SourcePlugin::class, + 'table' => Rich\TablePlugin::class, + 'timestamp' => Rich\TimestampPlugin::class, ]; public static $pre_render_sources = [ 'script' => [ - ['Kint\\Renderer\\RichRenderer', 'renderJs'], - ['Kint\\Renderer\\Rich\\MicrotimePlugin', 'renderJs'], + [self::class, 'renderJs'], + [Rich\MicrotimePlugin::class, 'renderJs'], ], 'style' => [ - ['Kint\\Renderer\\RichRenderer', 'renderCss'], + [self::class, 'renderCss'], ], 'raw' => [], ]; @@ -139,34 +151,29 @@ class RichRenderer extends Renderer protected $plugin_objs = []; protected $expand = false; protected $force_pre_render = false; - protected $pre_render; - protected $use_folder; + protected $use_folder = false; public function __construct() { - $this->pre_render = self::$needs_pre_render; - $this->use_folder = self::$folder; - - if (self::$always_pre_render) { - $this->setForcePreRender(); - } + $this->setUseFolder(self::$folder); + $this->setForcePreRender(self::$always_pre_render); } - public function setCallInfo(array $info) + public function setCallInfo(array $info): void { parent::setCallInfo($info); if (\in_array('!', $this->call_info['modifiers'], true)) { $this->setExpand(true); - $this->use_folder = false; + $this->setUseFolder(false); } if (\in_array('@', $this->call_info['modifiers'], true)) { - $this->setForcePreRender(); + $this->setForcePreRender(true); } } - public function setStatics(array $statics) + public function setStatics(array $statics): void { parent::setStatics($statics); @@ -175,49 +182,53 @@ public function setStatics(array $statics) } if (!empty($statics['return'])) { - $this->setForcePreRender(); + $this->setForcePreRender(true); } } - public function setExpand($expand) + public function setExpand(bool $expand): void { $this->expand = $expand; } - public function getExpand() + public function getExpand(): bool { return $this->expand; } - public function setForcePreRender() + public function setForcePreRender(bool $force_pre_render): void { - $this->force_pre_render = true; - $this->pre_render = true; + $this->force_pre_render = $force_pre_render; } - public function setPreRender($pre_render) + public function getForcePreRender(): bool { - $this->pre_render = $pre_render; + return $this->force_pre_render; } - public function getPreRender() + public function setUseFolder(bool $use_folder): void { - return $this->pre_render; + $this->use_folder = $use_folder; } - public function setUseFolder($use_folder) + public function getUseFolder(): bool { - $this->use_folder = $use_folder; + return $this->use_folder; } - public function getUseFolder() + public function shouldPreRender(): bool { - return $this->use_folder; + return $this->getForcePreRender() || self::$needs_pre_render; + } + + public function shouldFolderRender(): bool + { + return $this->getUseFolder() && ($this->getForcePreRender() || self::$needs_folder_render); } - public function render(Value $o) + public function render(Value $o): string { - if ($plugin = $this->getPlugin(self::$value_plugins, $o->hints)) { + if (($plugin = $this->getPlugin(self::$value_plugins, $o->hints)) && $plugin instanceof ValuePluginInterface) { $output = $plugin->renderValue($o); if (null !== $output && \strlen($output)) { return $output; @@ -230,19 +241,19 @@ public function render(Value $o) return '
'.$header.$children.'
'; } - public function renderNothing() + public function renderNothing(): string { return '
No argument
'; } - public function renderHeaderWrapper(Value $o, $has_children, $contents) + public function renderHeaderWrapper(Value $o, bool $has_children, string $contents): string { $out = 'expand) { + if ($this->getExpand()) { $out .= ' kint-show'; } @@ -251,7 +262,7 @@ public function renderHeaderWrapper(Value $o, $has_children, $contents) $out .= '>'; - if (self::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) { + if (self::$access_paths && $o->depth > 0 && ($ap = $o->getAccessPath())) { $out .= ''; } @@ -275,7 +286,7 @@ public function renderHeaderWrapper(Value $o, $has_children, $contents) return $out.''; } - public function renderHeader(Value $o) + public function renderHeader(Value $o): string { $output = ''; @@ -300,7 +311,13 @@ public function renderHeader(Value $o) $s = '&'.$s; } - $output .= ''.$s.' '; + $output .= ''.$s.''; + + if ($o instanceof InstanceValue && isset($o->spl_object_id)) { + $output .= '#'.((int) $o->spl_object_id); + } + + $output .= ' '; } if (null !== ($s = $o->getSize())) { @@ -323,7 +340,7 @@ public function renderHeader(Value $o) return \trim($output); } - public function renderChildren(Value $o) + public function renderChildren(Value $o): string { $contents = []; $tabs = []; @@ -375,11 +392,11 @@ public function renderChildren(Value $o) return $output.''; } - public function preRender() + public function preRender(): string { $output = ''; - if ($this->pre_render) { + if ($this->shouldPreRender()) { foreach (self::$pre_render_sources as $type => $values) { $contents = ''; foreach ($values as $v) { @@ -411,23 +428,23 @@ public function preRender() } // Don't pre-render on every dump - if (!$this->force_pre_render) { + if (!$this->getForcePreRender()) { self::$needs_pre_render = false; } } - $output .= '
force_pre_render) { - self::$needs_folder_render = false; - } - } + if ($this->getUseFolder()) { + $output .= ' kint-file'; } $output .= '">'; @@ -435,7 +452,7 @@ public function preRender() return $output; } - public function postRender() + public function postRender(): string { if (!$this->show_trace) { return '
'; @@ -455,7 +472,9 @@ public function postRender() ); } - if (isset($this->call_info['callee']['function']) && ( + if ( + isset($this->call_info['callee']['function']) && + ( !empty($this->call_info['callee']['class']) || !\in_array( $this->call_info['callee']['function'], @@ -465,12 +484,8 @@ public function postRender() ) ) { $output .= ' ['; - if (isset($this->call_info['callee']['class'])) { - $output .= $this->call_info['callee']['class']; - } - if (isset($this->call_info['callee']['type'])) { - $output .= $this->call_info['callee']['type']; - } + $output .= $this->call_info['callee']['class'] ?? ''; + $output .= $this->call_info['callee']['type'] ?? ''; $output .= $this->call_info['callee']['function'].'()]'; } @@ -486,12 +501,8 @@ public function postRender() && !\in_array($step['function'], ['include', 'include_once', 'require', 'require_once'], true) ) { $output .= ' ['; - if (isset($step['class'])) { - $output .= $step['class']; - } - if (isset($step['type'])) { - $output .= $step['type']; - } + $output .= $step['class'] ?? ''; + $output .= $step['type'] ?? ''; $output .= $step['function'].'()]'; } } @@ -503,7 +514,12 @@ public function postRender() return $output; } - public function escape($string, $encoding = false) + /** + * @psalm-param Encoding $encoding + * + * @param mixed $encoding + */ + public function escape(string $string, $encoding = false): string { if (false === $encoding) { $encoding = BlobValue::detectEncoding($string); @@ -525,7 +541,7 @@ public function escape($string, $encoding = false) return $string; } - public function ideLink($file, $line) + public function ideLink(string $file, int $line): string { $path = $this->escape(Kint::shortenPath($file)).':'.$line; $ideLink = Kint::getIdeLink($file, $line); @@ -543,9 +559,9 @@ public function ideLink($file, $line) return ''.$path.''; } - protected function renderTab(Value $o, Representation $rep) + protected function renderTab(Value $o, Representation $rep): string { - if ($plugin = $this->getPlugin(self::$tab_plugins, $rep->hints)) { + if (($plugin = $this->getPlugin(self::$tab_plugins, $rep->hints)) && $plugin instanceof TabPluginInterface) { $output = $plugin->renderTab($rep); if (null !== $output && \strlen($output)) { return $output; @@ -578,7 +594,7 @@ protected function renderTab(Value $o, Representation $rep) } else { if (\preg_match('/(:?[\\r\\n\\t\\f\\v]| {2})/', $rep->contents)) { $show_contents = true; - } elseif (self::$strlen_max && null !== $o->getValueShort() && BlobValue::strlen($o->getValueShort()) > self::$strlen_max) { + } elseif (self::$strlen_max && null !== ($vs = $o->getValueShort()) && BlobValue::strlen($vs) > self::$strlen_max) { $show_contents = true; } @@ -599,25 +615,31 @@ protected function renderTab(Value $o, Representation $rep) return ''; } - protected function getPlugin(array $plugins, array $hints) + /** + * @psalm-param PluginMap $plugins + * @psalm-param string[] $hints + */ + protected function getPlugin(array $plugins, array $hints): ?PluginInterface { if ($plugins = $this->matchPlugins($plugins, $hints)) { $plugin = \end($plugins); - if (!isset($this->plugin_objs[$plugin])) { + if (!isset($this->plugin_objs[$plugin]) && \is_subclass_of($plugin, PluginInterface::class)) { $this->plugin_objs[$plugin] = new $plugin($this); } return $this->plugin_objs[$plugin]; } + + return null; } - protected static function renderJs() + protected static function renderJs(): string { return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/rich.js'); } - protected static function renderCss() + protected static function renderCss(): string { if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) { return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme); @@ -626,7 +648,7 @@ protected static function renderCss() return \file_get_contents(self::$theme); } - protected static function renderFolder() + protected static function renderFolder(): string { return '
Kint
'; } diff --git a/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php b/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php new file mode 100644 index 000000000000..4d3c7e2a9791 --- /dev/null +++ b/system/ThirdParty/Kint/Renderer/Text/AbstractPlugin.php @@ -0,0 +1,63 @@ +renderer = $r; + } + + public function renderLockedHeader(Value $o, ?string $content = null): string + { + $out = ''; + + if (0 == $o->depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o); + + if (null !== $content) { + $out .= ' '.$this->renderer->colorValue($content); + } + + $out .= PHP_EOL; + + return $out; + } +} diff --git a/system/ThirdParty/Kint/Renderer/Text/ArrayLimitPlugin.php b/system/ThirdParty/Kint/Renderer/Text/ArrayLimitPlugin.php index 12c16f397b1b..6808736d3d60 100644 --- a/system/ThirdParty/Kint/Renderer/Text/ArrayLimitPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/ArrayLimitPlugin.php @@ -1,5 +1,7 @@ depth) { - $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; - } - - $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('ARRAY LIMIT').PHP_EOL; - - return $out; + return $this->renderLockedHeader($o, 'ARRAY LIMIT'); } } diff --git a/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php b/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php index 441368b10720..d07891247a72 100644 --- a/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php @@ -1,5 +1,7 @@ depth) { - $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; - } - - $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('BLACKLISTED').PHP_EOL; - - return $out; + return $this->renderLockedHeader($o, 'BLACKLISTED'); } } diff --git a/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php b/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php index cea6cdf89a50..cbb151882044 100644 --- a/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php @@ -1,5 +1,7 @@ depth) { - $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; - } - - $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('DEPTH LIMIT').PHP_EOL; - - return $out; + return $this->renderLockedHeader($o, 'DEPTH LIMIT'); } } diff --git a/system/ThirdParty/Kint/Renderer/Text/EnumPlugin.php b/system/ThirdParty/Kint/Renderer/Text/EnumPlugin.php index efb5ba5d193f..93d7b2935806 100644 --- a/system/ThirdParty/Kint/Renderer/Text/EnumPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/EnumPlugin.php @@ -1,5 +1,7 @@ depth) { - $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; - } - - $out .= $this->renderer->renderHeader($o).PHP_EOL; - - return $out; + return $this->renderLockedHeader($o); } } diff --git a/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php b/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php index ce63a5447d87..13bba75bab75 100644 --- a/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php @@ -1,5 +1,7 @@ getRepresentation('microtime'); - if (!$r instanceof MicrotimeRepresentation) { - return; + if (!$r instanceof MicrotimeRepresentation || !($dt = $r->getDateTime())) { + return null; } $out = ''; @@ -69,7 +71,7 @@ public function render(Value $o) } $out .= $indent.$this->renderer->colorType('TIME:').' '; - $out .= $this->renderer->colorValue($r->getDateTime()->format('Y-m-d H:i:s.u')).PHP_EOL; + $out .= $this->renderer->colorValue($dt->format('Y-m-d H:i:s.u')).PHP_EOL; if (null !== $r->lap) { $out .= $indent.$this->renderer->colorType('SINCE LAST CALL:').' '; @@ -121,7 +123,7 @@ public function render(Value $o) return $out; } - public static function renderJs() + public static function renderJs(): string { return RichPlugin::renderJs(); } diff --git a/system/ThirdParty/Kint/Renderer/Text/Plugin.php b/system/ThirdParty/Kint/Renderer/Text/PluginInterface.php similarity index 85% rename from system/ThirdParty/Kint/Renderer/Text/Plugin.php rename to system/ThirdParty/Kint/Renderer/Text/PluginInterface.php index 61a1820f48c8..65a4f5805772 100644 --- a/system/ThirdParty/Kint/Renderer/Text/Plugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/PluginInterface.php @@ -1,5 +1,7 @@ renderer = $r; - } + public function __construct(TextRenderer $r); - /** - * @return null|string - */ - abstract public function render(Value $o); + public function render(Value $o): ?string; } diff --git a/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php b/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php index 21956b6ec221..4d9b6c2571b9 100644 --- a/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php @@ -1,5 +1,7 @@ depth) { - $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; - } - - $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('RECURSION').PHP_EOL; - - return $out; + return $this->renderLockedHeader($o, 'RECURSION'); } } diff --git a/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php b/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php index b25f113e040b..113dc9821e0d 100644 --- a/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php +++ b/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php @@ -1,5 +1,7 @@ trace['function'])) { $framedesc .= $this->renderer->escape($frame->trace['function']).'(...)'; } elseif ($frame->trace['function'] instanceof MethodValue) { - $framedesc .= $this->renderer->escape($frame->trace['function']->getName()); - $framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')'; + if (null !== ($s = $frame->trace['function']->getName())) { + $framedesc .= $this->renderer->escape($s); + $framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')'; + } } $out .= $this->renderer->colorType($framedesc).PHP_EOL.PHP_EOL; diff --git a/system/ThirdParty/Kint/Renderer/TextRenderer.php b/system/ThirdParty/Kint/Renderer/TextRenderer.php index 3421e132b21e..833320a6c196 100644 --- a/system/ThirdParty/Kint/Renderer/TextRenderer.php +++ b/system/ThirdParty/Kint/Renderer/TextRenderer.php @@ -1,5 +1,7 @@ 'Kint\\Renderer\\Text\\ArrayLimitPlugin', - 'blacklist' => 'Kint\\Renderer\\Text\\BlacklistPlugin', - 'depth_limit' => 'Kint\\Renderer\\Text\\DepthLimitPlugin', - 'microtime' => 'Kint\\Renderer\\Text\\MicrotimePlugin', - 'recursion' => 'Kint\\Renderer\\Text\\RecursionPlugin', - 'trace' => 'Kint\\Renderer\\Text\\TracePlugin', - 'enum' => 'Kint\\Renderer\\Text\\EnumPlugin', + 'array_limit' => Text\ArrayLimitPlugin::class, + 'blacklist' => Text\BlacklistPlugin::class, + 'depth_limit' => Text\DepthLimitPlugin::class, + 'enum' => Text\EnumPlugin::class, + 'microtime' => Text\MicrotimePlugin::class, + 'recursion' => Text\RecursionPlugin::class, + 'trace' => Text\TracePlugin::class, ]; /** * Parser plugins must be instanceof one of these or * it will be removed for performance reasons. + * + * @psalm-var class-string[] */ public static $parser_plugin_whitelist = [ - 'Kint\\Parser\\ArrayLimitPlugin', - 'Kint\\Parser\\ArrayObjectPlugin', - 'Kint\\Parser\\BlacklistPlugin', - 'Kint\\Parser\\MicrotimePlugin', - 'Kint\\Parser\\StreamPlugin', - 'Kint\\Parser\\TracePlugin', - 'Kint\\Parser\\EnumPlugin', + Parser\ArrayLimitPlugin::class, + Parser\ArrayObjectPlugin::class, + Parser\BlacklistPlugin::class, + Parser\EnumPlugin::class, + Parser\MicrotimePlugin::class, + Parser\StreamPlugin::class, + Parser\TracePlugin::class, ]; /** @@ -107,7 +119,7 @@ public function __construct() $this->indent_width = self::$default_indent; } - public function render(Value $o) + public function render(Value $o): string { if ($plugin = $this->getPlugin(self::$plugins, $o->hints)) { $output = $plugin->render($o); @@ -128,7 +140,7 @@ public function render(Value $o) return $out; } - public function renderNothing() + public function renderNothing(): string { if (self::$decorations) { return $this->colorTitle( @@ -139,7 +151,7 @@ public function renderNothing() return $this->colorTitle('No argument').PHP_EOL; } - public function boxText($text, $width) + public function boxText(string $text, int $width): string { $out = '┌'.\str_repeat('─', $width - 2).'┐'.PHP_EOL; @@ -155,7 +167,7 @@ public function boxText($text, $width) return $out; } - public function renderTitle(Value $o) + public function renderTitle(Value $o): string { $name = (string) $o->getName(); @@ -166,7 +178,7 @@ public function renderTitle(Value $o) return Utils::truncateString($name, $this->header_width); } - public function renderHeader(Value $o) + public function renderHeader(Value $o): string { $output = []; @@ -189,7 +201,13 @@ public function renderHeader(Value $o) $s = '&'.$s; } - $output[] = $this->colorType($this->escape($s)); + $s = $this->colorType($this->escape($s)); + + if ($o instanceof InstanceValue && isset($o->spl_object_id)) { + $s .= '#'.((int) $o->spl_object_id); + } + + $output[] = $s; } if (null !== ($s = $o->getSize())) { @@ -206,7 +224,7 @@ public function renderHeader(Value $o) return \str_repeat(' ', $o->depth * $this->indent_width).\implode(' ', $output); } - public function renderChildren(Value $o) + public function renderChildren(Value $o): string { if ('array' === $o->type) { $output = ' ['; @@ -244,22 +262,22 @@ public function renderChildren(Value $o) return $output; } - public function colorValue($string) + public function colorValue(string $string): string { return $string; } - public function colorType($string) + public function colorType(string $string): string { return $string; } - public function colorTitle($string) + public function colorTitle(string $string): string { return $string; } - public function postRender() + public function postRender(): string { if (self::$decorations) { $output = \str_repeat('═', $this->header_width); @@ -278,7 +296,7 @@ public function postRender() return $this->colorTitle($output.$this->calledFrom().PHP_EOL); } - public function filterParserPlugins(array $plugins) + public function filterParserPlugins(array $plugins): array { $return = []; @@ -294,17 +312,22 @@ public function filterParserPlugins(array $plugins) return $return; } - public function ideLink($file, $line) + public function ideLink(string $file, int $line): string { return $this->escape(Kint::shortenPath($file)).':'.$line; } - public function escape($string, $encoding = false) + /** + * @psalm-param Encoding $encoding + * + * @param mixed $encoding + */ + public function escape(string $string, $encoding = false): string { return $string; } - protected function calledFrom() + protected function calledFrom(): string { $output = ''; @@ -315,7 +338,9 @@ protected function calledFrom() ); } - if (isset($this->call_info['callee']['function']) && ( + if ( + isset($this->call_info['callee']['function']) && + ( !empty($this->call_info['callee']['class']) || !\in_array( $this->call_info['callee']['function'], @@ -325,28 +350,30 @@ protected function calledFrom() ) ) { $output .= ' ['; - if (isset($this->call_info['callee']['class'])) { - $output .= $this->call_info['callee']['class']; - } - if (isset($this->call_info['callee']['type'])) { - $output .= $this->call_info['callee']['type']; - } + $output .= $this->call_info['callee']['class'] ?? ''; + $output .= $this->call_info['callee']['type'] ?? ''; $output .= $this->call_info['callee']['function'].'()]'; } return $output; } - protected function getPlugin(array $plugins, array $hints) + /** + * @psalm-param PluginMap $plugins + * @psalm-param string[] $hints + */ + protected function getPlugin(array $plugins, array $hints): ?PluginInterface { if ($plugins = $this->matchPlugins($plugins, $hints)) { $plugin = \end($plugins); - if (!isset($this->plugin_objs[$plugin])) { + if (!isset($this->plugin_objs[$plugin]) && \is_subclass_of($plugin, PluginInterface::class)) { $this->plugin_objs[$plugin] = new $plugin($this); } return $this->plugin_objs[$plugin]; } + + return null; } } diff --git a/system/ThirdParty/Kint/Utils.php b/system/ThirdParty/Kint/Utils.php index aa62bf623435..1394b0819095 100644 --- a/system/ThirdParty/Kint/Utils.php +++ b/system/ThirdParty/Kint/Utils.php @@ -1,5 +1,7 @@ = $length) { @@ -259,17 +268,25 @@ public static function truncateString($input, $length = PHP_INT_MAX, $end = '... return $input; } - public static function getTypeString(ReflectionType $type) + public static function getTypeString(ReflectionType $type): string { - if ($type instanceof ReflectionNamedType) { + // @codeCoverageIgnoreStart + // ReflectionType::__toString was deprecated in 7.4 and undeprecated in 8 + // and toString doesn't correctly show the nullable ? in the type before 8 + if (!KINT_PHP80) { + if (!$type instanceof ReflectionNamedType) { + throw new UnexpectedValueException('ReflectionType on PHP 7 must be ReflectionNamedType'); + } + $name = $type->getName(); - if ($type->allowsNull() && false === \strpos($name, '|')) { + if ($type->allowsNull() && 'mixed' !== $name && false === \strpos($name, '|')) { $name = '?'.$name; } return $name; } + // @codeCoverageIgnoreEnd - return (string) $type; // @codeCoverageIgnore + return (string) $type; } } diff --git a/system/ThirdParty/Kint/Zval/BlobValue.php b/system/ThirdParty/Kint/Zval/BlobValue.php index c5ac53acb096..cfee55e60ac8 100644 --- a/system/ThirdParty/Kint/Zval/BlobValue.php +++ b/system/ThirdParty/Kint/Zval/BlobValue.php @@ -1,5 +1,7 @@ encoding) { return 'binary '.$this->type; @@ -93,14 +99,16 @@ public function getType() return $this->encoding.' '.$this->type; } - public function getValueShort() + public function getValueShort(): ?string { if ($rep = $this->value) { return '"'.$rep->contents.'"'; } + + return null; } - public function transplant(Value $old) + public function transplant(Value $old): void { parent::transplant($old); @@ -109,7 +117,12 @@ public function transplant(Value $old) } } - public static function strlen($string, $encoding = false) + /** + * @psalm-param Encoding $encoding + * + * @param mixed $encoding + */ + public static function strlen(string $string, $encoding = false): int { if (\function_exists('mb_strlen')) { if (false === $encoding) { @@ -124,7 +137,12 @@ public static function strlen($string, $encoding = false) return \strlen($string); } - public static function substr($string, $start, $length = null, $encoding = false) + /** + * @psalm-param Encoding $encoding + * + * @param mixed $encoding + */ + public static function substr(string $string, int $start, ?int $length = null, $encoding = false): string { if (\function_exists('mb_substr')) { if (false === $encoding) { @@ -141,10 +159,13 @@ public static function substr($string, $start, $length = null, $encoding = false return ''; } - return \substr($string, $start, isset($length) ? $length : PHP_INT_MAX); + return \substr($string, $start, $length ?? PHP_INT_MAX); } - public static function detectEncoding($string) + /** + * @psalm-return Encoding + */ + public static function detectEncoding(string $string) { if (\function_exists('mb_detect_encoding')) { if ($ret = \mb_detect_encoding($string, self::$char_encodings, true)) { diff --git a/system/ThirdParty/Kint/Zval/ClosureValue.php b/system/ThirdParty/Kint/Zval/ClosureValue.php index 95dd3fea9e39..69e6818427ba 100644 --- a/system/ThirdParty/Kint/Zval/ClosureValue.php +++ b/system/ThirdParty/Kint/Zval/ClosureValue.php @@ -1,5 +1,7 @@ access_path) { return parent::getAccessPath().'('.$this->getParams().')'; } + + return null; } - public function getSize() + public function getSize(): ?string { + return null; } - public function getParams() + public function transplant(Value $old): void { - if (null !== $this->paramcache) { - return $this->paramcache; - } + parent::transplant($old); - $out = []; - - foreach ($this->parameters as $p) { - $type = $p->getType(); - - $ref = $p->reference ? '&' : ''; - - if ($type) { - $out[] = $type.' '.$ref.$p->getName(); - } else { - $out[] = $ref.$p->getName(); - } + if (0 === $this->depth && \preg_match('/^\\((function|fn)\\s*\\(/i', $this->access_path, $match)) { + $this->name = \strtolower($match[1]); } - - return $this->paramcache = \implode(', ', $out); } } diff --git a/system/ThirdParty/Kint/Zval/DateTimeValue.php b/system/ThirdParty/Kint/Zval/DateTimeValue.php index 1a8084ec3b9f..2ba53d628473 100644 --- a/system/ThirdParty/Kint/Zval/DateTimeValue.php +++ b/system/ThirdParty/Kint/Zval/DateTimeValue.php @@ -1,5 +1,7 @@ dt = clone $dt; } - public function getValueShort() + public function getValueShort(): string { $stamp = $this->dt->format('Y-m-d H:i:s'); if ((int) ($micro = $this->dt->format('u'))) { diff --git a/system/ThirdParty/Kint/Zval/EnumValue.php b/system/ThirdParty/Kint/Zval/EnumValue.php index 018eb68f0541..e9cfe19ed184 100644 --- a/system/ThirdParty/Kint/Zval/EnumValue.php +++ b/system/ThirdParty/Kint/Zval/EnumValue.php @@ -1,5 +1,7 @@ enumval = $enumval; } - public function getValueShort() + public function getValueShort(): ?string { if ($this->enumval instanceof BackedEnum) { if (\is_string($this->enumval->value)) { return '"'.$this->enumval->value.'"'; - } - if (\is_int($this->enumval->value)) { - return (string) $this->enumval->value; - } + } // Int + + return (string) $this->enumval->value; } + + return null; } - public function getType() + public function getType(): ?string { - return $this->classname.'::'.$this->enumval->name; + if (isset($this->classname)) { + if (isset($this->enumval->name)) { + return $this->classname.'::'.$this->enumval->name; + } + + return $this->classname; + } + + return null; } - public function getSize() + public function getSize(): ?string { + return null; } } diff --git a/system/ThirdParty/Kint/Zval/InstanceValue.php b/system/ThirdParty/Kint/Zval/InstanceValue.php index 1c26600ca47e..323733474825 100644 --- a/system/ThirdParty/Kint/Zval/InstanceValue.php +++ b/system/ThirdParty/Kint/Zval/InstanceValue.php @@ -1,5 +1,7 @@ classname; } - public function transplant(Value $old) + public function transplant(Value $old): void { parent::transplant($old); if ($old instanceof self) { $this->classname = $old->classname; $this->spl_object_hash = $old->spl_object_hash; + $this->spl_object_id = $old->spl_object_id; $this->filename = $old->filename; $this->startline = $old->startline; } } - public static function sortByHierarchy($a, $b) + /** + * @psalm-param class-string $a + * @psalm-param class-string $b + */ + public static function sortByHierarchy(string $a, string $b): int { - if (\is_string($a) && \is_string($b)) { - $aclass = $a; - $bclass = $b; - } elseif (!($a instanceof Value) || !($b instanceof Value)) { - return 0; - } elseif ($a instanceof self && $b instanceof self) { - $aclass = $a->classname; - $bclass = $b->classname; - } else { - return 0; - } - - if (\is_subclass_of($aclass, $bclass)) { + if (\is_subclass_of($a, $b)) { return -1; } - if (\is_subclass_of($bclass, $aclass)) { + if (\is_subclass_of($b, $a)) { return 1; } diff --git a/system/ThirdParty/Kint/Zval/MethodValue.php b/system/ThirdParty/Kint/Zval/MethodValue.php index 5d59a50765f2..55c320981d66 100644 --- a/system/ThirdParty/Kint/Zval/MethodValue.php +++ b/system/ThirdParty/Kint/Zval/MethodValue.php @@ -1,5 +1,7 @@ startline = $method->getStartLine(); $this->endline = $method->getEndLine(); $this->internal = $method->isInternal(); - $this->docstring = $method->getDocComment(); + $this->docstring = $method->getDocComment() ?: null; $this->return_reference = $method->returnsReference(); foreach ($method->getParameters() as $param) { $this->parameters[] = new ParameterValue($param); } - if (KINT_PHP70) { - $this->returntype = $method->getReturnType(); - if ($this->returntype) { - $this->returntype = Utils::getTypeString($this->returntype); - } + $this->returntype = $method->getReturnType(); + if ($this->returntype) { + $this->returntype = Utils::getTypeString($this->returntype); } if ($method instanceof ReflectionMethod) { @@ -89,10 +88,11 @@ public function __construct(ReflectionFunctionAbstract $method) return; } - $docstring = new DocstringRepresentation( - $this->docstring, + $docstring = new MethodDefinitionRepresentation( $this->filename, - $this->startline + $this->startline, + $this->owner_class, + $this->docstring ); $docstring->implicit_label = true; @@ -100,7 +100,7 @@ public function __construct(ReflectionFunctionAbstract $method) $this->value = $docstring; } - public function setAccessPathFrom(InstanceValue $parent) + public function setAccessPathFrom(InstanceValue $parent): void { static $magic = [ '__call' => true, @@ -141,9 +141,9 @@ public function setAccessPathFrom(InstanceValue $parent) } } - public function getValueShort() + public function getValueShort(): ?string { - if (!$this->value || !($this->value instanceof DocstringRepresentation)) { + if (!$this->value || !($this->value instanceof MethodDefinitionRepresentation)) { return parent::getValueShort(); } @@ -168,9 +168,11 @@ public function getValueShort() if (\strlen($out)) { return \rtrim($out); } + + return null; } - public function getModifiers() + public function getModifiers(): ?string { $mods = [ $this->abstract ? 'abstract' : null, @@ -190,47 +192,20 @@ public function getModifiers() if (\strlen($out)) { return \rtrim($out); } - } - - public function getAccessPath() - { - if (null !== $this->access_path) { - if ($this->showparams) { - return parent::getAccessPath().'('.$this->getParams().')'; - } - return parent::getAccessPath(); - } + return null; } - public function getParams() + public function getAccessPath(): ?string { - if (null !== $this->paramcache) { - return $this->paramcache; - } - - $out = []; - - foreach ($this->parameters as $p) { - $type = $p->getType(); - if ($type) { - $type .= ' '; - } - - $default = $p->getDefault(); - if ($default) { - $default = ' = '.$default; - } - - $ref = $p->reference ? '&' : ''; - - $out[] = $type.$ref.$p->getName().$default; + if (null !== $this->access_path && $this->showparams) { + return parent::getAccessPath().'('.$this->getParams().')'; } - return $this->paramcache = \implode(', ', $out); + return parent::getAccessPath(); } - public function getPhpDocUrl() + public function getPhpDocUrl(): ?string { if (!$this->internal) { return null; diff --git a/system/ThirdParty/Kint/Zval/ParameterHoldingTrait.php b/system/ThirdParty/Kint/Zval/ParameterHoldingTrait.php new file mode 100644 index 000000000000..c67ecd45c581 --- /dev/null +++ b/system/ThirdParty/Kint/Zval/ParameterHoldingTrait.php @@ -0,0 +1,63 @@ +paramcache) { + return $this->paramcache; + } + + $out = []; + + foreach ($this->parameters as $p) { + $type = $p->getType(); + if ($type) { + $type .= ' '; + } + + $default = $p->getDefault(); + if ($default) { + $default = ' = '.$default; + } + + $ref = $p->reference ? '&' : ''; + + $out[] = $type.$ref.$p->getName().$default; + } + + return $this->paramcache = \implode(', ', $out); + } +} diff --git a/system/ThirdParty/Kint/Zval/ParameterValue.php b/system/ThirdParty/Kint/Zval/ParameterValue.php index 29bcbe72bb2b..2e690b751935 100644 --- a/system/ThirdParty/Kint/Zval/ParameterValue.php +++ b/system/ThirdParty/Kint/Zval/ParameterValue.php @@ -1,5 +1,7 @@ getType()) { - $this->type_hint = Utils::getTypeString($type); - } - } else { - if ($param->isArray()) { - $this->type_hint = 'array'; - } else { - try { - if ($this->type_hint = $param->getClass()) { - $this->type_hint = $this->type_hint->name; - } - } catch (ReflectionException $e) { - \preg_match('/\\[\\s\\<\\w+?>\\s([\\w]+)/s', $param->__toString(), $matches); - $this->type_hint = isset($matches[1]) ? $matches[1] : ''; - } - } + if ($type = $param->getType()) { + $this->type_hint = Utils::getTypeString($type); } $this->reference = $param->isPassedByReference(); @@ -82,17 +68,17 @@ public function __construct(ReflectionParameter $param) } } - public function getType() + public function getType(): ?string { return $this->type_hint; } - public function getName() + public function getName(): string { return '$'.$this->name; } - public function getDefault() + public function getDefault(): ?string { return $this->default; } diff --git a/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php index 533ccb35d940..806a800667d4 100644 --- a/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/ColorRepresentation.php @@ -1,5 +1,7 @@ 'f0f8ff', @@ -201,7 +203,7 @@ class ColorRepresentation extends Representation public $implicit_label = true; public $hints = ['color']; - public function __construct($value) + public function __construct(string $value) { parent::__construct('Color'); @@ -209,7 +211,7 @@ public function __construct($value) $this->setValues($value); } - public function getColor($variant = null) + public function getColor(?int $variant = null): ?string { if (!$variant) { $variant = $this->variant; @@ -220,8 +222,8 @@ public function getColor($variant = null) $hex = \sprintf('%02x%02x%02x', $this->r, $this->g, $this->b); $hex_alpha = \sprintf('%02x%02x%02x%02x', $this->r, $this->g, $this->b, \round($this->a * 0xFF)); - return \array_search($hex, self::$color_map, true) ?: \array_search($hex_alpha, self::$color_map, true); - case self::COLOR_HEX_3: + return \array_search($hex, self::$color_map, true) ?: \array_search($hex_alpha, self::$color_map, true) ?: null; + case self::COLOR_HEX_3: if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11) { return \sprintf( '#%1X%1X%1X', @@ -231,7 +233,7 @@ public function getColor($variant = null) ); } - return false; + return null; case self::COLOR_HEX_6: return \sprintf('#%02X%02X%02X', $this->r, $this->g, $this->b); case self::COLOR_RGB: @@ -264,16 +266,16 @@ public function getColor($variant = null) ); } - return false; + return null; case self::COLOR_HEX_8: return \sprintf('#%02X%02X%02X%02X', $this->r, $this->g, $this->b, \round($this->a * 0xFF)); } - return false; + return null; } - public function hasAlpha($variant = null) + public function hasAlpha(?int $variant = null): bool { if (null === $variant) { $variant = $this->variant; @@ -294,7 +296,7 @@ public function hasAlpha($variant = null) } } - protected function setValues($value) + protected function setValues(string $value): void { $value = \strtolower(\trim($value)); // Find out which variant of color input it is @@ -330,7 +332,7 @@ protected function setValues($value) } } - protected function setValuesFromHex($hex) + protected function setValuesFromHex(string $hex): ?int { if (!\ctype_xdigit($hex)) { return null; @@ -376,7 +378,7 @@ protected function setValuesFromHex($hex) return $variant; } - protected function setValuesFromFunction($value) + protected function setValuesFromFunction(string $value): ?int { if (!\preg_match('/^((?:rgb|hsl)a?)\\s*\\(([0-9\\.%,\\s\\/\\-]+)\\)$/i', $value, $match)) { return null; @@ -425,7 +427,7 @@ protected function setValuesFromFunction($value) } } - /** @var non-empty-array $params Psalm bug workaround */ + /** @psalm-var non-empty-array $params Psalm bug workaround */ switch ($variant) { case self::COLOR_RGBA: case self::COLOR_RGB: @@ -453,7 +455,7 @@ protected function setValuesFromFunction($value) $params = self::hslToRgb($params[0], $params[1], $params[2]); } - list($this->r, $this->g, $this->b) = $params; + [$this->r, $this->g, $this->b] = $params; return $variant; } @@ -467,7 +469,7 @@ protected function setValuesFromFunction($value) * * @return int[] RGB array */ - public static function hslToRgb($h, $s, $l) + public static function hslToRgb(float $h, float $s, float $l): array { if (\min($h, $s, $l) < 0) { throw new InvalidArgumentException('The parameters for hslToRgb should be no less than 0'); @@ -494,13 +496,13 @@ public static function hslToRgb($h, $s, $l) /** * Converts RGB to HSL. Color inversion of previous black magic is white magic? * - * @param float|int $red Red - * @param float|int $green Green - * @param float|int $blue Blue + * @param float $red Red + * @param float $green Green + * @param float $blue Blue * * @return float[] HSL array */ - public static function rgbToHsl($red, $green, $blue) + public static function rgbToHsl(float $red, float $green, float $blue): array { if (\min($red, $green, $blue) < 0) { throw new InvalidArgumentException('The parameters for rgbToHsl should be no less than 0'); @@ -517,8 +519,8 @@ public static function rgbToHsl($red, $green, $blue) $L = ($clrMax + $clrMin) / 510; if (0 == $deltaMax) { - $H = 0; - $S = 0; + $H = 0.0; + $S = 0.0; } else { if (0.5 > $L) { $S = $deltaMax / ($clrMax + $clrMin); @@ -541,21 +543,17 @@ public static function rgbToHsl($red, $green, $blue) return [ \fmod($H * 360, 360), - (float) ($S * 100), - (float) ($L * 100), + $S * 100, + $L * 100, ]; } /** * Helper function for hslToRgb. Even blacker magic. * - * @param float $m1 - * @param float $m2 - * @param float $hue - * * @return float Color value */ - private static function hueToRgb($m1, $m2, $hue) + private static function hueToRgb(float $m1, float $m2, float $hue): float { $hue = ($hue < 0) ? $hue + 1 : (($hue > 1) ? $hue - 1 : $hue); if ($hue * 6 < 1) { diff --git a/system/ThirdParty/Kint/Zval/Representation/DocstringRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/MethodDefinitionRepresentation.php similarity index 86% rename from system/ThirdParty/Kint/Zval/Representation/DocstringRepresentation.php rename to system/ThirdParty/Kint/Zval/Representation/MethodDefinitionRepresentation.php index 8acdcc1e8583..6c1ca38bb4a9 100644 --- a/system/ThirdParty/Kint/Zval/Representation/DocstringRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/MethodDefinitionRepresentation.php @@ -1,5 +1,7 @@ file = $file; $this->line = $line; @@ -57,7 +60,7 @@ public function __construct($docstring, $file, $line, $class = null) * absolutely must have it without comments (ie renderValueShort) this will * probably do. * - * @return null|string Docstring with comments stripped + * @return ?string Docstring with comments stripped */ public function getDocstringWithoutComments() { diff --git a/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php index aedc2edffb6e..d25539b1c7c6 100644 --- a/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/MicrotimeRepresentation.php @@ -1,5 +1,7 @@ seconds = (int) $seconds; - $this->microseconds = (int) $microseconds; + $this->seconds = $seconds; + $this->microseconds = $microseconds; $this->group = $group; $this->lap = $lap; @@ -64,8 +66,8 @@ public function __construct($seconds, $microseconds, $group, $lap = null, $total $this->mem_peak_real = \memory_get_peak_usage(true); } - public function getDateTime() + public function getDateTime(): ?DateTime { - return DateTime::createFromFormat('U u', $this->seconds.' '.\str_pad($this->microseconds, 6, '0', STR_PAD_LEFT)); + return DateTime::createFromFormat('U u', $this->seconds.' '.\str_pad((string) $this->microseconds, 6, '0', STR_PAD_LEFT)) ?: null; } } diff --git a/system/ThirdParty/Kint/Zval/Representation/Representation.php b/system/ThirdParty/Kint/Zval/Representation/Representation.php index 2d649d077c13..c4680c3d1f75 100644 --- a/system/ThirdParty/Kint/Zval/Representation/Representation.php +++ b/system/ThirdParty/Kint/Zval/Representation/Representation.php @@ -1,5 +1,7 @@ label = $label; @@ -45,7 +47,7 @@ public function __construct($label, $name = null) $this->setName($name); } - public function getLabel() + public function getLabel(): string { if (\is_array($this->contents) && \count($this->contents) > 1) { return $this->label.' ('.\count($this->contents).')'; @@ -54,17 +56,17 @@ public function getLabel() return $this->label; } - public function getName() + public function getName(): string { return $this->name; } - public function setName($name) + public function setName(string $name): void { $this->name = \preg_replace('/[^a-z0-9]+/', '_', \strtolower($name)); } - public function labelIsImplicit() + public function labelIsImplicit(): bool { return $this->implicit_label; } diff --git a/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php index 65077d6218c6..d05bf088d46a 100644 --- a/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php +++ b/system/ThirdParty/Kint/Zval/Representation/SourceRepresentation.php @@ -1,5 +1,7 @@ typename.' ('.$this->getSize().')'; + if ($size = $this->getSize()) { + return $this->typename.' ('.$size.')'; + } + + return $this->typename; } - public function getSize() + public function getSize(): ?string { if ($this->size) { $size = Utils::getHumanReadableBytes($this->size); return \round($size['value'], 2).$size['unit']; } + + return null; } - public function getMTime() + public function getMTime(): ?string { - $year = \date('Y', $this->mtime); + if (null !== $this->mtime) { + $year = \date('Y', $this->mtime); + + if ($year !== \date('Y')) { + return \date('M d Y', $this->mtime); + } - if ($year !== \date('Y')) { - return \date('M d Y', $this->mtime); + return \date('M d H:i', $this->mtime); } - return \date('M d H:i', $this->mtime); + return null; } } diff --git a/system/ThirdParty/Kint/Zval/ResourceValue.php b/system/ThirdParty/Kint/Zval/ResourceValue.php index ef1c5541e476..e50266ac477f 100644 --- a/system/ThirdParty/Kint/Zval/ResourceValue.php +++ b/system/ThirdParty/Kint/Zval/ResourceValue.php @@ -1,5 +1,7 @@ resource_type) { return $this->resource_type.' resource'; @@ -38,7 +40,7 @@ public function getType() return 'resource'; } - public function transplant(Value $old) + public function transplant(Value $old): void { parent::transplant($old); diff --git a/system/ThirdParty/Kint/Zval/SimpleXMLElementValue.php b/system/ThirdParty/Kint/Zval/SimpleXMLElementValue.php index b385bc6daa2e..0f152230ea2b 100644 --- a/system/ThirdParty/Kint/Zval/SimpleXMLElementValue.php +++ b/system/ThirdParty/Kint/Zval/SimpleXMLElementValue.php @@ -1,5 +1,7 @@ is_string_value; + } + + public function setIsStringValue(bool $is_string_value): void { $this->is_string_value = $is_string_value; } - public function getValueShort() + public function getValueShort(): ?string { if ($this->is_string_value && ($rep = $this->value) && 'contents' === $rep->getName() && 'string' === \gettype($rep->contents)) { return '"'.$rep->contents.'"'; } + + return null; } } diff --git a/system/ThirdParty/Kint/Zval/StreamValue.php b/system/ThirdParty/Kint/Zval/StreamValue.php index af909c84f39a..01cd04870a31 100644 --- a/system/ThirdParty/Kint/Zval/StreamValue.php +++ b/system/ThirdParty/Kint/Zval/StreamValue.php @@ -1,5 +1,7 @@ stream_meta = $meta; } - public function getValueShort() + public function getValueShort(): ?string { if (empty($this->stream_meta['uri'])) { - return; + return null; } $uri = $this->stream_meta['uri']; diff --git a/system/ThirdParty/Kint/Zval/ThrowableValue.php b/system/ThirdParty/Kint/Zval/ThrowableValue.php index 26676481c26d..f6fcb51c1935 100644 --- a/system/ThirdParty/Kint/Zval/ThrowableValue.php +++ b/system/ThirdParty/Kint/Zval/ThrowableValue.php @@ -1,5 +1,7 @@ message = $throw->getMessage(); } - public function getValueShort() + public function getValueShort(): ?string { if (\strlen($this->message)) { return '"'.$this->message.'"'; } + + return null; } } diff --git a/system/ThirdParty/Kint/Zval/TraceFrameValue.php b/system/ThirdParty/Kint/Zval/TraceFrameValue.php index 62f7829192d2..bee073bb76d8 100644 --- a/system/ThirdParty/Kint/Zval/TraceFrameValue.php +++ b/system/ThirdParty/Kint/Zval/TraceFrameValue.php @@ -1,5 +1,7 @@ trace = [ 'function' => $raw_frame['function'], - 'line' => isset($raw_frame['line']) ? $raw_frame['line'] : null, - 'file' => isset($raw_frame['file']) ? $raw_frame['file'] : null, - 'class' => isset($raw_frame['class']) ? $raw_frame['class'] : null, - 'type' => isset($raw_frame['type']) ? $raw_frame['type'] : null, + 'line' => $raw_frame['line'] ?? null, + 'file' => $raw_frame['file'] ?? null, + 'class' => $raw_frame['class'] ?? null, + 'type' => $raw_frame['type'] ?? null, 'object' => null, 'args' => null, ]; diff --git a/system/ThirdParty/Kint/Zval/TraceValue.php b/system/ThirdParty/Kint/Zval/TraceValue.php index 4d0edc42219a..0136b8915085 100644 --- a/system/ThirdParty/Kint/Zval/TraceValue.php +++ b/system/ThirdParty/Kint/Zval/TraceValue.php @@ -1,5 +1,7 @@ size) { return 'empty'; diff --git a/system/ThirdParty/Kint/Zval/Value.php b/system/ThirdParty/Kint/Zval/Value.php index 747efb5f718f..facb6cd835e4 100644 --- a/system/ThirdParty/Kint/Zval/Value.php +++ b/system/ThirdParty/Kint/Zval/Value.php @@ -1,5 +1,7 @@ representations[$rep->getName()])) { return false; @@ -78,7 +81,7 @@ public function addRepresentation(Representation $rep, $pos = null) return true; } - public function replaceRepresentation(Representation $rep, $pos = null) + public function replaceRepresentation(Representation $rep, ?int $pos = null): void { if (null === $pos) { $this->representations[$rep->getName()] = $rep; @@ -88,41 +91,46 @@ public function replaceRepresentation(Representation $rep, $pos = null) } } - public function removeRepresentation($rep) + /** + * @param Representation|string $rep + */ + public function removeRepresentation($rep): void { if ($rep instanceof Representation) { unset($this->representations[$rep->getName()]); - } elseif (\is_string($rep)) { + } else { // String unset($this->representations[$rep]); } } - public function getRepresentation($name) + public function getRepresentation(string $name): ?Representation { - if (isset($this->representations[$name])) { - return $this->representations[$name]; - } + return $this->representations[$name] ?? null; } - public function getRepresentations() + public function getRepresentations(): array { return $this->representations; } - public function clearRepresentations() + public function clearRepresentations(): void { $this->representations = []; } - public function getType() + public function getType(): ?string { return $this->type; } - public function getModifiers() + public function getModifiers(): ?string { $out = $this->getAccess(); + if ($this->readonly) { + $out .= ' readonly'; + } + if ($this->const) { $out .= ' const'; } @@ -134,9 +142,11 @@ public function getModifiers() if (null !== $out && \strlen($out)) { return \ltrim($out); } + + return null; } - public function getAccess() + public function getAccess(): ?string { switch ($this->access) { case self::ACCESS_PRIVATE: @@ -146,14 +156,20 @@ public function getAccess() case self::ACCESS_PUBLIC: return 'public'; } + + return null; } - public function getName() + public function getName(): ?string { - return $this->name; + if (isset($this->name)) { + return (string) $this->name; + } + + return null; } - public function getOperator() + public function getOperator(): ?string { switch ($this->operator) { case self::OPERATOR_ARRAY: @@ -163,14 +179,20 @@ public function getOperator() case self::OPERATOR_STATIC: return '::'; } + + return null; } - public function getSize() + public function getSize(): ?string { - return $this->size; + if (isset($this->size)) { + return (string) $this->size; + } + + return null; } - public function getValueShort() + public function getValueShort(): ?string { if ($rep = $this->value) { if ('boolean' === $this->type) { @@ -178,22 +200,25 @@ public function getValueShort() } if ('integer' === $this->type || 'double' === $this->type) { - return $rep->contents; + return (string) $rep->contents; } } + + return null; } - public function getAccessPath() + public function getAccessPath(): ?string { return $this->access_path; } - public function transplant(Value $old) + public function transplant(self $old): void { $this->name = $old->name; $this->size = $old->size; $this->access_path = $old->access_path; $this->access = $old->access; + $this->readonly = $old->readonly; $this->static = $old->static; $this->const = $old->const; $this->type = $old->type; @@ -208,13 +233,8 @@ public function transplant(Value $old) /** * Creates a new basic object with a name and access path. - * - * @param null|string $name - * @param null|string $access_path - * - * @return \Kint\Zval\Value */ - public static function blank($name = null, $access_path = null) + public static function blank(?string $name = null, ?string $access_path = null): self { $o = new self(); $o->name = $name; @@ -223,7 +243,7 @@ public static function blank($name = null, $access_path = null) return $o; } - public static function sortByAccess(Value $a, Value $b) + public static function sortByAccess(self $a, self $b): int { static $sorts = [ self::ACCESS_PUBLIC => 1, @@ -235,14 +255,12 @@ public static function sortByAccess(Value $a, Value $b) return $sorts[$a->access] - $sorts[$b->access]; } - public static function sortByName(Value $a, Value $b) + public static function sortByName(self $a, self $b): int { - $ret = \strnatcasecmp($a->name, $b->name); - - if (0 === $ret) { + if ((string) $a->name === (string) $b->name) { return (int) \is_int($b->name) - (int) \is_int($a->name); } - return $ret; + return \strnatcasecmp((string) $a->name, (string) $b->name); } } diff --git a/system/ThirdParty/Kint/init.php b/system/ThirdParty/Kint/init.php index 2e7c62b4b1c9..431efe46c051 100644 --- a/system/ThirdParty/Kint/init.php +++ b/system/ThirdParty/Kint/init.php @@ -1,5 +1,7 @@ = 0)); -\define('KINT_PHP71', (\version_compare(PHP_VERSION, '7.1') >= 0)); -\define('KINT_PHP72', (\version_compare(PHP_VERSION, '7.2') >= 0)); -\define('KINT_PHP73', (\version_compare(PHP_VERSION, '7.3') >= 0)); -\define('KINT_PHP74', (\version_compare(PHP_VERSION, '7.4') >= 0)); -\define('KINT_PHP80', (\version_compare(PHP_VERSION, '8.0') >= 0)); -\define('KINT_PHP81', (\version_compare(PHP_VERSION, '8.1') >= 0)); +\define('KINT_PHP72', \version_compare(PHP_VERSION, '7.2') >= 0); +\define('KINT_PHP73', \version_compare(PHP_VERSION, '7.3') >= 0); +\define('KINT_PHP74', \version_compare(PHP_VERSION, '7.4') >= 0); +\define('KINT_PHP80', \version_compare(PHP_VERSION, '8.0') >= 0); +\define('KINT_PHP81', \version_compare(PHP_VERSION, '8.1') >= 0); +\define('KINT_PHP82', \version_compare(PHP_VERSION, '8.2') >= 0); +\define('KINT_PHP83', \version_compare(PHP_VERSION, '8.3') >= 0); // Dynamic default settings Kint::$file_link_format = \ini_get('xdebug.file_link_format'); diff --git a/system/ThirdParty/Kint/init_helpers.php b/system/ThirdParty/Kint/init_helpers.php index 8cd0fdb9fe9e..561425b2a0d6 100644 --- a/system/ThirdParty/Kint/init_helpers.php +++ b/system/ThirdParty/Kint/init_helpers.php @@ -1,5 +1,7 @@ e)&&(a[i].min=e),(void 0===a[i].max||a[i].maxe)&&(a[i].min=e),(void 0===a[i].max||a[i].max"},openInNewWindow:function(e){var t=window.open();t&&(t.document.open(),t.document.write(l.mktag("html")+l.mktag("head")+l.mktag("title")+"Kint ("+(new Date).toISOString()+")"+l.mktag("/title")+l.mktag('meta charset="utf-8"')+l.mktag('script class="kint-rich-script" nonce="'+l.script.nonce+'"')+l.script.innerHTML+l.mktag("/script")+l.mktag('style class="kint-rich-style" nonce="'+l.style.nonce+'"')+l.style.innerHTML+l.mktag("/style")+l.mktag("/head")+l.mktag("body")+'
'+e.parentNode.outerHTML+"
"+l.mktag("/body")),t.document.close())},sortTable:function(e,a){var t=e.tBodies[0];[].slice.call(e.tBodies[0].rows).sort(function(e,t){if(e=e.cells[a].textContent.trim().toLocaleLowerCase(),t=t.cells[a].textContent.trim().toLocaleLowerCase(),isNaN(e)||isNaN(t)){if(isNaN(e)&&!isNaN(t))return 1;if(isNaN(t)&&!isNaN(e))return-1}else e=parseFloat(e),t=parseFloat(t);return eli:not(.kint-active-tab)").forEach(function(e){l.isFolderOpen()&&!l.folder.contains(e)||0===e.offsetWidth&&0===e.offsetHeight||l.keyboardNav.targets.push(e)}),e&&-1!==l.keyboardNav.targets.indexOf(e)&&(l.keyboardNav.target=l.keyboardNav.targets.indexOf(e))},sync:function(e){var t=document.querySelector(".kint-focused");t&&t.classList.remove("kint-focused"),l.keyboardNav.active&&((t=l.keyboardNav.targets[l.keyboardNav.target]).classList.add("kint-focused"),e||l.keyboardNav.scroll(t))},scroll:function(e){var t,a;e!==l.folder.querySelector("dt > nav")&&(a=(t=function(e){return e.offsetTop+(e.offsetParent?t(e.offsetParent):0)})(e),l.isFolderOpen()?(e=l.folder.querySelector("dd.kint-foldout")).scrollTo(0,a-e.clientHeight/2):window.scrollTo(0,a-window.innerHeight/2))},moveCursor:function(e){for(l.keyboardNav.target+=e;l.keyboardNav.target<0;)l.keyboardNav.target+=l.keyboardNav.targets.length;for(;l.keyboardNav.target>=l.keyboardNav.targets.length;)l.keyboardNav.target-=l.keyboardNav.targets.length;l.keyboardNav.sync()},setCursor:function(e){if(l.isFolderOpen()&&!l.folder.contains(e))return!1;l.keyboardNav.fetchTargets();for(var t=0;t"},openInNewWindow:function(e){var t=window.open();t&&(t.document.open(),t.document.write(l.mktag("html")+l.mktag("head")+l.mktag("title")+"Kint ("+(new Date).toISOString()+")"+l.mktag("/title")+l.mktag('meta charset="utf-8"')+l.mktag('script class="kint-rich-script" nonce="'+l.script.nonce+'"')+l.script.innerHTML+l.mktag("/script")+l.mktag('style class="kint-rich-style" nonce="'+l.style.nonce+'"')+l.style.innerHTML+l.mktag("/style")+l.mktag("/head")+l.mktag("body")+'
'+e.parentNode.outerHTML+"
"+l.mktag("/body")),t.document.close())},sortTable:function(e,a){var t=e.tBodies[0];[].slice.call(e.tBodies[0].rows).sort(function(e,t){if(e=e.cells[a].textContent.trim().toLocaleLowerCase(),t=t.cells[a].textContent.trim().toLocaleLowerCase(),isNaN(e)||isNaN(t)){if(isNaN(e)&&!isNaN(t))return 1;if(isNaN(t)&&!isNaN(e))return-1}else e=parseFloat(e),t=parseFloat(t);return eli:not(.kint-active-tab)").forEach(function(e){l.isFolderOpen()&&!l.folder.contains(e)||0===e.offsetWidth&&0===e.offsetHeight||l.keyboardNav.targets.push(e)}),e&&-1!==l.keyboardNav.targets.indexOf(e)&&(l.keyboardNav.target=l.keyboardNav.targets.indexOf(e))},sync:function(e){var t=document.querySelector(".kint-focused");t&&t.classList.remove("kint-focused"),l.keyboardNav.active&&((t=l.keyboardNav.targets[l.keyboardNav.target]).classList.add("kint-focused"),e||l.keyboardNav.scroll(t))},scroll:function(e){var t,a;e!==l.folder.querySelector("dt > nav")&&(e=(t=function(e){return e.offsetTop+(e.offsetParent?t(e.offsetParent):0)})(e),l.isFolderOpen()?(a=l.folder.querySelector("dd.kint-foldout")).scrollTo(0,e-a.clientHeight/2):window.scrollTo(0,e-window.innerHeight/2))},moveCursor:function(e){for(l.keyboardNav.target+=e;l.keyboardNav.target<0;)l.keyboardNav.target+=l.keyboardNav.targets.length;for(;l.keyboardNav.target>=l.keyboardNav.targets.length;)l.keyboardNav.target-=l.keyboardNav.targets.length;l.keyboardNav.sync()},setCursor:function(e){if(!l.isFolderOpen()||l.folder.contains(e)){l.keyboardNav.fetchTargets();for(var t=0;t Date: Tue, 22 Nov 2022 21:08:21 +0900 Subject: [PATCH 2/4] config: update for Kint 5.0 --- app/Config/Kint.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Config/Kint.php b/app/Config/Kint.php index 370b2f06a106..7e0a0157c065 100644 --- a/app/Config/Kint.php +++ b/app/Config/Kint.php @@ -3,7 +3,7 @@ namespace Config; use CodeIgniter\Config\BaseConfig; -use Kint\Renderer\Renderer; +use Kint\Renderer\AbstractRenderer; /** * -------------------------------------------------------------------------- @@ -35,7 +35,7 @@ class Kint extends BaseConfig */ public string $richTheme = 'aante-light.css'; public bool $richFolder = false; - public int $richSort = Renderer::SORT_FULL; + public int $richSort = AbstractRenderer::SORT_FULL; public $richObjectPlugins; public $richTabPlugins; From 700c3d32a3d31ed86016f769ac080238800a6169 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Nov 2022 21:22:04 +0900 Subject: [PATCH 3/4] chore: update Kint to 5.0.1 --- admin/framework/composer.json | 2 +- composer.json | 2 +- system/ThirdParty/Kint/init.php | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/admin/framework/composer.json b/admin/framework/composer.json index b0581c77fbab..f4b5f68c0964 100644 --- a/admin/framework/composer.json +++ b/admin/framework/composer.json @@ -14,7 +14,7 @@ "psr/log": "^1.1" }, "require-dev": { - "kint-php/kint": "^4.2", + "kint-php/kint": "^5.0.1", "codeigniter/coding-standard": "^1.5", "fakerphp/faker": "^1.9", "friendsofphp/php-cs-fixer": "~3.13.0", diff --git a/composer.json b/composer.json index 1fa6482a0856..4715cae5ba08 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "psr/log": "^1.1" }, "require-dev": { - "kint-php/kint": "^5.0", + "kint-php/kint": "^5.0.1", "codeigniter/coding-standard": "^1.5", "fakerphp/faker": "^1.9", "friendsofphp/php-cs-fixer": "~3.13.0", diff --git a/system/ThirdParty/Kint/init.php b/system/ThirdParty/Kint/init.php index 431efe46c051..4c3a22bb500b 100644 --- a/system/ThirdParty/Kint/init.php +++ b/system/ThirdParty/Kint/init.php @@ -47,7 +47,9 @@ \define('KINT_PHP83', \version_compare(PHP_VERSION, '8.3') >= 0); // Dynamic default settings -Kint::$file_link_format = \ini_get('xdebug.file_link_format'); +if (false !== \ini_get('xdebug.file_link_format')) { + Kint::$file_link_format = \ini_get('xdebug.file_link_format'); +} if (isset($_SERVER['DOCUMENT_ROOT'])) { Kint::$app_root_dirs = [ $_SERVER['DOCUMENT_ROOT'] => '', From b86b13c4c4a77998a254772d947d30986d610bfc Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 22 Nov 2022 21:35:48 +0900 Subject: [PATCH 4/4] docs: add docs --- user_guide_src/source/changelogs/v4.3.0.rst | 1 + user_guide_src/source/installation/upgrade_430.rst | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/changelogs/v4.3.0.rst b/user_guide_src/source/changelogs/v4.3.0.rst index 889be19a89fc..660f167e0c91 100644 --- a/user_guide_src/source/changelogs/v4.3.0.rst +++ b/user_guide_src/source/changelogs/v4.3.0.rst @@ -260,6 +260,7 @@ Others - View Cells are now first-class citizens and can be located in the **app/Cells** directory. See :ref:`View Cells `. - Added ``Controlled Cells`` that provide more structure and flexibility to your View Cells. See :ref:`View Cells ` for details. - Now you can specify Composer packages to auto-discover manually. See :ref:`Code Modules `. +- **Debug:** Kint has been updated to 5.0.1. Message Changes *************** diff --git a/user_guide_src/source/installation/upgrade_430.rst b/user_guide_src/source/installation/upgrade_430.rst index 63e685518bd7..56c4db00c5fc 100644 --- a/user_guide_src/source/installation/upgrade_430.rst +++ b/user_guide_src/source/installation/upgrade_430.rst @@ -33,13 +33,14 @@ The following files received significant changes and Config Files ============ -If you are using the following Mock Config classes in testing, you need to update the corresponding Config files in **app/Config**: +- **app/Config/Kint.php** has been updated for Kint 5.0. You need to replace ``Kint\Renderer\Renderer`` with ``Kint\Renderer\AbstractRenderer`` and replace ``Renderer::SORT_FULL`` with ``AbstractRenderer::SORT_FULL``. +- If you are using the following Mock Config classes in testing, you need to update the corresponding Config files in **app/Config**: -- ``MockAppConfig`` (``Config\App``) -- ``MockCLIConfig`` (``Config\App``) -- ``MockSecurityConfig`` (``Config\Security``) + - ``MockAppConfig`` (``Config\App``) + - ``MockCLIConfig`` (``Config\App``) + - ``MockSecurityConfig`` (``Config\Security``) -Add **types** to the properties in these Config classes. You may need to fix the property values to match the property types. +- Add **types** to the properties in these Config classes. You may need to fix the property values to match the property types. Breaking Changes ****************
'.$this->renderer->escape($field->name).''; + if (null !== ($s = $field->getName())) { + $out .= $this->renderer->escape($s); + } + $out .= '
'; - $out .= $this->renderer->escape($row->name); + if (null !== ($s = $row->getName())) { + $out .= $this->renderer->escape($s); + } $out .= '