Skip to content

Commit

Permalink
Merge branch 'master' into feature/set-collection
Browse files Browse the repository at this point in the history
  • Loading branch information
EmilyShepherd authored Feb 18, 2017
2 parents 86adffa + 5648aaf commit 5527e9a
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 62 deletions.
212 changes: 174 additions & 38 deletions src/Factory/Reflection/ReflectionCompositeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

use Spaark\CompositeUtils\Factory\BaseFactory;
use Spaark\CompositeUtils\Model\Reflection\ReflectionComposite;
use Spaark\CompositeUtils\Model\Reflection\ReflectionProperty;
use Spaark\CompositeUtils\Model\Reflection\ReflectionMethod;
use Spaark\CompositeUtils\Model\Collection\FixedList;
use Spaark\CompositeUtils\Service\ReflectionCompositeProviderInterface;
use Spaark\CompositeUtils\Service\ReflectionCompositeProvider;
use \ReflectionClass as PHPNativeReflectionClass;
use \ReflectionProperty as PHPNativeReflectionProperty;
use \ReflectionMethod as PHPNativeReflectionMethod;
Expand All @@ -28,6 +33,13 @@ class ReflectionCompositeFactory extends ReflectorFactory
{
const REFLECTION_OBJECT = ReflectionComposite::class;

const PROPERTIES = [
'traits' => [''],
'interfaces' => [''],
'Methods' => ['local'],
'Properties' => ['local', 'required', 'optional', 'built']
];

/**
* @var PHPNativeReflector
*/
Expand All @@ -38,6 +50,11 @@ class ReflectionCompositeFactory extends ReflectorFactory
*/
protected $object;

/**
* @var ReflectionCompositeProviderInterface
*/
protected $provider;

/**
* Creates a new ReflectionCompositeFactory from the given
* classname
Expand All @@ -47,7 +64,28 @@ class ReflectionCompositeFactory extends ReflectorFactory
*/
public static function fromClassName(string $classname)
{
return new static(new PHPNativeReflectionClass($classname));
return new static
(
new PHPNativeReflectionClass($classname),
ReflectionCompositeProvider::getDefault()
);
}

/**
* Constructs the Factory with the given reflector and Composite
* provider
*
* @param PHPNativeReflectionClass $reflect
* @param ReflectionCompositeProviderInterface $provider
*/
public function __construct
(
PHPNativeReflectionClass $reflect,
ReflectionCompositeProviderInterface $provider
)
{
parent::__construct($reflect);
$this->provider = $provider;
}

/**
Expand All @@ -57,10 +95,28 @@ public static function fromClassName(string $classname)
*/
public function build()
{
$file =
(new ReflectionFileFactory($this->reflector->getFileName()))
->build();
$this->initObject();

foreach ($this->reflector->getTraits() as $trait)
{
$this->addInheritance('traits', $trait);
}

if ($parent = $this->reflector->getParentClass())
{
$this->addInheritance('parent', $parent, 'setRawValue');
}

foreach ($this->reflector->getInterfaces() as $interface)
{
$this->addInheritance('interfaces', $interface);
}

$fileName = $this->reflector->getFileName();

$file = (new ReflectionFileFactory($fileName))->build();
$this->accessor->setRawValue('file', $file);

$this->accessor->setRawValue
(
'classname',
Expand All @@ -72,71 +128,151 @@ public function build()
$file->namespaces[$this->reflector->getNamespaceName()]
);

foreach ($this->reflector->getProperties() as $property)
$this->addItems('properties', false, 'Property');
$this->addItems('methods', true, 'Method');

$this->resizeProperties();

return $this->object;
}

/**
* Initialise the object with fixed lists
*/
protected function initObject()
{
foreach (static::PROPERTIES as $name => $prefixes)
{
if ($this->checkIfLocal($property))
$size = count($this->reflector->{'get' . $name}());
foreach ($prefixes as $prefix)
{
$this->buildProperty($property);
$this->accessor->setRawValue
(
$prefix . $name,
new FixedList($size)
);
}
}
}

foreach ($this->reflector->getMethods() as $method)
/**
* Resize the FixedList properties down to their size
*/
protected function resizeProperties()
{
foreach (static::PROPERTIES as $name => $prefixes)
{
if ($this->checkIfLocal($method))
foreach ($prefixes as $prefix)
{
$this->buildMethod($method);
$this->object->{$prefix . $name}->resizeToFull();
}
}

return $this->object;
}

/**
* Uses a ReflectionPropertyFactory to build a ReflectionProperty,
* and adds that to this ReflectionComposite
* Loops through the list methods or properties adding them to the
* Composite
*
* @param PHPNativeReflectionProperty
* @param string $name
* @param bool $checkFile
* @param string $singular
*/
protected function buildProperty
protected function addItems
(
PHPNativeReflectionProperty $reflect
string $name,
bool $checkFile,
string $signular
)
{
$properties = $this->accessor->getRawValue('properties');

$properties[$reflect->getName()] =
(new ReflectionPropertyFactory($reflect))
->build
foreach ($this->reflector->{'get' . $name}() as $item)
{
// We only reflect on methods in userspace
if ($checkFile && !$item->getFileName())
{
continue;
}
// This belongs to a super class, use that definition
// instead
elseif ($item->class !== $this->reflector->getName())
{
$item = $this->provider->get($item->class)
->$name[$item->getName()];
}
// Parse this method
else
{
$factory =
'\Spaark\CompositeUtils\Factory\Reflection'
. '\Reflection' . $signular . 'Factory';
$item = $this->{'build' . $signular}
(
new $factory($item),
$item
);
$this->accessor->rawAddToValue
(
$this->object,
$this->reflector
->getDefaultProperties()[$reflect->getName()]
'local' . ucfirst($name),
$item
);
}

$this->accessor->getRawValue($name)[$item->name] = $item;
}
}

/**
* Adds a super class / interface / trait to this Composite
*
* @param string $group The type of superclass (parent, etc...)
* @param PHPNativeReflectionClass $reflect
* @param string $method
*/
protected function addInheritance
(
string $group,
PHPNativeReflectionClass $reflect,
string $method = 'rawAddToValue'
)
{
// We only reflect on classes within userspace
if ($reflect->getFileName())
{
$item = $this->provider->get($reflect->getName());
$this->accessor->$method($group, $item);
}
}

/**
* Uses a ReflectionMethodFactory to build a ReflectionMethod, and
* adds that to this ReflectionComposite
* Uses a ReflectionPropertyFactory to build a ReflectionProperty
*
* @param PHPNativeReflectionMethod
* @param ReflectionPropertyFactory $factory
* @return ReflectionProperty
*/
protected function buildMethod(PHPNativeReflectionMethod $reflect)
protected function buildProperty
(
ReflectionPropertyFactory $factory,
PHPNativeReflectionProperty $reflect
)
: ReflectionProperty
{
$methods = $this->accessor->getRawValue('methods');
$methods[$reflect->getName()] =
(new ReflectionMethodFactory($reflect))
->build($this->object);
return $factory->build
(
$this->object,
$this->reflector
->getDefaultProperties()[$reflect->getName()]
);
}

/**
* Checks if a property is defined in the class
* Uses a ReflectionMethodFactory to build a ReflectionMethod
*
* @param Reflector $reflector
* @return boolean
* @param ReflectionMethodFactory $factory
* @return ReflectionMethod
*/
protected function checkIfLocal(Reflector $reflector)
protected function buildMethod(ReflectionMethodFactory $factory)
: ReflectionMethod
{
return $reflector->class === $this->reflector->getName();
return $factory->build($this->object);
}
}

