Skip to content

Commit

Permalink
Remove collection traits and improve annotation handling
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHash committed Jul 14, 2020
1 parent 5613e1c commit 3c05f78
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 146 deletions.
16 changes: 8 additions & 8 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/TextList.php
Expand Up @@ -9,7 +9,7 @@
namespace Daikon\ValueObject;

/**
* @type Daikon\ValueObject\Text::fromNative
* @type(Daikon\ValueObject\Text)
*/
final class TextList extends ValueObjectList
{
Expand Down
2 changes: 1 addition & 1 deletion src/TextMap.php
Expand Up @@ -9,7 +9,7 @@
namespace Daikon\ValueObject;

/**
* @type Daikon\ValueObject\Text::fromNative
* @type(Daikon\ValueObject\Text)
*/
final class TextMap extends ValueObjectMap
{
Expand Down
76 changes: 18 additions & 58 deletions src/ValueObjectCollectionTrait.php
Expand Up @@ -9,42 +9,35 @@
namespace Daikon\ValueObject;

use Daikon\Interop\Assertion;
use Daikon\Interop\InvalidArgumentException;
use ReflectionClass;
use Daikon\Interop\SupportsAnnotations;

/**
* @type(Daikon\ValueObject\ValueObjectInterface)
*/
trait ValueObjectCollectionTrait
{
public function __construct(iterable $objects = [])
{
$validTypes = array_keys(static::getTypeFactories());
$this->init($objects, $validTypes);
}
use SupportsAnnotations;

/** @return static */
public static function makeEmpty(): self
{
return new static;
}

public function isEmpty(): bool
{
return count($this) === 0;
}

/** @param static $comparator */
public function equals($comparator): bool
{
$this->assertInitialized();
/**
* @psalm-suppress RedundantConditionGivenDocblockType
* @psalm-suppress DocblockTypeContradiction
*/
Assertion::isInstanceOf(
$comparator,
static::class,
sprintf(
"Invalid comparator type '%s' given to ".static::class,
is_object($comparator) ? get_class($comparator) : @gettype($comparator)
)
);
Assertion::isInstanceOf($comparator, static::class);

/** @var ValueObjectInterface $object */
foreach ($this as $index => $object) {
$comparison = $comparator->get($index, null);
foreach ($this as $key => $object) {
$comparison = $comparator->get($key, null);
if (!$comparison || !$object->equals($comparison)) {
return false;
}
Expand All @@ -60,17 +53,9 @@ public function equals($comparator): bool
public static function fromNative($state): self
{
Assertion::nullOrIsTraversable($state, 'State provided to '.static::class.' must be null or iterable.');
$typeFactories = static::getTypeFactories();
// Override fromNative() to support multiple types
Assertion::count($typeFactories, 1, sprintf("Only 1 @type annotation is supported by '%s'.", static::class));
/** @var array $typeFactory */
$typeFactory = current($typeFactories);
Assertion::isCallable($typeFactory, sprintf(
"@type factory '%s' is not callable in '%s'.",
implode('::', $typeFactory),
static::class
));

// Override fromNative() to support multiple types, currently first seen type factory is used.
$typeFactory = current(static::inferTypeFactories());
Assertion::isCallable($typeFactory, 'No valid type factory specified.');
$objects = [];
if (!is_null($state)) {
foreach ($state as $key => $data) {
Expand All @@ -81,8 +66,7 @@ public static function fromNative($state): self
return new static($objects);
}

/** @return array */
public function toNative()
public function toNative(): array
{
$this->assertInitialized();
$objects = [];
Expand All @@ -101,28 +85,4 @@ public function __toString(): string
}
return implode(', ', $parts);
}

private static function getTypeFactories(): array
{
$classReflection = new ReflectionClass(static::class);
if (!preg_match_all('#@type\s+(?<type>.+)#', (string)$classReflection->getDocComment(), $matches)) {
throw new InvalidArgumentException(sprintf("Missing @type annotation on '%s'.", static::class));
}

$callables = [];
foreach ($matches['type'] as $type) {
$callable = array_map('trim', explode('::', $type));
Assertion::keyNotExists(
$callables,
$callable[0],
sprintf("Ambiguous @type annotation for '$callable[0]' in '%s'.", static::class)
);
if (!isset($callable[1])) {
$callable[1] = 'fromNative';
}
$callables[$callable[0]] = $callable;
}

return $callables;
}
}
15 changes: 10 additions & 5 deletions src/ValueObjectList.php
Expand Up @@ -8,10 +8,15 @@

namespace Daikon\ValueObject;

/**
* @type Daikon\ValueObject\ValueObjectInterface
*/
class ValueObjectList implements ValueObjectListInterface
use Daikon\DataStructure\TypedList;
use Daikon\Interop\MakeEmptyInterface;

class ValueObjectList extends TypedList implements MakeEmptyInterface, ValueObjectInterface
{
use ValueObjectListTrait;
use ValueObjectCollectionTrait;

public function __construct(iterable $objects = [])
{
$this->init($objects, static::inferValidTypes());
}
}
16 changes: 0 additions & 16 deletions src/ValueObjectListInterface.php

This file was deleted.

17 changes: 0 additions & 17 deletions src/ValueObjectListTrait.php

This file was deleted.

15 changes: 10 additions & 5 deletions src/ValueObjectMap.php
Expand Up @@ -8,10 +8,15 @@

namespace Daikon\ValueObject;

/**
* @type Daikon\ValueObject\ValueObjectInterface
*/
class ValueObjectMap implements ValueObjectMapInterface
use Daikon\DataStructure\TypedMap;
use Daikon\Interop\MakeEmptyInterface;

class ValueObjectMap extends TypedMap implements MakeEmptyInterface, ValueObjectInterface
{
use ValueObjectMapTrait;
use ValueObjectCollectionTrait;

public function __construct(iterable $objects = [])
{
$this->init($objects, static::inferValidTypes());
}
}
16 changes: 0 additions & 16 deletions src/ValueObjectMapInterface.php

This file was deleted.

17 changes: 0 additions & 17 deletions src/ValueObjectMapTrait.php

This file was deleted.

2 changes: 1 addition & 1 deletion tests/Fixture/DateList.php
Expand Up @@ -11,7 +11,7 @@
use Daikon\ValueObject\ValueObjectList;

/**
* @type Daikon\ValueObject\Date::fromNative
* @type(Daikon\ValueObject\Date::fromNative)
*/
final class DateList extends ValueObjectList
{
Expand Down
2 changes: 1 addition & 1 deletion tests/Fixture/DateMap.php
Expand Up @@ -11,7 +11,7 @@
use Daikon\ValueObject\ValueObjectMap;

/**
* @type Daikon\ValueObject\Date
* @type(Daikon\ValueObject\Date)
*/
final class DateMap extends ValueObjectMap
{
Expand Down

0 comments on commit 3c05f78

Please sign in to comment.