Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Update Kint to 6.0.1 #9373

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 113 additions & 113 deletions system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
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;
Expand All @@ -42,7 +41,7 @@

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
Expand All @@ -69,162 +68,163 @@ public function parseComplete(&$var, AbstractValue $v, int $trigger): AbstractVa
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());

$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;
}
if ($statics = $this->getStatics($r, $v->getContext()->getDepth() + 1)) {
$v->addRepresentation(new ContainerRepresentation('Static properties', \array_values($statics), 'statics'));
}

$statics_parsed = [];
$found_statics = [];
if ($consts = $this->getCachedConstants($r, $deep)) {
$v->addRepresentation(new ContainerRepresentation('Class constants', \array_values($consts), 'constants'));
}

$cdepth = $v->getContext()->getDepth();
return $v;
}

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();
/** @psalm-return array<AbstractValue> */
private function getStatics(ReflectionClass $r, int $depth): array
{
$cdepth = $depth ?: 1;
$class = $r->getName();
$parent = $r->getParentClass();

if ($static->isProtected()) {
$prop->access = ClassDeclaredContext::ACCESS_PROTECTED;
} elseif ($static->isPrivate()) {
$prop->access = ClassDeclaredContext::ACCESS_PRIVATE;
}
$parent_statics = $parent ? $this->getStatics($parent, $depth) : [];
$statics = [];

if ($prop->isAccessible($parser->getCallerClass())) {
$prop->access_path = '\\'.$prop->owner_class.'::'.$prop->name;
}
foreach ($r->getProperties(ReflectionProperty::IS_STATIC) as $pr) {
$canon_name = \strtolower($pr->getDeclaringClass()->name.'::'.$pr->name);

if (isset($found_statics[$prop->name])) {
$statics_full_name = true;
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 {
$found_statics[$prop->name] = true;

if ($prop->owner_class !== $class && ClassDeclaredContext::ACCESS_PRIVATE === $prop->access) {
$statics_full_name = true;
}
// This should never happen since abstract static properties can't exist
$statics[$canon_name] = $this->buildStaticValue($pr, $cdepth); // @codeCoverageIgnore
}
}

if ($statics_full_name) {
$prop->name = $prop->owner_class.'::'.$prop->name;
}
foreach ($parent_statics as $canon_name => $value) {
$statics[$canon_name] = $value;
}

$static->setAccessible(true);
return $statics;
}

/**
* @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);
}
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;
}

if ($statics_parsed) {
$v->addRepresentation(new ContainerRepresentation('Static properties', $statics_parsed, 'statics'));
$parser = $this->getParser();

if ($context->isAccessible($parser->getCallerClass())) {
$context->access_path = '\\'.$context->owner_class.'::$'.$context->name;
}

if ($consts = $this->getCachedConstants($r)) {
$v->addRepresentation(new ContainerRepresentation('Class constants', $consts, 'constants'));
$pr->setAccessible(true);

/**
* @psalm-suppress TooFewArguments
* Appears to have been fixed in master.
*/
if (!$pr->isInitialized()) {
$context->access_path = null;

return new UninitializedValue($context);
}

return $v;
$val = $pr->getValue();

$out = $this->getParser()->parse($val, $context);
$context->access_path = null;

return $out;
}

/** @psalm-return list<AbstractValue> */
private function getCachedConstants(ReflectionClass $r): array
/** @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);

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;
}
}
}
if ($cr->getDeclaringClass()->name === $class) {
$context = $this->buildConstContext($cr);
$context->depth = $cdepth;

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][$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 $this->cache[$class][$pdepth_enabled];
return $context;
}
}
15 changes: 15 additions & 0 deletions system/ThirdParty/Kint/Parser/DomPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -458,6 +463,16 @@ public static function getKnownProperties(object $var): array
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) {
Expand Down
2 changes: 1 addition & 1 deletion system/ThirdParty/Kint/Parser/IteratorPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading
Loading