From cbfde1f0b6414a157d404a64e0e7c9e1c7ced956 Mon Sep 17 00:00:00 2001 From: Jonathan Vollebregt Date: Fri, 19 Jul 2024 17:05:04 +0200 Subject: [PATCH] Property type hints and psalm checks * Moved js_nonce and css_nonce to AbstractRenderer --- psalm.xml | 4 - src/CallFinder.php | 10 +- src/Kint.php | 34 ++++--- src/Parser/AbstractPlugin.php | 2 +- src/Parser/ArrayLimitPlugin.php | 12 +-- src/Parser/Base64Plugin.php | 8 +- src/Parser/BlacklistPlugin.php | 8 +- src/Parser/ClassMethodsPlugin.php | 2 +- src/Parser/ClassStaticsPlugin.php | 2 +- src/Parser/DOMDocumentPlugin.php | 8 +- src/Parser/DateTimePlugin.php | 4 +- src/Parser/EnumPlugin.php | 2 +- src/Parser/FsPathPlugin.php | 2 +- src/Parser/IteratorPlugin.php | 4 +- src/Parser/MicrotimePlugin.php | 8 +- src/Parser/MysqliPlugin.php | 14 +-- src/Parser/Parser.php | 12 +-- src/Parser/ProxyPlugin.php | 17 +--- src/Parser/SerializePlugin.php | 6 +- src/Parser/SimpleXMLElementPlugin.php | 4 +- src/Parser/TimestampPlugin.php | 2 +- src/Parser/ToStringPlugin.php | 2 +- src/Parser/TracePlugin.php | 4 +- src/Parser/XmlPlugin.php | 4 +- src/Renderer/AbstractRenderer.php | 9 +- src/Renderer/CliRenderer.php | 23 ++--- src/Renderer/PlainRenderer.php | 16 ++- src/Renderer/Rich/AbstractPlugin.php | 2 +- src/Renderer/Rich/BinaryPlugin.php | 4 +- src/Renderer/Rich/CallablePlugin.php | 4 +- src/Renderer/Rich/TablePlugin.php | 2 +- src/Renderer/RichRenderer.php | 53 ++++------ src/Renderer/Text/AbstractPlugin.php | 2 +- src/Renderer/Text/MicrotimePlugin.php | 2 +- src/Renderer/Text/TracePlugin.php | 18 +++- src/Renderer/TextRenderer.php | 38 +++----- src/Zval/BlobValue.php | 8 +- src/Zval/ClosureValue.php | 4 +- src/Zval/DateTimeValue.php | 8 +- src/Zval/EnumValue.php | 18 ++-- src/Zval/InstanceValue.php | 14 +-- src/Zval/MethodValue.php | 97 +++++++++++-------- src/Zval/ParameterHoldingTrait.php | 4 +- src/Zval/ParameterValue.php | 10 +- .../Representation/ColorRepresentation.php | 20 ++-- .../MethodDefinitionRepresentation.php | 10 +- .../MicrotimeRepresentation.php | 27 +++--- src/Zval/Representation/Representation.php | 8 +- .../Representation/SourceRepresentation.php | 12 +-- .../SplFileInfoRepresentation.php | 35 +++---- src/Zval/ResourceValue.php | 2 +- src/Zval/SimpleXMLElementValue.php | 4 +- src/Zval/StreamValue.php | 2 +- src/Zval/ThrowableValue.php | 4 +- src/Zval/TraceFrameValue.php | 8 +- src/Zval/TraceValue.php | 8 +- src/Zval/Value.php | 34 ++++--- tests/KintTestCase.php | 3 +- tests/Parser/ParserTest.php | 8 +- tests/ProphecyCompatabilityTestCase.php | 48 --------- 60 files changed, 328 insertions(+), 416 deletions(-) delete mode 100644 tests/ProphecyCompatabilityTestCase.php diff --git a/psalm.xml b/psalm.xml index 83b748ecd..25290ed19 100644 --- a/psalm.xml +++ b/psalm.xml @@ -10,8 +10,4 @@ - - - - diff --git a/src/CallFinder.php b/src/CallFinder.php index 61ce6b4b7..36131d8c6 100644 --- a/src/CallFinder.php +++ b/src/CallFinder.php @@ -33,7 +33,7 @@ */ class CallFinder { - private static $ignore = [ + private static array $ignore = [ T_CLOSE_TAG => true, T_COMMENT => true, T_DOC_COMMENT => true, @@ -49,7 +49,7 @@ class CallFinder * - Wrap the access path in parentheses if there * are any of these in the final short parameter. */ - private static $operator = [ + private static array $operator = [ T_AND_EQUAL => true, T_BOOLEAN_AND => true, T_BOOLEAN_OR => true, @@ -116,7 +116,7 @@ class CallFinder '~' => true, ]; - private static $strip = [ + private static array $strip = [ '(' => true, ')' => true, '[' => true, @@ -128,12 +128,12 @@ class CallFinder T_NS_SEPARATOR => true, ]; - private static $classcalls = [ + private static array $classcalls = [ T_DOUBLE_COLON => true, T_OBJECT_OPERATOR => true, ]; - private static $namespace = [ + private static array $namespace = [ T_STRING => true, ]; diff --git a/src/Kint.php b/src/Kint.php index 614731939..f6db652bc 100644 --- a/src/Kint.php +++ b/src/Kint.php @@ -37,6 +37,8 @@ /** * @psalm-consistent-constructor + * + * @psalm-type KintMode = string|bool */ class Kint implements FacadeInterface { @@ -51,27 +53,29 @@ class Kint implements FacadeInterface * false: Disabled * true: Enabled, default mode selection * other: Manual mode selection + * + * @psalm-var KintMode */ public static $enabled_mode = true; /** * Default mode. * - * @var string + * @psalm-var KintMode */ public static $mode_default = self::MODE_RICH; /** * Default mode in CLI with cli_detection on. * - * @var string + * @psalm-var KintMode */ public static $mode_default_cli = self::MODE_CLI; /** * @var bool Return output instead of echoing */ - public static $return; + public static bool $return = false; /** * @var string format of the link to the source file in trace entries. @@ -82,12 +86,12 @@ class Kint implements FacadeInterface * * Kint::$file_link_format = 'http://localhost:8091/?message=%f:%l'; */ - public static $file_link_format = ''; + public static string $file_link_format = ''; /** * @var bool whether to display where kint was called from */ - public static $display_called_from = true; + public static bool $display_called_from = true; /** * @var array base directories of your application that will be displayed instead of the full path. @@ -108,29 +112,29 @@ class Kint implements FacadeInterface * * Defaults to [$_SERVER['DOCUMENT_ROOT'] => ''] */ - public static $app_root_dirs = []; + public static array $app_root_dirs = []; /** * @var int depth limit for array/object traversal. 0 for no limit */ - public static $depth_limit = 7; + public static int $depth_limit = 7; /** * @var bool expand all trees by default for rich view */ - public static $expanded = false; + public static bool $expanded = false; /** * @var bool enable detection when Kint is command line. * * Formats output with whitespace only; does not HTML-escape it */ - public static $cli_detection = true; + public static bool $cli_detection = true; /** * @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces */ - public static $aliases = [ + public static array $aliases = [ ['Kint\\Kint', 'dump'], ['Kint\\Kint', 'trace'], ['Kint\\Kint', 'dumpAll'], @@ -139,7 +143,7 @@ class Kint implements FacadeInterface /** * @psalm-var class-string[] Array of modes to renderer class names */ - public static $renderers = [ + public static array $renderers = [ self::MODE_RICH => Renderer\RichRenderer::class, self::MODE_PLAIN => Renderer\PlainRenderer::class, self::MODE_TEXT => TextRenderer::class, @@ -149,7 +153,7 @@ class Kint implements FacadeInterface /** * @psalm-var class-string[] */ - public static $plugins = [ + public static array $plugins = [ \Kint\Parser\ArrayLimitPlugin::class, \Kint\Parser\ArrayObjectPlugin::class, \Kint\Parser\Base64Plugin::class, @@ -175,10 +179,10 @@ class Kint implements FacadeInterface \Kint\Parser\XmlPlugin::class, ]; - protected static $plugin_pool = []; + protected static array $plugin_pool = []; - protected $parser; - protected $renderer; + protected Parser $parser; + protected RendererInterface $renderer; public function __construct(Parser $p, RendererInterface $r) { diff --git a/src/Parser/AbstractPlugin.php b/src/Parser/AbstractPlugin.php index a3f896843..5e1748165 100644 --- a/src/Parser/AbstractPlugin.php +++ b/src/Parser/AbstractPlugin.php @@ -32,7 +32,7 @@ */ abstract class AbstractPlugin implements ConstructablePluginInterface { - protected $parser; + protected Parser $parser; public function __construct() { diff --git a/src/Parser/ArrayLimitPlugin.php b/src/Parser/ArrayLimitPlugin.php index 2e7fca938..d74bdeb86 100644 --- a/src/Parser/ArrayLimitPlugin.php +++ b/src/Parser/ArrayLimitPlugin.php @@ -35,24 +35,18 @@ class ArrayLimitPlugin extends AbstractPlugin { /** * Maximum size of arrays before limiting. - * - * @var int */ - public static $trigger = 1000; + public static int $trigger = 1000; /** * Maximum amount of items to show in a limited array. - * - * @var int */ - public static $limit = 50; + public static int $limit = 50; /** * Don't limit arrays with string keys. - * - * @var bool */ - public static $numeric_only = true; + public static bool $numeric_only = true; public function getTypes(): array { diff --git a/src/Parser/Base64Plugin.php b/src/Parser/Base64Plugin.php index a25a7343a..837fa5213 100644 --- a/src/Parser/Base64Plugin.php +++ b/src/Parser/Base64Plugin.php @@ -34,17 +34,13 @@ class Base64Plugin extends AbstractPlugin { /** * The minimum length before a string will be considered for base64 decoding. - * - * @var int */ - public static $min_length_hard = 16; + public static int $min_length_hard = 16; /** * The minimum length before the base64 decoding will take precedence. - * - * @var int */ - public static $min_length_soft = 50; + public static int $min_length_soft = 50; public function getTypes(): array { diff --git a/src/Parser/BlacklistPlugin.php b/src/Parser/BlacklistPlugin.php index fa54a3a67..506e16102 100644 --- a/src/Parser/BlacklistPlugin.php +++ b/src/Parser/BlacklistPlugin.php @@ -36,16 +36,16 @@ class BlacklistPlugin extends AbstractPlugin /** * List of classes and interfaces to blacklist. * - * @var array + * @var class-string[] */ - public static $blacklist = []; + public static array $blacklist = []; /** * List of classes and interfaces to blacklist except when dumped directly. * - * @var array + * @var class-string[] */ - public static $shallow_blacklist = [ContainerInterface::class]; + public static array $shallow_blacklist = [ContainerInterface::class]; public function getTypes(): array { diff --git a/src/Parser/ClassMethodsPlugin.php b/src/Parser/ClassMethodsPlugin.php index 8b90300ae..99271554e 100644 --- a/src/Parser/ClassMethodsPlugin.php +++ b/src/Parser/ClassMethodsPlugin.php @@ -35,7 +35,7 @@ class ClassMethodsPlugin extends AbstractPlugin { - private static $cache = []; + private static array $cache = []; public function getTypes(): array { diff --git a/src/Parser/ClassStaticsPlugin.php b/src/Parser/ClassStaticsPlugin.php index 63dbfa5a6..1440ebd7d 100644 --- a/src/Parser/ClassStaticsPlugin.php +++ b/src/Parser/ClassStaticsPlugin.php @@ -37,7 +37,7 @@ class ClassStaticsPlugin extends AbstractPlugin { - private static $cache = []; + private static array $cache = []; public function getTypes(): array { diff --git a/src/Parser/DOMDocumentPlugin.php b/src/Parser/DOMDocumentPlugin.php index 45919e22f..83edae14f 100644 --- a/src/Parser/DOMDocumentPlugin.php +++ b/src/Parser/DOMDocumentPlugin.php @@ -65,9 +65,9 @@ class DOMDocumentPlugin extends AbstractPlugin * * In retrospect - this is probably why print_r does the same * - * @var array + * @psalm-var array */ - public static $blacklist = [ + public static array $blacklist = [ 'parentNode' => 'DOMNode', 'firstChild' => 'DOMNode', 'lastChild' => 'DOMNode', @@ -78,10 +78,8 @@ class DOMDocumentPlugin extends AbstractPlugin /** * Show all properties and methods. - * - * @var bool */ - public static $verbose = false; + public static bool $verbose = false; public function getTypes(): array { diff --git a/src/Parser/DateTimePlugin.php b/src/Parser/DateTimePlugin.php index 038acea13..412ce4206 100644 --- a/src/Parser/DateTimePlugin.php +++ b/src/Parser/DateTimePlugin.php @@ -27,7 +27,7 @@ namespace Kint\Parser; -use DateTime; +use DateTimeInterface; use Kint\Zval\DateTimeValue; use Kint\Zval\Value; @@ -45,7 +45,7 @@ public function getTriggers(): int public function parse(&$var, Value &$o, int $trigger): void { - if (!$var instanceof DateTime) { + if (!$var instanceof DateTimeInterface) { return; } diff --git a/src/Parser/EnumPlugin.php b/src/Parser/EnumPlugin.php index d5d348aa5..8c15f6a67 100644 --- a/src/Parser/EnumPlugin.php +++ b/src/Parser/EnumPlugin.php @@ -35,7 +35,7 @@ class EnumPlugin extends AbstractPlugin { - private static $cache = []; + private static array $cache = []; public function getTypes(): array { diff --git a/src/Parser/FsPathPlugin.php b/src/Parser/FsPathPlugin.php index 1a98c6dcd..310c541c8 100644 --- a/src/Parser/FsPathPlugin.php +++ b/src/Parser/FsPathPlugin.php @@ -34,7 +34,7 @@ class FsPathPlugin extends AbstractPlugin { - public static $blacklist = ['/', '.']; + public static array $blacklist = ['/', '.']; public function getTypes(): array { diff --git a/src/Parser/IteratorPlugin.php b/src/Parser/IteratorPlugin.php index 7ebfe73e5..f04973a56 100644 --- a/src/Parser/IteratorPlugin.php +++ b/src/Parser/IteratorPlugin.php @@ -39,10 +39,8 @@ class IteratorPlugin extends AbstractPlugin * Certain classes (Such as PDOStatement) irreversibly lose information * when traversed. Others are just huge. Either way, put them in here * and you won't have to worry about them being parsed. - * - * @var array */ - public static $blacklist = [ + public static array $blacklist = [ 'DOMNamedNodeMap', 'DOMNodeList', 'mysqli_result', diff --git a/src/Parser/MicrotimePlugin.php b/src/Parser/MicrotimePlugin.php index 9531bbe73..e41169117 100644 --- a/src/Parser/MicrotimePlugin.php +++ b/src/Parser/MicrotimePlugin.php @@ -32,10 +32,10 @@ class MicrotimePlugin extends AbstractPlugin { - private static $last = null; - private static $start = null; - private static $times = 0; - private static $group = 0; + private static ?array $last = null; + private static ?float $start = null; + private static int $times = 0; + private static int $group = 0; public function getTypes(): array { diff --git a/src/Parser/MysqliPlugin.php b/src/Parser/MysqliPlugin.php index 22a23a901..882dbc287 100644 --- a/src/Parser/MysqliPlugin.php +++ b/src/Parser/MysqliPlugin.php @@ -41,21 +41,21 @@ class MysqliPlugin extends AbstractPlugin { // These 'properties' are actually globals - protected $always_readable = [ + public const ALWAYS_READABLE = [ 'client_version' => true, 'connect_errno' => true, 'connect_error' => true, ]; // These are readable on empty mysqli objects, but not on failed connections - protected $empty_readable = [ + public const EMPTY_READABLE = [ 'client_info' => true, 'errno' => true, 'error' => true, ]; // These are only readable on connected mysqli objects - protected $connected_readable = [ + public const CONNECTED_READABLE = [ 'affected_rows' => true, 'error_list' => true, 'field_count' => true, @@ -103,17 +103,17 @@ public function parse(&$var, Value &$o, int $trigger): void } foreach ($o->value->contents as $key => $obj) { - if (isset($this->connected_readable[$obj->name])) { + if (isset(self::CONNECTED_READABLE[$obj->name])) { if (!$connected) { // No failed connections after PHP 8.1 continue; // @codeCoverageIgnore } - } elseif (isset($this->empty_readable[$obj->name])) { + } elseif (isset(self::EMPTY_READABLE[$obj->name])) { // No failed connections after PHP 8.1 if (!$connected && !$empty) { // @codeCoverageIgnore continue; // @codeCoverageIgnore } - } elseif (!isset($this->always_readable[$obj->name])) { + } elseif (!isset(self::ALWAYS_READABLE[$obj->name])) { continue; } @@ -158,7 +158,7 @@ public function parse(&$var, Value &$o, int $trigger): void $pname = $prop->getName(); $param = null; - if (isset($this->connected_readable[$pname])) { + if (isset(self::CONNECTED_READABLE[$pname])) { if ($connected) { $param = $var->{$pname}; } diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php index b5409ce92..a54df8167 100644 --- a/src/Parser/Parser.php +++ b/src/Parser/Parser.php @@ -61,12 +61,12 @@ class Parser public const TRIGGER_DEPTH_LIMIT = 8; public const TRIGGER_COMPLETE = 14; - protected $caller_class; - protected $depth_limit = 0; - protected $marker; - protected $object_hashes = []; - protected $parse_break = false; - protected $plugins = []; + protected ?string $caller_class; + protected int $depth_limit = 0; + protected string $marker; + protected array $object_hashes = []; + protected bool $parse_break = false; + protected array $plugins = []; /** * @param int $depth_limit Maximum depth to parse data diff --git a/src/Parser/ProxyPlugin.php b/src/Parser/ProxyPlugin.php index 97050c6b4..7cce5841b 100644 --- a/src/Parser/ProxyPlugin.php +++ b/src/Parser/ProxyPlugin.php @@ -27,25 +27,18 @@ namespace Kint\Parser; -use InvalidArgumentException; use Kint\Zval\Value; class ProxyPlugin implements PluginInterface { - protected $parser; - protected $types; - protected $triggers; + protected Parser $parser; + protected array $types; + protected int $triggers; + /** @psalm-var callable */ protected $callback; - /** - * @param callable $callback - */ - public function __construct(array $types, int $triggers, $callback) + public function __construct(array $types, int $triggers, callable $callback) { - if (!\is_callable($callback)) { - throw new InvalidArgumentException('ProxyPlugin callback must be callable'); - } - $this->types = $types; $this->triggers = $triggers; $this->callback = $callback; diff --git a/src/Parser/SerializePlugin.php b/src/Parser/SerializePlugin.php index 499108784..ecbf5f91c 100644 --- a/src/Parser/SerializePlugin.php +++ b/src/Parser/SerializePlugin.php @@ -43,13 +43,11 @@ class SerializePlugin extends AbstractPlugin * * The natural way to stop that from happening is to just refuse to unserialize * stuff by default. Which is what we're doing for anything that's not scalar. - * - * @var bool */ - public static $safe_mode = true; + public static bool $safe_mode = true; /** - * @var bool|class-string[] + * @psalm-var bool|class-string[] */ public static $allowed_classes = false; diff --git a/src/Parser/SimpleXMLElementPlugin.php b/src/Parser/SimpleXMLElementPlugin.php index 275f4f282..5fb644b64 100644 --- a/src/Parser/SimpleXMLElementPlugin.php +++ b/src/Parser/SimpleXMLElementPlugin.php @@ -37,10 +37,8 @@ class SimpleXMLElementPlugin extends AbstractPlugin { /** * Show all properties and methods. - * - * @var bool */ - public static $verbose = false; + public static bool $verbose = false; public function getTypes(): array { diff --git a/src/Parser/TimestampPlugin.php b/src/Parser/TimestampPlugin.php index 9136ca800..869bd2c70 100644 --- a/src/Parser/TimestampPlugin.php +++ b/src/Parser/TimestampPlugin.php @@ -31,7 +31,7 @@ class TimestampPlugin extends AbstractPlugin { - public static $blacklist = [ + public static array $blacklist = [ 2147483648, 2147483647, 1073741824, diff --git a/src/Parser/ToStringPlugin.php b/src/Parser/ToStringPlugin.php index 478442beb..eac35d398 100644 --- a/src/Parser/ToStringPlugin.php +++ b/src/Parser/ToStringPlugin.php @@ -33,7 +33,7 @@ class ToStringPlugin extends AbstractPlugin { - public static $blacklist = [ + public static array $blacklist = [ 'SimpleXMLElement', 'SplFileObject', ]; diff --git a/src/Parser/TracePlugin.php b/src/Parser/TracePlugin.php index c699e20c9..976a9d9a6 100644 --- a/src/Parser/TracePlugin.php +++ b/src/Parser/TracePlugin.php @@ -34,8 +34,8 @@ class TracePlugin extends AbstractPlugin { - public static $blacklist = ['spl_autoload_call']; - public static $path_blacklist = []; + public static array $blacklist = ['spl_autoload_call']; + public static array $path_blacklist = []; public function getTypes(): array { diff --git a/src/Parser/XmlPlugin.php b/src/Parser/XmlPlugin.php index a17977654..c3d8b99fb 100644 --- a/src/Parser/XmlPlugin.php +++ b/src/Parser/XmlPlugin.php @@ -41,9 +41,9 @@ class XmlPlugin extends AbstractPlugin * however it's memory usage is very high and it takes longer to parse and * render. Plus it's a pain to work with. So SimpleXML is the default. * - * @var string + * @psalm-var 'SimpleXML'|'DOMDocument' */ - public static $parse_method = 'SimpleXML'; + public static string $parse_method = 'SimpleXML'; public function getTypes(): array { diff --git a/src/Renderer/AbstractRenderer.php b/src/Renderer/AbstractRenderer.php index adec8f071..fd29d9647 100644 --- a/src/Renderer/AbstractRenderer.php +++ b/src/Renderer/AbstractRenderer.php @@ -41,9 +41,12 @@ abstract class AbstractRenderer implements RendererInterface public const SORT_VISIBILITY = 1; public const SORT_FULL = 2; - protected $call_info = []; - protected $statics = []; - protected $show_trace = true; + public static ?string $js_nonce = null; + public static ?string $css_nonce = null; + + protected array $call_info = []; + protected array $statics = []; + protected bool $show_trace = true; public function setCallInfo(array $info): void { diff --git a/src/Renderer/CliRenderer.php b/src/Renderer/CliRenderer.php index baba851d3..321198565 100644 --- a/src/Renderer/CliRenderer.php +++ b/src/Renderer/CliRenderer.php @@ -35,46 +35,39 @@ class CliRenderer extends TextRenderer /** * @var bool enable colors */ - public static $cli_colors = true; + public static bool $cli_colors = true; /** * Forces utf8 output on windows. - * - * @var bool */ - public static $force_utf8 = false; + public static bool $force_utf8 = false; /** * Detects the terminal width on startup. - * - * @var bool */ - public static $detect_width = true; + public static bool $detect_width = true; /** * The minimum width to detect terminal size as. * * Less than this is ignored and falls back to default width. - * - * @var int */ - public static $min_terminal_width = 40; + public static int $min_terminal_width = 40; /** * Which stream to check for VT100 support on windows. * * uses STDOUT by default if it's defined * - * @var ?resource + * @psalm-var ?resource */ public static $windows_stream = null; - protected static $terminal_width = null; + protected static ?int $terminal_width = null; - /** @var bool */ - protected $windows_output = false; + protected bool $windows_output = false; - protected $colors = false; + protected bool $colors = false; public function __construct() { diff --git a/src/Renderer/PlainRenderer.php b/src/Renderer/PlainRenderer.php index 7210f55f3..102555dde 100644 --- a/src/Renderer/PlainRenderer.php +++ b/src/Renderer/PlainRenderer.php @@ -33,7 +33,7 @@ class PlainRenderer extends TextRenderer { - public static $pre_render_sources = [ + public static array $pre_render_sources = [ 'script' => [ ['Kint\\Renderer\\PlainRenderer', 'renderJs'], ['Kint\\Renderer\\Text\\MicrotimePlugin', 'renderJs'], @@ -46,23 +46,19 @@ class PlainRenderer extends TextRenderer /** * Path to the CSS file to load by default. - * - * @var string */ - public static $theme = 'plain.css'; + public static string $theme = 'plain.css'; /** * Output htmlentities instead of utf8. - * - * @var bool */ - public static $disable_utf8 = false; + public static bool $disable_utf8 = false; - public static $needs_pre_render = true; + public static bool $needs_pre_render = true; - public static $always_pre_render = false; + public static bool $always_pre_render = false; - protected $force_pre_render = false; + protected bool $force_pre_render = false; public function __construct() { diff --git a/src/Renderer/Rich/AbstractPlugin.php b/src/Renderer/Rich/AbstractPlugin.php index 082976c74..c0cf61d16 100644 --- a/src/Renderer/Rich/AbstractPlugin.php +++ b/src/Renderer/Rich/AbstractPlugin.php @@ -36,7 +36,7 @@ */ abstract class AbstractPlugin implements PluginInterface { - protected $renderer; + protected RichRenderer $renderer; public function __construct(RichRenderer $r) { diff --git a/src/Renderer/Rich/BinaryPlugin.php b/src/Renderer/Rich/BinaryPlugin.php index 4cbce1ae2..811f4ac87 100644 --- a/src/Renderer/Rich/BinaryPlugin.php +++ b/src/Renderer/Rich/BinaryPlugin.php @@ -32,9 +32,9 @@ class BinaryPlugin extends AbstractPlugin implements TabPluginInterface { /** @psalm-var positive-int */ - public static $line_length = 0x10; + public static int $line_length = 0x10; /** @psalm-var positive-int */ - public static $chunk_length = 0x4; + public static int $chunk_length = 0x4; public function renderTab(Representation $r): ?string { diff --git a/src/Renderer/Rich/CallablePlugin.php b/src/Renderer/Rich/CallablePlugin.php index 8ca45399b..03341d4c8 100644 --- a/src/Renderer/Rich/CallablePlugin.php +++ b/src/Renderer/Rich/CallablePlugin.php @@ -35,9 +35,7 @@ class CallablePlugin extends ClosurePlugin { - protected static $method_cache = []; - - protected $closure_plugin = null; + protected static array $method_cache = []; public function renderValue(Value $o): ?string { diff --git a/src/Renderer/Rich/TablePlugin.php b/src/Renderer/Rich/TablePlugin.php index 653342aa1..2b32a30fa 100644 --- a/src/Renderer/Rich/TablePlugin.php +++ b/src/Renderer/Rich/TablePlugin.php @@ -33,7 +33,7 @@ class TablePlugin extends AbstractPlugin implements TabPluginInterface { - public static $respect_str_length = true; + public static bool $respect_str_length = true; public function renderTab(Representation $r): ?string { diff --git a/src/Renderer/RichRenderer.php b/src/Renderer/RichRenderer.php index fa2cda7b9..cc3dd1af8 100644 --- a/src/Renderer/RichRenderer.php +++ b/src/Renderer/RichRenderer.php @@ -48,7 +48,7 @@ class RichRenderer extends AbstractRenderer * * @psalm-var PluginMap */ - public static $value_plugins = [ + public static array $value_plugins = [ 'array_limit' => Rich\ArrayLimitPlugin::class, 'blacklist' => Rich\BlacklistPlugin::class, 'callable' => Rich\CallablePlugin::class, @@ -64,7 +64,7 @@ class RichRenderer extends AbstractRenderer * * @psalm-var PluginMap */ - public static $tab_plugins = [ + public static array $tab_plugins = [ 'binary' => Rich\BinaryPlugin::class, 'color' => Rich\ColorPlugin::class, 'method_definition' => Rich\MethodDefinitionPlugin::class, @@ -74,7 +74,7 @@ class RichRenderer extends AbstractRenderer 'timestamp' => Rich\TimestampPlugin::class, ]; - public static $pre_render_sources = [ + public static array $pre_render_sources = [ 'script' => [ [self::class, 'renderJs'], [Rich\MicrotimePlugin::class, 'renderJs'], @@ -95,70 +95,55 @@ class RichRenderer extends AbstractRenderer * If this is an unacceptably large amount and your browser is groaning * under the weight of the access paths - your first order of buisiness * should be to get a new browser. Failing that, use this to turn them off. - * - * @var bool */ - public static $access_paths = true; + public static bool $access_paths = true; /** * The maximum length of a string before it is truncated. * * Falsey to disable - * - * @var int */ - public static $strlen_max = 80; + public static int $strlen_max = 80; /** * Path to the CSS file to load by default. - * - * @var string */ - public static $theme = 'original.css'; + public static string $theme = 'original.css'; /** * Assume types and sizes don't need to be escaped. * * Turn this off if you use anything but ascii in your class names, * but it'll cause a slowdown of around 10% - * - * @var bool */ - public static $escape_types = false; + public static bool $escape_types = false; /** * Move all dumps to a folder at the bottom of the body. - * - * @var bool */ - public static $folder = false; + public static bool $folder = false; /** * Sort mode for object properties. - * - * @var int */ - public static $sort = self::SORT_NONE; + public static int $sort = self::SORT_NONE; /** * Timestamp to print in footer in date() format. * * @var ?string */ - public static $timestamp = null; - - public static $needs_pre_render = true; - public static $needs_folder_render = true; + public static ?string $timestamp = null; - public static $always_pre_render = false; + public static bool $needs_pre_render = true; + public static bool $needs_folder_render = true; - public static $js_nonce = null; - public static $css_nonce = null; + public static bool $always_pre_render = false; - protected $plugin_objs = []; - protected $expand = false; - protected $force_pre_render = false; - protected $use_folder = false; + protected array $plugin_objs = []; + protected bool $expand = false; + protected bool $force_pre_render = false; + protected bool $use_folder = false; public function __construct() { @@ -320,8 +305,8 @@ public function renderHeader(Value $o): string $output .= ''.$s.''; - if ($o instanceof InstanceValue && isset($o->spl_object_id)) { - $output .= '#'.((int) $o->spl_object_id); + if ($o instanceof InstanceValue) { + $output .= '#'.$o->spl_object_id; } $output .= ' '; diff --git a/src/Renderer/Text/AbstractPlugin.php b/src/Renderer/Text/AbstractPlugin.php index 4d3c7e2a9..f31b0d27a 100644 --- a/src/Renderer/Text/AbstractPlugin.php +++ b/src/Renderer/Text/AbstractPlugin.php @@ -35,7 +35,7 @@ */ abstract class AbstractPlugin implements PluginInterface { - protected $renderer; + protected TextRenderer $renderer; public function __construct(TextRenderer $r) { diff --git a/src/Renderer/Text/MicrotimePlugin.php b/src/Renderer/Text/MicrotimePlugin.php index 13bba75ba..9d53d679d 100644 --- a/src/Renderer/Text/MicrotimePlugin.php +++ b/src/Renderer/Text/MicrotimePlugin.php @@ -36,7 +36,7 @@ class MicrotimePlugin extends AbstractPlugin { - protected $useJs = false; + protected bool $useJs = false; public function __construct(TextRenderer $r) { diff --git a/src/Renderer/Text/TracePlugin.php b/src/Renderer/Text/TracePlugin.php index 113dc9821..b9679e7af 100644 --- a/src/Renderer/Text/TracePlugin.php +++ b/src/Renderer/Text/TracePlugin.php @@ -28,6 +28,9 @@ namespace Kint\Renderer\Text; use Kint\Zval\MethodValue; +use Kint\Zval\Representation\SourceRepresentation; +use Kint\Zval\TraceFrameValue; +use Kint\Zval\TraceValue; use Kint\Zval\Value; class TracePlugin extends AbstractPlugin @@ -42,9 +45,14 @@ public function render(Value $o): string $out .= $this->renderer->renderHeader($o).':'.PHP_EOL; + if (!$o instanceof TraceValue || !isset($o->value->contents) || !\is_array($o->value->contents)) { + return $out; + } + $indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width); $i = 1; + /** @psalm-var TraceFrameValue[] $o->value->contents */ foreach ($o->value->contents as $frame) { $framedesc = $indent.\str_pad($i.': ', 4, ' '); @@ -69,15 +77,15 @@ public function render(Value $o): string if (\is_string($frame->trace['function'])) { $framedesc .= $this->renderer->escape($frame->trace['function']).'(...)'; } elseif ($frame->trace['function'] instanceof MethodValue) { - if (null !== ($s = $frame->trace['function']->getName())) { - $framedesc .= $this->renderer->escape($s); - $framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')'; - } + $framedesc .= $this->renderer->escape($frame->trace['function']->getName()); + $framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')'; } $out .= $this->renderer->colorType($framedesc).PHP_EOL.PHP_EOL; - if ($source = $frame->getRepresentation('source')) { + $source = $frame->getRepresentation('source'); + + if ($source instanceof SourceRepresentation && null !== $source->source) { $line_wanted = $source->line; $source = $source->source; diff --git a/src/Renderer/TextRenderer.php b/src/Renderer/TextRenderer.php index 2538e4da0..fd518ca34 100644 --- a/src/Renderer/TextRenderer.php +++ b/src/Renderer/TextRenderer.php @@ -45,7 +45,7 @@ class TextRenderer extends AbstractRenderer * * @psalm-var PluginMap */ - public static $plugins = [ + public static array $plugins = [ 'array_limit' => Text\ArrayLimitPlugin::class, 'blacklist' => Text\BlacklistPlugin::class, 'depth_limit' => Text\DepthLimitPlugin::class, @@ -61,7 +61,7 @@ class TextRenderer extends AbstractRenderer * * @psalm-var class-string[] */ - public static $parser_plugin_whitelist = [ + public static array $parser_plugin_whitelist = [ Parser\ArrayLimitPlugin::class, Parser\ArrayObjectPlugin::class, Parser\BlacklistPlugin::class, @@ -75,50 +75,40 @@ class TextRenderer extends AbstractRenderer * The maximum length of a string before it is truncated. * * Falsey to disable - * - * @var int */ - public static $strlen_max = 0; + public static int $strlen_max = 0; /** * The default width of the terminal for headers. - * - * @var int */ - public static $default_width = 80; + public static int $default_width = 80; /** * Indentation width. - * - * @var int */ - public static $default_indent = 4; + public static int $default_indent = 4; /** * Decorate the header and footer. - * - * @var bool */ - public static $decorations = true; + public static bool $decorations = true; /** * Sort mode for object properties. - * - * @var int */ - public static $sort = self::SORT_NONE; + public static int $sort = self::SORT_NONE; /** * Timestamp to print in footer in date() format. * * @var ?string */ - public static $timestamp = null; + public static ?string $timestamp = null; - public $header_width = 80; - public $indent_width = 4; + public int $header_width = 80; + public int $indent_width = 4; - protected $plugin_objs = []; + protected array $plugin_objs = []; public function __construct() { @@ -210,8 +200,8 @@ public function renderHeader(Value $o): string $s = $this->colorType($this->escape($s)); - if ($o instanceof InstanceValue && isset($o->spl_object_id)) { - $s .= '#'.((int) $o->spl_object_id); + if ($o instanceof InstanceValue) { + $s .= '#'.$o->spl_object_id; } $output[] = $s; @@ -244,6 +234,8 @@ public function renderChildren(Value $o): string $children = ''; if ($o->value && \is_array($o->value->contents)) { + /** @psalm-suppress PossiblyNullReference + * Psalm bug #11052 */ if ($o instanceof InstanceValue && 'properties' === $o->value->getName()) { foreach (self::sortProperties($o->value->contents, self::$sort) as $obj) { $children .= $this->render($obj); diff --git a/src/Zval/BlobValue.php b/src/Zval/BlobValue.php index 32f267d18..e9a563b36 100644 --- a/src/Zval/BlobValue.php +++ b/src/Zval/BlobValue.php @@ -56,7 +56,7 @@ class BlobValue extends Value * * This depends on the mbstring extension */ - public static $char_encodings = [ + public static array $char_encodings = [ 'ASCII', 'UTF-8', ]; @@ -82,12 +82,12 @@ class BlobValue extends Value * * This depends on the iconv extension */ - public static $legacy_encodings = []; + public static array $legacy_encodings = []; - public $type = 'string'; + public ?string $type = 'string'; /** @psalm-var Encoding */ public $encoding = false; - public $hints = ['string']; + public array $hints = ['string']; public function getType(): ?string { diff --git a/src/Zval/ClosureValue.php b/src/Zval/ClosureValue.php index 69e681842..3d8805883 100644 --- a/src/Zval/ClosureValue.php +++ b/src/Zval/ClosureValue.php @@ -31,7 +31,7 @@ class ClosureValue extends InstanceValue { use ParameterHoldingTrait; - public $hints = ['object', 'callable', 'closure']; + public array $hints = ['object', 'callable', 'closure']; public function getAccessPath(): ?string { @@ -51,7 +51,7 @@ public function transplant(Value $old): void { parent::transplant($old); - if (0 === $this->depth && \preg_match('/^\\((function|fn)\\s*\\(/i', $this->access_path, $match)) { + if (0 === $this->depth && null !== $this->access_path && \preg_match('/^\\((function|fn)\\s*\\(/i', $this->access_path, $match)) { $this->name = \strtolower($match[1]); } } diff --git a/src/Zval/DateTimeValue.php b/src/Zval/DateTimeValue.php index 2ba53d628..907fc7919 100644 --- a/src/Zval/DateTimeValue.php +++ b/src/Zval/DateTimeValue.php @@ -27,15 +27,15 @@ namespace Kint\Zval; -use DateTime; +use DateTimeInterface; class DateTimeValue extends InstanceValue { - public $dt; + public DateTimeInterface $dt; - public $hints = ['object', 'datetime']; + public array $hints = ['object', 'datetime']; - public function __construct(DateTime $dt) + public function __construct(DateTimeInterface $dt) { parent::__construct(); diff --git a/src/Zval/EnumValue.php b/src/Zval/EnumValue.php index e9cfe19ed..49251742b 100644 --- a/src/Zval/EnumValue.php +++ b/src/Zval/EnumValue.php @@ -32,9 +32,9 @@ class EnumValue extends InstanceValue { - public $enumval; + public UnitEnum $enumval; - public $hints = ['object', 'enum']; + public array $hints = ['object', 'enum']; public function __construct(UnitEnum $enumval) { @@ -46,7 +46,7 @@ public function getValueShort(): ?string if ($this->enumval instanceof BackedEnum) { if (\is_string($this->enumval->value)) { return '"'.$this->enumval->value.'"'; - } // Int + } return (string) $this->enumval->value; } @@ -54,17 +54,13 @@ public function getValueShort(): ?string return null; } - public function getType(): ?string + public function getType(): string { - if (isset($this->classname)) { - if (isset($this->enumval->name)) { - return $this->classname.'::'.$this->enumval->name; - } - - return $this->classname; + if (isset($this->enumval->name)) { + return $this->classname.'::'.$this->enumval->name; } - return null; + return $this->classname; } public function getSize(): ?string diff --git a/src/Zval/InstanceValue.php b/src/Zval/InstanceValue.php index 323733474..ccbccce64 100644 --- a/src/Zval/InstanceValue.php +++ b/src/Zval/InstanceValue.php @@ -29,13 +29,13 @@ class InstanceValue extends Value { - public $type = 'object'; - public $classname; - public $spl_object_hash; - public $spl_object_id = null; - public $filename; - public $startline; - public $hints = ['object']; + public ?string $type = 'object'; + public string $classname; + public string $spl_object_hash; + public int $spl_object_id; + public ?string $filename = null; + public ?int $startline = null; + public array $hints = ['object']; public function getType(): ?string { diff --git a/src/Zval/MethodValue.php b/src/Zval/MethodValue.php index e3e0dd10a..704a65287 100644 --- a/src/Zval/MethodValue.php +++ b/src/Zval/MethodValue.php @@ -31,44 +31,68 @@ use Kint\Zval\Representation\MethodDefinitionRepresentation; use ReflectionFunctionAbstract; use ReflectionMethod; +use UnexpectedValueException; class MethodValue extends Value { use ParameterHoldingTrait; - public $type = 'method'; - public $filename; - public $startline; - public $endline; - public $abstract; - public $final; - public $internal; - public $docstring; - public $returntype; - public $return_reference = false; - public $hints = ['callable', 'method']; - public $showparams = true; + public const MAGIC_NAMES = [ + '__construct' => true, + '__destruct' => true, + '__call' => true, + '__callStatic' => true, + '__get' => true, + '__set' => true, + '__isset' => true, + '__unset' => true, + '__sleep' => true, + '__wakeup' => true, + '__serialize' => true, + '__unserialize' => true, + '__toString' => true, + '__invoke' => true, + '__set_state' => true, + '__clone' => true, + '__debugInfo' => true, + ]; + + public ?string $type = 'method'; + public ?string $filename; + public ?int $startline; + public ?int $endline; + public bool $abstract = false; + public bool $final = false; + public bool $internal; + public ?string $docstring; + public ?string $returntype = null; + public bool $return_reference; + public array $hints = ['callable', 'method']; + public bool $showparams = true; public function __construct(ReflectionFunctionAbstract $method) { parent::__construct(); $this->name = $method->getName(); - $this->filename = $method->getFileName(); - $this->startline = $method->getStartLine(); - $this->endline = $method->getEndLine(); + $t = $method->getFileName(); + $this->filename = false === $t ? null : $t; + $t = $method->getStartLine(); + $this->startline = false === $t ? null : $t; + $t = $method->getEndLine(); + $this->endline = false === $t ? null : $t; $this->internal = $method->isInternal(); - $ds = $method->getDocComment(); - $this->docstring = false === $ds ? null : $ds; + $t = $method->getDocComment(); + $this->docstring = false === $t ? null : $t; $this->return_reference = $method->returnsReference(); foreach ($method->getParameters() as $param) { $this->parameters[] = new ParameterValue($param); } - $this->returntype = $method->getReturnType(); - if ($this->returntype) { - $this->returntype = Utils::getTypeString($this->returntype); + $rt = $method->getReturnType(); + if ($rt) { + $this->returntype = Utils::getTypeString($rt); } if ($method instanceof ReflectionMethod) { @@ -103,25 +127,7 @@ public function __construct(ReflectionFunctionAbstract $method) public function setAccessPathFrom(InstanceValue $parent): void { - static $magic = [ - '__call' => true, - '__callstatic' => true, - '__clone' => true, - '__construct' => true, - '__debuginfo' => true, - '__destruct' => true, - '__get' => true, - '__invoke' => true, - '__isset' => true, - '__set' => true, - '__set_state' => true, - '__sleep' => true, - '__tostring' => true, - '__unset' => true, - '__wakeup' => true, - ]; - - $name = \strtolower($this->name); + $name = \strtolower($this->getName()); if ('__construct' === $name) { $this->access_path = 'new \\'.$parent->getType(); @@ -133,7 +139,7 @@ public function setAccessPathFrom(InstanceValue $parent): void } elseif ('__tostring' === $name) { $this->access_path = '(string) '.$parent->access_path; $this->showparams = false; - } elseif (isset($magic[$name])) { + } elseif (isset(self::MAGIC_NAMES[$name])) { $this->access_path = null; } elseif ($this->static) { $this->access_path = '\\'.$this->owner_class.'::'.$this->name; @@ -142,6 +148,15 @@ public function setAccessPathFrom(InstanceValue $parent): void } } + public function getName(): string + { + if (!isset($this->name) || !\is_string($this->name)) { + throw new UnexpectedValueException('MethodValue must have name'); + } + + return $this->name; + } + public function getValueShort(): ?string { if (!$this->value || !($this->value instanceof MethodDefinitionRepresentation)) { @@ -218,7 +233,7 @@ public function getPhpDocUrl(): ?string $class = 'function'; } - $funcname = \str_replace('_', '-', \strtolower($this->name)); + $funcname = \str_replace('_', '-', \strtolower($this->getName())); if (0 === \strpos($funcname, '--') && 0 !== \strpos($funcname, '-', 2)) { $funcname = \substr($funcname, 2); diff --git a/src/Zval/ParameterHoldingTrait.php b/src/Zval/ParameterHoldingTrait.php index c67ecd45c..ef9101d1d 100644 --- a/src/Zval/ParameterHoldingTrait.php +++ b/src/Zval/ParameterHoldingTrait.php @@ -30,9 +30,9 @@ trait ParameterHoldingTrait { /** @var ParameterValue[] */ - public $parameters = []; + public array $parameters = []; - private $paramcache; + private ?string $paramcache = null; public function getParams(): string { diff --git a/src/Zval/ParameterValue.php b/src/Zval/ParameterValue.php index a30f3753a..b97608153 100644 --- a/src/Zval/ParameterValue.php +++ b/src/Zval/ParameterValue.php @@ -32,10 +32,10 @@ class ParameterValue extends Value { - public $type_hint; - public $default; - public $position; - public $hints = ['parameter']; + public ?string $type_hint; + public ?string $default; + public int $position; + public array $hints = ['parameter']; public function __construct(ReflectionParameter $param) { @@ -76,7 +76,6 @@ public function __construct(ReflectionParameter $param) } } - /** @psalm-return ?truthy-string */ public function getType(): ?string { return $this->type_hint; @@ -87,7 +86,6 @@ public function getName(): string return '$'.$this->name; } - /** @psalm-return ?truthy-string */ public function getDefault(): ?string { return $this->default; diff --git a/src/Zval/Representation/ColorRepresentation.php b/src/Zval/Representation/ColorRepresentation.php index 80e419695..09679808b 100644 --- a/src/Zval/Representation/ColorRepresentation.php +++ b/src/Zval/Representation/ColorRepresentation.php @@ -42,7 +42,7 @@ class ColorRepresentation extends Representation public const COLOR_HEX_8 = 9; /** @psalm-var array */ - public static $color_map = [ + public static array $color_map = [ 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'aqua' => '00ffff', @@ -196,13 +196,13 @@ class ColorRepresentation extends Representation 'yellowgreen' => '9acd32', ]; - public $r = 0; - public $g = 0; - public $b = 0; - public $a = 1.0; - public $variant; - public $implicit_label = true; - public $hints = ['color']; + public int $r = 0; + public int $g = 0; + public int $b = 0; + public float $a = 1.0; + public ?int $variant; + public bool $implicit_label = true; + public array $hints = ['color']; public function __construct(string $value) { @@ -341,10 +341,6 @@ protected function setValues(string $value): void $this->variant = null; // @codeCoverageIgnore } else { $this->variant = $variant; - $this->r = (int) $this->r; - $this->g = (int) $this->g; - $this->b = (int) $this->b; - $this->a = (float) $this->a; } } diff --git a/src/Zval/Representation/MethodDefinitionRepresentation.php b/src/Zval/Representation/MethodDefinitionRepresentation.php index bcc5499d7..870e17031 100644 --- a/src/Zval/Representation/MethodDefinitionRepresentation.php +++ b/src/Zval/Representation/MethodDefinitionRepresentation.php @@ -29,11 +29,11 @@ class MethodDefinitionRepresentation extends Representation { - public $file; - public $line; - public $class; - public $inherited = false; - public $hints = ['method_definition']; + public ?string $file; + public ?int $line; + public ?string $class; + public bool $inherited = false; + public array $hints = ['method_definition']; public function __construct(?string $file, ?int $line, ?string $class, ?string $docstring) { diff --git a/src/Zval/Representation/MicrotimeRepresentation.php b/src/Zval/Representation/MicrotimeRepresentation.php index d25539b1c..304c749d6 100644 --- a/src/Zval/Representation/MicrotimeRepresentation.php +++ b/src/Zval/Representation/MicrotimeRepresentation.php @@ -28,21 +28,22 @@ namespace Kint\Zval\Representation; use DateTime; +use DateTimeInterface; class MicrotimeRepresentation extends Representation { - public $seconds; - public $microseconds; - public $group; - public $lap; - public $total; - public $avg; - public $i = 0; - public $mem = 0; - public $mem_real = 0; - public $mem_peak = 0; - public $mem_peak_real = 0; - public $hints = ['microtime']; + public int $seconds; + public int $microseconds; + public int $group; + public ?float $lap; + public ?float $total; + public ?float $avg = null; + public int $i; + public int $mem; + public int $mem_real; + public int $mem_peak; + public int $mem_peak_real; + public array $hints = ['microtime']; public function __construct(int $seconds, int $microseconds, int $group, ?float $lap = null, ?float $total = null, int $i = 0) { @@ -66,7 +67,7 @@ public function __construct(int $seconds, int $microseconds, int $group, ?float $this->mem_peak_real = \memory_get_peak_usage(true); } - public function getDateTime(): ?DateTime + public function getDateTime(): ?DateTimeInterface { return DateTime::createFromFormat('U u', $this->seconds.' '.\str_pad((string) $this->microseconds, 6, '0', STR_PAD_LEFT)) ?: null; } diff --git a/src/Zval/Representation/Representation.php b/src/Zval/Representation/Representation.php index b47a0ef47..0628af26b 100644 --- a/src/Zval/Representation/Representation.php +++ b/src/Zval/Representation/Representation.php @@ -29,14 +29,14 @@ class Representation { - public $label; - public $implicit_label = false; - public $hints = []; + public string $label; + public bool $implicit_label = false; + public array $hints = []; /** @psalm-var null|scalar|\Kint\Zval\Value|\Kint\Zval\Value[] */ public $contents = []; - protected $name; + protected string $name; public function __construct(string $label, ?string $name = null) { diff --git a/src/Zval/Representation/SourceRepresentation.php b/src/Zval/Representation/SourceRepresentation.php index d05bf088d..cce120f85 100644 --- a/src/Zval/Representation/SourceRepresentation.php +++ b/src/Zval/Representation/SourceRepresentation.php @@ -29,11 +29,11 @@ class SourceRepresentation extends Representation { - public $hints = ['source']; - public $source = []; - public $filename; - public $line = 0; - public $showfilename = false; + public array $hints = ['source']; + public ?array $source = []; + public string $filename; + public int $line; + public bool $showfilename = false; public function __construct(string $filename, int $line, int $padding = 7) { @@ -57,7 +57,7 @@ public function __construct(string $filename, int $line, int $padding = 7) * @param int $start_line The first line to display (1 based) * @param null|int $length Amount of lines to show */ - public static function getSource(string $filename, int $start_line = 1, ?int $length = null): ?array + private static function getSource(string $filename, int $start_line = 1, ?int $length = null): ?array { if (!$filename || !\file_exists($filename) || !\is_readable($filename)) { return null; diff --git a/src/Zval/Representation/SplFileInfoRepresentation.php b/src/Zval/Representation/SplFileInfoRepresentation.php index b09aea5fa..356afff6d 100644 --- a/src/Zval/Representation/SplFileInfoRepresentation.php +++ b/src/Zval/Representation/SplFileInfoRepresentation.php @@ -33,25 +33,22 @@ class SplFileInfoRepresentation extends Representation { - public $perms = null; - public $flags; - public $path; - public $realpath = null; - public $linktarget = null; - public $size = null; - /** @var bool */ - public $is_dir = false; - /** @var bool */ - public $is_file = false; - /** @var bool */ - public $is_link = false; - public $owner = null; - public $group = null; - public $ctime = null; - public $mtime = null; - public $typename = 'Unknown file'; - public $typeflag = '-'; - public $hints = ['fspath']; + public int $perms = 0; + public array $flags; + public string $path; + public ?string $realpath = null; + public ?string $linktarget = null; + public ?int $size = null; + public bool $is_dir = false; + public bool $is_file = false; + public bool $is_link = false; + public ?int $owner = null; + public ?int $group = null; + public ?int $ctime = null; + public ?int $mtime = null; + public string $typename = 'Unknown file'; + public string $typeflag = '-'; + public array $hints = ['fspath']; public function __construct(SplFileInfo $fileInfo) { diff --git a/src/Zval/ResourceValue.php b/src/Zval/ResourceValue.php index e50266ac4..3ea7e9901 100644 --- a/src/Zval/ResourceValue.php +++ b/src/Zval/ResourceValue.php @@ -29,7 +29,7 @@ class ResourceValue extends Value { - public $resource_type; + public string $resource_type; public function getType(): string { diff --git a/src/Zval/SimpleXMLElementValue.php b/src/Zval/SimpleXMLElementValue.php index 0f152230e..bd18bf2d5 100644 --- a/src/Zval/SimpleXMLElementValue.php +++ b/src/Zval/SimpleXMLElementValue.php @@ -29,9 +29,9 @@ class SimpleXMLElementValue extends InstanceValue { - public $hints = ['object', 'simplexml_element']; + public array $hints = ['object', 'simplexml_element']; - protected $is_string_value = false; + protected bool $is_string_value = false; public function isStringValue(): bool { diff --git a/src/Zval/StreamValue.php b/src/Zval/StreamValue.php index f0866d735..41b72fde6 100644 --- a/src/Zval/StreamValue.php +++ b/src/Zval/StreamValue.php @@ -31,7 +31,7 @@ class StreamValue extends ResourceValue { - public $stream_meta; + public ?array $stream_meta; public function __construct(?array $meta = null) { diff --git a/src/Zval/ThrowableValue.php b/src/Zval/ThrowableValue.php index f6fcb51c1..6b126f0cf 100644 --- a/src/Zval/ThrowableValue.php +++ b/src/Zval/ThrowableValue.php @@ -31,8 +31,8 @@ class ThrowableValue extends InstanceValue { - public $message; - public $hints = ['object', 'throwable']; + public string $message; + public array $hints = ['object', 'throwable']; public function __construct(Throwable $throw) { diff --git a/src/Zval/TraceFrameValue.php b/src/Zval/TraceFrameValue.php index 70937789b..753f60c7f 100644 --- a/src/Zval/TraceFrameValue.php +++ b/src/Zval/TraceFrameValue.php @@ -35,8 +35,8 @@ class TraceFrameValue extends Value { - public $trace; - public $hints = ['trace_frame']; + public array $trace; + public array $hints = ['trace_frame']; public function __construct(Value $base, array $raw_frame) { @@ -44,7 +44,7 @@ public function __construct(Value $base, array $raw_frame) $this->transplant($base); - if (!isset($this->value)) { + if (!isset($this->value->contents) || !\is_array($this->value->contents)) { throw new InvalidArgumentException('Tried to create TraceFrameValue from Value with no value representation'); } @@ -73,6 +73,7 @@ public function __construct(Value $base, array $raw_frame) $this->trace['object']->operator = Value::OPERATOR_NONE; } if ('args' === $frame_prop->name) { + /** @psalm-var ParameterValue[] $frame_prop->value->contents */ $this->trace['args'] = $frame_prop->value->contents; if ($this->trace['function'] instanceof MethodValue) { @@ -98,6 +99,7 @@ public function __construct(Value $base, array $raw_frame) } if (null !== $this->trace['object']) { + /** @psalm-var InstanceValue $this->trace['object'] */ $callee = new Representation('object'); $callee->label = 'Callee object ['.$this->trace['object']->classname.']'; $callee->contents = [$this->trace['object']]; diff --git a/src/Zval/TraceValue.php b/src/Zval/TraceValue.php index 0136b8915..b8b849497 100644 --- a/src/Zval/TraceValue.php +++ b/src/Zval/TraceValue.php @@ -29,7 +29,7 @@ class TraceValue extends Value { - public $hints = ['trace']; + public array $hints = ['trace']; public function getType(): string { @@ -38,10 +38,10 @@ public function getType(): string public function getSize(): ?string { - if (!$this->size) { - return 'empty'; + if ($this->size > 0) { + return parent::getSize(); } - return parent::getSize(); + return 'empty'; } } diff --git a/src/Zval/Value.php b/src/Zval/Value.php index 4e3bf2279..02e725fff 100644 --- a/src/Zval/Value.php +++ b/src/Zval/Value.php @@ -41,23 +41,24 @@ class Value public const OPERATOR_OBJECT = 2; public const OPERATOR_STATIC = 3; - public $name; - public $type; - public $readonly = false; - public $static = false; - public $const = false; - public $access = self::ACCESS_NONE; - public $owner_class = null; - public $access_path; - public $operator = self::OPERATOR_NONE; - public $reference = false; - public $depth = 0; - public $size; - public $hints = []; - public $value; + /** @psalm-var int|string|null */ + public $name = null; + public ?string $type = null; + public bool $readonly = false; + public bool $static = false; + public bool $const = false; + public ?int $access = self::ACCESS_NONE; + public ?string $owner_class = null; + public ?string $access_path = null; + public ?int $operator = self::OPERATOR_NONE; + public bool $reference = false; + public int $depth = 0; + public ?int $size = null; + public array $hints = []; + public ?Representation $value = null; /** @var Representation[] */ - protected $representations = []; + protected array $representations = []; public function __construct() { @@ -199,10 +200,12 @@ public function getValueShort(): ?string { if ($rep = $this->value) { if ('boolean' === $this->type) { + /** @psalm-var bool $rep->contents */ return $rep->contents ? 'true' : 'false'; } if ('integer' === $this->type || 'double' === $this->type) { + /** @psalm-var int|double $rep->contents */ return (string) $rep->contents; } } @@ -255,6 +258,7 @@ public static function sortByAccess(self $a, self $b): int self::ACCESS_NONE => 4, ]; + /** @psalm-suppress PossiblyNullArrayOffset */ return $sorts[$a->access] - $sorts[$b->access]; } diff --git a/tests/KintTestCase.php b/tests/KintTestCase.php index d81604cdb..e66911aa6 100644 --- a/tests/KintTestCase.php +++ b/tests/KintTestCase.php @@ -37,11 +37,12 @@ use Kint\Renderer\TextRenderer; use Kint\Zval\BlobValue; use Kint\Zval\Representation\ColorRepresentation; +use PHPUnit\Framework\TestCase; /** * @coversNothing */ -class KintTestCase extends ProphecyCompatabilityTestCase +class KintTestCase extends TestCase { protected $kint_statics; protected $rich_statics; diff --git a/tests/Parser/ParserTest.php b/tests/Parser/ParserTest.php index 97bcab6eb..073ea0184 100644 --- a/tests/Parser/ParserTest.php +++ b/tests/Parser/ParserTest.php @@ -823,7 +823,7 @@ public function testPlugins() $o = $p->parse($v, clone $b); - $this->assertObjectNotHasAttribute('testPluginCorrectlyActivated', $o); + $this->assertObjectNotHasProperty('testPluginCorrectlyActivated', $o); $pl = new ProxyPlugin( ['integer'], @@ -836,13 +836,13 @@ function (&$var, &$o) { $o = $p->parse($v, clone $b); - $this->assertObjectHasAttribute('testPluginCorrectlyActivated', $o); + $this->assertObjectHasProperty('testPluginCorrectlyActivated', $o); $p->clearPlugins(); $o = $p->parse($v, clone $b); - $this->assertObjectNotHasAttribute('testPluginCorrectlyActivated', $o); + $this->assertObjectNotHasProperty('testPluginCorrectlyActivated', $o); $pl = new ProxyPlugin( [], @@ -946,7 +946,7 @@ function (&$var, &$o) { $o = $p->parse($v, clone $b); - $this->assertObjectNotHasAttribute('testPluginCorrectlyActivated', $o); + $this->assertObjectNotHasProperty('testPluginCorrectlyActivated', $o); } /** diff --git a/tests/ProphecyCompatabilityTestCase.php b/tests/ProphecyCompatabilityTestCase.php deleted file mode 100644 index 7aef438ec..000000000 --- a/tests/ProphecyCompatabilityTestCase.php +++ /dev/null @@ -1,48 +0,0 @@ -