mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 12:24:49 +01:00
Remove file map cache when re-analyzing files (#5084)
* Remove file map cache when re-analyzing files When the project is re-analyzed under the single thread condition (not using a process pool), the filemaps are not cleared before re-analyzing files. This means that file maps only get appended to. If you delete the contents of a file via the LSP, the file map will still be populated with all the old values for example. In doing this I had to write a few more tests to check my assumptions too, so adding those additional tests. * Rename test * Formatting * Formatting again!
This commit is contained in:
parent
6c0b2f8cb9
commit
c837535c9d
@ -576,6 +576,11 @@ class Analyzer
|
||||
$i = 0;
|
||||
|
||||
foreach ($this->files_to_analyze as $file_path => $_) {
|
||||
// Remove all current maps for the file, so new analysis doesn't
|
||||
// only append to existing data.
|
||||
unset($this->reference_map[$file_path]);
|
||||
unset($this->type_map[$file_path]);
|
||||
unset($this->argument_map[$file_path]);
|
||||
$analysis_worker($i, $file_path);
|
||||
++$i;
|
||||
|
||||
|
@ -1318,4 +1318,40 @@ class AnalyzedMethodTest extends \Psalm\Tests\TestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testFileMapsUpdated(): void
|
||||
{
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
|
||||
$config = $codebase->config;
|
||||
$config->throw_exception = false;
|
||||
|
||||
$this->file_provider->registerFile('somefile.php', '
|
||||
<?php
|
||||
|
||||
function foo() : void {
|
||||
}
|
||||
|
||||
foo();
|
||||
');
|
||||
|
||||
$codebase->addFilesToAnalyze(['somefile.php' => 'somefile.php']);
|
||||
$codebase->scanFiles();
|
||||
$codebase->analyzer->analyzeFiles($this->project_analyzer, 1, false);
|
||||
|
||||
$maps = $codebase->analyzer->getMapsForFile('somefile.php');
|
||||
|
||||
$this->assertNotEmpty($maps[0]);
|
||||
|
||||
$this->file_provider->setOpenContents('somefile.php', '');
|
||||
|
||||
$codebase->reloadFiles($this->project_analyzer, ['somefile.php']);
|
||||
$codebase->analyzer->analyzeFiles($this->project_analyzer, 1, false);
|
||||
|
||||
$updated_maps = $codebase->analyzer->getMapsForFile('somefile.php');
|
||||
|
||||
$this->assertSame([], $updated_maps[0]);
|
||||
$this->assertSame([], $updated_maps[1]);
|
||||
$this->assertSame([], $updated_maps[2]);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,13 @@ class FakeFileProvider extends \Psalm\Internal\Provider\FileProvider
|
||||
$this->fake_files[$file_path] = $file_contents;
|
||||
}
|
||||
|
||||
public function setOpenContents(string $file_path, string $file_contents): void
|
||||
{
|
||||
if (isset($this->fake_files[strtolower($file_path)])) {
|
||||
$this->fake_files[strtolower($file_path)] = $file_contents;
|
||||
}
|
||||
}
|
||||
|
||||
public function getModifiedTime(string $file_path): int
|
||||
{
|
||||
if (isset($this->fake_file_times[$file_path])) {
|
||||
|
103
tests/LanguageServer/FileMapTest.php
Normal file
103
tests/LanguageServer/FileMapTest.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
namespace Psalm\Tests\LanguageServer;
|
||||
|
||||
use LanguageServerProtocol\Position;
|
||||
use Psalm\Context;
|
||||
use Psalm\Internal\Analyzer\ProjectAnalyzer;
|
||||
use Psalm\Internal\Provider\Providers;
|
||||
use Psalm\Tests\Internal\Provider;
|
||||
use Psalm\Tests\TestConfig;
|
||||
|
||||
class FileMapTest extends \Psalm\Tests\TestCase
|
||||
{
|
||||
public function setUp() : void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->file_provider = new \Psalm\Tests\Internal\Provider\FakeFileProvider();
|
||||
|
||||
$config = new TestConfig();
|
||||
|
||||
$providers = new Providers(
|
||||
$this->file_provider,
|
||||
new \Psalm\Tests\Internal\Provider\ParserInstanceCacheProvider(),
|
||||
null,
|
||||
null,
|
||||
new Provider\FakeFileReferenceCacheProvider(),
|
||||
new \Psalm\Tests\Internal\Provider\ProjectCacheProvider()
|
||||
);
|
||||
|
||||
$this->project_analyzer = new ProjectAnalyzer(
|
||||
$config,
|
||||
$providers
|
||||
);
|
||||
$this->project_analyzer->setPhpVersion('7.3');
|
||||
$this->project_analyzer->getCodebase()->store_node_types = true;
|
||||
}
|
||||
|
||||
public function testMapIsUpdatedOnReloadFiles(): void
|
||||
{
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
$config = $codebase->config;
|
||||
$config->throw_exception = false;
|
||||
|
||||
$this->addFile(
|
||||
'somefile.php',
|
||||
'<?php
|
||||
class A {
|
||||
function __construct( string $var ) {
|
||||
}
|
||||
}
|
||||
$a = new A( "foo" );'
|
||||
);
|
||||
|
||||
$codebase->file_provider->openFile('somefile.php');
|
||||
$codebase->scanFiles();
|
||||
$this->analyzeFile('somefile.php', new Context());
|
||||
[ $type_map ] = $codebase->analyzer->getMapsForFile('somefile.php');
|
||||
|
||||
$this->assertTrue(!empty($type_map));
|
||||
|
||||
$codebase->file_provider->setOpenContents('somefile.php', '');
|
||||
$codebase->reloadFiles($this->project_analyzer, ['somefile.php']);
|
||||
[ $type_map ] = $codebase->analyzer->getMapsForFile('somefile.php');
|
||||
|
||||
$this->assertSame([], $type_map);
|
||||
}
|
||||
|
||||
public function testGetTypeMap(): void
|
||||
{
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
$config = $codebase->config;
|
||||
$config->throw_exception = false;
|
||||
|
||||
$this->addFile(
|
||||
'somefile.php',
|
||||
'<?php
|
||||
class A {
|
||||
function __construct( string $var ) {
|
||||
}
|
||||
}
|
||||
$a = new A( "foo" );'
|
||||
);
|
||||
|
||||
$codebase->file_provider->openFile('somefile.php');
|
||||
$codebase->scanFiles();
|
||||
$this->analyzeFile('somefile.php', new Context());
|
||||
[ $type_map ] = $codebase->analyzer->getMapsForFile('somefile.php');
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
155 => [
|
||||
156,
|
||||
'A',
|
||||
],
|
||||
146 => [
|
||||
148,
|
||||
'146-147:A',
|
||||
],
|
||||
],
|
||||
$type_map
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user