Skip to content

Commit

Permalink
Reflection works
Browse files Browse the repository at this point in the history
  • Loading branch information
patrykbaszak committed Aug 16, 2024
1 parent 65cf773 commit ee1df74
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 13 deletions.
31 changes: 28 additions & 3 deletions src/Reflection/Domain/Entities/ClassReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public static function create(
throw new ReflectionException("Cannot create instance of $name class.", "Please do not use `ClassReflection::create` method to create instance of $name class.", 1);
}

if ($root->hasClassReflection($name)) {
return $root->classReflections($name);
}

try {
$reflection = new \ReflectionClass($name);
} catch (\ReflectionException $e) {
Expand All @@ -78,15 +82,36 @@ public static function create(

if (true === $result = $root->addClassReflection($instance)) {
foreach ($reflection->getAttributes() as $attribute) {
AttributeReflection::create($attribute, $instance);
$instance->addAttribute(
AttributeReflection::create($attribute, $instance)
);
}

foreach ($reflection->getProperties() as $property) {
PropertyReflection::create($property, $instance, $parentProperty);
$instance->addProperty(
$property = PropertyReflection::create($property, $instance, $parentProperty)
);
$classes = $property->type()->getListOfClasses();
foreach ($classes as $class) {
ClassReflection::create($class, $root, $property);
}
}

foreach ($reflection->getMethods() as $method) {
MethodReflection::create($method, $instance);
$instance->addMethod(
$method = MethodReflection::create($method, $instance)
);
$classes = $method->returnType()->getListOfClasses();
foreach ($classes as $class) {
ClassReflection::create($class, $root);
}

foreach ($method->parameters() as $parameter) {
$classes = $parameter->type()->getListOfClasses();
foreach ($classes as $class) {
ClassReflection::create($class, $root);
}
}
}

return $instance;
Expand Down
6 changes: 3 additions & 3 deletions src/Reflection/Domain/Entities/PropertyReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class PropertyReflection extends Entity implements Normalizable, Attribute
use Attributes;

private ClassReflection $parent;
private PropertyReflection $parentProperty;
private ?PropertyReflection $parentProperty;

private function __construct(
private ReflectionId $id,
Expand All @@ -30,7 +30,7 @@ private function __construct(
$this->attributes = $attributes;
}

public static function create(\ReflectionProperty $reflectionProperty, ClassReflection $parent, ?\ReflectionProperty $parentProperty): static
public static function create(\ReflectionProperty $reflectionProperty, ClassReflection $parent, ?PropertyReflection $parentProperty): static
{
$instance = new static(
id: ReflectionId::uuid(),
Expand Down Expand Up @@ -88,7 +88,7 @@ public function parent(?ClassReflection $parent = null): ClassReflection
throw new \InvalidArgumentException('Cannot set parent property. Parent property is read-only.');
}

public function parentProperty(?PropertyReflection $parentProperty = null): PropertyReflection
public function parentProperty(?PropertyReflection $parentProperty = null): ?PropertyReflection
{
if (!$parentProperty) {
return $this->parentProperty;
Expand Down
12 changes: 12 additions & 0 deletions src/Reflection/Domain/Entities/Type/CollectionTypeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ public function allowsNull(): bool
return false;
}

public function getListOfClasses(): array
{
$types = [$this->collectionType, $this->keyType, $this->valueType];

$classes = [];
foreach ($types as $type) {
$classes = array_merge($classes, $type->getListOfClasses());
}

return array_unique($classes);
}

public function normalize(): array
{
return [
Expand Down
10 changes: 10 additions & 0 deletions src/Reflection/Domain/Entities/Type/IntersectionTypeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ public function normalize(): array
];
}

public function getListOfClasses(): array
{
$classes = [];
foreach ($this->types as $type) {
$classes = array_merge($classes, $type->getListOfClasses());
}

return array_unique($classes);
}

public static function denormalize(array $data): static
{
return static::recreate(
Expand Down
9 changes: 9 additions & 0 deletions src/Reflection/Domain/Entities/Type/NamedTypeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ public function allowsNull(): bool
return 'null' === $this->name || 'mixed' === $this->name;
}

public function getListOfClasses(): array
{
if ($this->isClass() && !$this->isAbstractClass()) {
return [$this->name];
}

return [];
}

public function normalize(): array
{
return [
Expand Down
3 changes: 3 additions & 0 deletions src/Reflection/Domain/Entities/Type/TypeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@
abstract class TypeReflection implements Normalizable
{
abstract public function allowsNull(): bool;

/** @return class-string[] */
abstract public function getListOfClasses(): array;
}
10 changes: 10 additions & 0 deletions src/Reflection/Domain/Entities/Type/UnionTypeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ public function allowsNull(): bool
return false;
}

public function getListOfClasses(): array
{
$classes = [];
foreach ($this->types as $type) {
$classes = array_merge($classes, $type->getListOfClasses());
}

return array_unique($classes);
}

public function normalize(): array
{
return [
Expand Down
10 changes: 10 additions & 0 deletions src/Reflection/Domain/Reflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ public function classReflections(?string $filter = null): array|ClassReflection
return $this->classReflections;
}

/**
* @param class-string|string $className
*
* @return bool Whether the class reflection exists in the collection
*/
public function hasClassReflection(string $className): bool
{
return array_key_exists($className, $this->classReflections);
}

/**
* @return true|ClassReflection If the class reflection already exists in the collection, it returns the existing one.
* Otherwise, it returns true to indicate that the class reflection was successfully added.
Expand Down
27 changes: 27 additions & 0 deletions tests/Unit/Reflection/Domain/ReflectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace PBaszak\UltraMapper\Tests\Unit\Reflection\Domain;

use PBaszak\UltraMapper\Reflection\Domain\Reflection;
use PBaszak\UltraMapper\Tests\Support\Assets\DTO\Dummy;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;

#[Group('unit')]
class ReflectionTest extends TestCase
{
public function testCreate(): void
{
$class = Dummy::class;
$reflection = Reflection::create($class);

self::assertSame($class, $reflection->rootClass());
}

public function testRecreate(): void
{
$this->markTestIncomplete('This test has not been implemented yet.');
}
}
19 changes: 12 additions & 7 deletions tools/phpstan/fpm-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ parameters:
count: 1
path: ../../src/Reflection/Domain/Entities/ClassReflection.php

-
message: "#^Argument of an invalid type array\\<string, PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ParameterReflection\\>\\|PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ParameterReflection supplied for foreach, only iterables are supported\\.$#"
count: 1
path: ../../src/Reflection/Domain/Entities/ClassReflection.php

-
message: "#^Argument of an invalid type array\\<string, PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\PropertyReflection\\>\\|PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\PropertyReflection supplied for foreach, only iterables are supported\\.$#"
count: 1
Expand Down Expand Up @@ -70,6 +75,11 @@ parameters:
count: 1
path: ../../src/Reflection/Domain/Entities/ClassReflection.php

-
message: "#^Method PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ClassReflection\\:\\:create\\(\\) should return PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ClassReflection but returns array\\<string, PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ClassReflection\\>\\|PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ClassReflection\\.$#"
count: 1
path: ../../src/Reflection/Domain/Entities/ClassReflection.php

-
message: "#^Method PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\ClassReflection\\:\\:denormalizeAttributes\\(\\) has parameter \\$attributes with no value type specified in iterable type array\\.$#"
count: 1
Expand Down Expand Up @@ -120,11 +130,6 @@ parameters:
count: 2
path: ../../src/Reflection/Domain/Entities/ClassReflection.php

-
message: "#^Parameter \\#3 \\$parentProperty of static method PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\PropertyReflection\\:\\:create\\(\\) expects ReflectionProperty\\|null, PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\PropertyReflection\\|null given\\.$#"
count: 1
path: ../../src/Reflection/Domain/Entities/ClassReflection.php

-
message: "#^Part \\$id \\(PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Identity\\\\ReflectionId\\) of encapsed string cannot be cast to string\\.$#"
count: 1
Expand Down Expand Up @@ -286,9 +291,9 @@ parameters:
path: ../../src/Reflection/Domain/Entities/PropertyReflection.php

-
message: "#^Property PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\PropertyReflection\\:\\:\\$parentProperty \\(PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\PropertyReflection\\) does not accept ReflectionProperty\\|null\\.$#"
message: "#^Method PBaszak\\\\UltraMapper\\\\Reflection\\\\Domain\\\\Entities\\\\Type\\\\NamedTypeReflection\\:\\:getListOfClasses\\(\\) should return array\\<class\\-string\\> but returns array\\<int, string\\>\\.$#"
count: 1
path: ../../src/Reflection/Domain/Entities/PropertyReflection.php
path: ../../src/Reflection/Domain/Entities/Type/NamedTypeReflection.php

-
message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\<T of object\\>\\|T of object, string given\\.$#"
Expand Down

0 comments on commit ee1df74

Please sign in to comment.