Skip to content

Commit d4bc879

Browse files
committed
Update internal api
1 parent c00834c commit d4bc879

File tree

8 files changed

+79
-68
lines changed

8 files changed

+79
-68
lines changed

src/Integration/Assertion/Collector/HaveCodeAssertionCollector.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ public static function collect(Assertions $data, AssertionCollectingContext $con
3333
private static function getClosureReturnType(AssertionCollectingContext $context): Option
3434
{
3535
return first($context->assertion_call->args)
36-
->flatMap(Psalm::getArgType($context->event))
37-
->flatMap(Psalm::asSingleAtomicOf(TClosure::class))
36+
->flatMap(fn($arg) => Psalm::getArgType($context->event, $arg))
37+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TClosure::class, $union))
3838
->map(fn($atomic) => $atomic->return_type ?? Type::getVoid());
3939
}
4040

src/Integration/Assertion/Collector/SeePsalmIssuesCollector.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private static function getFormattingArgs(AssertionCollectingContext $context):
4141
{
4242
$formatting_args = Option::do(function() use ($context) {
4343
$issue_args = yield self::getSeePsalmIssueArg($context, position: 2)
44-
->flatMap(Psalm::asSingleAtomicOf(Type\Atomic\TKeyedArray::class));
44+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TKeyedArray::class, $union));
4545

4646
$replacements = [];
4747

@@ -61,7 +61,7 @@ private static function getFormattingArgs(AssertionCollectingContext $context):
6161
private static function getLiteralStringValue(): Closure
6262
{
6363
return fn(Type\Union $atomic) => Option::some($atomic)
64-
->flatMap(Psalm::asSingleAtomicOf(TLiteralString::class))
64+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TLiteralString::class, $union))
6565
->map(fn($atomic) => $atomic->value);
6666
}
6767

@@ -70,7 +70,8 @@ private static function getLiteralStringValue(): Closure
7070
*/
7171
private static function getSeePsalmIssueArg(AssertionCollectingContext $context, int $position): Option
7272
{
73-
return at($context->assertion_call->args, $position)->flatMap(Psalm::getArgType($context->event));
73+
return at($context->assertion_call->args, $position)
74+
->flatMap(fn($arg) => Psalm::getArgType($context->event, $arg));
7475
}
7576

7677
public static function isSupported(AssertionCollectingContext $context): bool

src/Integration/Assertion/Collector/SeeReturnTypeAssertionCollector.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ public static function collect(Assertions $data, AssertionCollectingContext $con
3535
private static function getExpectedReturnType(AssertionCollectingContext $context): Option
3636
{
3737
return first($context->assertion_call->args)
38-
->flatMap(Psalm::getArgType($context->event))
39-
->flatMap(Psalm::asSingleAtomicOf(TGenericObject::class))
40-
->flatMap(Psalm::getTypeParam(StaticTypeInterface::class, position: 0));
38+
->flatMap(fn($arg) => Psalm::getArgType($context->event, $arg))
39+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TGenericObject::class, $union))
40+
->flatMap(fn($generic) => Psalm::getTypeParam($generic, StaticTypeInterface::class, position: 0));
4141
}
4242

