From 3a0d6fe660d3595e6f0a7bba39b1f99d790f1442 Mon Sep 17 00:00:00 2001 From: Andrea Marco Sartori Date: Wed, 14 Jun 2023 23:59:46 +0200 Subject: [PATCH] Leverage PHP 8.1 features --- src/Decoders/ConfigurableDecoder.php | 2 +- src/Decoders/DecodedValue.php | 30 ++++++------ src/Decoders/JsonDecoder.php | 2 +- src/Decoders/SimdjsonDecoder.php | 2 +- src/Exceptions/DecodingException.php | 2 +- .../IntersectingPointersException.php | 2 +- src/Exceptions/InvalidPointerException.php | 2 +- src/Exceptions/SyntaxException.php | 2 +- src/Exceptions/UnsupportedSourceException.php | 2 +- src/JsonParser.php | 28 +++++------ src/Pointers/Pointer.php | 49 +++---------------- src/Pointers/Pointers.php | 2 +- src/Sources/Source.php | 16 ++---- src/Tokens/Comma.php | 2 +- src/Tokens/CompoundBegin.php | 8 ++- src/Tokens/CompoundEnd.php | 4 +- src/Tokens/Constant.php | 2 +- src/Tokens/Lexer.php | 4 +- src/Tokens/Parser.php | 8 +-- src/Tokens/ScalarString.php | 2 +- src/Tokens/Tokenizer.php | 2 +- src/ValueObjects/State.php | 16 ++---- src/ValueObjects/Tree.php | 8 +-- 23 files changed, 72 insertions(+), 125 deletions(-) diff --git a/src/Decoders/ConfigurableDecoder.php b/src/Decoders/ConfigurableDecoder.php index 43a7e2b..f493501 100644 --- a/src/Decoders/ConfigurableDecoder.php +++ b/src/Decoders/ConfigurableDecoder.php @@ -16,7 +16,7 @@ final class ConfigurableDecoder * * @param Config $config */ - public function __construct(private Config $config) + public function __construct(private readonly Config $config) { } diff --git a/src/Decoders/DecodedValue.php b/src/Decoders/DecodedValue.php index f00fd22..5b11313 100644 --- a/src/Decoders/DecodedValue.php +++ b/src/Decoders/DecodedValue.php @@ -10,21 +10,6 @@ use Throwable; */ final class DecodedValue { - /** - * Instantiate the class. - * - * @param mixed $value - */ - private function __construct( - public bool $succeeded, - public mixed $value = null, - public ?string $error = null, - public ?int $code = null, - public ?Throwable $exception = null, - public ?string $json = null, - ) { - } - /** * Retrieve a successfully decoded value * @@ -47,4 +32,19 @@ final class DecodedValue { return new self(false, null, $e->getMessage(), $e->getCode(), $e, $json); } + + /** + * Instantiate the class. + * + * @param mixed $value + */ + private function __construct( + public readonly bool $succeeded, + public mixed $value = null, + public readonly ?string $error = null, + public readonly ?int $code = null, + public readonly ?Throwable $exception = null, + public readonly ?string $json = null, + ) { + } } diff --git a/src/Decoders/JsonDecoder.php b/src/Decoders/JsonDecoder.php index 641741b..5eb4dfd 100644 --- a/src/Decoders/JsonDecoder.php +++ b/src/Decoders/JsonDecoder.php @@ -14,7 +14,7 @@ final class JsonDecoder extends AbstractDecoder * @param bool $decodesToArray * @param int<1, max> $depth */ - public function __construct(private bool $decodesToArray = true, private int $depth = 512) + public function __construct(private readonly bool $decodesToArray = true, private readonly int $depth = 512) { } diff --git a/src/Decoders/SimdjsonDecoder.php b/src/Decoders/SimdjsonDecoder.php index ecccafe..cda6616 100644 --- a/src/Decoders/SimdjsonDecoder.php +++ b/src/Decoders/SimdjsonDecoder.php @@ -14,7 +14,7 @@ final class SimdjsonDecoder extends AbstractDecoder * @param bool $decodesToArray * @param int $depth */ - public function __construct(private bool $decodesToArray = true, private int $depth = 512) + public function __construct(private readonly bool $decodesToArray = true, private readonly int $depth = 512) { } diff --git a/src/Exceptions/DecodingException.php b/src/Exceptions/DecodingException.php index cb17067..8acbb53 100644 --- a/src/Exceptions/DecodingException.php +++ b/src/Exceptions/DecodingException.php @@ -16,7 +16,7 @@ final class DecodingException extends Exception implements JsonParserException * * @param DecodedValue $decoded */ - public function __construct(public DecodedValue $decoded) + public function __construct(public readonly DecodedValue $decoded) { parent::__construct('Decoding error: ' . $decoded->error, (int) $decoded->code); } diff --git a/src/Exceptions/IntersectingPointersException.php b/src/Exceptions/IntersectingPointersException.php index cca6993..0939eb6 100644 --- a/src/Exceptions/IntersectingPointersException.php +++ b/src/Exceptions/IntersectingPointersException.php @@ -17,7 +17,7 @@ class IntersectingPointersException extends Exception implements JsonParserExcep * @param Pointer $pointer1 * @param Pointer $pointer2 */ - public function __construct(public Pointer $pointer1, public Pointer $pointer2) + public function __construct(public readonly Pointer $pointer1, public readonly Pointer $pointer2) { parent::__construct("The pointers [$pointer1] and [$pointer2] are intersecting"); } diff --git a/src/Exceptions/InvalidPointerException.php b/src/Exceptions/InvalidPointerException.php index c71973e..dcfe7ea 100644 --- a/src/Exceptions/InvalidPointerException.php +++ b/src/Exceptions/InvalidPointerException.php @@ -15,7 +15,7 @@ final class InvalidPointerException extends Exception implements JsonParserExcep * * @param string $pointer */ - public function __construct(public string $pointer) + public function __construct(public readonly string $pointer) { parent::__construct("The string [$pointer] is not a valid JSON pointer"); } diff --git a/src/Exceptions/SyntaxException.php b/src/Exceptions/SyntaxException.php index 111f00a..6b7cca9 100644 --- a/src/Exceptions/SyntaxException.php +++ b/src/Exceptions/SyntaxException.php @@ -22,7 +22,7 @@ final class SyntaxException extends Exception implements JsonParserException * * @param string $value */ - public function __construct(public string $value) + public function __construct(public readonly string $value) { parent::__construct("Syntax error: unexpected '$value'"); } diff --git a/src/Exceptions/UnsupportedSourceException.php b/src/Exceptions/UnsupportedSourceException.php index 5e28be5..72e32ae 100644 --- a/src/Exceptions/UnsupportedSourceException.php +++ b/src/Exceptions/UnsupportedSourceException.php @@ -15,7 +15,7 @@ final class UnsupportedSourceException extends Exception implements JsonParserEx * * @param mixed $source */ - public function __construct(public mixed $source) + public function __construct(public readonly mixed $source) { parent::__construct('Unable to load JSON from the provided source'); } diff --git a/src/JsonParser.php b/src/JsonParser.php index 37bdc2e..6fe0a71 100644 --- a/src/JsonParser.php +++ b/src/JsonParser.php @@ -27,21 +27,32 @@ final class JsonParser implements IteratorAggregate * * @var Config */ - private Config $config; + private readonly Config $config; /** * The lexer. * * @var Lexer */ - private Lexer $lexer; + private readonly Lexer $lexer; /** * The parser. * * @var Parser */ - private Parser $parser; + private readonly Parser $parser; + + /** + * Instantiate the class statically + * + * @param mixed $source + * @return self + */ + public static function parse(mixed $source): self + { + return new self($source); + } /** * Instantiate the class. @@ -55,17 +66,6 @@ final class JsonParser implements IteratorAggregate $this->parser = new Parser($this->lexer->getIterator(), $this->config); } - /** - * Instantiate the class statically - * - * @param mixed $source - * @return self - */ - public static function parse(mixed $source): self - { - return new self($source); - } - /** * Retrieve the lazily iterable JSON * diff --git a/src/Pointers/Pointer.php b/src/Pointers/Pointer.php index 5fc24ef..613b343 100644 --- a/src/Pointers/Pointer.php +++ b/src/Pointers/Pointer.php @@ -22,21 +22,14 @@ final class Pointer implements Stringable * * @var string[] */ - private array $referenceTokens; + public readonly array $referenceTokens; /** * The pointer depth. * * @var int */ - private int $depth; - - /** - * The pointer callback. - * - * @var Closure - */ - private ?Closure $callback; + public readonly int $depth; /** * Whether the pointer was found. @@ -52,11 +45,13 @@ final class Pointer implements Stringable * @param bool $isLazy * @param Closure|null $callback */ - public function __construct(private string $pointer, private bool $isLazy = false, Closure $callback = null) - { + public function __construct( + private readonly string $pointer, + public readonly bool $isLazy = false, + private readonly ?Closure $callback = null, + ) { $this->referenceTokens = $this->toReferenceTokens(); $this->depth = count($this->referenceTokens); - $this->callback = $callback; } /** @@ -76,36 +71,6 @@ final class Pointer implements Stringable return array_slice($referenceTokens, 1); } - /** - * Determine whether the pointer is lazy - * - * @return bool - */ - public function isLazy(): bool - { - return $this->isLazy; - } - - /** - * Retrieve the reference tokens - * - * @return string[] - */ - public function referenceTokens(): array - { - return $this->referenceTokens; - } - - /** - * Retrieve the JSON pointer depth - * - * @return int - */ - public function depth(): int - { - return $this->depth; - } - /** * Call the pointer callback * diff --git a/src/Pointers/Pointers.php b/src/Pointers/Pointers.php index 1f62ff3..3398e92 100644 --- a/src/Pointers/Pointers.php +++ b/src/Pointers/Pointers.php @@ -76,7 +76,7 @@ final class Pointers $originalTree = $tree->original(); foreach ($this->pointers as $pointer) { - if ($pointer->referenceTokens() == $originalTree) { + if ($pointer->referenceTokens == $originalTree) { return $this->matching = $pointer; } diff --git a/src/Sources/Source.php b/src/Sources/Source.php index 55d1802..5590c7b 100644 --- a/src/Sources/Source.php +++ b/src/Sources/Source.php @@ -13,13 +13,6 @@ use Traversable; */ abstract class Source implements IteratorAggregate { - /** - * The configuration. - * - * @var Config - */ - protected Config $config; - /** * The cached size of the JSON source. * @@ -57,14 +50,15 @@ abstract class Source implements IteratorAggregate abstract protected function calculateSize(): ?int; /** - * Enforce the factory method to instantiate the class. + * Instantiate the class. * * @param mixed $source * @param Config|null $config */ - final public function __construct(protected mixed $source, Config $config = null) - { - $this->config = $config ?: new Config(); + final public function __construct( + protected readonly mixed $source, + protected readonly Config $config = new Config(), + ) { } /** diff --git a/src/Tokens/Comma.php b/src/Tokens/Comma.php index 12b092a..57c4181 100644 --- a/src/Tokens/Comma.php +++ b/src/Tokens/Comma.php @@ -18,7 +18,7 @@ final class Comma extends Token */ public function mutateState(State $state): void { - $state->expectsKey = $state->tree()->inObject(); + $state->expectsKey = $state->tree->inObject(); $state->expectedToken = $state->expectsKey ? Tokens::SCALAR_STRING : Tokens::VALUE_ANY; } } diff --git a/src/Tokens/CompoundBegin.php b/src/Tokens/CompoundBegin.php index 35c75f1..fc9c3e1 100644 --- a/src/Tokens/CompoundBegin.php +++ b/src/Tokens/CompoundBegin.php @@ -25,16 +25,14 @@ final class CompoundBegin extends Token */ public function mutateState(State $state): void { - $tree = $state->tree(); - - if ($this->shouldLazyLoad = $this->shouldLazyLoad && $tree->depth() >= 0) { - $state->expectedToken = $tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; + if ($this->shouldLazyLoad = $this->shouldLazyLoad && $state->tree->depth() >= 0) { + $state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; return; } $state->expectsKey = $beginsObject = $this->value == '{'; $state->expectedToken = $beginsObject ? Tokens::AFTER_OBJECT_BEGIN : Tokens::AFTER_ARRAY_BEGIN; - $tree->deepen($beginsObject); + $state->tree->deepen($beginsObject); } /** diff --git a/src/Tokens/CompoundEnd.php b/src/Tokens/CompoundEnd.php index 5152eef..b78044a 100644 --- a/src/Tokens/CompoundEnd.php +++ b/src/Tokens/CompoundEnd.php @@ -18,9 +18,9 @@ final class CompoundEnd extends Token */ public function mutateState(State $state): void { - $state->tree()->emerge(); + $state->tree->emerge(); - $state->expectedToken = $state->tree()->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; + $state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; } /** diff --git a/src/Tokens/Constant.php b/src/Tokens/Constant.php index 97cc119..c365118 100644 --- a/src/Tokens/Constant.php +++ b/src/Tokens/Constant.php @@ -18,7 +18,7 @@ final class Constant extends Token */ public function mutateState(State $state): void { - $state->expectedToken = $state->tree()->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; + $state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; } /** diff --git a/src/Tokens/Lexer.php b/src/Tokens/Lexer.php index 0ac3e90..2ff64bb 100644 --- a/src/Tokens/Lexer.php +++ b/src/Tokens/Lexer.php @@ -25,7 +25,7 @@ final class Lexer implements IteratorAggregate * * @var Progress */ - private Progress $progress; + private readonly Progress $progress; /** * The current position. @@ -39,7 +39,7 @@ final class Lexer implements IteratorAggregate * * @param Source $source */ - public function __construct(private Source $source) + public function __construct(private readonly Source $source) { $this->progress = new Progress(); } diff --git a/src/Tokens/Parser.php b/src/Tokens/Parser.php index ea4a50a..b21a60c 100644 --- a/src/Tokens/Parser.php +++ b/src/Tokens/Parser.php @@ -25,7 +25,7 @@ final class Parser implements IteratorAggregate * * @var ConfigurableDecoder */ - private ConfigurableDecoder $decoder; + private readonly ConfigurableDecoder $decoder; /** * Whether the parser is fast-forwarding. @@ -40,7 +40,7 @@ final class Parser implements IteratorAggregate * @param Generator $tokens * @param Config $config */ - public function __construct(private Generator $tokens, private Config $config) + public function __construct(private readonly Generator $tokens, private readonly Config $config) { $this->decoder = new ConfigurableDecoder($config); } @@ -63,13 +63,13 @@ final class Parser implements IteratorAggregate $state->mutateByToken($token); - if (!$token->endsChunk() || $state->tree()->isDeep()) { + if (!$token->endsChunk() || $state->tree->isDeep()) { continue; } if ($state->hasBuffer()) { /** @var string|int $key */ - $key = $this->decoder->decode($state->key()); + $key = $this->decoder->decode($state->tree->currentKey()); $value = $this->decoder->decode($state->value()); yield $key => $state->callPointer($value, $key); diff --git a/src/Tokens/ScalarString.php b/src/Tokens/ScalarString.php index f811b3b..5e27d5c 100644 --- a/src/Tokens/ScalarString.php +++ b/src/Tokens/ScalarString.php @@ -31,7 +31,7 @@ final class ScalarString extends Token return; } - $state->expectedToken = $state->tree()->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; + $state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE; } /** diff --git a/src/Tokens/Tokenizer.php b/src/Tokens/Tokenizer.php index 6a85e42..94394b4 100644 --- a/src/Tokens/Tokenizer.php +++ b/src/Tokens/Tokenizer.php @@ -20,7 +20,7 @@ final class Tokenizer * * @var array */ - private array $tokensMap; + private array $tokensMap = []; /** * Retrieve the singleton instance diff --git a/src/ValueObjects/State.php b/src/ValueObjects/State.php index c1ef011..b4bd7b7 100644 --- a/src/ValueObjects/State.php +++ b/src/ValueObjects/State.php @@ -20,7 +20,7 @@ final class State * * @var Tree */ - private Tree $tree; + public readonly Tree $tree; /** * The JSON buffer. @@ -49,7 +49,7 @@ final class State * @param Pointers $pointers * @param Closure $lazyLoad */ - public function __construct(private Pointers $pointers, private Closure $lazyLoad) + public function __construct(private readonly Pointers $pointers, private readonly Closure $lazyLoad) { $this->tree = new Tree($pointers); } @@ -64,16 +64,6 @@ final class State return $this->tree; } - /** - * Retrieve the current key of the JSON tree - * - * @return string|int - */ - public function key(): string|int - { - return $this->tree->currentKey(); - } - /** * Determine whether the parser can stop parsing * @@ -109,7 +99,7 @@ final class State if ($this->tree->isMatched() && ((!$this->expectsKey && $token->isValue()) || $this->tree->isDeep())) { $pointer = $this->pointers->markAsFound(); - if ($token instanceof CompoundBegin && $pointer->isLazy()) { + if ($token instanceof CompoundBegin && $pointer->isLazy) { $this->buffer = ($this->lazyLoad)(); $token->shouldLazyLoad = true; } else { diff --git a/src/ValueObjects/Tree.php b/src/ValueObjects/Tree.php index 91cbe39..8430d6a 100644 --- a/src/ValueObjects/Tree.php +++ b/src/ValueObjects/Tree.php @@ -46,7 +46,7 @@ final class Tree * * @param Pointers $pointers */ - public function __construct(private Pointers $pointers) + public function __construct(private readonly Pointers $pointers) { } @@ -121,7 +121,7 @@ final class Tree { $pointer = $this->pointers->matching(); - return $pointer == '' ? $this->depth > 0 : $this->depth >= $pointer->depth(); + return $pointer == '' ? $this->depth > 0 : $this->depth >= $pointer->depth; } /** @@ -135,7 +135,7 @@ final class Tree { $pointer = $this->pointers->matching(); - if ($pointer != '' && $this->depth >= $pointer->depth()) { + if ($pointer != '' && $this->depth >= $pointer->depth) { return; } elseif ($expectsKey) { $this->traverseKey($token); @@ -191,7 +191,7 @@ final class Tree array_splice($this->inObjectByDepth, $offset); } - $referenceTokens = $this->pointers->matchTree($this)->referenceTokens(); + $referenceTokens = $this->pointers->matchTree($this)->referenceTokens; $this->wildcarded[$this->depth] = ($referenceTokens[$this->depth] ?? null) == '-' ? '-' : $index; if (count($this->wildcarded) > $offset) {