reflection of function decorators
This commit is contained in:
parent
dcee45e10b
commit
e46fbb3cc0
16
src/Exception/ApplicationException.php
Normal file
16
src/Exception/ApplicationException.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2018 Kacper Donat
|
||||
*
|
||||
* @author Kacper "Kadet" Donat <kacper@kadet.net>
|
||||
*
|
||||
* Full license available in separate LICENSE file
|
||||
*/
|
||||
|
||||
namespace Kadet\Functional\Exception;
|
||||
|
||||
|
||||
class ApplicationException extends FunctionalException
|
||||
{
|
||||
|
||||
}
|
16
src/Exception/FunctionalException.php
Normal file
16
src/Exception/FunctionalException.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2018 Kacper Donat
|
||||
*
|
||||
* @author Kacper "Kadet" Donat <kacper@kadet.net>
|
||||
*
|
||||
* Full license available in separate LICENSE file
|
||||
*/
|
||||
|
||||
namespace Kadet\Functional\Exception;
|
||||
|
||||
|
||||
class FunctionalException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
150
src/Reflection/ReflectionDecoratedFunction.php
Normal file
150
src/Reflection/ReflectionDecoratedFunction.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2018 Kacper Donat
|
||||
*
|
||||
* @author Kacper "Kadet" Donat <kacper@kadet.net>
|
||||
*
|
||||
* Full license available in separate LICENSE file
|
||||
*/
|
||||
|
||||
namespace Kadet\Functional\Reflection;
|
||||
|
||||
|
||||
use function Kadet\Functional\reflect;
|
||||
|
||||
class ReflectionDecoratedFunction extends \ReflectionFunction
|
||||
{
|
||||
public $reflection;
|
||||
public $decorated;
|
||||
|
||||
public function __construct(callable $decorated)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
$this->reflection = reflect($decorated);
|
||||
}
|
||||
|
||||
public function inNamespace()
|
||||
{
|
||||
return $this->reflection->inNamespace();
|
||||
}
|
||||
|
||||
public function isClosure()
|
||||
{
|
||||
return $this->reflection->isVariadic();
|
||||
}
|
||||
|
||||
public function isDeprecated()
|
||||
{
|
||||
return $this->reflection->isDeprecated();
|
||||
}
|
||||
|
||||
public function isInternal()
|
||||
{
|
||||
return $this->reflection->isInternal();
|
||||
}
|
||||
|
||||
public function isUserDefined()
|
||||
{
|
||||
return $this->reflection->isUserDefined();
|
||||
}
|
||||
|
||||
public function getClosureThis()
|
||||
{
|
||||
return $this->reflection->getClosureThis();
|
||||
}
|
||||
|
||||
public function getClosureScopeClass()
|
||||
{
|
||||
return $this->reflection->getClosureScopeClass();
|
||||
}
|
||||
|
||||
public function getDocComment()
|
||||
{
|
||||
return $this->reflection->getDocComment();
|
||||
}
|
||||
|
||||
public function getEndLine()
|
||||
{
|
||||
return $this->reflection->getEndLine();
|
||||
}
|
||||
|
||||
public function getExtension()
|
||||
{
|
||||
return $this->reflection->getExtension();
|
||||
}
|
||||
|
||||
public function getExtensionName()
|
||||
{
|
||||
return $this->reflection->getExtensionName();
|
||||
}
|
||||
|
||||
public function getFileName()
|
||||
{
|
||||
return $this->reflection->getFileName();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->reflection->getName();
|
||||
}
|
||||
|
||||
public function getNamespaceName()
|
||||
{
|
||||
return $this->reflection->getNamespaceName();
|
||||
}
|
||||
|
||||
public function getNumberOfParameters()
|
||||
{
|
||||
return $this->reflection->getNumberOfParameters();
|
||||
}
|
||||
|
||||
public function getNumberOfRequiredParameters()
|
||||
{
|
||||
return $this->reflection->getNumberOfRequiredParameters();
|
||||
}
|
||||
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->reflection->getParameters();
|
||||
}
|
||||
|
||||
public function getReturnType()
|
||||
{
|
||||
return $this->reflection->getReturnType();
|
||||
}
|
||||
|
||||
public function getShortName()
|
||||
{
|
||||
return $this->reflection->getShortName();
|
||||
}
|
||||
|
||||
public function getStartLine()
|
||||
{
|
||||
return $this->reflection->getStartLine();
|
||||
}
|
||||
|
||||
public function getStaticVariables()
|
||||
{
|
||||
return $this->reflection->getStaticVariables();
|
||||
}
|
||||
|
||||
public function hasReturnType()
|
||||
{
|
||||
return $this->reflection->hasReturnType();
|
||||
}
|
||||
|
||||
public function returnsReference()
|
||||
{
|
||||
return $this->reflection->returnsReference();
|
||||
}
|
||||
|
||||
public function isGenerator()
|
||||
{
|
||||
return $this->reflection->isGenerator();
|
||||
}
|
||||
|
||||
public function isVariadic()
|
||||
{
|
||||
return $this->reflection->isVariadic();
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ namespace Kadet\Functional\Reflection;
|
||||
|
||||
use Kadet\Functional\Utils\FixedFunction;
|
||||
|
||||
class ReflectionFixedFunction extends \ReflectionFunction
|
||||
class ReflectionFixedFunction extends ReflectionDecoratedFunction
|
||||
{
|
||||
public function __construct(FixedFunction $function)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ namespace Kadet\Functional\Reflection;
|
||||
use Kadet\Functional\Utils\CurriedFunction;
|
||||
use Kadet\Functional\Utils\PartiallyAppliedFunction;
|
||||
|
||||
class ReflectionPartiallyAppliedFunction extends \ReflectionFunction
|
||||
class ReflectionPartiallyAppliedFunction extends ReflectionDecoratedFunction
|
||||
{
|
||||
public $applied;
|
||||
|
||||
|
@ -32,7 +32,7 @@ class FixedFunction implements Decorator
|
||||
|
||||
public function __invoke(...$args)
|
||||
{
|
||||
return ($this->fixed)($this)(...$args);
|
||||
return apply($this->fixed, $this, ...$args);
|
||||
}
|
||||
|
||||
public function getDecorated()
|
||||
|
@ -21,11 +21,29 @@ function partial(callable $callable, ...$args): PartiallyAppliedFunction
|
||||
|
||||
function apply(callable $callable, ...$args)
|
||||
{
|
||||
$threshold = reflect($callable)->getNumberOfRequiredParameters();
|
||||
try {
|
||||
$reflection = reflect($callable);
|
||||
$required = $reflection->getNumberOfRequiredParameters();
|
||||
$all = $reflection->getNumberOfParameters();
|
||||
|
||||
return count($args) >= $threshold
|
||||
? $callable(...$args)
|
||||
: partial($callable, ...$args);
|
||||
switch (true) {
|
||||
case $reflection->isVariadic():
|
||||
return partial($callable, ...$args);
|
||||
|
||||
case count($args) >= $all:
|
||||
$applied = $callable(...array_slice($args, 0, $all));
|
||||
return is_callable($applied) ? apply($applied, ...array_slice($args, $all)) : $applied;
|
||||
|
||||
case count($args) >= $required:
|
||||
return $callable(...$args);
|
||||
|
||||
default:
|
||||
return partial($callable, ...$args);
|
||||
}
|
||||
} catch (\ReflectionException $exception) {
|
||||
// if cannot gather necessary information for intelligent application just use normal one
|
||||
return $callable(...$args);
|
||||
}
|
||||
}
|
||||
|
||||
function curry(callable $callable, int $threshold = null, ...$args): CurriedFunction
|
||||
|
@ -6,7 +6,6 @@ use Kadet\Functional\Predicate\AllOfPredicate;
|
||||
use Kadet\Functional\Predicate\AnyOfPredicate;
|
||||
use Kadet\Functional\Predicate\ClosurePredicate;
|
||||
use Kadet\Functional\Predicate\ConstantPredicate;
|
||||
use function Kadet\Functional\Predicates\instance;
|
||||
use Kadet\Functional\Reflection\ReflectionFixedFunction;
|
||||
use Kadet\Functional\Reflection\ReflectionPartiallyAppliedFunction;
|
||||
use Kadet\Functional\Utils\FixedFunction;
|
||||
@ -71,7 +70,13 @@ function symbol($name = null)
|
||||
return sprintf("%s(%s)", $name ?: 'symbol', $id);
|
||||
}
|
||||
|
||||
function reflect(callable $callable): \ReflectionFunctionAbstract
|
||||
/**
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return \ReflectionFunction
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
function reflect(callable $callable): \ReflectionFunction
|
||||
{
|
||||
switch (true) {
|
||||
case $callable instanceof PartiallyAppliedFunction:
|
||||
|
Loading…
Reference in New Issue
Block a user