1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-10 23:18:40 +01:00
psalm/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php
Daniil Gentili d0be59e16e
Immutable unions (#8627)
* Immutable CodeLocation

* Remove excess clones

* Remove external clones

* Remove leftover clones

* Fix final clone issue

* Immutable storages

* Refactoring

* Fixes

* Fixes

* Fix

* Fix

* Fixes

* Simplify

* Fixes

* Fix

* Fixes

* Update

* Fix

* Cache global types

* Fix

* Update

* Update

* Fixes

* Fixes

* Refactor

* Fixes

* Fix

* Fix

* More caching

* Fix

* Fix

* Update

* Update

* Fix

* Fixes

* Update

* Refactor

* Update

* Fixes

* Break one more test

* Fix

* FIx

* Fix

* Fix

* Fix

* Fix

* Improve performance and readability

* Equivalent logic

* Fixes

* Revert

* Revert "Revert"

This reverts commit f9175100c8452c80559234200663fd4c4f4dd889.

* Fix

* Fix reference bug

* Make default TypeVisitor immutable

* Bugfix

* Remove clones

* Partial refactoring

* Refactoring

* Fixes

* Fix

* Fixes

* Fixes

* cs-fix

* Fix final bugs

* Add test

* Misc fixes

* Update

* Fixes

* Experiment with removing different property

* revert "Experiment with removing different property"

This reverts commit ac1156e077fc4ea633530d51096d27b6e88bfdf9.

* Uniform naming

* Uniform naming

* Hack hotfix

* Clean up $_FILES ref #8621

* Undo hack, try fixing properly

* Helper method

* Remove redundant call

* Partially fix bugs

* Cleanup

* Change defaults

* Fix bug

* Fix (?, hope this doesn't break anything else)

* cs-fix

* Review fixes

* Bugfix

* Bugfix

* Improve logic

* Update
2022-11-04 19:04:23 +01:00

142 lines
3.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 $storage = [];
/**
* @var array<string, ClassLikeStorage>
*/
private static $new_storage = [];
/**
* @var ?ClassLikeStorageCacheProvider
*/
public $cache;
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 theres 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 = [];
}
}