Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rodber committed Dec 10, 2023
1 parent 83a4705 commit b0792bb
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 78 deletions.
25 changes: 24 additions & 1 deletion src/Attributes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Chevere\Parameter\Attributes;

use Chevere\Parameter\Interfaces\ArgumentsInterface;
use LogicException;
use ReflectionFunction;
use ReflectionMethod;
use function Chevere\Parameter\parameterAttr;
Expand Down Expand Up @@ -67,6 +68,9 @@ function genericAttr(string $name): GenericAttr
return parameterAttr($name, $caller);
}

/**
* Get Arguments for an array parameter.
*/
function arrayArguments(string $name): ArgumentsInterface
{
$caller = debug_backtrace(0, 2)[1];
Expand Down Expand Up @@ -95,7 +99,6 @@ function arrayArguments(string $name): ArgumentsInterface

/**
* Validates argument `$name` against attribute rules.
* @throws LogicException
*/
function validate(?string $name = null): void
{
Expand All @@ -120,3 +123,23 @@ function validate(?string $name = null): void
}
$parameters->get($name)->__invoke($arguments[$name]);
}

/**
* Validates `$var` against the return attribute.
*
* @return mixed The validated `$var`.
*/
function returnAttr(mixed $var): mixed
{
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];
$class = $caller['class'] ?? null;
$method = $caller['function'];
$reflection = $class
? new ReflectionMethod($class, $method)
: new ReflectionFunction($method);
/** @var ReflectionAttribute<ReturnAttr> $attribute */
$attribute = $reflection->getAttributes(ReturnAttr::class)[0]

Check failure on line 141 in src/Attributes/functions.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 test on ubuntu-latest

PHPDoc tag @var for variable $attribute contains unknown class Chevere\Parameter\Attributes\ReflectionAttribute.

Check failure on line 141 in src/Attributes/functions.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 test on ubuntu-latest

PHPDoc tag @var for variable $attribute contains unknown class Chevere\Parameter\Attributes\ReflectionAttribute.

Check failure on line 141 in src/Attributes/functions.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 test on ubuntu-latest

PHPDoc tag @var for variable $attribute contains unknown class Chevere\Parameter\Attributes\ReflectionAttribute.
?? throw new LogicException('No return attribute found');

return $attribute->newInstance()->__invoke($var);

Check failure on line 144 in src/Attributes/functions.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 test on ubuntu-latest

Call to method newInstance() on an unknown class Chevere\Parameter\Attributes\ReflectionAttribute.

Check failure on line 144 in src/Attributes/functions.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 test on ubuntu-latest

Call to method newInstance() on an unknown class Chevere\Parameter\Attributes\ReflectionAttribute.

Check failure on line 144 in src/Attributes/functions.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 test on ubuntu-latest

Call to method newInstance() on an unknown class Chevere\Parameter\Attributes\ReflectionAttribute.
}
14 changes: 1 addition & 13 deletions src/ReflectionParameterTyped.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@

