55namespace Klimick \PsalmTest \Integration ;
66
77use Closure ;
8+ use Fp \Collections \ArrayList ;
89use PhpParser \Node ;
910use Psalm \Type ;
1011use Psalm \Plugin \EventHandler \Event \FunctionReturnTypeProviderEvent ;
1617use function Fp \Collection \first ;
1718use function Fp \Evidence \proveOf ;
1819
20+ /**
21+ * @internal
22+ */
1923final class Psalm
2024{
2125 /**
22- * @return Closure(Node\Expr | Node\Name | Node\Stmt\Return_): Option<Type\Union>
26+ * @return Option<Type\Union>
2327 */
2428 public static function getType (
2529 MethodReturnTypeProviderEvent | FunctionReturnTypeProviderEvent | AfterExpressionAnalysisEvent $ from ,
26- ): Closure
30+ Node \Expr | Node \Name | Node \Stmt \Return_ $ for ,
31+ ): Option
2732 {
28- $ provider = match (true ) {
29- $ from instanceof MethodReturnTypeProviderEvent => $ from ->getSource ()-> getNodeTypeProvider () ,
30- $ from instanceof FunctionReturnTypeProviderEvent => $ from ->getStatementsSource ()-> getNodeTypeProvider () ,
31- $ from instanceof AfterExpressionAnalysisEvent => $ from ->getStatementsSource ()-> getNodeTypeProvider () ,
33+ $ source = match (true ) {
34+ $ from instanceof MethodReturnTypeProviderEvent => $ from ->getSource (),
35+ $ from instanceof FunctionReturnTypeProviderEvent => $ from ->getStatementsSource (),
36+ $ from instanceof AfterExpressionAnalysisEvent => $ from ->getStatementsSource (),
3237 };
38+ $ provider = $ source ->getNodeTypeProvider ();
3339
34- return fn ( Node \ Expr | Node \ Name | Node \ Stmt \ Return_ $ for ) => Option::fromNullable ($ provider ->getType ($ for ));
40+ return Option::fromNullable ($ provider ->getType ($ for ));
3541 }
3642
3743 /**
38- * @return Closure(Node\Arg|Node\VariadicPlaceholder): Option<Type\Union>
44+ * @return Option<ArrayList< Type\Union> >
3945 */
40- public static function getArgType (MethodReturnTypeProviderEvent | AfterExpressionAnalysisEvent $ from ): Closure
46+ public static function getArgTypes (MethodReturnTypeProviderEvent | FunctionReturnTypeProviderEvent $ from ): Option
4147 {
42- $ getType = self ::getType ($ from );
48+ return ArrayList::collect ($ from ->getCallArgs ())
49+ ->map (fn (Node \Arg $ arg ) => $ arg ->value )
50+ ->everyMap (fn ($ expr ) => self ::getType ($ from , $ expr ));
51+ }
52+
53+ /**
54+ * @return ArrayList<Type\Union>
55+ */
56+ public static function getTemplates (MethodReturnTypeProviderEvent $ from ): ArrayList
57+ {
58+ return ArrayList::collect ($ from ->getTemplateTypeParameters () ?? []);
59+ }
4360
44- return fn (Node \Arg |Node \VariadicPlaceholder $ arg ) => $ arg instanceof Node \Arg
45- ? $ getType ($ arg ->value )
61+ /**
62+ * @return Option<Type\Union>
63+ */
64+ public static function getArgType (
65+ MethodReturnTypeProviderEvent | AfterExpressionAnalysisEvent $ from ,
66+ Node \Arg | Node \VariadicPlaceholder $ for ,
67+ ): Option
68+ {
69+ return $ for instanceof Node \Arg
70+ ? self ::getType ($ from , $ for ->value )
4671 : Option::none ();
4772 }
4873
4974 /**
50- * @return Closure(Type\Union): Option<Type\Atomic>
75+ * @return Option<Type\Atomic>
5176 */
52- public static function asSingleAtomic (): Closure
77+ public static function asSingleAtomic (Type \ Union $ union ): Option
5378 {
54- return fn (Type \Union $ union ) => Option::some ($ union )
55- ->map (fn ($ union ) => $ union ->getAtomicTypes ())
79+ return Option::some ($ union ->getAtomicTypes ())
5680 ->map (fn ($ atomics ) => asList ($ atomics ))
5781 ->filter (fn ($ atomics ) => 1 === count ($ atomics ))
5882 ->flatMap (fn ($ atomics ) => first ($ atomics ));
@@ -61,11 +85,11 @@ public static function asSingleAtomic(): Closure
6185 /**
6286 * @param class-string $of
6387 * @param 0|positive-int $position
64- * @return Closure(Type\Atomic\TGenericObject): Option<Type\Union>
88+ * @return Option<Type\Union>
6589 */
66- public static function getTypeParam (string $ of , int $ position ): Closure
90+ public static function getTypeParam (Type \ Atomic \ TGenericObject $ from , string $ of , int $ position ): Option
6791 {
68- return fn ( Type \ Atomic \ TGenericObject $ generic ) => Option::some ($ generic )
92+ return Option::some ($ from )
6993 ->filter (fn ($ a ) => $ a ->value === $ of )
7094 ->flatMap (fn ($ a ) => at ($ a ->type_params , $ position ));
7195 }
@@ -74,24 +98,10 @@ public static function getTypeParam(string $of, int $position): Closure
7498 * @template TAtomic of Type\Atomic
7599 *
76100 * @param class-string<TAtomic> $class
77- * @return Closure(Type\Union): Option<TAtomic>
78- */
79- public static function asSingleAtomicOf (string $ class ): Closure
80- {
81- $ asSingleAtomic = self ::asSingleAtomic ();
82-
83- return fn (Type \Union $ union ) => $ asSingleAtomic ($ union )
84- ->flatMap (fn (Type \Atomic $ atomic ) => proveOf ($ atomic , $ class ));
85- }
86-
87- /**
88- * @template T
89- *
90- * @param class-string<T> $of
91- * @return Closure(string): Option<class-string<T>>
101+ * @return Option<TAtomic>
92102 */
93- public static function asSubclass (string $ of ): Closure
103+ public static function asSingleAtomicOf (string $ class , Type \ Union $ union ): Option
94104 {
95- return fn ( string $ class ) => Option:: some ( $ class )->filter (fn ($ self ) => is_subclass_of ( $ self , $ of ));
105+ return self :: asSingleAtomic ( $ union )->flatMap (fn (Type \ Atomic $ atomic ) => proveOf ( $ atomic , $ class ));
96106 }
97107}
0 commit comments