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 .vscode
.idea .idea
vendor/ vendor/
.phpls/
composer.lock composer.lock

View File

@ -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));
}
} }

View File

@ -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
* *

View File

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