1
0
Fork 0

Cache index on disk

pull/82/head
Felix Becker 2016-10-14 00:27:23 +02:00
parent 8e36e59e9a
commit 69b0a5b0cd
4 changed files with 102 additions and 3 deletions

1
.gitignore vendored
View File

@ -2,4 +2,5 @@
.vscode
.idea
vendor/
.phpls/
composer.lock

View File

@ -10,10 +10,12 @@ use LanguageServer\Protocol\{
TextDocumentSyncKind,
Message,
MessageType,
InitializeResult
InitializeResult,
SymbolInformation
};
use AdvancedJsonRpc;
use Sabre\Event\Loop;
use JsonMapper;
use Exception;
use Throwable;
@ -42,6 +44,12 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
private $protocolWriter;
private $client;
/**
* The root project path that was passed to initialize()
*
* @var string
*/
private $rootPath;
private $project;
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
{
$this->rootPath = $rootPath;
$this->restoreCache();
// start building project index
if ($rootPath) {
$this->indexProject($rootPath);
@ -124,7 +136,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
*/
public function shutdown()
{
$this->saveCache();
}
/**
@ -174,9 +186,62 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$duration = (int)(microtime(true) - $startTime);
$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->saveCache();
}
};
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));
}
}

View File

@ -160,6 +160,17 @@ class Project
$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
* and removes all references pointing to that symbol
@ -221,6 +232,28 @@ class Project
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
*

View File

@ -21,7 +21,7 @@ class SymbolInformation
/**
* The kind of this symbol.
*
* @var number
* @var int
*/
public $kind;