Cache index on disk
parent
8e36e59e9a
commit
69b0a5b0cd
|
@ -2,4 +2,5 @@
|
||||||
.vscode
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
vendor/
|
vendor/
|
||||||
|
.phpls/
|
||||||
composer.lock
|
composer.lock
|
||||||
|
|
|
@ -10,10 +10,12 @@ use LanguageServer\Protocol\{
|
||||||
TextDocumentSyncKind,
|
TextDocumentSyncKind,
|
||||||
Message,
|
Message,
|
||||||
MessageType,
|
MessageType,
|
||||||
InitializeResult
|
InitializeResult,
|
||||||
|
SymbolInformation
|
||||||
};
|
};
|
||||||
use AdvancedJsonRpc;
|
use AdvancedJsonRpc;
|
||||||
use Sabre\Event\Loop;
|
use Sabre\Event\Loop;
|
||||||
|
use JsonMapper;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
|
@ -42,6 +44,12 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
private $protocolWriter;
|
private $protocolWriter;
|
||||||
private $client;
|
private $client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root project path that was passed to initialize()
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $rootPath;
|
||||||
private $project;
|
private $project;
|
||||||
|
|
||||||
public function __construct(ProtocolReader $reader, ProtocolWriter $writer)
|
public function __construct(ProtocolReader $reader, ProtocolWriter $writer)
|
||||||
|
@ -91,6 +99,10 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
*/
|
*/
|
||||||
public function initialize(int $processId, ClientCapabilities $capabilities, string $rootPath = null): InitializeResult
|
public function initialize(int $processId, ClientCapabilities $capabilities, string $rootPath = null): InitializeResult
|
||||||
{
|
{
|
||||||
|
$this->rootPath = $rootPath;
|
||||||
|
|
||||||
|
$this->restoreCache();
|
||||||
|
|
||||||
// start building project index
|
// start building project index
|
||||||
if ($rootPath) {
|
if ($rootPath) {
|
||||||
$this->indexProject($rootPath);
|
$this->indexProject($rootPath);
|
||||||
|
@ -124,7 +136,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
*/
|
*/
|
||||||
public function shutdown()
|
public function shutdown()
|
||||||
{
|
{
|
||||||
|
$this->saveCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,9 +186,62 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
$duration = (int)(microtime(true) - $startTime);
|
$duration = (int)(microtime(true) - $startTime);
|
||||||
$mem = (int)(memory_get_usage(true) / (1024 * 1024));
|
$mem = (int)(memory_get_usage(true) / (1024 * 1024));
|
||||||
$this->client->window->logMessage(MessageType::INFO, "All PHP files parsed in $duration seconds. $mem MiB allocated.");
|
$this->client->window->logMessage(MessageType::INFO, "All PHP files parsed in $duration seconds. $mem MiB allocated.");
|
||||||
|
$this->saveCache();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Loop\setTimeout($processFile, 0);
|
Loop\setTimeout($processFile, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the definition and reference index from the .phpls cache directory, if available
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restoreCache()
|
||||||
|
{
|
||||||
|
$cacheDir = $this->rootPath . '/.phpls';
|
||||||
|
if (is_dir($cacheDir)) {
|
||||||
|
if (file_exists($cacheDir . '/symbols.json')) {
|
||||||
|
$json = json_decode(file_get_contents($cacheDir . '/symbols.json'));
|
||||||
|
$mapper = new JsonMapper;
|
||||||
|
$symbols = $mapper->mapArray($json, [], SymbolInformation::class);
|
||||||
|
$count = count($symbols);
|
||||||
|
$this->project->setSymbols($symbols);
|
||||||
|
$this->client->window->logMessage(MessageType::INFO, "Restoring $count symbols");
|
||||||
|
}
|
||||||
|
if (file_exists($cacheDir . '/references.json')) {
|
||||||
|
$references = json_decode(file_get_contents($cacheDir . '/references.json'), true);
|
||||||
|
$count = array_sum(array_map('count', $references));
|
||||||
|
$this->project->setReferenceUris($references);
|
||||||
|
$this->client->window->logMessage(MessageType::INFO, "Restoring $count references");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->client->window->logMessage(MessageType::INFO, 'No cache found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the definition and reference index to the .phpls cache directory
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function saveCache()
|
||||||
|
{
|
||||||
|
// Cache definitions, references
|
||||||
|
$cacheDir = $this->rootPath . '/.phpls';
|
||||||
|
if (!is_dir($cacheDir)) {
|
||||||
|
mkdir($cacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
$symbols = $this->project->getSymbols();
|
||||||
|
$count = count($symbols);
|
||||||
|
$this->client->window->logMessage(MessageType::INFO, "Saving $count symbols to cache");
|
||||||
|
file_put_contents($cacheDir . "/symbols.json", json_encode($symbols, JSON_UNESCAPED_SLASHES));
|
||||||
|
|
||||||
|
$references = $this->project->getReferenceUris();
|
||||||
|
$count = array_sum(array_map('count', $references));
|
||||||
|
$this->client->window->logMessage(MessageType::INFO, "Saving $count references to cache");
|
||||||
|
file_put_contents($cacheDir . "/references.json", json_encode($references, JSON_UNESCAPED_SLASHES));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,17 @@ class Project
|
||||||
$this->symbols[$fqn] = $symbol;
|
$this->symbols[$fqn] = $symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the SymbolInformation index
|
||||||
|
*
|
||||||
|
* @param SymbolInformation[] $symbols
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setSymbols(array $symbols)
|
||||||
|
{
|
||||||
|
$this->symbols = $symbols;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets the SymbolInformation for a specific symbol
|
* Unsets the SymbolInformation for a specific symbol
|
||||||
* and removes all references pointing to that symbol
|
* and removes all references pointing to that symbol
|
||||||
|
@ -221,6 +232,28 @@ class Project
|
||||||
return array_map([$this, 'getDocument'], $this->references[$fqn]);
|
return array_map([$this, 'getDocument'], $this->references[$fqn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an associative array [string => string[]] that maps fully qualified symbol names
|
||||||
|
* to URIs of the document where the symbol is referenced
|
||||||
|
*
|
||||||
|
* @return string[][]
|
||||||
|
*/
|
||||||
|
public function getReferenceUris()
|
||||||
|
{
|
||||||
|
return $this->references;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the reference index
|
||||||
|
*
|
||||||
|
* @param string[][] $references an associative array [string => string[]] from FQN to URIs
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setReferenceUris(array $references)
|
||||||
|
{
|
||||||
|
$this->references = $references;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the document where a symbol is defined
|
* Returns the document where a symbol is defined
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,7 +21,7 @@ class SymbolInformation
|
||||||
/**
|
/**
|
||||||
* The kind of this symbol.
|
* The kind of this symbol.
|
||||||
*
|
*
|
||||||
* @var number
|
* @var int
|
||||||
*/
|
*/
|
||||||
public $kind;
|
public $kind;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue