44
55namespace Fp \Psalm \Hook \FunctionReturnTypeProvider ;
66
7+ use Fp \Collections \ArrayList ;
8+ use Fp \Collections \NonEmptyArrayList ;
79use Fp \Collections \NonEmptyHashMap ;
810use Fp \Functional \Either \Either ;
11+ use Fp \Functional \Option \Option ;
912use Fp \Psalm \Util \Sequence \GetEitherTypeParam ;
1013use Fp \PsalmToolkit \Toolkit \CallArg ;
1114use Fp \PsalmToolkit \Toolkit \PsalmApi ;
1821
1922use function Fp \Callable \ctor ;
2023use function Fp \Collection \sequenceOptionT ;
24+ use function Fp \Evidence \of ;
25+ use function Fp \Evidence \proveTrue ;
2126
2227final class SequenceEitherFunctionReturnTypeProvider implements FunctionReturnTypeProviderInterface
2328{
2429 public static function getFunctionIds (): array
2530 {
2631 return [
2732 strtolower ('Fp\Collection\sequenceEither ' ),
33+ strtolower ('Fp\Collection\sequenceEitherT ' ),
2834 ];
2935 }
3036
3137 public static function getFunctionReturnType (FunctionReturnTypeProviderEvent $ event ): ?Union
3238 {
33- return PsalmApi::$ args ->getCallArgs ($ event )
34- ->flatMap (fn ($ args ) => $ args ->head ())
35- ->flatMap (fn (CallArg $ arg ) => PsalmApi::$ types ->asSingleAtomicOf (TKeyedArray::class, $ arg ->type ))
39+ return self ::getInputTypeFromSequenceEither ($ event )
40+ ->orElse (fn () => self ::getInputTypeFromSequenceEitherT ($ event ))
3641 ->flatMap (fn (TKeyedArray $ types ) => sequenceOptionT (
3742 fn () => NonEmptyHashMap::collectNonEmpty ($ types ->properties )
3843 ->traverseOption (GetEitherTypeParam::left (...))
@@ -56,4 +61,29 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
5661 ->map (ctor (Union::class))
5762 ->get ();
5863 }
64+
65+ /**
66+ * @return Option<TKeyedArray>
67+ */
68+ private static function getInputTypeFromSequenceEither (FunctionReturnTypeProviderEvent $ event ): Option
69+ {
70+ return proveTrue (strtolower ('Fp\Collection\sequenceEither ' ) === $ event ->getFunctionId ())
71+ ->flatMap (fn () => PsalmApi::$ args ->getCallArgs ($ event ))
72+ ->flatMap (fn ($ args ) => $ args ->head ())
73+ ->flatMap (fn (CallArg $ arg ) => PsalmApi::$ types ->asSingleAtomic ($ arg ->type ))
74+ ->flatMap (of (TKeyedArray::class));
75+ }
76+
77+ /**
78+ * @return Option<TKeyedArray>
79+ */
80+ private static function getInputTypeFromSequenceEitherT (FunctionReturnTypeProviderEvent $ event ): Option
81+ {
82+ return proveTrue (strtolower ('Fp\Collection\sequenceEitherT ' ) === $ event ->getFunctionId ())
83+ ->flatMap (fn () => PsalmApi::$ args ->getCallArgs ($ event ))
84+ ->flatMap (fn (ArrayList $ args ) => $ args ->toNonEmptyArrayList ())
85+ ->map (fn (NonEmptyArrayList $ args ) => new TKeyedArray (
86+ $ args ->map (fn (CallArg $ arg ) => $ arg ->type )->toNonEmptyList (),
87+ ));
88+ }
5989}
0 commit comments