final class ReflectionParameterTyped implements ReflectionParameterTypedInterface
{
/**
* @var array<string, string>
*/
public const TYPE_TO_PARAMETER = [
'array' => ArrayParameter::class,
'bool' => BoolParameter::class,
'float' => FloatParameter::class,
'int' => IntParameter::class,
'string' => StringParameter::class,
'object' => ObjectParameter::class,
];

private ReflectionNamedType $type;

private ParameterInterface $parameter;
Expand Down Expand Up @@ -76,7 +64,7 @@ private function getType(): ReflectionNamedType
if ($reflectionType === null) {
throw new TypeError(
(string) message(
'Missing type declaration for parameter %parameter%',
'Missing type declaration for parameter `%parameter%`',
parameter: '$' . $this->reflection->getName()
)
);
Expand Down
114 changes: 51 additions & 63 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,37 +170,21 @@ function assertNamedArgument(
}
}

function reflectionToParameters(ReflectionFunction|ReflectionMethod $functionOrMethod): ParametersInterface
function toParameter(string $type): ParameterInterface
{
$parameters = parameters();
foreach ($functionOrMethod->getParameters() as $reflection) {
$reflectionParameter = new ReflectionParameterTyped($reflection);
$callable = match ($reflection->isOptional()) {
true => 'withOptional',
default => 'withRequired',
};

$parameters = $parameters->{$callable}(
$reflection->getName(),
$reflectionParameter->parameter()
);
$class = TypeInterface::TYPE_TO_PARAMETER[$type]
?? null;
if ($class === null) {
$class = TypeInterface::TYPE_TO_PARAMETER['object'];
$className = $type;
}

return $parameters;
}

function reflectionToReturnParameter(ReflectionFunction|ReflectionMethod $reflection): ParameterInterface
{
$attributes = $reflection->getAttributes(ReturnAttr::class);
if ($attributes === []) {
$type =
throw new LogicException('No `ReturnAttr` attribute found');
$parameter = new $class();
if (isset($className)) {
// @phpstan-ignore-next-line
$parameter = $parameter->withClassName($className);
}

/** @var ReflectionAttribute<ReturnAttr> $attribute */
$attribute = $attributes[0];

return $attribute->newInstance()->parameter();
return $parameter;
}

function arrayFrom(
Expand Down Expand Up @@ -266,26 +250,6 @@ function getType(mixed $variable): string
};
}

/**
* Validates `$var` against the return attribute.
*
* @return mixed The validated `$var`.
*/
function returnAttr(mixed $var): mixed
{
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];
$class = $caller['class'] ?? null;
$method = $caller['function'];
$reflection = $class
? new ReflectionMethod($class, $method)
: new ReflectionFunction($method);
/** @var ReflectionAttribute<ReturnAttr> $attribute */
$attribute = $reflection->getAttributes(ReturnAttr::class)[0]
?? throw new LogicException('No return attribute found');

return $attribute->newInstance()->__invoke($var);
}

/**
* Retrieves a Parameter attribute instance from a function or method parameter.
* @param array<string, string> $caller The result of debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]
Expand All @@ -309,6 +273,46 @@ function parameterAttr(string $parameter, array $caller): ParameterAttributeInte
);
}

/**
* Get Parameters from a function or method reflection.
*/
function reflectionToParameters(ReflectionFunction|ReflectionMethod $reflection): ParametersInterface
{
$parameters = parameters();
foreach ($reflection->getParameters() as $parameter) {
$reflectionParameter = new ReflectionParameterTyped($parameter);
$callable = match ($parameter->isOptional()) {
true => 'withOptional',
default => 'withRequired',
};

$parameters = $parameters->{$callable}(
$parameter->getName(),
$reflectionParameter->parameter()
);
}

return $parameters;
}

/**
* Get a return Parameter from a function or method reflection.
*/
function reflectionToReturnParameter(ReflectionFunction|ReflectionMethod $reflection): ParameterInterface
{
$attributes = $reflection->getAttributes(ReturnAttr::class);
if ($attributes === []) {
$returnType = (string) $reflection->getReturnType();

return toParameter($returnType);
}

/** @var ReflectionAttribute<ReturnAttr> $attribute */
$attribute = $attributes[0];

return $attribute->newInstance()->parameter();
}

function reflectedParameterAttribute(
string $parameter,
ReflectionParameter $reflection,
Expand All @@ -329,19 +333,3 @@ function reflectedParameterAttribute(
(string) message('No parameter attribute for `%name%`', name: $parameter)
);
}

function toParameter(string $type): ParameterInterface
{
$class = TypeInterface::TYPE_TO_PARAMETER[$type]
?? null;
if ($class === null) {
$class = TypeInterface::TYPE_TO_PARAMETER['object'];
$className = $type;
}
$parameter = new $class();
if (isset($className)) {
$parameter = $parameter->withClassName($className);
}

return $parameter;
}
2 changes: 1 addition & 1 deletion tests/src/UsesParameterAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
use function Chevere\Parameter\Attributes\arrayAttr;
use function Chevere\Parameter\Attributes\genericAttr;
use function Chevere\Parameter\Attributes\intAttr;
use function Chevere\Parameter\Attributes\returnAttr;
use function Chevere\Parameter\Attributes\stringAttr;
use function Chevere\Parameter\Attributes\validate;
use function Chevere\Parameter\returnAttr;

final class UsesParameterAttributes
{
Expand Down

0 comments on commit b0792bb

Please sign in to comment.