Skip to content

Commit 6df13bd

Browse files
committed
DomPlugin: Use reflection to get fields from PHP 8.1
1 parent 52452c8 commit 6df13bd

File tree

3 files changed

+43
-23
lines changed

3 files changed

+43
-23
lines changed

build/kint.phar

964 Bytes
Binary file not shown.

src/Parser/DomPlugin.php

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@
5555
use Kint\Value\Representation\ContainerRepresentation;
5656
use Kint\Value\StringValue;
5757
use LogicException;
58+
use ReflectionClass;
5859

5960
class DomPlugin extends AbstractPlugin implements PluginBeginInterface
6061
{
6162
/**
62-
* Reflection doesn't work below 8.1, also it won't show readonly status.
63+
* Reflection doesn't show readonly status.
6364
*
6465
* In order to ensure this is stable enough we're only going to provide
6566
* properties for element and node. If subclasses like attr or document
@@ -104,10 +105,7 @@ class DomPlugin extends AbstractPlugin implements PluginBeginInterface
104105
'innerHTML' => false,
105106
'outerHTML' => true,
106107
'substitutedNodeValue' => false,
107-
];
108-
109-
public const DOM_NS_VERSIONS = [
110-
'outerHTML' => KINT_PHP85,
108+
'children' => true,
111109
];
112110

113111
/**
@@ -208,6 +206,9 @@ class DomPlugin extends AbstractPlugin implements PluginBeginInterface
208206
*/
209207
public static bool $verbose = false;
210208

209+
/** @psalm-var array<class-string, array<string, bool>> cache of properties for getKnownProperties */
210+
protected static array $property_cache = [];
211+
211212
protected ClassMethodsPlugin $methods_plugin;
212213
protected ClassStaticsPlugin $statics_plugin;
213214

@@ -259,12 +260,14 @@ public function parseBegin(&$var, ContextInterface $c): ?AbstractValue
259260
/** @psalm-param Node|DOMNode $var */
260261
private function parseProperty(object $var, string $prop, ContextInterface $c): AbstractValue
261262
{
262-
if (!isset($var->{$prop})) {
263+
// Suppress deprecation message
264+
if (@!isset($var->{$prop})) {
263265
return new FixedWidthValue($c, null);
264266
}
265267

266268
$parser = $this->getParser();
267-
$value = $var->{$prop};
269+
// Suppress deprecation message
270+
@$value = $var->{$prop};
268271

269272
if (\is_scalar($value)) {
270273
return $parser->parse($value, $c);
@@ -450,25 +453,42 @@ private function parseNode(object $var, ContextInterface $c): DomNodeValue
450453
*/
451454
public static function getKnownProperties(object $var): array
452455
{
453-
if ($var instanceof Node) {
454-
$known_properties = self::NODE_PROPS;
455-
if ($var instanceof Element) {
456-
$known_properties += self::ELEMENT_PROPS;
457-
}
458-
459-
if ($var instanceof Document) {
460-
$known_properties['textContent'] = true;
461-
}
456+
if (KINT_PHP81) {
457+
$r = new ReflectionClass($var);
458+
$classname = $r->getName();
459+
460+
if (!isset(self::$property_cache[$classname])) {
461+
self::$property_cache[$classname] = [];
462+
463+
foreach ($r->getProperties() as $prop) {
464+
if ($prop->isStatic()) {
465+
continue;
466+
}
467+
468+
$declaring = $prop->getDeclaringClass()->getName();
469+
$name = $prop->name;
470+
471+
if (\in_array($declaring, [Node::class, Element::class], true)) {
472+
$readonly = self::NODE_PROPS[$name] ?? self::ELEMENT_PROPS[$name];
473+
} elseif (\in_array($declaring, [DOMNode::class, DOMElement::class], true)) {
474+
$readonly = self::DOMNODE_PROPS[$name] ?? self::DOMELEMENT_PROPS[$name];
475+
} else {
476+
continue;
477+
}
478+
479+
self::$property_cache[$classname][$prop->name] = $readonly;
480+
}
462481

463-
if ($var instanceof Attr || $var instanceof CharacterData) {
464-
$known_properties['nodeValue'] = false;
465-
}
482+
if ($var instanceof Document) {
483+
self::$property_cache[$classname]['textContent'] = true;
484+
}
466485

467-
foreach (self::DOM_NS_VERSIONS as $key => $val) {
468-
if (false === $val) {
469-
unset($known_properties[$key]); // @codeCoverageIgnore
486+
if ($var instanceof Attr || $var instanceof CharacterData) {
487+
self::$property_cache[$classname]['nodeValue'] = false;
470488
}
471489
}
490+
491+
$known_properties = self::$property_cache[$classname];
472492
} else {
473493
$known_properties = self::DOMNODE_PROPS;
474494
if ($var instanceof DOMElement) {

tests/Parser/DomPluginTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ private function getExpectedPropsCount(bool $old)
11291129
];
11301130

11311131
if (KINT_PHP85) {
1132-
++$expected_props['ELEMENT_PROPS'];
1132+
$expected_props['ELEMENT_PROPS'] += 2;
11331133
}
11341134
}
11351135

0 commit comments

Comments
 (0)