From 6b77778dad552760d12def1a1b90d02546a79f4b Mon Sep 17 00:00:00 2001 From: azjezz Date: Sun, 4 Apr 2021 19:22:02 +0100 Subject: [PATCH] introduce more return type providers --- src/Argument.php | 29 +++++++++ .../Iter/Count/FunctionReturnTypeProvider.php | 64 +++++++++++++++++++ .../Iter/First/FunctionReturnTypeProvider.php | 55 ++++++++++++++++ .../Iter/Last/FunctionReturnTypeProvider.php | 59 +++++++++++++++++ .../Str/After/FunctionReturnTypeProvider.php | 44 +++++++++++++ .../Str/Before/FunctionReturnTypeProvider.php | 44 +++++++++++++ .../Str/Chunk/FunctionReturnTypeProvider.php | 56 ++++++++++++++++ .../Lowercase/FunctionReturnTypeProvider.php | 39 +++++++++++ .../Str/Repeat/FunctionReturnTypeProvider.php | 59 +++++++++++++++++ .../Str/Slice/FunctionReturnTypeProvider.php | 35 ++++++++++ .../Str/Splice/FunctionReturnTypeProvider.php | 40 ++++++++++++ .../Str/Split/FunctionReturnTypeProvider.php | 56 ++++++++++++++++ .../Uppercase/FunctionReturnTypeProvider.php | 43 +++++++++++++ .../Optional/FunctionReturnTypeProvider.php | 16 ++--- .../Type/Shape/FunctionReturnTypeProvider.php | 22 ++----- src/Plugin.php | 41 ++++++++++-- 16 files changed, 669 insertions(+), 33 deletions(-) create mode 100644 src/Argument.php create mode 100644 src/EventHandler/Iter/Count/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Iter/First/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Iter/Last/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/After/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Before/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Chunk/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Lowercase/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Repeat/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Slice/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Splice/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Split/FunctionReturnTypeProvider.php create mode 100644 src/EventHandler/Str/Uppercase/FunctionReturnTypeProvider.php diff --git a/src/Argument.php b/src/Argument.php new file mode 100644 index 0000000..be72b38 --- /dev/null +++ b/src/Argument.php @@ -0,0 +1,29 @@ + $arguments + * @param 0|positive-int $index + */ + public static function getType( + array $arguments, + StatementsSource $statements_source, + int $index + ): ?Type\Union { + $argument = $arguments[$index] ?? null; + if (null === $argument) { + return null; + } + + return $statements_source->getNodeTypeProvider()->getType($argument->value); + } +} diff --git a/src/EventHandler/Iter/Count/FunctionReturnTypeProvider.php b/src/EventHandler/Iter/Count/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..2de9898 --- /dev/null +++ b/src/EventHandler/Iter/Count/FunctionReturnTypeProvider.php @@ -0,0 +1,64 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\count', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { + return Type::getInt(); + } + + $array_argument_type = $argument_type->getAtomicTypes()['array'] ?? null; + if (null === $array_argument_type) { + return Type::getInt(); + } + + // non-empty-array/non-empty-list -> positive-int / literal-int + if ($array_argument_type instanceof Type\Atomic\TNonEmptyList) { + $count = $array_argument_type->count; + if (null === $count) { + return Type::getPositiveInt(); + } + + return Type::getInt(false, $count); + } + + if ($array_argument_type instanceof Type\Atomic\TNonEmptyArray) { + $count = $array_argument_type->count; + if (null === $count) { + return Type::getPositiveInt(); + } + + return Type::getInt(false, $count); + } + + // array{foo: bar} -> literal-int(1) + if ($array_argument_type instanceof Type\Atomic\TKeyedArray) { + return Type::getInt(false, count($array_argument_type->properties)); + } + + return Type::getInt(); + } +} diff --git a/src/EventHandler/Iter/First/FunctionReturnTypeProvider.php b/src/EventHandler/Iter/First/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..7168824 --- /dev/null +++ b/src/EventHandler/Iter/First/FunctionReturnTypeProvider.php @@ -0,0 +1,55 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\iter\first', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { + return null; + } + + $array_argument_type = $argument_type->getAtomicTypes()['array'] ?? null; + if (null === $array_argument_type) { + return null; + } + + if ($array_argument_type instanceof Type\Atomic\TNonEmptyArray) { + return clone $array_argument_type->type_params[1]; + } + + if ($array_argument_type instanceof Type\Atomic\TNonEmptyList) { + return clone $array_argument_type->type_param; + } + + if ($array_argument_type instanceof Type\Atomic\TKeyedArray) { + // TODO(azjezz): add support for this once psalm starts enforcing the shape order ( if ever ). + // + // foreach ($properties as $property) { + // return clone $property; + // } + return clone $array_argument_type->getGenericValueType(); + } + + return null; + } +} diff --git a/src/EventHandler/Iter/Last/FunctionReturnTypeProvider.php b/src/EventHandler/Iter/Last/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..6a7a8c8 --- /dev/null +++ b/src/EventHandler/Iter/Last/FunctionReturnTypeProvider.php @@ -0,0 +1,59 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\iter\last', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { + return null; + } + + $array_argument_type = $argument_type->getAtomicTypes()['array'] ?? null; + if (null === $array_argument_type) { + return null; + } + + if ($array_argument_type instanceof Type\Atomic\TNonEmptyArray) { + return clone $array_argument_type->type_params[1]; + } + + if ($array_argument_type instanceof Type\Atomic\TNonEmptyList) { + return clone $array_argument_type->type_param; + } + + if ($array_argument_type instanceof Type\Atomic\TKeyedArray) { + // TODO(azjezz): add support for this once psalm starts enforcing the shape order ( if ever ). + // + // $properties = $array_argument_type->properties; + // $last_property = null; + // foreach ($properties as $property) { + // $last_property = $property; + // } + // + // return clone $last_property; + return clone $array_argument_type->getGenericValueType(); + } + + return null; + } +} diff --git a/src/EventHandler/Str/After/FunctionReturnTypeProvider.php b/src/EventHandler/Str/After/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..34c245c --- /dev/null +++ b/src/EventHandler/Str/After/FunctionReturnTypeProvider.php @@ -0,0 +1,44 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\after', + 'psl\str\after_ci', + 'psl\str\after_last', + 'psl\str\after_last_ci', + 'psl\str\byte\after', + 'psl\str\byte\after_ci', + 'psl\str\byte\after_last', + 'psl\str\byte\after_last_ci', + 'psl\str\grapheme\after', + 'psl\str\grapheme\after_ci', + 'psl\str\grapheme\after_last', + 'psl\str\grapheme\after_last_ci', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if ($argument_type === null || !$argument_type->hasLowercaseString()) { + return Type::combineUnionTypes(Type::getNull(), Type::getString()); + } + + return new Type\Union([new Type\Atomic\TLowercaseString(), new Type\Atomic\TNull()]); + } +} diff --git a/src/EventHandler/Str/Before/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Before/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..b8c4e9a --- /dev/null +++ b/src/EventHandler/Str/Before/FunctionReturnTypeProvider.php @@ -0,0 +1,44 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\before', + 'psl\str\before_ci', + 'psl\str\before_last', + 'psl\str\before_last_ci', + 'psl\str\byte\before', + 'psl\str\byte\before_ci', + 'psl\str\byte\before_last', + 'psl\str\byte\before_last_ci', + 'psl\str\grapheme\before', + 'psl\str\grapheme\before_ci', + 'psl\str\grapheme\before_last', + 'psl\str\grapheme\before_last_ci', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if ($argument_type === null || !$argument_type->hasLowercaseString()) { + return Type::combineUnionTypes(Type::getNull(), Type::getString()); + } + + return new Type\Union([new Type\Atomic\TNull(), new Type\Atomic\TLowercaseString()]); + } +} diff --git a/src/EventHandler/Str/Chunk/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Chunk/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..9e5b4d7 --- /dev/null +++ b/src/EventHandler/Str/Chunk/FunctionReturnTypeProvider.php @@ -0,0 +1,56 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\chunk', + 'psl\str\byte\chunk', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { + // [unknown] -> list + return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString()]))]); + } + + $string_argument_type = $argument_type->getAtomicTypes()['string'] ?? null; + if (null === $string_argument_type) { + // [unknown] -> list + return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString()]))]); + } + + if ($string_argument_type instanceof Type\Atomic\TNonEmptyString) { + // non-empty-lowercase-string => non-empty-list + if ($string_argument_type instanceof Type\Atomic\TNonEmptyLowercaseString) { + return new Type\Union([ + new Type\Atomic\TNonEmptyList(new Type\Union([ + new Type\Atomic\TNonEmptyLowercaseString() + ])) + ]); + } + + // non-empty-string => non-empty-list + return new Type\Union([new Type\Atomic\TNonEmptyList(new Type\Union([new Type\Atomic\TNonEmptyString()]))]); + } + + // string -> list + return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString()]))]); + } +} diff --git a/src/EventHandler/Str/Lowercase/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Lowercase/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..f1adf37 --- /dev/null +++ b/src/EventHandler/Str/Lowercase/FunctionReturnTypeProvider.php @@ -0,0 +1,39 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\lowercase', + 'psl\str\byte\lowercase', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if ($argument_type === null) { + return new Type\Union([new Type\Atomic\TLowercaseString()]); + } + + $string_argument_type = $argument_type->getAtomicTypes()['string'] ?? null; + if ($string_argument_type instanceof Type\Atomic\TNonEmptyString) { + return new Type\Union([new Type\Atomic\TNonEmptyLowercaseString()]); + } + + return new Type\Union([new Type\Atomic\TLowercaseString()]); + } +} diff --git a/src/EventHandler/Str/Repeat/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Repeat/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..0e3900e --- /dev/null +++ b/src/EventHandler/Str/Repeat/FunctionReturnTypeProvider.php @@ -0,0 +1,59 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\repeat', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if ($argument_type === null || !$argument_type->hasLowercaseString()) { + return Type::getString(); + } + + $string_argument_type = $argument_type->getAtomicTypes()['string'] ?? null; + if ($string_argument_type instanceof Type\Atomic\TNonEmptyString) { + if ($string_argument_type instanceof Type\Atomic\TNonEmptyLowercaseString) { + return new Type\Union([new Type\Atomic\TNonEmptyLowercaseString()]); + } + + return new Type\Union([new Type\Atomic\TNonEmptyString()]); + } + + if ($string_argument_type instanceof Type\Atomic\TLowercaseString) { + return new Type\Union([new Type\Atomic\TLowercaseString()]); + } + + if ($string_argument_type instanceof Type\Atomic\TLiteralString) { + $multiplier_argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 1); + if (null !== $multiplier_argument_type && $multiplier_argument_type->hasLiteralInt()) { + /** @psalm-suppress MissingThrowsDocblock */ + return Type::getString(str_repeat( + $string_argument_type->value, + $multiplier_argument_type->getSingleIntLiteral()->value + )); + } + } + + return Type::getString(); + } +} diff --git a/src/EventHandler/Str/Slice/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Slice/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..1a56bdc --- /dev/null +++ b/src/EventHandler/Str/Slice/FunctionReturnTypeProvider.php @@ -0,0 +1,35 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\slice', + 'psl\str\byte\slice', + 'psl\str\grapheme\slice' + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if ($argument_type === null || !$argument_type->hasLowercaseString()) { + return Type::getString(); + } + + return new Type\Union([new Type\Atomic\TLowercaseString()]); + } +} diff --git a/src/EventHandler/Str/Splice/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Splice/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..a6ff178 --- /dev/null +++ b/src/EventHandler/Str/Splice/FunctionReturnTypeProvider.php @@ -0,0 +1,40 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\splice', + 'psl\str\byte\splice', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + $replacement_argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 1); + + if ($argument_type === null || $replacement_argument_type === null) { + return Type::getString(); + } + + if (!$argument_type->hasLowercaseString() || !$replacement_argument_type->hasLowercaseString()) { + return Type::getString(); + } + + return new Type\Union([new Type\Atomic\TLowercaseString()]); + } +} diff --git a/src/EventHandler/Str/Split/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Split/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..ba4025e --- /dev/null +++ b/src/EventHandler/Str/Split/FunctionReturnTypeProvider.php @@ -0,0 +1,56 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\split', + 'psl\str\byte\split', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { + // [unknown] -> list + return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString()]))]); + } + + $string_argument_type = $argument_type->getAtomicTypes()['string'] ?? null; + if (null === $string_argument_type) { + // [unknown] -> list + return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString()]))]); + } + + if ($string_argument_type instanceof Type\Atomic\TNonEmptyString) { + // non-empty-lowercase-string => non-empty-list + if ($string_argument_type instanceof Type\Atomic\TNonEmptyLowercaseString) { + return new Type\Union([ + new Type\Atomic\TNonEmptyList(new Type\Union([ + new Type\Atomic\TNonEmptyLowercaseString() + ])) + ]); + } + + // non-empty-string => non-empty-list + return new Type\Union([new Type\Atomic\TNonEmptyList(new Type\Union([new Type\Atomic\TNonEmptyString()]))]); + } + + // string -> list + return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString()]))]); + } +} diff --git a/src/EventHandler/Str/Uppercase/FunctionReturnTypeProvider.php b/src/EventHandler/Str/Uppercase/FunctionReturnTypeProvider.php new file mode 100644 index 0000000..143dc74 --- /dev/null +++ b/src/EventHandler/Str/Uppercase/FunctionReturnTypeProvider.php @@ -0,0 +1,43 @@ + + */ + public static function getFunctionIds(): array + { + return [ + 'psl\str\uppercase', + 'psl\str\byte\uppercase', + ]; + } + + public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union + { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { + return Type::getString(); + } + + $string_argument_type = $argument_type->getAtomicTypes()['string'] ?? null; + if (null === $string_argument_type) { + return Type::getString(); + } + + if ($string_argument_type instanceof Type\Atomic\TNonEmptyString) { + return new Type\Union([new Type\Atomic\TNonEmptyString()]); + } + + return Type::getString(); + } +} diff --git a/src/EventHandler/Type/Optional/FunctionReturnTypeProvider.php b/src/EventHandler/Type/Optional/FunctionReturnTypeProvider.php index 5a42d67..2c0fbb3 100644 --- a/src/EventHandler/Type/Optional/FunctionReturnTypeProvider.php +++ b/src/EventHandler/Type/Optional/FunctionReturnTypeProvider.php @@ -7,6 +7,7 @@ use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent; use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface; use Psalm\Type; +use Psl\Psalm\Argument; final class FunctionReturnTypeProvider implements FunctionReturnTypeProviderInterface { @@ -22,21 +23,12 @@ public static function getFunctionIds(): array public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union { - $argument = $event->getCallArgs()[0] ?? null; - if (null === $argument) { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { return null; } - $type = $event - ->getStatementsSource() - ->getNodeTypeProvider() - ->getType($argument->value); - - if (null === $type) { - return null; - } - - $clone = clone $type; + $clone = clone $argument_type; $clone->possibly_undefined = true; return $clone; diff --git a/src/EventHandler/Type/Shape/FunctionReturnTypeProvider.php b/src/EventHandler/Type/Shape/FunctionReturnTypeProvider.php index ee96feb..3650a1a 100644 --- a/src/EventHandler/Type/Shape/FunctionReturnTypeProvider.php +++ b/src/EventHandler/Type/Shape/FunctionReturnTypeProvider.php @@ -7,6 +7,7 @@ use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent; use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface; use Psalm\Type; +use Psl\Psalm\Argument; use function array_values; @@ -24,8 +25,8 @@ public static function getFunctionIds(): array public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union { - $argument = $event->getCallArgs()[0] ?? null; - if (null === $argument) { + $argument_type = Argument::getType($event->getCallArgs(), $event->getStatementsSource(), 0); + if (null === $argument_type) { return new Type\Union([new Type\Atomic\TGenericObject('Psl\Type\TypeInterface', [ new Type\Union([ new Type\Atomic\TArray([ @@ -36,21 +37,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev ])]); } - $statements_source = $event->getStatementsSource(); - $type = $statements_source->getNodeTypeProvider()->getType($argument->value); - if (null === $type) { - return new Type\Union([new Type\Atomic\TGenericObject('Psl\Type\TypeInterface', [ - new Type\Union([ - new Type\Atomic\TArray([ - new Type\Union([new Type\Atomic\TArrayKey()]), - new Type\Union([new Type\Atomic\TMixed()]) - ]) - ]) - ])]); - } - - $atomic = $type->getAtomicTypes(); - $argument_shape = $atomic['array'] ?? null; + $argument_shape = $argument_type->getAtomicTypes()['array'] ?? null; if (!$argument_shape instanceof Type\Atomic\TKeyedArray) { return new Type\Union([new Type\Atomic\TGenericObject('Psl\Type\TypeInterface', [ new Type\Union([ @@ -62,6 +49,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev ])]); } + $properties = []; foreach ($argument_shape->properties as $name => $value) { $type = array_values($value->getAtomicTypes())[0] ?? null; diff --git a/src/Plugin.php b/src/Plugin.php index e470905..6f8aa9f 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -4,18 +4,51 @@ namespace Psl\Psalm; +use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface; use Psalm\Plugin\PluginEntryPointInterface; use Psalm\Plugin\RegistrationInterface; use SimpleXMLElement; +use function str_replace; + final class Plugin implements PluginEntryPointInterface { public function __invoke(RegistrationInterface $registration, ?SimpleXMLElement $config = null): void { - require_once __DIR__ . '/EventHandler/Type/Optional/FunctionReturnTypeProvider.php'; - require_once __DIR__ . '/EventHandler/Type/Shape/FunctionReturnTypeProvider.php'; + require_once __DIR__ . '/Argument.php'; + foreach ($this->getHooks() as $hook) { + /** @psalm-suppress UnresolvableInclude */ + require_once __DIR__ . '/' . str_replace([__NAMESPACE__, '\\'], ['', '/'], $hook) . '.php'; + + $registration->registerHooksFromClass($hook); + } + } + + /** + * @return iterable> + */ + private function getHooks(): iterable + { + // Psl\Iter hooks + yield EventHandler\Iter\First\FunctionReturnTypeProvider::class; + yield EventHandler\Iter\Last\FunctionReturnTypeProvider::class; + yield EventHandler\Iter\Count\FunctionReturnTypeProvider::class; + + // Psl\Str hooks + yield EventHandler\Str\After\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Before\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Chunk\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Lowercase\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Repeat\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Repeat\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Repeat\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Slice\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Splice\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Split\FunctionReturnTypeProvider::class; + yield EventHandler\Str\Uppercase\FunctionReturnTypeProvider::class; - $registration->registerHooksFromClass(EventHandler\Type\Optional\FunctionReturnTypeProvider::class); - $registration->registerHooksFromClass(EventHandler\Type\Shape\FunctionReturnTypeProvider::class); + // Psl\Iter hooks + yield EventHandler\Type\Optional\FunctionReturnTypeProvider::class; + yield EventHandler\Type\Shape\FunctionReturnTypeProvider::class; } }