chore: Update Kint to 6.0.1 (#9373)

This commit is contained in:
neznaika0 2025-01-06 16:24:04 +03:00 committed by GitHub
parent c3bfac5261
commit 24a5ae0d30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 347 additions and 296 deletions

View File

@ -30,7 +30,6 @@ namespace Kint\Parser;
use Kint\Value\AbstractValue;
use Kint\Value\Context\ClassConstContext;
use Kint\Value\Context\ClassDeclaredContext;
use Kint\Value\Context\ClassOwnedContext;
use Kint\Value\Context\StaticPropertyContext;
use Kint\Value\InstanceValue;
use Kint\Value\Representation\ContainerRepresentation;
@ -42,7 +41,7 @@ use UnitEnum;
class ClassStaticsPlugin extends AbstractPlugin implements PluginCompleteInterface
{
/** @psalm-var array<class-string, array<1|0, list<AbstractValue>>> */
/** @psalm-var array<class-string, array<1|0, array<AbstractValue>>> */
private array $cache = [];
public function getTypes(): array
@ -69,162 +68,163 @@ class ClassStaticsPlugin extends AbstractPlugin implements PluginCompleteInterfa
return $v;
}
$class = $v->getClassName();
$parser = $this->getParser();
$r = new ReflectionClass($class);
$deep = 0 === $this->getParser()->getDepthLimit();
$statics_full_name = false;
$statics = [];
$props = $r->getProperties(ReflectionProperty::IS_STATIC);
foreach ($props as $prop) {
$statics[$prop->name] = $prop;
$r = new ReflectionClass($v->getClassName());
if ($statics = $this->getStatics($r, $v->getContext()->getDepth() + 1)) {
$v->addRepresentation(new ContainerRepresentation('Static properties', \array_values($statics), 'statics'));
}
$parent = $r;
while ($parent = $parent->getParentClass()) {
foreach ($parent->getProperties(ReflectionProperty::IS_STATIC) as $static) {
if (isset($statics[$static->name]) && $statics[$static->name]->getDeclaringClass()->name === $static->getDeclaringClass()->name) {
continue;
}
$statics[] = $static;
}
}
$statics_parsed = [];
$found_statics = [];
$cdepth = $v->getContext()->getDepth();
foreach ($statics as $static) {
$prop = new StaticPropertyContext(
'$'.$static->getName(),
$static->getDeclaringClass()->name,
ClassDeclaredContext::ACCESS_PUBLIC
);
$prop->depth = $cdepth + 1;
$prop->final = KINT_PHP84 && $static->isFinal();
if ($static->isProtected()) {
$prop->access = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($static->isPrivate()) {
$prop->access = ClassDeclaredContext::ACCESS_PRIVATE;
}
if ($prop->isAccessible($parser->getCallerClass())) {
$prop->access_path = '\\'.$prop->owner_class.'::'.$prop->name;
}
if (isset($found_statics[$prop->name])) {
$statics_full_name = true;
} else {
$found_statics[$prop->name] = true;
if ($prop->owner_class !== $class && ClassDeclaredContext::ACCESS_PRIVATE === $prop->access) {
$statics_full_name = true;
}
}
if ($statics_full_name) {
$prop->name = $prop->owner_class.'::'.$prop->name;
}
$static->setAccessible(true);
/**
* @psalm-suppress TooFewArguments
* Appears to have been fixed in master
*/
if (!$static->isInitialized()) {
$statics_parsed[] = new UninitializedValue($prop);
} else {
$static = $static->getValue();
$statics_parsed[] = $parser->parse($static, $prop);
}
}
if ($statics_parsed) {
$v->addRepresentation(new ContainerRepresentation('Static properties', $statics_parsed, 'statics'));
}
if ($consts = $this->getCachedConstants($r)) {
$v->addRepresentation(new ContainerRepresentation('Class constants', $consts, 'constants'));
if ($consts = $this->getCachedConstants($r, $deep)) {
$v->addRepresentation(new ContainerRepresentation('Class constants', \array_values($consts), 'constants'));
}
return $v;
}
/** @psalm-return list<AbstractValue> */
private function getCachedConstants(ReflectionClass $r): array
/** @psalm-return array<AbstractValue> */
private function getStatics(ReflectionClass $r, int $depth): array
{
$cdepth = $depth ?: 1;
$class = $r->getName();
$parent = $r->getParentClass();
$parent_statics = $parent ? $this->getStatics($parent, $depth) : [];
$statics = [];
foreach ($r->getProperties(ReflectionProperty::IS_STATIC) as $pr) {
$canon_name = \strtolower($pr->getDeclaringClass()->name.'::'.$pr->name);
if ($pr->getDeclaringClass()->name === $class) {
$statics[$canon_name] = $this->buildStaticValue($pr, $cdepth);
} elseif (isset($parent_statics[$canon_name])) {
$statics[$canon_name] = $parent_statics[$canon_name];
unset($parent_statics[$canon_name]);
} else {
// This should never happen since abstract static properties can't exist
$statics[$canon_name] = $this->buildStaticValue($pr, $cdepth); // @codeCoverageIgnore
}
}
foreach ($parent_statics as $canon_name => $value) {
$statics[$canon_name] = $value;
}
return $statics;
}
private function buildStaticValue(ReflectionProperty $pr, int $depth): AbstractValue
{
$context = new StaticPropertyContext(
$pr->name,
$pr->getDeclaringClass()->name,
ClassDeclaredContext::ACCESS_PUBLIC
);
$context->depth = $depth;
$context->final = KINT_PHP84 && $pr->isFinal();
if ($pr->isProtected()) {
$context->access = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($pr->isPrivate()) {
$context->access = ClassDeclaredContext::ACCESS_PRIVATE;
}
$parser = $this->getParser();
if ($context->isAccessible($parser->getCallerClass())) {
$context->access_path = '\\'.$context->owner_class.'::$'.$context->name;
}
$pr->setAccessible(true);
/**
* @psalm-suppress TooFewArguments
* Appears to have been fixed in master.
*/
if (!$pr->isInitialized()) {
$context->access_path = null;
return new UninitializedValue($context);
}
$val = $pr->getValue();
$out = $this->getParser()->parse($val, $context);
$context->access_path = null;
return $out;
}
/** @psalm-return array<AbstractValue> */
private function getCachedConstants(ReflectionClass $r, bool $deep): array
{
$parser = $this->getParser();
$pdepth = $parser->getDepthLimit();
$pdepth_enabled = (int) ($pdepth > 0);
$cdepth = $parser->getDepthLimit() ?: 1;
$deepkey = (int) $deep;
$class = $r->getName();
// Separate cache for dumping with/without depth limit
// This means we can do immediate depth limit on normal dumps
if (!isset($this->cache[$class][$pdepth_enabled])) {
if (!isset($this->cache[$class][$deepkey])) {
$consts = [];
$reflectors = [];
$parent_consts = [];
if ($parent = $r->getParentClass()) {
$parent_consts = $this->getCachedConstants($parent, $deep);
}
foreach ($r->getConstants() as $name => $val) {
$cr = new ReflectionClassConstant($class, $name);
// Skip enum constants
if (\is_a($cr->class, UnitEnum::class, true) && $val instanceof UnitEnum && $cr->class === \get_class($val)) {
if ($cr->class === $class && \is_a($class, UnitEnum::class, true)) {
continue;
}
$reflectors[$cr->name] = [$cr, $val];
$consts[$cr->name] = null;
}
$canon_name = \strtolower($cr->getDeclaringClass()->name.'::'.$name);
if ($r = $r->getParentClass()) {
$parents = $this->getCachedConstants($r);
if ($cr->getDeclaringClass()->name === $class) {
$context = $this->buildConstContext($cr);
$context->depth = $cdepth;
foreach ($parents as $value) {
$c = $value->getContext();
$cname = $c->getName();
if (isset($reflectors[$cname]) && $c instanceof ClassOwnedContext && $reflectors[$cname][0]->getDeclaringClass()->name === $c->owner_class) {
$consts[$cname] = $value;
unset($reflectors[$cname]);
} else {
$value = clone $value;
$c = $value->getContext();
if ($c instanceof ClassOwnedContext) {
$c->name = $c->owner_class.'::'.$cname;
}
$consts[] = $value;
}
}
}
foreach ($reflectors as [$cr, $val]) {
$context = new ClassConstContext(
$cr->name,
$cr->getDeclaringClass()->name,
ClassDeclaredContext::ACCESS_PUBLIC
);
$context->depth = $pdepth ?: 1;
$context->final = KINT_PHP81 && $cr->isFinal();
if ($cr->isProtected()) {
$context->access = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($cr->isPrivate()) {
$context->access = ClassDeclaredContext::ACCESS_PRIVATE;
$consts[$canon_name] = $parser->parse($val, $context);
$context->access_path = null;
} elseif (isset($parent_consts[$canon_name])) {
$consts[$canon_name] = $parent_consts[$canon_name];
} else {
// No access path for protected/private. Tough shit the cache is worth it
$context->access_path = '\\'.$context->owner_class.'::'.$context->name;
$context = $this->buildConstContext($cr);
$context->depth = $cdepth;
$consts[$canon_name] = $parser->parse($val, $context);
$context->access_path = null;
}
$consts[$cr->name] = $parser->parse($val, $context);
unset($parent_consts[$canon_name]);
}
/** @psalm-var AbstractValue[] $consts */
$this->cache[$class][$pdepth_enabled] = \array_values($consts);
$this->cache[$class][$deepkey] = $consts + $parent_consts;
}
return $this->cache[$class][$pdepth_enabled];
return $this->cache[$class][$deepkey];
}
private function buildConstContext(ReflectionClassConstant $cr): ClassConstContext
{
$context = new ClassConstContext(
$cr->name,
$cr->getDeclaringClass()->name,
ClassDeclaredContext::ACCESS_PUBLIC
);
$context->final = KINT_PHP81 && $cr->isFinal();
if ($cr->isProtected()) {
$context->access = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($cr->isPrivate()) {
$context->access = ClassDeclaredContext::ACCESS_PRIVATE;
} else {
$context->access_path = '\\'.$context->owner_class.'::'.$context->name;
}
return $context;
}
}

View File

@ -102,9 +102,14 @@ class DomPlugin extends AbstractPlugin implements PluginBeginInterface
'previousElementSibling' => true,
'nextElementSibling' => true,
'innerHTML' => false,
'outerHTML' => false,
'substitutedNodeValue' => false,
];
public const DOM_NS_VERSIONS = [
'outerHTML' => KINT_PHP85,
];
/**
* @psalm-var non-empty-array<string, bool> Property names to readable status
*/
@ -458,6 +463,16 @@ class DomPlugin extends AbstractPlugin implements PluginBeginInterface
if ($var instanceof Attr || $var instanceof CharacterData) {
$known_properties['nodeValue'] = false;
}
foreach (self::DOM_NS_VERSIONS as $key => $val) {
/**
* @psalm-var bool $val
* Psalm bug #4509
*/
if (false === $val) {
unset($known_properties[$key]); // @codeCoverageIgnore
}
}
} else {
$known_properties = self::DOMNODE_PROPS;
if ($var instanceof DOMElement) {

View File

@ -54,7 +54,7 @@ class IteratorPlugin extends AbstractPlugin implements PluginCompleteInterface
* when traversed. Others are just huge. Either way, put them in here
* and you won't have to worry about them being parsed.
*
* @psalm-var class-string<Traversable>[]
* @psalm-var class-string[]
*/
public static array $blacklist = [
NamedNodeMap::class,

View File

@ -28,7 +28,6 @@ declare(strict_types=1);
namespace Kint\Parser;
use DomainException;
use Exception;
use InvalidArgumentException;
use Kint\Utils;
use Kint\Value\AbstractValue;
@ -52,6 +51,7 @@ use ReflectionClass;
use ReflectionObject;
use ReflectionProperty;
use ReflectionReference;
use Throwable;
/**
* @psalm-type ParserTrigger int-mask-of<Parser::TRIGGER_*>
@ -173,6 +173,12 @@ class Parser
public function addPlugin(PluginInterface $p): void
{
try {
$this->noRecurseCall();
} catch (DomainException $e) { // @codeCoverageIgnore
\trigger_error('Calling Kint\\Parser::addPlugin from inside a parse is deprecated', E_USER_DEPRECATED); // @codeCoverageIgnore
}
if (!$types = $p->getTypes()) {
return;
}
@ -209,6 +215,12 @@ class Parser
public function clearPlugins(): void
{
try {
$this->noRecurseCall();
} catch (DomainException $e) { // @codeCoverageIgnore
\trigger_error('Calling Kint\\Parser::clearPlugins from inside a parse is deprecated', E_USER_DEPRECATED); // @codeCoverageIgnore
}
$this->plugins = [];
}
@ -216,17 +228,13 @@ class Parser
{
$bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
$caller_frame = [
'function' => __FUNCTION__,
];
while (isset($bt[0]['object']) && $bt[0]['object'] === $this) {
$caller_frame = \array_shift($bt);
}
\reset($bt);
/** @psalm-var class-string $caller_frame['class'] */
$caller_frame = \next($bt);
foreach ($bt as $frame) {
if (isset($frame['object']) && $frame['object'] === $this) {
throw new DomainException(__CLASS__.'::'.$caller_frame['function'].' cannot be called from inside a parse');
if (isset($frame['object']) && $frame['object'] === $this && 'parse' === $frame['function']) {
throw new DomainException($caller_frame['class'].'::'.$caller_frame['function'].' cannot be called from inside a parse');
}
}
}
@ -265,45 +273,41 @@ class Parser
return $this->applyPluginsComplete($var, $array, self::TRIGGER_RECURSION);
}
$this->array_ref_stack[$parentRef] = true;
try {
$this->array_ref_stack[$parentRef] = true;
$cdepth = $c->getDepth();
$ap = $c->getAccessPath();
$cdepth = $c->getDepth();
$ap = $c->getAccessPath();
if ($size > 0 && $this->depth_limit && $cdepth >= $this->depth_limit) {
$array = new ArrayValue($c, $size, $contents);
$array->flags |= AbstractValue::FLAG_DEPTH_LIMIT;
if ($size > 0 && $this->depth_limit && $cdepth >= $this->depth_limit) {
$array = new ArrayValue($c, $size, $contents);
$array->flags |= AbstractValue::FLAG_DEPTH_LIMIT;
$array = $this->applyPluginsComplete($var, $array, self::TRIGGER_DEPTH_LIMIT);
unset($this->array_ref_stack[$parentRef]);
return $array;
}
foreach ($var as $key => $_) {
$child = new ArrayContext($key);
$child->depth = $cdepth + 1;
$child->reference = null !== ReflectionReference::fromArrayElement($var, $key);
if (null !== $ap) {
$child->access_path = $ap.'['.\var_export($key, true).']';
return $this->applyPluginsComplete($var, $array, self::TRIGGER_DEPTH_LIMIT);
}
$contents[$key] = $this->parse($var[$key], $child);
foreach ($var as $key => $_) {
$child = new ArrayContext($key);
$child->depth = $cdepth + 1;
$child->reference = null !== ReflectionReference::fromArrayElement($var, $key);
if (null !== $ap) {
$child->access_path = $ap.'['.\var_export($key, true).']';
}
$contents[$key] = $this->parse($var[$key], $child);
}
$array = new ArrayValue($c, $size, $contents);
if ($contents) {
$array->addRepresentation(new ContainerRepresentation('Contents', $contents, null, true));
}
return $this->applyPluginsComplete($var, $array, self::TRIGGER_SUCCESS);
} finally {
unset($this->array_ref_stack[$parentRef]);
}
$array = new ArrayValue($c, $size, $contents);
if ($contents) {
$array->addRepresentation(new ContainerRepresentation('Contents', $contents, null, true));
}
$array = $this->applyPluginsComplete($var, $array, self::TRIGGER_SUCCESS);
unset($this->array_ref_stack[$parentRef]);
return $array;
}
/**
@ -374,129 +378,126 @@ class Parser
return $this->applyPluginsComplete($var, $object, self::TRIGGER_RECURSION);
}
$this->object_hashes[$hash] = true;
try {
$this->object_hashes[$hash] = true;
$cdepth = $c->getDepth();
$ap = $c->getAccessPath();
$cdepth = $c->getDepth();
$ap = $c->getAccessPath();
if ($this->depth_limit && $cdepth >= $this->depth_limit) {
$object = new InstanceValue($c, $classname, $hash, \spl_object_id($var));
$object->flags |= AbstractValue::FLAG_DEPTH_LIMIT;
if ($this->depth_limit && $cdepth >= $this->depth_limit) {
$object = new InstanceValue($c, $classname, $hash, \spl_object_id($var));
$object->flags |= AbstractValue::FLAG_DEPTH_LIMIT;
$object = $this->applyPluginsComplete($var, $object, self::TRIGGER_DEPTH_LIMIT);
unset($this->object_hashes[$hash]);
return $object;
}
if (KINT_PHP81) {
$props = $this->getPropsOrdered(new ReflectionObject($var));
} else {
$props = $this->getPropsOrderedOld(new ReflectionObject($var)); // @codeCoverageIgnore
}
$values = (array) $var;
$properties = [];
foreach ($props as $rprop) {
$rprop->setAccessible(true);
$name = $rprop->getName();
// Casting object to array:
// private properties show in the form "\0$owner_class_name\0$property_name";
// protected properties show in the form "\0*\0$property_name";
// public properties show in the form "$property_name";
// http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
$key = $name;
if ($rprop->isProtected()) {
$key = "\0*\0".$name;
} elseif ($rprop->isPrivate()) {
$key = "\0".$rprop->getDeclaringClass()->getName()."\0".$name;
}
$initialized = \array_key_exists($key, $values);
if ($key === (string) (int) $key) {
$key = (int) $key;
return $this->applyPluginsComplete($var, $object, self::TRIGGER_DEPTH_LIMIT);
}
if ($rprop->isDefault()) {
$child = new PropertyContext(
$name,
$rprop->getDeclaringClass()->getName(),
ClassDeclaredContext::ACCESS_PUBLIC
);
if (KINT_PHP81) {
$props = $this->getPropsOrdered(new ReflectionObject($var));
} else {
$props = $this->getPropsOrderedOld(new ReflectionObject($var)); // @codeCoverageIgnore
}
$child->readonly = KINT_PHP81 && $rprop->isReadOnly();
$values = (array) $var;
$properties = [];
foreach ($props as $rprop) {
$rprop->setAccessible(true);
$name = $rprop->getName();
// Casting object to array:
// private properties show in the form "\0$owner_class_name\0$property_name";
// protected properties show in the form "\0*\0$property_name";
// public properties show in the form "$property_name";
// http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
$key = $name;
if ($rprop->isProtected()) {
$child->access = ClassDeclaredContext::ACCESS_PROTECTED;
$key = "\0*\0".$name;
} elseif ($rprop->isPrivate()) {
$child->access = ClassDeclaredContext::ACCESS_PRIVATE;
$key = "\0".$rprop->getDeclaringClass()->getName()."\0".$name;
}
$initialized = \array_key_exists($key, $values);
if ($key === (string) (int) $key) {
$key = (int) $key;
}
if (KINT_PHP84) {
if ($rprop->isProtectedSet()) {
$child->access_set = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($rprop->isPrivateSet()) {
$child->access_set = ClassDeclaredContext::ACCESS_PRIVATE;
if ($rprop->isDefault()) {
$child = new PropertyContext(
$name,
$rprop->getDeclaringClass()->getName(),
ClassDeclaredContext::ACCESS_PUBLIC
);
$child->readonly = KINT_PHP81 && $rprop->isReadOnly();
if ($rprop->isProtected()) {
$child->access = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($rprop->isPrivate()) {
$child->access = ClassDeclaredContext::ACCESS_PRIVATE;
}
$hooks = $rprop->getHooks();
if (isset($hooks['get'])) {
$child->hooks |= PropertyContext::HOOK_GET;
if ($hooks['get']->returnsReference()) {
$child->hooks |= PropertyContext::HOOK_GET_REF;
if (KINT_PHP84) {
if ($rprop->isProtectedSet()) {
$child->access_set = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($rprop->isPrivateSet()) {
$child->access_set = ClassDeclaredContext::ACCESS_PRIVATE;
}
$hooks = $rprop->getHooks();
if (isset($hooks['get'])) {
$child->hooks |= PropertyContext::HOOK_GET;
if ($hooks['get']->returnsReference()) {
$child->hooks |= PropertyContext::HOOK_GET_REF;
}
}
if (isset($hooks['set'])) {
$child->hooks |= PropertyContext::HOOK_SET;
$child->hook_set_type = (string) $rprop->getSettableType();
if ($child->hook_set_type !== (string) $rprop->getType()) {
$child->hooks |= PropertyContext::HOOK_SET_TYPE;
} elseif ('' === $child->hook_set_type) {
$child->hook_set_type = null;
}
}
}
if (isset($hooks['set'])) {
$child->hooks |= PropertyContext::HOOK_SET;
$child->hook_set_type = (string) $rprop->getSettableType();
if ($child->hook_set_type !== (string) $rprop->getType()) {
$child->hooks |= PropertyContext::HOOK_SET_TYPE;
} elseif ('' === $child->hook_set_type) {
$child->hook_set_type = null;
}
}
}
} else {
$child = new ClassOwnedContext($name, $rprop->getDeclaringClass()->getName());
}
$child->reference = $initialized && null !== ReflectionReference::fromArrayElement($values, $key);
$child->depth = $cdepth + 1;
if (null !== $ap && $child->isAccessible($this->caller_class)) {
/** @psalm-var string $child->name */
if (Utils::isValidPhpName($child->name)) {
$child->access_path = $ap.'->'.$child->name;
} else {
$child->access_path = $ap.'->{'.\var_export($child->name, true).'}';
$child = new ClassOwnedContext($name, $rprop->getDeclaringClass()->getName());
}
$child->reference = $initialized && null !== ReflectionReference::fromArrayElement($values, $key);
$child->depth = $cdepth + 1;
if (null !== $ap && $child->isAccessible($this->caller_class)) {
/** @psalm-var string $child->name */
if (Utils::isValidPhpName($child->name)) {
$child->access_path = $ap.'->'.$child->name;
} else {
$child->access_path = $ap.'->{'.\var_export($child->name, true).'}';
}
}
if (KINT_PHP84 && $rprop->isVirtual()) {
$properties[] = new VirtualValue($child);
} elseif (!$initialized) {
$properties[] = new UninitializedValue($child);
} else {
$properties[] = $this->parse($values[$key], $child);
}
}
if (KINT_PHP84 && $rprop->isVirtual()) {
$properties[] = new VirtualValue($child);
} elseif (!$initialized) {
$properties[] = new UninitializedValue($child);
} else {
$properties[] = $this->parse($values[$key], $child);
$object = new InstanceValue($c, $classname, $hash, \spl_object_id($var));
if ($props) {
$object->setChildren($properties);
}
if ($properties) {
$object->addRepresentation(new ContainerRepresentation('Properties', $properties));
}
return $this->applyPluginsComplete($var, $object, self::TRIGGER_SUCCESS);
} finally {
unset($this->object_hashes[$hash]);
}
$object = new InstanceValue($c, $classname, $hash, \spl_object_id($var));
if ($props) {
$object->setChildren($properties);
}
if ($properties) {
$object->addRepresentation(new ContainerRepresentation('Properties', $properties));
}
$object = $this->applyPluginsComplete($var, $object, self::TRIGGER_SUCCESS);
unset($this->object_hashes[$hash]);
return $object;
}
/**
@ -555,9 +556,9 @@ class Parser
if ($v = $plugin->parseBegin($var, $c)) {
return $v;
}
} catch (Exception $e) {
} catch (Throwable $e) {
\trigger_error(
'An exception ('.Utils::errorSanitizeString(\get_class($e)).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing "'.Utils::errorSanitizeString(\get_class($plugin)).'"->parseBegin. Error message: '.Utils::errorSanitizeString($e->getMessage()),
Utils::errorSanitizeString(\get_class($e)).' was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing '.Utils::errorSanitizeString(\get_class($plugin)).'->parseBegin. Error message: '.Utils::errorSanitizeString($e->getMessage()),
E_USER_WARNING
);
}
@ -578,9 +579,9 @@ class Parser
foreach ($plugins as $plugin) {
try {
$v = $plugin->parseComplete($var, $v, $trigger);
} catch (Exception $e) {
} catch (Throwable $e) {
\trigger_error(
'An exception ('.Utils::errorSanitizeString(\get_class($e)).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing "'.Utils::errorSanitizeString(\get_class($plugin)).'"->parseComplete. Error message: '.Utils::errorSanitizeString($e->getMessage()),
Utils::errorSanitizeString(\get_class($e)).' was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing '.Utils::errorSanitizeString(\get_class($plugin)).'->parseComplete. Error message: '.Utils::errorSanitizeString($e->getMessage()),
E_USER_WARNING
);
}

View File

@ -31,7 +31,7 @@ trait AssetRendererTrait
{
public static ?string $theme = null;
/** @psalm-var array{js?:string, css?:array<path, string>} */
/** @psalm-var array{js?:string, css?:array<path, string|false>} */
private static array $assetCache = [];
/** @psalm-api */
@ -54,11 +54,17 @@ trait AssetRendererTrait
if (!isset(self::$assetCache['css'][self::$theme])) {
if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) {
self::$assetCache['css'][self::$theme] = \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme);
} else {
} elseif (\file_exists(self::$theme)) {
self::$assetCache['css'][self::$theme] = \file_get_contents(self::$theme);
} else {
self::$assetCache['css'][self::$theme] = false;
}
}
if (false === self::$assetCache['css'][self::$theme]) {
return null;
}
return self::$assetCache['css'][self::$theme];
}
}

View File

@ -28,6 +28,7 @@ declare(strict_types=1);
namespace Kint\Renderer\Rich;
use Kint\Value\AbstractValue;
use Kint\Value\MethodValue;
use Kint\Value\TraceFrameValue;
class TraceFramePlugin extends AbstractPlugin implements ValuePluginInterface
@ -45,7 +46,13 @@ class TraceFramePlugin extends AbstractPlugin implements ValuePluginInterface
}
if ($callable = $v->getCallable()) {
$function = $this->renderer->escape($callable->getDisplayName());
if ($callable instanceof MethodValue) {
$function = $callable->getFullyQualifiedDisplayName();
} else {
$function = $callable->getDisplayName();
}
$function = $this->renderer->escape($function);
if (null !== ($url = $callable->getPhpDocUrl())) {
$function = '<a href="'.$url.'" target=_blank>'.$function.'</a>';

View File

@ -221,15 +221,15 @@ class RichRenderer extends AbstractRenderer
$out .= '>';
if (self::$access_paths && $c->getDepth() > 0 && null !== ($ap = $c->getAccessPath())) {
$out .= '<span class="kint-access-path-trigger" title="Show access path">&rlarr;</span>';
$out .= '<span class="kint-access-path-trigger" title="Show access path"></span>';
}
if ($has_children) {
if (0 === $c->getDepth()) {
if (!$this->use_folder) {
$out .= '<span class="kint-folder-trigger" title="Move to folder">&mapstodown;</span>';
$out .= '<span class="kint-folder-trigger" title="Move to folder"></span>';
}
$out .= '<span class="kint-search-trigger" title="Show search box">&telrec;</span>';
$out .= '<span class="kint-search-trigger" title="Show search box"></span>';
$out .= '<input type="text" class="kint-search" value="">';
}
@ -412,7 +412,13 @@ class RichRenderer extends AbstractRenderer
return '</div>';
}
$output = '<footer>';
$output = '<footer';
if ($this->expand) {
$output .= ' class="kint-show"';
}
$output .= '>';
if (!$this->use_folder) {
$output .= '<span class="kint-folder-trigger" title="Move to folder">&mapstodown;</span>';

View File

@ -309,7 +309,7 @@ final class Utils
*/
public static function errorSanitizeString(string $input): string
{
if (KINT_PHP82) {
if (KINT_PHP82 || '' === $input) {
return $input;
}

View File

@ -31,6 +31,11 @@ class ClassConstContext extends ClassDeclaredContext
{
public bool $final = false;
public function getName(): string
{
return $this->owner_class.'::'.$this->name;
}
public function getOperator(): string
{
return '::';

View File

@ -31,6 +31,11 @@ class StaticPropertyContext extends DoubleAccessMemberContext
{
public bool $final = false;
public function getName(): string
{
return $this->owner_class.'::$'.$this->name;
}
public function getOperator(): string
{
return '::';

View File

@ -88,17 +88,22 @@ class MethodValue extends AbstractValue
return $this->definition_rep;
}
public function getFullyQualifiedDisplayName(): string
{
$c = $this->getContext();
return $c->owner_class.'::'.$c->getName().'('.$this->callable_bag->getParams().')';
}
public function getDisplayName(): string
{
$c = $this->getContext();
$name = $c->getName();
if ($c->static || (ClassDeclaredContext::ACCESS_PRIVATE === $c->access && $c->inherited)) {
$name = $c->owner_class.'::'.$name;
return $this->getFullyQualifiedDisplayName();
}
return $name.'('.$this->callable_bag->getParams().')';
return $c->getName().'('.$this->callable_bag->getParams().')';
}
public function getDisplayValue(): ?string

View File

@ -44,6 +44,7 @@ if (\version_compare(PHP_VERSION, '7.4') < 0) {
\define('KINT_PHP82', \version_compare(PHP_VERSION, '8.2') >= 0);
\define('KINT_PHP83', \version_compare(PHP_VERSION, '8.3') >= 0);
\define('KINT_PHP84', \version_compare(PHP_VERSION, '8.4') >= 0);
\define('KINT_PHP85', \version_compare(PHP_VERSION, '8.5') >= 0);
// Dynamic default settings
if (\strlen((string) \ini_get('xdebug.file_link_format')) > 0) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.kint-plain{background:rgba(255,255,255,.9);white-space:pre;display:block;font-family:monospace;color:#222}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-js .kint-microtime-lap{text-shadow:1px 0 #d00,0 1px #d00,-1px 0 #d00,0 -1px #d00;color:#fff;font-weight:bold}
.kint-plain{background:rgba(255,255,255,.9);white-space:pre;display:block;font-family:monospace;color:#222;line-height:normal}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-js .kint-microtime-lap{text-shadow:1px 0 #d00,0 1px #d00,-1px 0 #d00,0 -1px #d00;color:#fff;font-weight:bold}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long