mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
commit
715a91d15c
@ -68,6 +68,7 @@ use function file_exists;
|
||||
use function file_get_contents;
|
||||
use function flock;
|
||||
use function fopen;
|
||||
use function function_exists;
|
||||
use function get_class;
|
||||
use function get_defined_constants;
|
||||
use function get_defined_functions;
|
||||
@ -331,6 +332,9 @@ class Config
|
||||
/** @var bool */
|
||||
public $use_igbinary = false;
|
||||
|
||||
/** @var bool */
|
||||
public $use_gzip = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@ -1192,6 +1196,10 @@ class Config
|
||||
$config->use_igbinary = version_compare($igbinary_version, '2.0.5') >= 0;
|
||||
}
|
||||
|
||||
if ($config->use_gzip) {
|
||||
$config->use_gzip = function_exists('gzinflate');
|
||||
}
|
||||
|
||||
if (!isset($config_xml['findUnusedBaselineEntry'])) {
|
||||
$config->config_warnings[] = '"findUnusedBaselineEntry" will be defaulted to "true" in Psalm 6.'
|
||||
. ' You should explicitly enable or disable this setting.';
|
||||
|
92
src/Psalm/Internal/Cache.php
Normal file
92
src/Psalm/Internal/Cache.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Internal;
|
||||
|
||||
use Psalm\Config;
|
||||
use Psalm\Internal\Provider\Providers;
|
||||
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
use function gzdeflate;
|
||||
use function gzinflate;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
use function serialize;
|
||||
use function unlink;
|
||||
use function unserialize;
|
||||
|
||||
use const LOCK_EX;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Cache
|
||||
{
|
||||
private Config $config;
|
||||
|
||||
public bool $use_igbinary;
|
||||
|
||||
public function __construct(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->use_igbinary = $config->use_igbinary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|object|string|null
|
||||
*/
|
||||
public function getItem(string $path)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cache = Providers::safeFileGetContents($path);
|
||||
if ($this->config->use_gzip) {
|
||||
$inflated = @gzinflate($cache);
|
||||
if ($inflated !== false) {
|
||||
$cache = $inflated;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->config->use_igbinary) {
|
||||
/** @var object|false $unserialized */
|
||||
$unserialized = igbinary_unserialize($cache);
|
||||
} else {
|
||||
/** @var object|false $unserialized */
|
||||
$unserialized = @unserialize($cache);
|
||||
}
|
||||
|
||||
return $unserialized !== false ? $unserialized : null;
|
||||
}
|
||||
|
||||
public function deleteItem(string $path): void
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|object|string $item
|
||||
*/
|
||||
public function saveItem(string $path, $item): void
|
||||
{
|
||||
if ($this->config->use_igbinary) {
|
||||
$serialized = igbinary_serialize($item);
|
||||
} else {
|
||||
$serialized = serialize($item);
|
||||
}
|
||||
|
||||
if ($this->config->use_gzip) {
|
||||
$serialized = gzdeflate($serialized);
|
||||
}
|
||||
|
||||
file_put_contents($path, $serialized, LOCK_EX);
|
||||
}
|
||||
|
||||
public function getCacheDirectory(): ?string
|
||||
{
|
||||
return $this->config->getCacheDirectory();
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ class FileReferenceCacheProvider extends InternalFileReferenceCacheProvider
|
||||
|
||||
public function __construct(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function getCachedFileReferences(): ?array
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Psalm\Internal\Provider;
|
||||
|
||||
use Psalm\Config;
|
||||
use Psalm\Internal\Cache;
|
||||
use Psalm\Storage\ClassLikeStorage;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
@ -10,22 +11,16 @@ use UnexpectedValueException;
|
||||
use function array_merge;
|
||||
use function dirname;
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function get_class;
|
||||
use function hash;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
use function is_dir;
|
||||
use function is_null;
|
||||
use function mkdir;
|
||||
use function serialize;
|
||||
use function strtolower;
|
||||
use function unlink;
|
||||
use function unserialize;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const LOCK_EX;
|
||||
use const PHP_VERSION_ID;
|
||||
|
||||
/**
|
||||
@ -33,7 +28,7 @@ use const PHP_VERSION_ID;
|
||||
*/
|
||||
class ClassLikeStorageCacheProvider
|
||||
{
|
||||
private Config $config;
|
||||
private Cache $cache;
|
||||
|
||||
private string $modified_timestamps = '';
|
||||
|
||||
@ -41,7 +36,7 @@ class ClassLikeStorageCacheProvider
|
||||
|
||||
public function __construct(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->cache = new Cache($config);
|
||||
|
||||
$storage_dir = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR;
|
||||
|
||||
@ -64,7 +59,7 @@ class ClassLikeStorageCacheProvider
|
||||
$this->modified_timestamps .= ' ' . filemtime($dependent_file_path);
|
||||
}
|
||||
|
||||
$this->modified_timestamps .= $this->config->computeHash();
|
||||
$this->modified_timestamps .= $config->computeHash();
|
||||
}
|
||||
|
||||
public function writeToCache(ClassLikeStorage $storage, string $file_path, string $file_contents): void
|
||||
@ -80,11 +75,7 @@ class ClassLikeStorageCacheProvider
|
||||
}
|
||||
|
||||
$cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path, true);
|
||||
if ($this->config->use_igbinary) {
|
||||
file_put_contents($cache_location, igbinary_serialize($storage), LOCK_EX);
|
||||
} else {
|
||||
file_put_contents($cache_location, serialize($storage), LOCK_EX);
|
||||
}
|
||||
$this->cache->saveItem($cache_location, $storage);
|
||||
}
|
||||
|
||||
public function getLatestFromCache(
|
||||
@ -118,31 +109,11 @@ class ClassLikeStorageCacheProvider
|
||||
return PHP_VERSION_ID >= 8_01_00 ? hash('xxh128', $data) : hash('md4', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MixedAssignment
|
||||
*/
|
||||
private function loadFromCache(string $fq_classlike_name_lc, ?string $file_path): ?ClassLikeStorage
|
||||
{
|
||||
$cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path);
|
||||
|
||||
if (file_exists($cache_location)) {
|
||||
if ($this->config->use_igbinary) {
|
||||
$storage = igbinary_unserialize(Providers::safeFileGetContents($cache_location));
|
||||
|
||||
if ($storage instanceof ClassLikeStorage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$storage = unserialize(Providers::safeFileGetContents($cache_location));
|
||||
|
||||
if ($storage instanceof ClassLikeStorage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
return null;
|
||||
$storage = $this->cache->getItem($this->getCacheLocationForClass($fq_classlike_name_lc, $file_path));
|
||||
if ($storage instanceof ClassLikeStorage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -153,7 +124,7 @@ class ClassLikeStorageCacheProvider
|
||||
?string $file_path,
|
||||
bool $create_directory = false
|
||||
): string {
|
||||
$root_cache_directory = $this->config->getCacheDirectory();
|
||||
$root_cache_directory = $this->cache->getCacheDirectory();
|
||||
|
||||
if (!$root_cache_directory) {
|
||||
throw new UnexpectedValueException('No cache directory defined');
|
||||
@ -186,6 +157,6 @@ class ClassLikeStorageCacheProvider
|
||||
return $parser_cache_directory
|
||||
. DIRECTORY_SEPARATOR
|
||||
. $file_path_sha
|
||||
. ($this->config->use_igbinary ? '-igbinary' : '');
|
||||
. ($this->cache->use_igbinary ? '-igbinary' : '');
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
namespace Psalm\Internal\Provider;
|
||||
|
||||
use Psalm\Config;
|
||||
use Psalm\Internal\Cache;
|
||||
use Psalm\Storage\FileStorage;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
@ -10,21 +11,14 @@ use UnexpectedValueException;
|
||||
use function array_merge;
|
||||
use function dirname;
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function get_class;
|
||||
use function hash;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
use function serialize;
|
||||
use function strtolower;
|
||||
use function unlink;
|
||||
use function unserialize;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const LOCK_EX;
|
||||
use const PHP_VERSION_ID;
|
||||
|
||||
/**
|
||||
@ -34,13 +28,13 @@ class FileStorageCacheProvider
|
||||
{
|
||||
private string $modified_timestamps = '';
|
||||
|
||||
private Config $config;
|
||||
private Cache $cache;
|
||||
|
||||
private const FILE_STORAGE_CACHE_DIRECTORY = 'file_cache';
|
||||
|
||||
public function __construct(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->cache = new Cache($config);
|
||||
|
||||
$storage_dir = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR;
|
||||
|
||||
@ -64,7 +58,7 @@ class FileStorageCacheProvider
|
||||
$this->modified_timestamps .= ' ' . filemtime($dependent_file_path);
|
||||
}
|
||||
|
||||
$this->modified_timestamps .= $this->config->computeHash();
|
||||
$this->modified_timestamps .= $config->computeHash();
|
||||
}
|
||||
|
||||
public function writeToCache(FileStorage $storage, string $file_contents): void
|
||||
@ -73,11 +67,7 @@ class FileStorageCacheProvider
|
||||
$cache_location = $this->getCacheLocationForPath($file_path, true);
|
||||
$storage->hash = $this->getCacheHash($file_path, $file_contents);
|
||||
|
||||
if ($this->config->use_igbinary) {
|
||||
file_put_contents($cache_location, igbinary_serialize($storage), LOCK_EX);
|
||||
} else {
|
||||
file_put_contents($cache_location, serialize($storage), LOCK_EX);
|
||||
}
|
||||
$this->cache->saveItem($cache_location, $storage);
|
||||
}
|
||||
|
||||
public function getLatestFromCache(string $file_path, string $file_contents): ?FileStorage
|
||||
@ -105,11 +95,7 @@ class FileStorageCacheProvider
|
||||
|
||||
public function removeCacheForFile(string $file_path): void
|
||||
{
|
||||
$cache_path = $this->getCacheLocationForPath($file_path);
|
||||
|
||||
if (file_exists($cache_path)) {
|
||||
unlink($cache_path);
|
||||
}
|
||||
$this->cache->deleteItem($this->getCacheLocationForPath($file_path));
|
||||
}
|
||||
|
||||
private function getCacheHash(string $_unused_file_path, string $file_contents): string
|
||||
@ -121,31 +107,11 @@ class FileStorageCacheProvider
|
||||
return PHP_VERSION_ID >= 8_01_00 ? hash('xxh128', $data) : hash('md4', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MixedAssignment
|
||||
*/
|
||||
private function loadFromCache(string $file_path): ?FileStorage
|
||||
{
|
||||
$cache_location = $this->getCacheLocationForPath($file_path);
|
||||
|
||||
if (file_exists($cache_location)) {
|
||||
if ($this->config->use_igbinary) {
|
||||
$storage = igbinary_unserialize(Providers::safeFileGetContents($cache_location));
|
||||
|
||||
if ($storage instanceof FileStorage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$storage = unserialize(Providers::safeFileGetContents($cache_location));
|
||||
|
||||
if ($storage instanceof FileStorage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
return null;
|
||||
$storage = $this->cache->getItem($this->getCacheLocationForPath($file_path));
|
||||
if ($storage instanceof FileStorage) {
|
||||
return $storage;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -153,7 +119,7 @@ class FileStorageCacheProvider
|
||||
|
||||
private function getCacheLocationForPath(string $file_path, bool $create_directory = false): string
|
||||
{
|
||||
$root_cache_directory = $this->config->getCacheDirectory();
|
||||
$root_cache_directory = $this->cache->getCacheDirectory();
|
||||
|
||||
if (!$root_cache_directory) {
|
||||
throw new UnexpectedValueException('No cache directory defined');
|
||||
@ -188,6 +154,6 @@ class FileStorageCacheProvider
|
||||
return $parser_cache_directory
|
||||
. DIRECTORY_SEPARATOR
|
||||
. $hash
|
||||
. ($this->config->use_igbinary ? '-igbinary' : '');
|
||||
. ($this->cache->use_igbinary ? '-igbinary' : '');
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use JsonException;
|
||||
use PhpParser;
|
||||
use PhpParser\Node\Stmt;
|
||||
use Psalm\Config;
|
||||
use Psalm\Internal\Cache;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
@ -15,8 +16,6 @@ use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function gettype;
|
||||
use function hash;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
use function is_array;
|
||||
use function is_dir;
|
||||
use function is_readable;
|
||||
@ -25,10 +24,8 @@ use function json_decode;
|
||||
use function json_encode;
|
||||
use function mkdir;
|
||||
use function scandir;
|
||||
use function serialize;
|
||||
use function touch;
|
||||
use function unlink;
|
||||
use function unserialize;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
@ -45,7 +42,7 @@ class ParserCacheProvider
|
||||
private const PARSER_CACHE_DIRECTORY = 'php-parser';
|
||||
private const FILE_CONTENTS_CACHE_DIRECTORY = 'file-caches';
|
||||
|
||||
private Config $config;
|
||||
private Cache $cache;
|
||||
|
||||
/**
|
||||
* A map of filename hashes to contents hashes
|
||||
@ -65,7 +62,7 @@ class ParserCacheProvider
|
||||
|
||||
public function __construct(Config $config, bool $use_file_cache = true)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->cache = new Cache($config);
|
||||
$this->use_file_cache = $use_file_cache;
|
||||
}
|
||||
|
||||
@ -92,13 +89,8 @@ class ParserCacheProvider
|
||||
&& is_readable($cache_location)
|
||||
&& filemtime($cache_location) > $file_modified_time
|
||||
) {
|
||||
if ($this->config->use_igbinary) {
|
||||
/** @var list<Stmt> */
|
||||
$stmts = igbinary_unserialize(Providers::safeFileGetContents($cache_location));
|
||||
} else {
|
||||
/** @var list<Stmt> */
|
||||
$stmts = unserialize(Providers::safeFileGetContents($cache_location));
|
||||
}
|
||||
/** @var list<Stmt> $stmts */
|
||||
$stmts = $this->cache->getItem($cache_location);
|
||||
|
||||
return $stmts;
|
||||
}
|
||||
@ -118,13 +110,10 @@ class ParserCacheProvider
|
||||
$cache_location = $this->getCacheLocationForPath($file_path, self::PARSER_CACHE_DIRECTORY);
|
||||
|
||||
if (is_readable($cache_location)) {
|
||||
if ($this->config->use_igbinary) {
|
||||
/** @var list<Stmt> */
|
||||
return igbinary_unserialize(Providers::safeFileGetContents($cache_location)) ?: null;
|
||||
}
|
||||
/** @var list<Stmt> $stmts */
|
||||
$stmts = $this->cache->getItem($cache_location);
|
||||
|
||||
/** @var list<Stmt> */
|
||||
return unserialize(Providers::safeFileGetContents($cache_location)) ?: null;
|
||||
return $stmts;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -138,11 +127,10 @@ class ParserCacheProvider
|
||||
|
||||
$cache_location = $this->getCacheLocationForPath($file_path, self::FILE_CONTENTS_CACHE_DIRECTORY);
|
||||
|
||||
if (is_readable($cache_location)) {
|
||||
return Providers::safeFileGetContents($cache_location);
|
||||
}
|
||||
/** @var string $cache_item */
|
||||
$cache_item = $this->cache->getItem($cache_location);
|
||||
|
||||
return null;
|
||||
return $cache_item;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,7 +143,7 @@ class ParserCacheProvider
|
||||
}
|
||||
|
||||
if ($this->existing_file_content_hashes === null) {
|
||||
$root_cache_directory = $this->config->getCacheDirectory();
|
||||
$root_cache_directory = $this->cache->getCacheDirectory();
|
||||
$file_hashes_path = $root_cache_directory . DIRECTORY_SEPARATOR . self::FILE_HASHES;
|
||||
|
||||
if (!$root_cache_directory) {
|
||||
@ -234,11 +222,7 @@ class ParserCacheProvider
|
||||
if ($touch_only) {
|
||||
touch($cache_location);
|
||||
} else {
|
||||
if ($this->config->use_igbinary) {
|
||||
file_put_contents($cache_location, igbinary_serialize($stmts), LOCK_EX);
|
||||
} else {
|
||||
file_put_contents($cache_location, serialize($stmts), LOCK_EX);
|
||||
}
|
||||
$this->cache->saveItem($cache_location, $stmts);
|
||||
|
||||
$file_cache_key = $this->getParserCacheKey($file_path);
|
||||
$this->new_file_content_hashes[$file_cache_key] = $file_content_hash;
|
||||
@ -267,7 +251,7 @@ class ParserCacheProvider
|
||||
return;
|
||||
}
|
||||
|
||||
$root_cache_directory = $this->config->getCacheDirectory();
|
||||
$root_cache_directory = $this->cache->getCacheDirectory();
|
||||
|
||||
if (!$root_cache_directory) {
|
||||
return;
|
||||
@ -299,13 +283,12 @@ class ParserCacheProvider
|
||||
}
|
||||
|
||||
$cache_location = $this->getCacheLocationForPath($file_path, self::FILE_CONTENTS_CACHE_DIRECTORY, true);
|
||||
|
||||
file_put_contents($cache_location, $file_contents, LOCK_EX);
|
||||
$this->cache->saveItem($cache_location, $file_contents);
|
||||
}
|
||||
|
||||
public function deleteOldParserCaches(float $time_before): int
|
||||
{
|
||||
$cache_directory = $this->config->getCacheDirectory();
|
||||
$cache_directory = $this->cache->getCacheDirectory();
|
||||
|
||||
$this->existing_file_content_hashes = null;
|
||||
$this->new_file_content_hashes = [];
|
||||
@ -346,7 +329,7 @@ class ParserCacheProvider
|
||||
$hash = hash('md4', $file_path);
|
||||
}
|
||||
|
||||
return $hash . ($this->config->use_igbinary ? '-igbinary' : '') . '-r';
|
||||
return $hash . ($this->cache->use_igbinary ? '-igbinary' : '') . '-r';
|
||||
}
|
||||
|
||||
|
||||
@ -355,7 +338,7 @@ class ParserCacheProvider
|
||||
string $subdirectory,
|
||||
bool $create_directory = false
|
||||
): string {
|
||||
$root_cache_directory = $this->config->getCacheDirectory();
|
||||
$root_cache_directory = $this->cache->getCacheDirectory();
|
||||
|
||||
if (!$root_cache_directory) {
|
||||
throw new UnexpectedValueException('No cache directory defined');
|
||||
|
@ -60,7 +60,7 @@ class FakeFileReferenceCacheProvider extends FileReferenceCacheProvider
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = Config::getInstance();
|
||||
parent::__construct(Config::getInstance());
|
||||
}
|
||||
|
||||
public function getCachedFileReferences(): ?array
|
||||
|
Loading…
Reference in New Issue
Block a user