From 1faec743e65ed7d8bb08990c051385f44d191931 Mon Sep 17 00:00:00 2001 From: Exanlv <51094537+Exanlv@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:20:35 +0200 Subject: [PATCH] Array cache reflection in mapper (#94) * Array cache reflection in mapper * Fix namespaces --- src/Mapping/Mapper.php | 50 +++++++++++++++---- tests/Gateway/ConnectionTest.php | 6 ++- tests/Gateway/Handlers/ReadyEventTest.php | 8 +-- tests/Rest/GlobalCommandTest.php | 2 +- tests/Rest/GuildCommandTest.php | 2 +- tests/Rest/GuildStickerTest.php | 1 - .../Helpers/Command/CommandBuilderTest.php | 2 +- .../Command/CommandOptionBuilderTest.php | 2 +- tests/Rest/Helpers/GetNewTest.php | 2 +- tests/Rest/WebhookTest.php | 2 +- 10 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/Mapping/Mapper.php b/src/Mapping/Mapper.php index 87996c59..b28f8be6 100644 --- a/src/Mapping/Mapper.php +++ b/src/Mapping/Mapper.php @@ -14,6 +14,21 @@ class Mapper { + /** + * @var ReflectionClass[] + */ + private array $reflectionClasses = []; + + /** + * @var ReflectionProperty[] + */ + private array $reflectionProperties = []; + + /** + * @var (ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null)[] + */ + private array $reflectionTypes = []; + public function map(mixed $source, string $definition): CompletedMapping { if (is_object($source)) { @@ -34,7 +49,6 @@ public function map(mixed $source, string $definition): CompletedMapping private function mapFromObject(mixed $source, string $definition): CompletedMapping { - $reflection = new ReflectionClass($definition); $instance = new $definition(); $errors = []; @@ -44,7 +58,8 @@ private function mapFromObject(mixed $source, string $definition): CompletedMapp try { $this->setProperty( $value, - $reflection->getProperty($key), + $this->getReflectionProperty($definition, $key), + $this->getReflectionType($definition, $key), $instance, $errors ); @@ -59,15 +74,14 @@ private function mapFromObject(mixed $source, string $definition): CompletedMapp private function setProperty( mixed $value, ReflectionProperty $reflectionProperty, + ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $reflectionType, mixed &$instance, array &$errors, ): void { - $type = $reflectionProperty->getType(); - /** * Typing should match for Union Types & non-set types */ - if ($type instanceof ReflectionUnionType || is_null($type)) { + if ($reflectionType instanceof ReflectionUnionType || is_null($reflectionType)) { $this->setFlat($reflectionProperty, $instance, $value, $errors); return; } @@ -76,7 +90,7 @@ private function setProperty( * IntersecionType is not used * e.g. TypeA&TypeB */ - if ($type instanceof ReflectionIntersectionType) { + if ($reflectionType instanceof ReflectionIntersectionType) { $errors[] = new MappingException('Unsupported typing', $reflectionProperty->getName(), get_class($instance)); return; } @@ -84,12 +98,12 @@ private function setProperty( /** * Scalar types */ - if (($type instanceof ReflectionNamedType && $type->isBuiltin())) { - $this->setNamedType($reflectionProperty, $type, $instance, $value, $errors); + if (($reflectionType instanceof ReflectionNamedType && $reflectionType->isBuiltin())) { + $this->setNamedType($reflectionProperty, $reflectionType, $instance, $value, $errors); return; } - $typeName = $type->getName(); + $typeName = $reflectionType->getName(); if (enum_exists($typeName)) { $this->setEnum($reflectionProperty, $instance, $value, $typeName, $errors); @@ -240,4 +254,22 @@ private function mapEnumArray(array $values, ArrayMapping $arrayMapping, array & return $new; } + + private function getReflectionProperty(string $definition, string $key): ReflectionProperty + { + if (isset($this->reflectionProperties[$definition][$key])) { + return $this->reflectionProperties[$definition][$key]; + } + + $reflectionClass = $this->reflectionClasses[$definition] + ?? $this->reflectionClasses[$definition] = new ReflectionClass($definition); + + return $this->reflectionProperties[$definition][$key] = $reflectionClass->getProperty($key); + } + + private function getReflectionType(string $definition, string $key): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + { + return $this->reflectionTypes[$definition][$key] + ?? $this->reflectionTypes[$definition][$key] = $this->getReflectionProperty($definition, $key)->getType(); + } } diff --git a/tests/Gateway/ConnectionTest.php b/tests/Gateway/ConnectionTest.php index 517d5782..823c31e5 100644 --- a/tests/Gateway/ConnectionTest.php +++ b/tests/Gateway/ConnectionTest.php @@ -2,23 +2,25 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Gateway; use Exan\Eventer\Eventer; use Fakes\Ragnarok\Fenrir\PromiseFake; use Mockery; use Mockery\Adapter\Phpunit\MockeryTestCase; -use Mockery\Mock; use Mockery\MockInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Ragnarok\Fenrir\Bitwise\Bitwise; use Ragnarok\Fenrir\Constants\MetaEvents; use Ragnarok\Fenrir\Constants\WebsocketEvents; +use Ragnarok\Fenrir\DataMapper; +use Ragnarok\Fenrir\EventHandler; use Ragnarok\Fenrir\Gateway\Connection; use Ragnarok\Fenrir\Gateway\Helpers\PresenceUpdateBuilder; use Ragnarok\Fenrir\Gateway\Objects\Payload; use Ragnarok\Fenrir\Gateway\Shard; +use Ragnarok\Fenrir\Websocket; use Ratchet\RFC6455\Messaging\MessageInterface; use React\EventLoop\LoopInterface; use React\EventLoop\TimerInterface; diff --git a/tests/Gateway/Handlers/ReadyEventTest.php b/tests/Gateway/Handlers/ReadyEventTest.php index 977d84a3..d41bafcc 100644 --- a/tests/Gateway/Handlers/ReadyEventTest.php +++ b/tests/Gateway/Handlers/ReadyEventTest.php @@ -104,7 +104,7 @@ public static function payloadProvider(): array 'session_id' => '::session id::', ] ], - 'expectation' => true, + 'shouldSet' => true, ], 'No resume url' => [ @@ -114,7 +114,7 @@ public static function payloadProvider(): array 'session_id' => '::session id::', ] ], - 'expectation' => false, + 'shouldSet' => false, ], 'No session id' => [ @@ -124,14 +124,14 @@ public static function payloadProvider(): array 'resume_gateway_url' => '::resume gateway url::', ] ], - 'expectation' => false, + 'shouldSet' => false, ], 'No d' => [ 'payload' => (object) [ 't' => Events::READY, ], - 'expectation' => false, + 'shouldSet' => false, ], ]; } diff --git a/tests/Rest/GlobalCommandTest.php b/tests/Rest/GlobalCommandTest.php index 4db3ad9c..490f1d65 100644 --- a/tests/Rest/GlobalCommandTest.php +++ b/tests/Rest/GlobalCommandTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Rest; use Ragnarok\Fenrir\Parts\ApplicationCommand; use Ragnarok\Fenrir\Rest\GlobalCommand; diff --git a/tests/Rest/GuildCommandTest.php b/tests/Rest/GuildCommandTest.php index 5998943a..66cf182f 100644 --- a/tests/Rest/GuildCommandTest.php +++ b/tests/Rest/GuildCommandTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Rest; use Ragnarok\Fenrir\Parts\ApplicationCommand; use Ragnarok\Fenrir\Rest\GuildCommand; diff --git a/tests/Rest/GuildStickerTest.php b/tests/Rest/GuildStickerTest.php index 1c310791..f938b8fd 100644 --- a/tests/Rest/GuildStickerTest.php +++ b/tests/Rest/GuildStickerTest.php @@ -4,7 +4,6 @@ namespace Tests\Ragnarok\Fenrir\Rest; -use Ragnarok\Fenrir\Parts\StickerPack; use Ragnarok\Fenrir\Parts\Sticker; use Ragnarok\Fenrir\Rest\GuildSticker; use Ragnarok\Fenrir\Rest\Helpers\GuildSticker\ModifyStickerBuilder; diff --git a/tests/Rest/Helpers/Command/CommandBuilderTest.php b/tests/Rest/Helpers/Command/CommandBuilderTest.php index 03539af6..608beae8 100644 --- a/tests/Rest/Helpers/Command/CommandBuilderTest.php +++ b/tests/Rest/Helpers/Command/CommandBuilderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Rest\Helpers\Command; use PHPUnit\Framework\TestCase; use Ragnarok\Fenrir\Bitwise\Bitwise; diff --git a/tests/Rest/Helpers/Command/CommandOptionBuilderTest.php b/tests/Rest/Helpers/Command/CommandOptionBuilderTest.php index 43122560..e5d3d871 100644 --- a/tests/Rest/Helpers/Command/CommandOptionBuilderTest.php +++ b/tests/Rest/Helpers/Command/CommandOptionBuilderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Rest\Helpers\Command; use Mockery; use PHPUnit\Framework\TestCase; diff --git a/tests/Rest/Helpers/GetNewTest.php b/tests/Rest/Helpers/GetNewTest.php index ac21e553..a56048f3 100644 --- a/tests/Rest/Helpers/GetNewTest.php +++ b/tests/Rest/Helpers/GetNewTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Rest\Helpers; use Ragnarok\Fenrir\Rest\Helpers\GetNew; use PHPUnit\Framework\TestCase; diff --git a/tests/Rest/WebhookTest.php b/tests/Rest/WebhookTest.php index a15bff22..405b1099 100644 --- a/tests/Rest/WebhookTest.php +++ b/tests/Rest/WebhookTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Ragnarok\Fenrir; +namespace Tests\Ragnarok\Fenrir\Rest; use Ragnarok\Fenrir\Enums\InteractionCallbackType; use Ragnarok\Fenrir\Interaction\Helpers\InteractionCallbackBuilder;