2 changes: 1 addition & 1 deletion src/Model/Collection/AbstractList.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function offsetSet($offset, $value)
{
if ($offset === null)
{
$this->push($value);
$this->add($value);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/Model/Collection/ArrayList.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ArrayList extends AbstractList
/**
* {@inheritDoc}
*/
public function push($item)
public function add($item)
{
$this->data[] = $item;
}
Expand Down
30 changes: 29 additions & 1 deletion src/Model/Collection/FixedList.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __construct(int $size = 0)
/**
* {@inheritDoc}
*/
public function push($item)
public function add($item)
{
$this->data[$this->pointer++] = $item;
}
Expand Down Expand Up @@ -102,5 +102,33 @@ public function size() : int
{
return count($this->data);
}

/**
* Resizes the FixedList, throwing away any unused elements
*
* @param int $size The new size
*/
public function resize(int $size)
{
$this->data->setSize($size);
}

/**
* Returns the current pointer position
*
* @return int
*/
public function getCurrentPosition() : int
{
return $this->pointer;
}

/**
* Resizes to the current pointer
*/
public function resizeToFull()
{
$this->resize($this->getCurrentPosition());
}
}

2 changes: 1 addition & 1 deletion src/Model/Collection/ListInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface ListInterface extends CollectionInterface
*
* @param ValueType $item The item to add
*/
public function push($item);
public function add($item);

/**
* Adds a new item at the specified position
Expand Down
Loading

0 comments on commit 5527e9a

Please sign in to comment.