From 0693dc5d6cee30150f41d38f2c4cbc014aff7e81 Mon Sep 17 00:00:00 2001 From: Tim MacDonald Date: Sat, 18 May 2024 16:56:58 +1000 Subject: [PATCH] Update types --- src/HasParameters.php | 99 ++++++++++++++++++++------- tests/HasParametersTest.php | 8 +++ tests/Middleware/Aliased.php | 3 + tests/Middleware/OptionalRequired.php | 1 + 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/src/HasParameters.php b/src/HasParameters.php index e7d4232..371ff5c 100644 --- a/src/HasParameters.php +++ b/src/HasParameters.php @@ -12,7 +12,7 @@ trait HasParameters { /** - * @param array $arguments + * @param Collection|array $arguments */ public static function with($arguments): string { @@ -22,10 +22,7 @@ public static function with($arguments): string self::validateArgumentMapIsAnAssociativeArray($arguments); - $aliases = new Collection( - /** @phpstan-ignore-next-line */ - static::parameterAliasMap() - ); + $aliases = new Collection(self::parameterAliasMap()); if ($aliases->isNotEmpty()) { self::validateAliasesReferenceParameters($parameters, $aliases); @@ -39,15 +36,18 @@ public static function with($arguments): string self::validateNoUnexpectedArguments($parameters, $arguments); - self::validateParametersAreOptional($parameters->diffKeys($arguments)); + self::validateParametersAreOptional( + /** @phpstan-ignore argument.type */ + $parameters->diffKeys($arguments) + ); - $arguments = self::parseArgumentMap($parameters, new Collection($arguments)); + $arguments = self::parseArgumentMap($parameters, $arguments); return self::formatArguments($arguments); } /** - * @param array $arguments + * @param Collection|array $arguments */ public static function in($arguments): string { @@ -76,6 +76,9 @@ protected static function parameterAliasMap(): array ]; } + /** + * @param Collection $arguments + */ private static function formatArguments(Collection $arguments): string { if ($arguments->isEmpty()) { @@ -85,27 +88,32 @@ private static function formatArguments(Collection $arguments): string return static::class.':'.$arguments->implode(','); } + /** + * @param Collection $arguments + * @return Collection + */ private static function parseArgumentList(Collection $arguments): Collection { - return $arguments->map( - /** - * @param mixed $argument - */ - static function ($argument): string { - return self::castToString($argument); - } - ); + return $arguments->map(function ($argument): string { + return self::castToString($argument); + }); } + /** + * @param Collection $parameters + * @param Collection $arguments + * @return Collection + */ private static function parseArgumentMap(Collection $parameters, Collection $arguments): Collection { - return $parameters->map(static function (ReflectionParameter $parameter) use ($arguments): ?string { + /** @phpstan-ignore return.type */ + return $parameters->map(function (ReflectionParameter $parameter) use ($arguments): ?string { if ($parameter->isVariadic()) { return self::parseVariadicArgument($parameter, $arguments); } return self::parseStandardArgument($parameter, $arguments); - })->reject(static function (?string $argument): bool { + })->reject(function (?string $argument): bool { /** * A null value indicates that the last item in the parameter list * is a variadic function that is not expecting any values. Because @@ -117,12 +125,16 @@ private static function parseArgumentMap(Collection $parameters, Collection $arg }); } + /** + * @param Collection $arguments + */ private static function parseVariadicArgument(ReflectionParameter $parameter, Collection $arguments): ?string { if (! $arguments->has($parameter->getName())) { return null; } + /** @phpstan-ignore argument.type */ $values = new Collection($arguments->get($parameter->getName())); if ($values->isEmpty()) { @@ -133,12 +145,15 @@ private static function parseVariadicArgument(ReflectionParameter $parameter, Co /** * @param mixed $value */ - static function ($value) { + function ($value) { return self::castToString($value); } )->implode(','); } + /** + * @param Collection $arguments + */ private static function parseStandardArgument(ReflectionParameter $parameter, Collection $arguments): string { if ($arguments->has($parameter->getName())) { @@ -148,13 +163,16 @@ private static function parseStandardArgument(ReflectionParameter $parameter, Co return self::castToString($parameter->getDefaultValue()); } + /** + * @return Collection + */ private static function parameters(): Collection { $handle = new ReflectionMethod(static::class, 'handle'); return Collection::make($handle->getParameters()) - ->slice(2) - ->keyBy(static function (ReflectionParameter $parameter): string { + ->skip(2) + ->keyBy(function (ReflectionParameter $parameter): string { return $parameter->getName(); }); } @@ -169,17 +187,23 @@ private static function castToString($value): string } if ($value instanceof BackedEnum) { - return $value->value; + return (string) $value->value; } + /** @phpstan-ignore cast.string */ return (string) $value; } + /** + * @param Collection $arguments + * @param Collection $aliases + * @return Collection + */ private static function normaliseArguments(Collection $arguments, Collection $aliases): Collection { return $arguments->mapWithKeys( /** @param mixed $value */ - static function ($value, string $name) use ($aliases): array { + function ($value, string $name) use ($aliases): array { if ($aliases->has($name)) { /** @var string */ $newName = $aliases[$name]; @@ -192,10 +216,13 @@ static function ($value, string $name) use ($aliases): array { ); } + /** + * @param Collection $parameters + */ private static function validateParametersAreOptional(Collection $parameters): void { /** @var ?ReflectionParameter */ - $missingRequiredParameter = $parameters->reject(static function (ReflectionParameter $parameter): bool { + $missingRequiredParameter = $parameters->reject(function (ReflectionParameter $parameter): bool { return $parameter->isDefaultValueAvailable() || $parameter->isVariadic(); })->first(); @@ -206,6 +233,9 @@ private static function validateParametersAreOptional(Collection $parameters): v throw new TypeError('Missing required argument $'.$missingRequiredParameter->getName().' for middleware '.static::class.'::handle()'); } + /** + * @param Collection $arguments + */ private static function validateArgumentListIsNotAnAssociativeArray(Collection $arguments): void { if (Arr::isAssoc($arguments->all())) { @@ -213,6 +243,9 @@ private static function validateArgumentListIsNotAnAssociativeArray(Collection $ } } + /** + * @param Collection $arguments + */ private static function validateArgumentMapIsAnAssociativeArray(Collection $arguments): void { if ($arguments->isNotEmpty() && ! Arr::isAssoc($arguments->all())) { @@ -220,11 +253,15 @@ private static function validateArgumentMapIsAnAssociativeArray(Collection $argu } } + /** + * @param Collection $parameters + * @param Collection $arguments + */ private static function validateNoUnexpectedArguments(Collection $parameters, Collection $arguments): void { /** @var ?string */ $unexpectedArgument = $arguments->keys() - ->first(static function (string $name) use ($parameters): bool { + ->first(function (string $name) use ($parameters): bool { return ! $parameters->has($name); }); @@ -235,6 +272,10 @@ private static function validateNoUnexpectedArguments(Collection $parameters, Co throw new TypeError('Unknown argument $'.$unexpectedArgument.' passed to middleware '.static::class.'::handle()'); } + /** + * @param Collection $arguments + * @param Collection $aliases + */ private static function validateOriginalAndAliasHaveNotBeenPassed(Collection $arguments, Collection $aliases): void { if ($arguments->intersectByKeys($aliases->flip())->isNotEmpty()) { @@ -242,6 +283,9 @@ private static function validateOriginalAndAliasHaveNotBeenPassed(Collection $ar } } + /** + * @param Collection $aliases + */ private static function validateAliasesDontPointToSameParameters(Collection $aliases): void { if ($aliases->unique()->count() !== $aliases->count()) { @@ -249,8 +293,13 @@ private static function validateAliasesDontPointToSameParameters(Collection $ali } } + /** + * @param Collection $parameters + * @param Collection $aliases + */ private static function validateAliasesReferenceParameters(Collection $parameters, Collection $aliases): void { + /** @phpstan-ignore argument.type */ if ($aliases->flip()->diffKeys($parameters)->isNotEmpty()) { throw new TypeError('Aliases must reference existing parameters.'); } diff --git a/tests/HasParametersTest.php b/tests/HasParametersTest.php index be575c7..41a132d 100644 --- a/tests/HasParametersTest.php +++ b/tests/HasParametersTest.php @@ -123,6 +123,7 @@ public function testListDoesNotAcceptAssociativeArray(): void $this->expectException(TypeError::class); $this->expectExceptionMessage('Expected a non-associative array in HasParameters::in() but received an associative array. You should use the HasParameters::with() method instead.'); + /** @phpstan-ignore argument.type */ Basic::in(['framework' => 'laravel']); } @@ -305,6 +306,7 @@ public function testMapDoesNotAcceptANonAssociativeArray(): void $this->expectException(TypeError::class); $this->expectExceptionMessage('Expected an associative array in HasParameters::with() but received a non-associative array. You should use the HasParameters::in() method instead.'); + /** @phpstan-ignore argument.type */ Basic::with(['framework', 'laravel']); } @@ -362,6 +364,9 @@ public function handle(Request $request, Closure $next, string $original, string // } + /** + * @return array + */ private static function parameterAliasMap(): array { return [ @@ -392,6 +397,9 @@ public function handle(Request $request, Closure $next, string $original): void // } + /** + * @return array + */ private static function parameterAliasMap(): array { return [ diff --git a/tests/Middleware/Aliased.php b/tests/Middleware/Aliased.php index 1abf2a9..4505e64 100644 --- a/tests/Middleware/Aliased.php +++ b/tests/Middleware/Aliased.php @@ -15,6 +15,9 @@ public function handle(Request $request, Closure $next, string $originalFirst, s // } + /** + * @return array + */ private static function parameterAliasMap(): array { return [ diff --git a/tests/Middleware/OptionalRequired.php b/tests/Middleware/OptionalRequired.php index 8a22c85..1e2b98e 100644 --- a/tests/Middleware/OptionalRequired.php +++ b/tests/Middleware/OptionalRequired.php @@ -12,6 +12,7 @@ class OptionalRequired { use HasParameters; + /** @phpstan-ignore parameter.requiredAfterOptional */ public function handle(Request $request, Closure $next, string $optional = 'default', string $required): void { //