/
ClassLikeStorageProvider.php
137 lines (109 loc) · 3.63 KB
/
ClassLikeStorageProvider.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
namespace Psalm\Internal\Provider;
use InvalidArgumentException;
use LogicException;
use Psalm\Storage\ClassLikeStorage;
use function array_merge;
use function strtolower;
/**
* @internal
*/
class ClassLikeStorageProvider
{
/**
* Storing this statically is much faster (at least in PHP 7.2.1)
*
* @var array<string, ClassLikeStorage>
*/
private static array $storage = [];
/**
* @var array<string, ClassLikeStorage>
*/
private static array $new_storage = [];
public ?ClassLikeStorageCacheProvider $cache = null;
public function __construct(?ClassLikeStorageCacheProvider $cache = null)
{
$this->cache = $cache;
}
/**
* @psalm-mutation-free
* @throws InvalidArgumentException when class does not exist
*/
public function get(string $fq_classlike_name): ClassLikeStorage
{
$fq_classlike_name_lc = strtolower($fq_classlike_name);
/** @psalm-suppress ImpureStaticProperty Used only for caching */
if (!isset(self::$storage[$fq_classlike_name_lc])) {
throw new InvalidArgumentException('Could not get class storage for ' . $fq_classlike_name_lc);
}
/** @psalm-suppress ImpureStaticProperty Used only for caching */
return self::$storage[$fq_classlike_name_lc];
}
public function has(string $fq_classlike_name): bool
{
$fq_classlike_name_lc = strtolower($fq_classlike_name);
return isset(self::$storage[$fq_classlike_name_lc]);
}
public function exhume(string $fq_classlike_name, string $file_path, string $file_contents): ClassLikeStorage
{
$fq_classlike_name_lc = strtolower($fq_classlike_name);
if (isset(self::$storage[$fq_classlike_name_lc])) {
return self::$storage[$fq_classlike_name_lc];
}
if (!$this->cache) {
throw new LogicException('Cannot exhume when there’s no cache');
}
$cached_value = $this->cache->getLatestFromCache($fq_classlike_name_lc, $file_path, $file_contents);
self::$storage[$fq_classlike_name_lc] = $cached_value;
self::$new_storage[$fq_classlike_name_lc] = $cached_value;
return $cached_value;
}
/**
* @return array<string, ClassLikeStorage>
*/
public function getAll(): array
{
return self::$storage;
}
/**
* @return array<string, ClassLikeStorage>
*/
public function getNew(): array
{
return self::$new_storage;
}
/**
* @param array<string, ClassLikeStorage> $more
*/
public function addMore(array $more): void
{
self::$new_storage = array_merge(self::$new_storage, $more);
self::$storage = array_merge(self::$storage, $more);
}
public function makeNew(string $fq_classlike_name_lc): void
{
self::$new_storage[$fq_classlike_name_lc] = self::$storage[$fq_classlike_name_lc];
}
public function create(string $fq_classlike_name): ClassLikeStorage
{
$fq_classlike_name_lc = strtolower($fq_classlike_name);
$storage = new ClassLikeStorage($fq_classlike_name);
self::$storage[$fq_classlike_name_lc] = $storage;
self::$new_storage[$fq_classlike_name_lc] = $storage;
return $storage;
}
public function remove(string $fq_classlike_name): void
{
$fq_classlike_name_lc = strtolower($fq_classlike_name);
unset(self::$storage[$fq_classlike_name_lc]);
}
public static function deleteAll(): void
{
self::$storage = [];
self::$new_storage = [];
}
public static function populated(): void
{
self::$new_storage = [];
}
}