generated from php-standard-library/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 5
/
PipeArgumentsProvider.php
97 lines (80 loc) · 2.89 KB
/
PipeArgumentsProvider.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
declare(strict_types=1);
namespace Psl\Psalm\EventHandler\Fun\Pipe;
use Psalm\Plugin\DynamicFunctionStorage;
use Psalm\Plugin\DynamicTemplateProvider;
use Psalm\Plugin\EventHandler\DynamicFunctionStorageProviderInterface;
use Psalm\Plugin\EventHandler\Event\DynamicFunctionStorageProviderEvent;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Union;
use function array_map;
use function count;
use function range;
final class PipeArgumentsProvider implements DynamicFunctionStorageProviderInterface
{
/**
* @return array<lowercase-string>
*/
public static function getFunctionIds(): array
{
return ['psl\fun\pipe'];
}
public static function getFunctionStorage(DynamicFunctionStorageProviderEvent $event): ?DynamicFunctionStorage
{
$template_provider = $event->getTemplateProvider();
$callable_args_count = count($event->getArgs()) - 1;
if ($callable_args_count < 1) {
return null;
}
// All expected callables for pipe
$pipe_callables = array_map(
static fn ($callable_offset) => self::createABCallable($callable_offset, $template_provider),
range(1, $callable_args_count)
);
$pipe_storage = new DynamicFunctionStorage();
$pipe_storage->params = [
// First pipe param
self::createParam(
'pipe_input',
new Union([$template_provider->createTemplate('T1')])
),
// Rest pipe callable params
...array_map(
fn(TCallable $callable, int $offset) => self::createParam(
'fn_' . $offset,
new Union([$callable]),
),
$pipe_callables,
array_keys($pipe_callables)
)
];
// Pipe return type from last callable
$pipe_storage->return_type = $pipe_callables[array_key_last($pipe_callables)]->return_type;
// Pipe template list for each callable
$pipe_storage->templates = array_map(
fn($offset) => $template_provider->createTemplate('T' . $offset),
range(1, $callable_args_count + 1),
);
return $pipe_storage;
}
private static function createABCallable(
int $callable_offset,
DynamicTemplateProvider $template_provider
): TCallable {
$a = self::createParam(
'input',
new Union([
$template_provider->createTemplate('T' . $callable_offset),
])
);
$b = new Union([
$template_provider->createTemplate('T' . ($callable_offset + 1)),
]);
return new TCallable('callable', [$a], $b);
}
private static function createParam(string $name, Union $type): FunctionLikeParameter
{
return new FunctionLikeParameter($name, false, $type);
}
}