Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
patrykbaszak committed Oct 19, 2023
1 parent c4049ac commit b2243b3
Show file tree
Hide file tree
Showing 9 changed files with 1,364 additions and 115 deletions.
1,262 changes: 1,252 additions & 10 deletions output.yaml

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace PBaszak\DedicatedMapper;

use LogicException;
use PBaszak\DedicatedMapper\Reflection\ClassReflection;
use PBaszak\DedicatedMapper\Reflection\ReflectionFactory;
use PBaszak\DedicatedMapper\Reflection\Type\ClassType;
use PBaszak\DedicatedMapper\Reflection\Type\TypeFactory;
Expand All @@ -32,10 +31,7 @@ public function __construct(protected string $className)
public function reflect(): self
{
ClassType::$classTypes = [];
$type = (new TypeFactory(new ReflectionFactory()))->createFromReflection(
new \ReflectionClass($this->className)
);
ClassType::create($type);
(new TypeFactory())->createFromString($this->className);
$this->classes = ClassType::$classTypes;

return $this;
Expand Down
2 changes: 1 addition & 1 deletion src/Reflection/Type/ClassType.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static function supports(Type $type): bool
return count($classTypes) === 1;
}

public static function create(Type $type): self
public static function create(Type $type): static
{
if (!self::supports($type)) {
throw new LogicException('Given Type does not support class type.');
Expand Down
37 changes: 2 additions & 35 deletions src/Reflection/Type/CollectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@

namespace PBaszak\DedicatedMapper\Reflection\Type;

use ArrayObject;
use PBaszak\DedicatedMapper\Reflection\AttributeReflection;
use PBaszak\DedicatedMapper\Reflection\PropertyReflection;
use PBaszak\DedicatedMapper\Utils\ToArrayTrait;

class CollectionType implements TypeInterface
{
public function toArray(): array
{
return [
'attributes' => $this->attributes->toArray(),
'classType' => self::class,
'type' => $this->type->toArray(),
];
Expand All @@ -25,51 +19,24 @@ public static function supports(Type $type): bool
return $type->isCollection();
}

public static function create(Type $type): TypeInterface
public static function create(Type $type): static
{

return new self($type);
}

public function __construct(
/**
* @var null|PropertyReflection|TypeInterface $parent
* collection can be nested in another collection, if `null` then it is root collection
*/
protected null|PropertyReflection|TypeInterface $parent,

/**
* @var Type $type
*/
protected Type $type,

/**
* @var AttributeReflection $attributes
*/
protected AttributeReflection $attributes,
) {
}

/**
* @return null|PropertyReflection|TypeInterface
*/
public function getParent(): null|PropertyReflection|TypeInterface
{
return $this->parent;
}

/**
* @return Type
*/
public function getType(): Type
{
return $this->type;
}

/**
* @return AttributeReflection
*/
public function getAttributes(): AttributeReflection
{
return $this->attributes;
}
}
4 changes: 2 additions & 2 deletions src/Reflection/Type/CompoundType.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public function __construct(
throw new InvalidArgumentException('Given type is not a union type.');
}

foreach ($type->getTypes() as $type) {
$this->types[] = TypeFactory::create($type);
foreach ($type->getTypes() as $t) {
$this->types[] = (new TypeFactory)->createFromString($t, $type->getPropertyReflection(), $type);
}
}

Expand Down
79 changes: 22 additions & 57 deletions src/Reflection/Type/SimpleObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,76 +25,57 @@ class SimpleObjectType implements TypeInterface
public function toArray(): array
{
return [
'classType' => self::class,
'simpleObject' => $this->simpleObjectAttr ? [
'class' => $this->simpleObjectAttr->class,
'arguments' => $this->simpleObjectAttr->arguments,
'instance' => var_export($this->simpleObjectAttr->instance, true),
] : null,
'type' => $this->type->toArray(),
'attributes' => $this->attributes->toArray(),
'collection' => $this->collection?->toArray(),
];
}

public static function supports(PropertyReflection $property, Type $type, int $depth): bool
public static function supports(Type $type): bool
{
if (!$type->isClass()) {
return false;
}

foreach ($type->getTypes() as $t) {
if (class_exists($t, false)) {
if (isset(self::NATIVE_SIMPLE_OBJECTS[$t])) {
if (isset(self::NATIVE_SIMPLE_OBJECTS['\\' . ltrim($t, '\\')])) {
return true;
}
$reflection = new ReflectionClass($t);
if ($reflection->getAttributes(SimpleObject::class)) {
if (!empty($reflection->getAttributes(SimpleObject::class))) {
return true;
}
}
}

$index = 0;
$attributes = $property->getAttributes();
do {
$attr = $attributes->getAttributes(SimpleObject::class);
$attributes = $attributes->getAttributes(ApplyToCollectionItems::class)[0] ?? null;
$index++;
} while ($index <= $depth && !empty($attributes?->getAttributes(ApplyToCollectionItems::class)));
return $type->hasAttribute(SimpleObject::class);
}

return !empty($attr);
public static function create(Type $type): static
{
return new static(
$type,
$type->getAttribute(SimpleObject::class)
);
}

public function __construct(
/**
* @var CollectionType|PropertyReflection $parent
*/
protected CollectionType|PropertyReflection $parent,

/**
* @var Type $type of simpleObject main property
*/
protected Type $type,

/**
* @var AttributeReflection $attributes
*/
protected AttributeReflection $attributes,

/**
* @var CollectionType|null $collection if `null`, then property is not collection
* @var null|object{"class": string, "arguments": mixed[], "instance": ?object} $simpleObjectAttr
*/
protected ?CollectionType $collection = null,

/**
* @var ReflectionClass|null $reflection
*/
protected ?ReflectionClass $reflection = null,
protected ?object $simpleObjectAttr,
) {}

/**
* @return CollectionType|PropertyReflection
*/
public function getParent(): CollectionType|PropertyReflection
{
return $this->parent;
}

/**
* @return Type
*/
Expand All @@ -104,26 +85,10 @@ public function getType(): Type
}

/**
* @return AttributeReflection
*/
public function getAttributes(): AttributeReflection
{
return $this->attributes;
}

/**
* @return null|CollectionType
*/
public function getCollection(): ?CollectionType
{
return $this->collection;
}

/**
* @return bool
* @return null|object{"class": string, "arguments": mixed[], "instance": ?object}
*/
public function isCollection(): bool
public function getAttribute(): ?object
{
return $this->collection !== null;
return $this->simpleObjectAttr;
}
}
75 changes: 75 additions & 0 deletions src/Reflection/Type/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace PBaszak\DedicatedMapper\Reflection\Type;

use PBaszak\DedicatedMapper\Attribute\ApplyToCollectionItems;
use PBaszak\DedicatedMapper\Reflection\PropertyReflection;
use phpDocumentor\Reflection\Type as PhpDocumentorType;
use ReflectionType;
Expand Down Expand Up @@ -98,6 +99,16 @@ public function getParent(): null|PropertyReflection|TypeInterface
return $this->parent;
}

public function getPropertyReflection(): null|PropertyReflection
{
$ref = $this;
do {
$ref = $ref->getParent();
} while ($ref instanceof TypeInterface);

return $ref;
}

/**
* @return array<string>
*/
Expand Down Expand Up @@ -193,4 +204,68 @@ public function getPhpDocumentorReflectionType(): null|PhpDocumentorType
{
return $this->phpDocumentorReflectionType;
}

/**
* @param class-string $class
*/
public function hasAttribute(string $class): bool
{
$ref = $this;
$depth = 0;
do {
$ref = $ref->getParent();
$depth++;
} while ($ref instanceof TypeInterface);

if (!$ref) {
return false;
/** @var PropertyReflection $ref */
}

if ($depth > 1) {
$attributes = $ref->getAttributes();
$index = 1;
do {
$attributes = $attributes->getAttribute(ApplyToCollectionItems::class)[0] ?? null;
$index++;
} while ($index <= $depth && !empty($attributes?->getAttribute(ApplyToCollectionItems::class)));
if ($attributes) {
return $attributes->getAttribute()->hasAttribute($class);
}
}

return $ref->getAttributes()->hasAttribute($class);
}

/**
* @param class-string $class
*/
public function getAttribute(string $class): ?object
{
$ref = $this;
$depth = 0;
do {
$ref = $ref->getParent();
$depth++;
} while ($ref instanceof TypeInterface);

if (!$ref) {
return null;
/** @var PropertyReflection $ref */
}

if ($depth > 1) {
$attributes = $ref->getAttributes();
$index = 1;
do {
$attributes = $attributes->getAttributes(ApplyToCollectionItems::class)[0] ?? null;
$index++;
} while ($index <= $depth && !empty($attributes?->getAttributes(ApplyToCollectionItems::class)));
if ($attributes) {
return $attributes->getAttributes()->getAttribute($class);
}
}

return $ref->getAttributes()->getAttribute($class);
}
}
10 changes: 7 additions & 3 deletions src/Reflection/Type/TypeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ protected function createFromPhpDocumentatorType(PhpDocumentorType $type, null|P
$ref->getProperty('class')->setValue($instance, true);
}
}
$types[] = $fqsen ? (string) $fqsen : 'array';
$types[] = isset($fqsen) && null !== $fqsen ? (string) $fqsen : 'array';
$ref->getProperty('collection')->setValue($instance, true);
$ref->getProperty('innerTypes')->setValue($instance, $this->createFromPhpDocumentatorType($type->getValueType(), $instance));
$ref->getProperty('innerType')->setValue($instance, $this->createFromPhpDocumentatorType($type->getValueType(), $instance));
} else {
$t = (string) $type;
if (class_exists($t, false)) {
Expand Down Expand Up @@ -188,6 +188,10 @@ protected function combineTypes(TypeInterface ...$types): TypeInterface

protected function resolveTypeInterface(Type $type): TypeInterface
{
return $type;
foreach (self::AVAILABLE_TYPES_BY_PRIORITY as $typeClass) {
if ($typeClass::supports($type)) {
return $typeClass::create($type);
}
}
}
}
4 changes: 2 additions & 2 deletions src/Reflection/Type/TypeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
interface TypeInterface
{
public function toArray(): array;
// public static function supports(Type $type): bool;
// public static function create(Type $type): TypeInterface;
public static function supports(Type $type): bool;
public static function create(Type $type): TypeInterface;
}

0 comments on commit b2243b3

Please sign in to comment.