1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-16 03:17:02 +01:00
psalm/src/Psalm/Internal/Provider/FileProvider.php
Josh Di Fabio d37cddea27 FileProvider: Consider file open if temp changes
The VS Code LSP client does not always send didOpen messages when a file
is being edited. This causes code completion requests to fail because the
completion request refers to files which are not 'open' according to
FileProvider.

This commit changes FileProvider so that a file is considered 'open' if it is
being modified, even if no didOpen message was received from the LSP
client.
2019-05-17 11:27:45 -04:00

142 lines
3.3 KiB
PHP

<?php
namespace Psalm\Internal\Provider;
class FileProvider
{
/**
* @var array<string, string>
*/
protected $temp_files = [];
/**
* @var array<string, string>
*/
protected $open_files = [];
/**
* @param string $file_path
*
* @return string
*/
public function getContents($file_path, bool $go_to_source = false)
{
if (!$go_to_source && isset($this->temp_files[strtolower($file_path)])) {
return $this->temp_files[strtolower($file_path)];
}
if (isset($this->open_files[strtolower($file_path)])) {
return $this->open_files[strtolower($file_path)];
}
return (string)file_get_contents($file_path);
}
/**
* @param string $file_path
* @param string $file_contents
*
* @return void
*/
public function setContents($file_path, $file_contents)
{
if (isset($this->open_files[strtolower($file_path)])) {
$this->open_files[strtolower($file_path)] = $file_contents;
}
if (isset($this->temp_files[strtolower($file_path)])) {
$this->temp_files[strtolower($file_path)] = $file_contents;
}
file_put_contents($file_path, $file_contents);
}
/**
* @param string $file_path
*
* @return int
*/
public function getModifiedTime($file_path)
{
return (int)filemtime($file_path);
}
/**
* @return void
*/
public function addTemporaryFileChanges(string $file_path, string $new_content)
{
$this->temp_files[strtolower($file_path)] = $new_content;
}
/**
* @return void
*/
public function removeTemporaryFileChanges(string $file_path)
{
unset($this->temp_files[strtolower($file_path)]);
}
/**
* @return void
*/
public function openFile(string $file_path)
{
$this->open_files[strtolower($file_path)] = $this->getContents($file_path, true);
}
/**
* @return bool
*/
public function isOpen(string $file_path)
{
return isset($this->temp_files[strtolower($file_path)]) || isset($this->open_files[strtolower($file_path)]);
}
/**
* @return void
*/
public function closeFile(string $file_path)
{
unset($this->temp_files[strtolower($file_path)]);
unset($this->open_files[strtolower($file_path)]);
}
/**
* @param string $file_path
*
* @return bool
*/
public function fileExists($file_path)
{
return file_exists($file_path);
}
/**
* @param string $dir_path
* @param array<string> $file_extensions
*
* @return array<int, string>
*/
public function getFilesInDir($dir_path, array $file_extensions)
{
$file_paths = [];
/** @var \RecursiveDirectoryIterator */
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir_path));
$iterator->rewind();
while ($iterator->valid()) {
if (!$iterator->isDot()) {
$extension = $iterator->getExtension();
if (in_array($extension, $file_extensions, true)) {
$file_paths[] = (string)$iterator->getRealPath();
}
}
$iterator->next();
}
return $file_paths;
}
}