/
HasIntersectionTrait.php
103 lines (92 loc) · 2.81 KB
/
HasIntersectionTrait.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
98
99
100
101
102
103
<?php
namespace Psalm\Type\Atomic;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Codebase;
trait HasIntersectionTrait
{
/**
* @var array<string, TNamedObject|TTemplateParam|TIterable>|null
*/
public $extra_types;
/**
* @param array<string, string> $aliased_classes
*
* @return string
*/
private function getNamespacedIntersectionTypes(
?string $namespace,
array $aliased_classes,
?string $this_class,
bool $use_phpdoc_format
) {
if (!$this->extra_types) {
return '';
}
return '&' . implode(
'&',
array_map(
/**
* @param TNamedObject|TTemplateParam|TIterable $extra_type
* @return string
*/
function (Atomic $extra_type) use (
$namespace,
$aliased_classes,
$this_class,
$use_phpdoc_format
) {
return $extra_type->toNamespacedString(
$namespace,
$aliased_classes,
$this_class,
$use_phpdoc_format
);
},
$this->extra_types
)
);
}
/**
* @param TNamedObject $type
*
* @return void
*/
public function addIntersectionType(TNamedObject $type)
{
$this->extra_types[$type->getKey()] = $type;
}
/**
* @return array<string, TNamedObject|TTemplateParam|TIterable>|null
*/
public function getIntersectionTypes()
{
return $this->extra_types;
}
/**
* @param array<string, array<string, array{Type\Union, 1?:int}>> $template_types
*
* @return void
*/
public function replaceIntersectionTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase)
{
if (!$this->extra_types) {
return;
}
$new_types = [];
foreach ($this->extra_types as $extra_type) {
if ($extra_type instanceof TTemplateParam && isset($template_types[$extra_type->param_name])) {
$template_type = clone $template_types[$extra_type->param_name][$extra_type->defining_class ?: ''][0];
foreach ($template_type->getTypes() as $template_type_part) {
if ($template_type_part instanceof TNamedObject) {
$new_types[$template_type_part->getKey()] = $template_type_part;
}
}
} else {
$extra_type->replaceTemplateTypesWithArgTypes($template_types, $codebase);
$new_types[$extra_type->getKey()] = $extra_type;
}
}
$this->extra_types = $new_types;
}
}