4343
/**
@@ -46,8 +46,8 @@ private static function getExpectedReturnType(AssertionCollectingContext $contex
4646
private static function isInvariantCompare(AssertionCollectingContext $context): Option
4747
{
4848
return second($context->assertion_call->args)
49-
->flatMap(Psalm::getArgType($context->event))
50-
->flatMap(Psalm::asSingleAtomic())
49+
->flatMap(fn($arg) => Psalm::getArgType($context->event, $arg))
50+
->flatMap(fn($union) => Psalm::asSingleAtomic($union))
5151
->filter(fn($atomic) => $atomic instanceof TTrue || $atomic instanceof TFalse)
5252
->map(fn($atomic) => match(true) {
5353
$atomic instanceof TTrue => true,

src/Integration/Hook/GenericObjectReturnTypeProvider.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public static function getMethodReturnType(MethodReturnTypeProviderEvent $event)
5050
private static function getTypeConstructor(MethodReturnTypeProviderEvent $event): Option
5151
{
5252
return first($event->getCallArgs())
53-
->flatMap(Psalm::getArgType(from: $event))
54-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TLiteralClassString::class))
53+
->flatMap(fn($arg) => Psalm::getArgType($event, $arg))
54+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TLiteralClassString::class, $union))
5555
->map(fn($atomic) => $atomic->value);
5656
}
5757

@@ -61,8 +61,8 @@ private static function getTypeConstructor(MethodReturnTypeProviderEvent $event)
6161
private static function getTypeParams(MethodReturnTypeProviderEvent $event): Option
6262
{
6363
return second($event->getCallArgs())
64-
->flatMap(Psalm::getArgType(from: $event))
65-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TKeyedArray::class))
64+
->flatMap(fn($arg) => Psalm::getArgType($event, $arg))
65+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TKeyedArray::class, $union))
6666
->filter(fn($keyed_array) => $keyed_array->is_list)
6767
->map(fn($keyed_array) => $keyed_array->properties)
6868
->flatMap(self::collectTypeParams());
@@ -79,8 +79,8 @@ private static function collectTypeParams(): Closure
7979

8080
foreach ($properties as $property) {
8181
$type_param[] = yield Option::some($property)
82-
->flatMap(Psalm::asSingleAtomicOf(class: TGenericObject::class))
83-
->flatMap(Psalm::getTypeParam(of: StaticTypeInterface::class, position: 0));
82+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TGenericObject::class, $union))
83+
->flatMap(fn($generic) => Psalm::getTypeParam($generic, StaticTypeInterface::class, position: 0));
8484
}
8585

8686
return $type_param;

src/Integration/Hook/IntersectionReturnTypeProvider.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ private static function getTypes(MethodReturnTypeProviderEvent $event): Option
5252
{
5353
return Option::do(function() use ($event) {
5454
$keyed_array = yield first($event->getCallArgs())
55-
->flatMap(Psalm::getArgType(from: $event))
56-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TKeyedArray::class))
55+
->flatMap(fn($arg) => Psalm::getArgType($event, $arg))
56+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TKeyedArray::class, $union))
5757
->filter(fn($keyed_array) => $keyed_array->is_list);
5858

5959
$types = [];
6060

6161
foreach ($keyed_array->properties as $property) {
6262
$types[] = yield Option::some($property)
63-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TGenericObject::class))
64-
->flatMap(Psalm::getTypeParam(of: StaticTypeInterface::class, position: 0))
65-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TNamedObject::class));
63+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TGenericObject::class, $union))
64+
->flatMap(fn($generic) => Psalm::getTypeParam($generic, StaticTypeInterface::class, position: 0))
65+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TNamedObject::class, $union));
6666
}
6767

6868
return NonEmptyLinkedList::collectNonEmpty($types);

src/Integration/Hook/ShapeReturnTypeProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ public static function getMethodReturnType(MethodReturnTypeProviderEvent $event)
2727
yield proveTrue('shape' === $event->getMethodNameLowercase());
2828

2929
$arg_type = yield first($event->getCallArgs())
30-
->flatMap(Psalm::getArgType(from: $event))
31-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TKeyedArray::class));
30+
->flatMap(fn($arg) => Psalm::getArgType($event, $arg))
31+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TKeyedArray::class, $union));
3232

3333
$remapped = [];
3434

3535
foreach ($arg_type->properties as $key => $type) {
3636
$remapped[$key] = yield Option::some($type)
37-
->flatMap(Psalm::asSingleAtomicOf(class: Type\Atomic\TGenericObject::class))
38-
->flatMap(Psalm::getTypeParam(of: StaticTypeInterface::class, position: 0));
37+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(Type\Atomic\TGenericObject::class, $union))
38+
->flatMap(fn($generic) => Psalm::getTypeParam($generic, StaticTypeInterface::class, position: 0));
3939
}
4040

4141
$keyed_array = new Type\Atomic\TKeyedArray($remapped);

src/Integration/Hook/TestCaseAnalysis.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ private static function collectAssertions(Assertions $assertions, AssertionColle
120120
private static function getAssertionName(AfterExpressionAnalysisEvent $event, MethodCall $method_call): Option
121121
{
122122
return Option::some($method_call->var)
123-
->flatMap(Psalm::getType($event))
124-
->flatMap(Psalm::asSingleAtomicOf(TNamedObject::class))
123+
->flatMap(fn($expr) => Psalm::getType($event, $expr))
124+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TNamedObject::class, $union))
125125
->filter(fn($a) => $a->value === StaticTestCase::class || $a->value === PsalmCodeBlockFactory::class)
126126
->flatMap(fn() => proveOf($method_call->name, Identifier::class))
127127
->map(fn($id) => $id->name)
@@ -134,7 +134,7 @@ private static function getAssertionName(AfterExpressionAnalysisEvent $event, Me
134134
private static function getTestClass(Context $context): Option
135135
{
136136
return Option::fromNullable($context->self)
137-
->flatMap(Psalm::asSubclass(of: PsalmTest::class));
137+
->filter(fn($self) => is_subclass_of($self, PsalmTest::class));
138138
}
139139

140140
/**
@@ -143,10 +143,10 @@ private static function getTestClass(Context $context): Option
143143
private static function getTestMethod(AfterExpressionAnalysisEvent $event, MethodCall $assertion_call): Option
144144
{
145145
return Option::some($assertion_call)
146-
->flatMap(Psalm::getType($event))
147-
->flatMap(Psalm::asSingleAtomicOf(class: TGenericObject::class))
148-
->flatMap(Psalm::getTypeParam(of: StaticTestCase::class, position: 0))
149-
->flatMap(Psalm::asSingleAtomicOf(class: TLiteralString::class))
146+
->flatMap(fn($expr) => Psalm::getType($event, $expr))
147+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TGenericObject::class, $union))
148+
->flatMap(fn($generic) => Psalm::getTypeParam($generic, StaticTestCase::class, position: 0))
149+
->flatMap(fn($union) => Psalm::asSingleAtomicOf(TLiteralString::class, $union))
150150
->map(fn($literal) => strtolower($literal->value));
151151
}
152152
}

src/Integration/Psalm.php

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Klimick\PsalmTest\Integration;
66

77
use Closure;
8+
use Fp\Collections\ArrayList;
89
use PhpParser\Node;
910
use Psalm\Type;
1011
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
@@ -16,43 +17,66 @@
1617
use function Fp\Collection\first;
1718
use function Fp\Evidence\proveOf;
1819

20+
/**
21+
* @internal
22+
*/
1923
final 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

Comments
 (0)